アップルvs司法省 独占禁止法訴訟の判決読んだ感想

Appleが、電子書籍の価格のカルテルに中心的な働きをしたとして、独占禁止法(シャーマン法第1条)に違反したとして、司法省と争っていて、Appleが敗訴したという件。

最初、このニュースを聴いた時に、アップルがなぜ敗訴したのか理解できませんでした。
関連記事を探して読んでも、すっきりとした説明がされているものがなく、仕方がないので、判決原文を読んでみました。

http://dockets.justia.com/docket/new-york/nysdce/1:2012cv02826/394628/
※このページに判決や、関連文書が整理されています。今回読んだのは、Document 326 。

読み終えてみたものの、やっぱり腑に落ちるものではなく、疑問が広がってしまいました。

自分の理解の整理も兼ねて、まとめてみました。
米国独禁法については、かなりの新参者なので、誤解している点などありましたら、ご指摘いただけると励みになります。

【ザックリとした判決概要】

AppleiPad と iBookStore で電子書籍業界に参入するまで、電子書籍の価格は平均して$8-$9程度で推移していたのに、Appleの参入後、その平均価格が上昇した。
特に新刊書籍の価格は、Amazonが一律$9.99で販売していたものが、Apple参入後は$12.99 / $14.99 に上昇。
これは、出版社による共謀があったためで、Appleが、その共謀の中心的役割を果たした。
出版社とAppleが共謀したことは、米国独禁法(シャーマン法第1条)に違反する。


【背景】

Amazon は、電子書籍・紙の書籍、どちらについても wholesaleモデルで販売していました。

wholesaleモデルとは、Amazonが出版社から、書籍を買い取り、自分のリスクで値段を決めて、販売する方式。
この場合、出版社は Amazonに対して、「希望小売価格」を伝えることはできるが、実際に販売する金額(「再販価格」とか "Retail Price"とか言います。)は、Amazonが自由に決定できます。この場合、出版社が小売価格を強制することは、独占禁止法で禁止されている。(「再販価格維持行為」とか "Retail Price Maintenance"とか言います。)

余談ですが、日本では書籍については「再販価格維持制度」が特別に認められています。

Apple は、ここに agency モデルを持ち込みました。agency モデルでは、Appleは、iBookstore という売り場を提供するだけで、法的な意味での「売主」は出版社になります。売上に応じた「手数料」が、出版社からAppleに支払われます。
出版社が売主なので、いくらで売るかは、出版社が自由に決められます。
ちなみにAppleiPhone 向けにアプリを販売してる AppStore でも、agency モデルを採用しています


Amazon電子書籍についても wholesale モデルを採用していたので、Amazonは、新刊書について、赤字を出してでも$9.99で売るという戦略を取っていました。
例えば、紙の新刊書が $28.00で売り出されるとき、電子書籍の卸売価格は、その半分の$14.00であるにも関わらず、Amazonは、それを$9.99で売っていたのだそうです。一冊あたり$4.01の損になりますが、構わない、ということのようです。

出版社としては、$14.00で売れるのは良いけれど、こんな販売政策を続けていたら、誰も紙の書籍を高い値段で買わなくなるだけでなく、そもそも書籍の価値は$9.99くらいのものだと思うようになってしまう、と懸念を持っていました。出版社は、Amazonに対して、$9.99政策に不満であり、agency モデルへの移行を提案していましたが、天下のAmazon聞く耳を持たなかったようです。

そこに、新たなプレーヤー Apple が登場します。

Apple は、agency モデルでいいよ、と出版社の要望に応えます。また、$9.99という安すぎる価格は、出版社にとって面白くないことも分かるので、もっと高い価格で売れるようにすべき、とも言ってくれます。(一冊$16を越えるようだと、流石に売れないんじゃないかと、Jobsが言っていたと記録にはありますが。)

しかし、同じ書籍が Amazon で $9.99で売られているのに、Appleでそれより高い値段で売られていたら、誰も買わないだろうことは、Appleだって分かってます。

ですので、Apple は、他の電子書籍販売会社(Amazon / Kobo / Sony 等)とも、契約を変更してagency モデルにすること、そしてAppleのサイトで売る価格は、他の電子書籍販売会社より高くないようにすること (「最恵国待遇条項」 "Most Favored Nation Clause" =MFN Clause とか言います)を、Appleとagency モデルの契約を結ぶ際の条件として提示しました。

Amazonが猛反発することは、出版社も容易に予想できます。しかし、この千載一遇の好機を活かさないと、永遠にAmazonの独壇場が続き、書籍の価格はどんどん下がっていくという未来も予想できます。
そこで出版社は、一致団結してAmazon と闘う覚悟を決めました。

最初に口火を切ったのは、Macmillan。Macmillanは覚悟を決めて、Amazonに通告します。
「agencyモデルへの移行を要求する。要求が受け入れられない場合、新刊書の供給は、紙の書籍発売後7ヶ月経ってからとする。」
これに怒った Amazon、ネット上のMacmillanの書籍販売のページ(電子書籍・紙の書籍の両方)から「カートに入れる」ボタンを消してしまいました。

ユーザーは、Macmillan の本を Amazon サイトで見ることは出来るけれど、買うことができない状態になってしまいました。
しかし、その後、他の4社も同調して agency モデルへの移行要求を突きつけてきました。
いくらAmazonと言えども、大手出版社6社の内、5社の書籍を販売しない(最大手の Random House は、協議に参加していなかった)ことはできないので、降参することになりました。

屈服させられたままで終わる訳にはいかないということで、Amazonは、FTC(連邦取引委員会)に、Appleと出版社で共謀がなされたようである、と告発し、この裁判へとつながります。

【シャーマン法第1条】

Appleが違反したという、シャーマン法第1条の主文は非常に短くて、こんな内容。

原文: Every contract, combination in the form of trust or otherwise, or consipracy, in restraint of trade or commerce among the several States, or with foreign nations, is declared to be illegal.

和訳: 州間もしくは外国との取引または通商を制限する全ての契約、トラストその他の形態による結合または共謀は、これを違法とする。

随分とシンプルな条文ですが、これに基づいた数多の判例が、積み重なっています。
その結果、この条文は「非合理な取引制限を禁止するのであり、当該共同行為の内容、目的、効果などを総合してその違法性が決定される」と解釈されています。(quot.弘文堂「アメリ独占禁止法」村上政博 p.9)
ちなみに、この考え方を「合理の原則」"Rule of Reason" と言います。

それに対して、総合判断など一切不要で、問答無用で違法だ!という考え方もあり、それは「当然違法の原則」"per se illegal"と呼ばれています。例えば、入札談合とか、抱き合わせ契約などが、これに当たります。


【スッキリしない点1:「何についての共謀か」】

確かに、Appleと出版社は共謀しました。しかし、それは「Amazonとの契約を、agencyモデルに変更する」ことの共謀と解釈すべきではないかと思うのです。確かに、agencyモデルにすることで、電子書籍の単価を上げたいというモチベーションはありましたが、少なくともその点について「共謀」されたと言えるような記録は無いようです。

agencyモデル自体は、過去に米国の最高裁でも合法と認められていますので、協調してagencyモデルへの移行を突きつける行為を違法とするというのは、ちょっと納得出来ないです。



【スッキリしない点2:商品市場の考え方】

これまで、「電子書籍」と一つの商品のように呼んできましたが、実際にはいろんな種類の本があるわけで、それらを一括りにして「一つの商品市場」と見て良いのか?という問題があります。

カルテルが問題となる場合、対象となる商品の範疇は、その商品を一般的に購入する立場の人からみて、代替性があって、価格だけが問題となるもの、であることが多いです。

工業製品などがイメージしやすいですが、例えば「電線」など。
電機を通す部分が、銅(純度xx%)で、添加物としてyyが入っていて、被覆が塩化ビニールで、、、とスペックだけ決めてしまえば、後は値段勝負という、そういう世界。

ポイントは、どの会社が作った電線であっても、代替可能、というところ。


翻って、書籍について考えると、基本的に代替性はないと思うのです。

例えば、村上春樹の「1Q84」の単行本(ハードカバー)が、BOOK1,BOOK2共に \1,890で売られていますが、代替性はありません。具体的に言うと、BOOK1を読み終えた人が、BOOK2を買いに本屋に行ったけど、BOOK2が無いから、代わりに在庫があった BOOK1を買うということはあり得ません。
初めて読んでみる気になった人が、BOOK1を買いに行ったけど、代わりにBOOK2を買うということもあり得ません。



もちろん、例外があるという主張も一理あります。

辞書とか専門書については、代替性のあるものもあるでしょう。
岩波書店六法全書と、三省堂六法全書、まあ、索引などに違いがあるかも知れませんが、代替は可能でしょう。

松下先生の「アメリ独占禁止法」の本を買いたかったけど、高くて手が出なくて、村上先生の「アメリ独占禁止法」の本を買う、ということはあるでしょうけれど、初学者レベル向けに書かれたものと、次のレベルを目指す人向けに書かれたものとでは、完全に代替できるかというと、そういうことは無いでしょう。

しかし、全く同じ本というものは存在しない以上、「原則として、代替性はない」と考えた上で、一部例外があるというアプローチの方が、より実態に合っているとおもいます。

ハーレクイーン文庫などは、代替性があるかも知れませんが、、、、読んだことがないので分かりません (^^;
あと、フランス書院文庫とか(爆)


話が逸れましたが、代替性がない商品が多数ある市場において、カルテルが成立すると言えるのか?というのが疑問です。
例えて言うなら、Random House が、ダン・ブラウンの"The Lost Symbol"の単行本を$12.00で売っていて、
一方で、Pocket Booksが、Vince Flynn の "Pursuit of Honor" の単行本を$12.47 で売っているとします。

ここで、何らかの理由で両者が共謀して、同時に値上げしたとします。こんなふうに。

The Lost Symbol : $12.00 → $14.00
Pursuit of Honor: $12.47 → $14.47

これって、カルテルなんでしょうか?
私はカルテルには当たらないと思います。


【スッキリしない点3:Retail Price】

判決の中では、何度も「Appleの参入で Retail Priceが上昇した」と述べています。
公開されているグラフを見ても、確かに上昇していますし、新刊本について言えば、$9.99 → $12.99と確実に値段が上がっています。

しかし、そもそも論で言えば、何をいくらで売るかは、売手の自由です。 高すぎる値をつけて売れなくなれば、売手は値を下げるでしょう。それが市場というものです。
今回、電子書籍の販売モデルが、 wholesale モデルから、agency モデルに変わったことで、売主が Amazon から出版社に替わり、新たな売主である出版社が値段を上げた、ただ、それだけのことです。

それのどこが問題だというのでしょうか?


【スッキリしない点4:Amazonは罰されないの?】

Amazonに対して最初に口火を切った Macmillanに対し、Amazonは、自社サイトからMacmillanの書籍を買えないようにしてしまいました。電子書籍の販売だけ閉めるというならともかく、紙の書籍についても買えなくしたというのは、やり過ぎの感があります。

これって、何かの法律に違反しているのではないかと期待して調べてみましたが、法令で禁止されているということは無さそうです。
同じ事が日本で起きたら、どうだろう?と思い、独占禁止法の「不公正な取引方法」とか「優越的地位の濫用」とか、何か使えそうな規定がないかと調べてみましたが、ストレートにアウトと言えそうな規定は、ちょっと無い感じ。
強いて言えば、「優越的地位の濫用」第4号、「前三号に該当する行為のほか、取引の条件又は実施について相手方に不利益を与えること。」くらいが辛うじて適用可能かも知れない、というレベル。

公正取引委員会が、「流通・取引慣行に関する独占禁止法上の指針」を公表して、小売業者による優越的地位の濫用行為として、押し付け販売、返品、従業員等の派遣の要請、協賛金等の負担の要請、および多頻度小口配送等の要請について、それぞれに具体例を挙げて、適法性判断の指針を示していますが、今回のAmazonのような事例を禁止するものではありません。

独占禁止法って、基本的に「競争が進んで、価格が下ることは良いことだ」「独占的な供給者の手足を縛ろう」という思想で作られてるから、Amazon のように、圧倒的な Buying Power を持った買手の行為を制限しようという発想にはならないみたいですね。

なんだかなぁ、、、、という感じです。



【スッキリしない点5:仮に共謀が違法だとして、どうするの?】

仮に、Appleと出版社の共謀が違法だとして、司法省は、agency モデルを破棄して、wholesaleモデルに戻せというのでしょうか。 agencyモデル自体は合法的なものですし、これを今更 wholesale モデルに移行させる理由がありません。

結局、Appleが課徴金を払うだけ? (出版社5社は、早々に司法省と和解し、お金を支払ってます。)

先に和解した出版社の、新刊本の電子書籍価格が下がったという情報は無いようですし、司法省の自己満足的な裁判だったのかも知れません。

Value Engineering (VE) という考え方

数年前から、典型的な製造業の会社でお仕事しているのですが、そこで初めて Value Engineering (VE) という言葉を知りました。
直訳すると「価値工学」になりますが、それだけじゃ意味が分かりません(笑)

詳しい説明は、下のリンクから読めますので、割愛します。
http://www.atmarkit.co.jp/aig/04biz/ve.html

大雑把に言っちゃうと、
ある製品の価値:V
その製品の持つ機能:F
その製品のコスト:C
とした時に、V = F / C として表されると考え、このVをより大きくしましょう、という考え方なんだそうです。

先のリンクによると、この考え方は、とても大事な考え方だそうで、、、
『VEはモノやコトを対象に、その価値の改善・向上・保証を目的に行われる工学的マネジメント手法である。
IE、QCに並ぶ「3大管理技術」の1つと称されることもある。』んだそうです。

「3大管理技術」とは、なんともご大層な!(笑う箇所ではないんでしょうけど。。。)


まあ、Fを、どう数値化するのかという問題は、一旦横に置いておくとして、Vを増やす方法は簡単で、
V' = F * a / C * b  
という V'が、V より大きくなるための条件 (ただし、a>0, b>0) を考えると、
a>b であれば良いということになる。

つまり、Fを減らしたとしても (例:a = 0.8) Cをもっと減らす (例:b = 0.5) という選択肢もあって良いと言えそう。

と・こ・ろ・が、
Value Engineering の教科書では「機能の引き下げは別製品の開発と看做され、VEの範囲外となる。」と教えられるんだそうです!!!!
つまり、a≧1 でないと、イケナイんだそうです。(ええっ!って思いません?!?!)

なんか、ここに、日本の製造業が陥ってしまった教条主義的な考え方があるような気がします。

日本の従順な技術者は、「3大管理技術」の一つのVEの考え方に基づいて、
「機能を増やすことは、絶対的な善である」
「機能の引き下げは、VEの範囲外となる」
等と教えられるわけです。それが正しいか正しくないかを自分の頭で考えることもなく。

これはもはや洗脳と言っても良いかもしれません。

そのように叩きこまれた技術者は、標準的なユーザーが求めないであろうオーバースペックであっても、「機能を増やすことは、絶対的な善である」と信じて、それに邁進しちゃうのかな、と。

で、この数式の一番の問題は、あたかも機能(F)が無限に増やせるような錯覚に陥ることだと思います。
ユーザーが求めていない機能は、評価されるべきではないと思うんですよ。

 技術者が、「機能を1増やした!」と思ったとしても、お客様がそれを「価値のある機能」と思わなければ、価値は増えてないハズですよね。

 そうやって考えていくと、最初の(一旦横に置いといた)「機能(F)は、どうやって数値化するのか(評価するのか)」という問題に、対面することになります。

Steve Jobsじゃないけど、それは「顧客が真に求めているものは何か」ということを、愚直なまでに追求して考える、、、ということなんだと思います。

iOS プログラミング メモ audioPlayerDidFinishPlaying の使い方

2月11日の「掲示板」とは別の掲示板で、AVAudioPlayer の再生終了時に特定の処理をさせたいという人がいたので、また自分の練習を兼ねてサンプルのプログラムを書いてみました。

"Push Me" と書いてあるボタンを押すと、mp3が再生され、ボタンの文字が"Wait" に変わります。
mp3の再生が終了すると、ボタンの文字が "Push Me"に戻ります。

まず、 .h ファイルで AVAudioPlayerDelegate デリゲートを使う旨を宣言する。

@interface ViewController : UIViewController{


そして、.m ファイルで myPlayer を実装した後で、delegate を自分自身に設定

[myPlayer setDelegate:self];

最後に、 .mファイルに以下のメソッドを追加する。

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{

[aButton setTitle:@"Push Me" forState:UIControlStateNormal];
}

こうすることで、myPlayer の再生終了時に、同じクラス内の audioPlayerDidFinishPlaying というメソッドが自動的に呼び出されるというワケ。

ちなみに、スライダーを動かすと、ボリュームが変わります。

iOS プログラミング メモ 画像の回転

iPhoneアプリ関係の掲示板で、画像を回転させる方法を探している人がいたので、サンプルのプログラムを作ってみました。

画面下のスライダーを動かすと、矢印がぐるぐる回るという、単純なものです。

画像を回転させるには、アフィン変換の関数を使えば良いということで、こんな風に書けば良いようです。
imageView.transform = CGAffineTransformMakeRotation(degreeDbr*(M_PI / 180.0));


作っていて、ちょっとツマヅイたのが、角度を表示する箇所。

角度はdouble値で保持しているので、仮にこう書くと、123.08245687 みたいに、小数点以下がダラダラと書かれてしまう。
[良くない例] degreeLbl.text = [NSString stringWithFormat:@"%f", Degree];

小数点以下二桁だけ表示したいときはどうすればよいか調べてみたら
[修正案] degreeLbl.text = [NSString stringWithFormat:@"%.2f", Degree];
と書けばよいことが分かった。なるほどね。

どうやらC言語でも、同じルールみたいなんだけど、C言語やってたわけじゃないので(汗)

今回も、ソースをアップしてみました。 こんなものでも、誰かの助けになることを願いつつ。

Yahoo!ボックス - 大切な思い出をずっと大事にお預かりします

iOS プログラミング メモ シングルトンクラスの作成について

iOS には、シングルトンという考え方があるのを知って、どうやって実装するのか、実際に手を動かして見ることにした。

備忘録も兼ねて、整理してみた。

プロジェクト名は、SingletonTest (ベタやなあ)
ファイルの構成は、こんな感じ。

AppData.h / AppData.m が、シングルトンクラス。
下は、AppData.h の中身で、AppDataには、4つの変数を持たせている。

一つのポイントとなるのは、

+ (id)sharedInstance;
とメソッドを宣言して、他のインスタンスから直接呼び出せるようにしておくところ。

こうしておいて、他のインスタンスから、下のようにして呼び出す。
ちなみに、これはViewController.m から呼び出しているところ。

このようにして呼び出すと、AppData.h / AppData.m から生成されたインスタンスが、
 (1)存在していないとき→ 新たに生成する
 (2)既に存在しているとき→ 既に存在しているインスタンスを返す

という処理をしてくれるみたい。


AppData.m の中身は、こんな感じ。

ほとんど呪文で、正直、中身は全然理解できてない。。。。
dispatch_once というのが重要らしいです。「スレッドセーフ」だそうな。
スレッドがいくつも走るようなアプリを作ったことがないので、今ひとつピンとは来ないけど。

ビルドして実行すると、ViewControllerクラスから作られた画面が表示される。

テキストフィールドに文字を記入すると、その内容が(AppDataクラスから作られた)インスタンスの内容に反映される。
UP というボタンを押すと、左の数字が一つ増え、その内容が(AppDataクラスから作られた)インスタンスの内容に反映される。

右下のボタンを押すと、似たようなもう一つの画面が開く。
これは、SecondViewController から作られた画面。

(AppDataクラスから作られた)インスタンスの内容を表示させているので、前の画面で表示されていたものと同じ内容が表示される。
さっきと同様に、
テキストフィールドに文字を記入すると、その内容が(AppDataクラスから作られた)インスタンスの内容に反映され、
UP というボタンを押すと、左の数字が倍になって、その内容が(AppDataクラスから作られた)インスタンスの内容に反映される。

複数のViewController 間で、変数を共有したい場合などに使える機能だね。


今回作成したプロジェクト一式は、下のリンクからダウンロードできるようにしておきましたので、拙いソースですが、DLしてみたい方はどうぞ。
Yahoo!ボックス - 大切な思い出をずっと大事にお預かりします

参考にさせていただいたblog
http://d.hatena.ne.jp/koichirohonda/20120325/1332651629

iOS プログラミング メモ KVOについて

さっき作った プロジェクト「SingletonTest」 を再利用して、KVO の実験をしてみた。
KVOというのは、Key Value Observing の略で、「オブジェクトの値の変化」を監視するための仕組み。

Objective-C逆引きハンドブック」を読みながら実験してみた。
Amazon CAPTCHA

監視する側とされる側は、次のようにしてみる。
  監視する側: ViewController クラスから作られるインスタンス
  監視される側:AppDataクラスから作られるインスタンス

ソースをいじるのは、監視する側の ViewController.m だけ。
まず、監視するという設定をしてあげる。
今回は、viewDidLoadの中に、次の文言を追加した。

    NSKeyValueObservingOptions options = (NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld);
    [appData addObserver:self forKeyPath:@"intB" options:options context:nil];

 2行目の設定により、appDataというインスタンスの intB という値に変化があった場合に、このクラス(self)の然るべきメソッドを呼び出すように設定がされる。

 そして、その「然るべきメソッド」とは、次のメソッド。これを ViewController.m の中の適当な場所に加える。

 -(void)observeValueForKeyPath:(NSString *)keyPath
   ofObject:(id)object
 change:(NSDictionary *)change
 context:(void *)context
{
    NSLog(@"***Observed");
    NSLog(@"KeyPath = %@", keyPath);
    NSLog(@"change = %@",[change description]);
}

このメソッドは、どんな変化があったのかを表示する機能しかない。

SecondViewController が生成した2番めの画面で、intBの値を変化させた時でも、この監視機能が生きていて、ちゃんとNSLogでメッセージが吐き出されることが確認できる。

必要な作業は、これだけ。
監視される側については、何もする必要がないというので、少し驚いた。


先のソースから、変更点はごく僅かなので、ソースのULは省きます。

Outlook:作業時間を集計するマクロを作ってみた 

 Outlook でスケジュール管理をしています。

 予定を管理するだけでなく、過去に使った時間を計算できないかと考えて、マクロを作成しました。

 自分で言うのも何ですが、なかなか便利にできたと思いますので、ご希望の方は使ってみてください。

 仕事の時間を計算するために作りましたが、学生さんなら、各科目をどれだけ勉強したか計測してみると良いと思います。
もう2●年前、まだ、中学生だったころ、各科目の勉強時間を集計してみたことがありました。
勉強時間が少ない科目は、テストの結果が悪く、勉強時間が多い科目は、テストの結果が良くなることが確認できました。(笑)


【集計方法】

 マクロの登録が完了すると、2つのマクロを呼び出せるようになります。
(1) SumThisMonth()
(2) SumSelectedTerm()

 (1) のSumThisMonth() を呼び出すと当月の、(2)のSumSelectedTerm()を呼び出すと、指定した期間の作業時間を集計して、集計結果をExcelで表示します。

 なお、「作業時間」として集計したい項目の件名の冒頭に「#」(半角シャープ)をつけておきます。

こんな感じ(↓)
20090320145919

集計するために、同じように全部で4件の項目をつくりました(↓)
20090320145920

この期間を集計すると、このような集計表(↓)が表示されます。

20090320145921

【マクロの登録方法】

まずは、outlook でマクロが使えるように設定して、、、とステップがあるのですが、Millefeuille さんが作成された「Outlook VBA マクロ、はじめの一歩 - Windows Live」というページで、とても詳しく説明されていますので、こちらを見て設定してください。

 私も、Millefilleさんの説明に従って、マクロを使えるように設定しました (^^;
 また、これ以上に上手に書けるとは思いません。。。

Excelを呼び出すための一手間】

 Excel を呼び出すために、マクロの「参照設定」を行う必要があります。
VBAの編集画面から、「ツール」→「参照設定(R)」を選び、

Microsoft Excel xx.x Object Library」にチェックを入れてください。
※下の画像は、チェックした後なので、リストの上の方に来ていますが、最初はアルファベット順に並んでいますので、もっと下のほうにあります。

【注意事項】
Outlook 2007 で作成しましたので、古いバージョンだと動かないかも知れません。
作業用のファイルを c:\temp に作成しますので、あらかじめ c;\temp というディレクトリを作っておいてください。

※ Public Sub SumCalendar(ByVal strStart As String, ByVal strEnd As String) の中の、
この部分、「 Const CSV_FILE_NAME = "c:\temp\spenthours.csv"」のファイル名を適宜変更していただいてもOKです。

 マクロの改変・転送は自由ですが、copyright 表記だけは、残しておいていただけると嬉しいです。

'copyright @ KIWATA Shin 

Public Sub SumThisMonth()
    'Calculate the hours spent for current month
    '当月に使った時間を集計する。

    strStart = Year(Now) & "/" & Month(Now) & "/1 00:00"
    
    strEnd = DateAdd("m", 1, CDate(strStart)) & " 00:00"

    Call SumCalendar(strStart, strEnd)
   
    
End Sub

Public Sub SumSelectedTerm()
    ' caluculate the hours spent for the designated period
    ' 指定された期間内に使った時間を集計する。
    
    Dim tmpStr
    Dim strStart As String
    Dim strEnd As String
    
Label1:

    tmpStr = InputBox("Input start date")

    If IsDate(tmpStr) Then
        strStart = tmpStr
    Else
        MsgBox ("please input again")
        GoTo Label1
    End If
    
    
Label2:
    tmpStr = InputBox("Input end date")
    
    If IsDate(tmpStr) Then
        strEnd = tmpStr
    Else
        MsgBox ("please input again")
        GoTo Label2
    End If
    
    Call SumCalendar(strStart, strEnd)
    
    
End Sub
    
Public Sub SumCalendar(ByVal strStart As String, ByVal strEnd As String)
    
    Dim objFSO 'As FileSystemObject
    Dim stmCSVFile 'As TextStream
    Const CSV_FILE_NAME = "c:\temp\spenthours.csv"
    Dim colAppts As Items
    Dim objAppt 'As AppointmentItem
    
    Dim sumAppt
    Set sumAppt = CreateObject("Scripting.Dictionary")
    
    Dim strLine As String
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    On Error GoTo MyError
    
    Set stmCSVFile = objFSO.CreateTextFile(CSV_FILE_NAME, True)
    
    stmCSVFile.WriteLine """Subject"",""minutes"",""start time"",""end time"""
'    stmCSVFile.WriteLine """件名"",""所要時間(分)"",""開始日時"",""終了日時"""
    
    Set colAppts = Application.Session.GetDefaultFolder(olFolderCalendar).Items
    colAppts.Sort "[Start]"
    colAppts.IncludeRecurrences = True
    Set objAppt = colAppts.Find("[Start] < """ & strEnd & """ AND [End] >= """ & strStart & """")
    
    While Not objAppt Is Nothing
        If Left(objAppt.Subject, 1) = "#" Then
        
            strLine = """" & objAppt.Subject & _
            """,""" & DateDiff("n", objAppt.Start, objAppt.End) & _
            """,""" & objAppt.Start & _
            """,""" & objAppt.End & _
            """"
            If sumAppt.Exists(AfterStar(objAppt.Subject)) Then
                sumAppt.Item(AfterStar(objAppt.Subject)) = sumAppt.Item(AfterStar(objAppt.Subject)) + DateDiff("n", objAppt.Start, objAppt.End) / 60
            Else
                sumAppt.Add AfterStar(objAppt.Subject), DateDiff("n", objAppt.Start, objAppt.End) / 60
            End If
            
            stmCSVFile.WriteLine strLine
        End If
        
        Set objAppt = colAppts.FindNext
    Wend
    stmCSVFile.WriteLine "-----"
    
        stmCSVFile.WriteLine """Subject"",""hours"""
'        stmCSVFile.WriteLine """件名"",""所要累計時間"""

    Dim i As Integer
    keys = sumAppt.keys
    
    For i = 0 To sumAppt.Count - 1
    
    strLine = """" & keys(i) & _
            """,""" & sumAppt.Item(keys(i)) & _
            """"
    stmCSVFile.WriteLine strLine
            
    Next i
    
    stmCSVFile.Close
    

'  Excel を開かなくて良い場合は、以下5行を削除
'  If you don't wish open the file by Excel, delete following 5 lines.

Dim xlApp As Excel.Application
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
xlApp.Workbooks.Open CSV_FILE_NAME
Set xlApp = Nothing

Exit Sub

MyError:

    If Err.Number = 70 Then
    
    MsgBox ("cannot open temporary file." & vbCrLf & _
    "please close it if opend.")
'    MsgBox ("テンポラリファイルが開けません。" & vbCrLf & _
    "既に開いているファイルを閉じてください。")
    
    Else
    MsgBox ("Error No:" & Err.Number & " is happend." & vbCrLf & _
    Err.Description & _
    "Operation is cancelled.")

'    MsgBox ("エラー番号:" & Err.Number & " が起こりました。" & vbCrLf & _
    Err.Description & _
    "処理は中断しました。")
    End If

End Sub
Public Function AfterStar(ByVal Words As String)

    Dim i As Integer
    For i = 2 To Len(Words)
    
        If Mid(Words, i, 1) = " " Then
        Exit For
        End If
        
        If Mid(Words, i, 1) = " " Then
        Exit For
        End If
        
    Next i
    
    AfterStar = Mid(Words, 2, i - 2)
    
End Function