見出し画像

IT古典良書を読み解く《第18回》Excelのバグ? 1900年2月29日問題の真相を追う

第18回  Joel on Software(ジョエル オン ソフトウェア) 〜その11〜
「Excelのバグ? 1900年2月29日 問題の真相を追う」


Excel先生

こんにちは。スクラムマスターの伊藤です。

皆さんはExcel(エクセル)をお使いでしょうか? Excelは表計算ソフトなのですが、計算やグラフ描画はもちろんのこと、各種ドキュメントフォーマット、図形描画、マクロを使った便利ツールといった多種多様な使い方が出来て、本来ならWordで作るようなファイルもExcelで作っている方も多数いる万能ツールです。特に日本ではExcelを方眼紙にして使うという開発者もびっくりな使い方まであるほどです。あまりに便利すぎて、Excel依存になってしまってたため脱Excelという言葉があるぐらいです。

本blogで度々扱っているJoel on Software(ジョエル オン ソフトウェア)の著者JoelはExcel開発者の一人です。正確に言うとプログラムマネージャーという肩書だったそうです。

今回は少し趣向を変えて、JoelがExcelの設計書をビル・ゲイツにレビューしていただいた「はじめてのBillGレビュー」を中心に、Excelのバグと言われる1900年2月29日の真相、更によもやま話は、Excel-Tipsとして個人的に便利なExcelの小技を紹介していくというExcel三昧の内容になっております。(コーナーを紹介するラジオのオープニングのようだな…)。

 More Joel on Software
3ページ「第1章 はじめてのBillGレビューのこと」
(原文)  My First BillG Review
(日本語アーカイブ)  https://bit.ly/30icZq0

《よもやまExcel-Tips》

今回はよもやま話もExcel仕様。ちょっと便利なTipsを紹介していきます。以下のバージョンで動作を確認しています。古いExcelでは動作しない可能性もありますご了承下さい。

まず手始めですが、複数のセルを選択すると選択範囲の平均、個数、合計が右下に表示されます。意外と便利です。(数値以外は個数のみ)

はじめてのBillGレビュー

社会人であれば自分が作った成果物に対してのレビューは避けて通れないものですが、そのレビューアがビル・ゲイツであり対面式で行うとなれば緊張極まりないと思われます。

JoelがBillGレビューを受けた1992年6月30日、マイクロソフトは既にWindows3.1とOfficeをリリースしており、その地位を固めつつありましたが、重要な機能についてはビル・ゲイツのレビューを受けることになっていたそうです。そして、JoelはExcelの仕様書(500枚!)を印刷してレビューを受けることになるのですが、その興奮が伝わってきます。

ビルが入ってきた。

彼が2本の足と、2本の腕と、1つの頭を持っていて、普通の人類とほとんど同じように見えるのが、私には不思議に思えた。

彼は私が書いた仕様書を手にしていた。

彼が私の書いた仕様書を手にしている! (中略)

彼は私の仕様書の最初のページを読み、欄外に書き込みをしたのだ!
(中略)

彼が私の仕様書をパラパラとめくっていて[落ち着けよ!小娘みたいじゃないか!]…そして仕様書のすべてのページの欄外に書き込みがあるのを見たのだ。彼はあの分厚い仕様書をすべて読んで、欄外に書き込みをしたのだ。

全部読んだんだ![ウワーッ、なんてこった!]

BillGレビューには、ビル・ゲイツがF***と何回言うか数える人が同席している。ビル・ゲイツは質問をどんどん難しくしていって、コントロール出来てるかを確認し、出来ていないと怒鳴りつけるといったものだったそうです。Joelは順調に質問に答えていきますが…

最後にとっておきの質問がきた。
「わからないんだが」ビルは言った。「これをどうやって実現するのか本当に詳細に調べたものが誰かいるのか? たとえば、日付と時刻に関するあのたくさんの関数だ。Excelには日付と時刻の関数がすごくたくさんある。Basicが同じ関数を持つようになるのか? それが全部同じように動くようになるのか?」
「なります」と私は答えた。「1900年の1月と2月以外は」(中略)
「いいだろう。よくやった」とビルが言った。彼は書き込みをした仕様書を手に取った。

……あ、待って! それ、欲しい……
そして彼は行ってしまった。

「4回」とF***カウンタの男が宣言した。「ワォ、これは私の知る限り一番少ないぞ。ビルも年で丸くなったようだ」

ちなみに、当時のビル・ゲイツは36歳です。ところで、1900年の1月と2月ってなんのことでしょうか。こちらは後述します。

《よもやまExcel-Tips》

便利なキー操作


JoelがExcelに追加してくれた機能

JoelはExcelにプログラムマネージャーとして参画したことは前述しましたが具体的には何をつくったのでしょうか。一言で言うとExcelのためのVisual Basic、現在のマクロ機能VBAになります。

VBAは、BillGレビューの翌年1993年にExcel 5.0で初めて搭載されて大成功を収めます。

ちなみにマクロ問題はBasicで解決することは暗黙の了解だったようでJoelは嫌だったみたいですが、Basic開発チームと交渉してどうにか以下の機能を実装させたとのことです。

1. Variant型
どんな型でも保持できる共用のデータ型、型宣言厳守主義者には受け入れられないでしょうがセルにどんな型が来るのか不明な表計算ソフトでは、これが無いと物凄く不便なものになってしまっていた

2. COMオートメーション
これはCOMオートメーション対応のソフト同士なら容易に連携が出来るというもの、Excel VBAからOutlookやブラウザを操作できるのはこれのおかげ

3. For Each文
シェルスクリプトから持ってきたとのこと

4. With文
Pascalから持ってきたとのこと

VBAはもちろん、4つとも無いととても不便でした。Thank you, Joel.

《よもやまExcel-Tips》

曜日を表示させる方法

1.      Ctrl + ; など日付型でセルを入力

2.      右クリック > セルの書式設定を開く

3.      分類のユーザー定義を選択し曜日を入れたい箇所にaaaと追加する(例ではyyyy/m/d(aaa)

4.      完成! このセルを連続コピーすればあっという間に曜日付き日付の一覧も作れます。

5.      ちなみにaaaaと打つと月曜日といった表示にddd, ddddは英語表記になります。

1900年2月29日問題の真相とは?

さぁ、いよいよ1900年2月29日問題について語ります。

1900年2月29日は、1900年は4で割り切れるため、うるう年のようですが、うるう年のルールには100で割り切れて、400で割り切れない年はうるう年ではないというものがあり、1900年はこれに該当するため、うるう年ではありません。よって、1900年2月29日は存在しない日付です。

Excelでは1900年1月1日以降が日付型として扱えることになっています。

試しに、1900/1/1, 1900/2/28, 1899/12/31とセルに書き込み連続コピーをしてみましょう。

なんと、存在しないはずの1900年2月29日が表示されてしまいます。とんでもないバグを見つけてしまいました。

それではVBAではどうなるのでしょうか。特殊な使い方で申し訳ないですが、VBAでは1900年2月29日は正しい日付ではないと判断されました。

ExcelのバグはVBAでは解消されているようです。(逆に動きが違うので困ることもありそうですが、VBAはVisual Basicと同じ仕様になるため、この障害は許容できないでしょう)。
JoelはExcelは1900年1月1日を1として数えているのにBasicでは1899年12月31日を1として数えていることに気付き、開発者に質問します。

私はその理由を覚えていそうな古株のExcel開発者を探すことにした。
エド・フライズなら答えを知っているかもしれない。

「ああ、それね」と彼は言った。(中略)

「これはExcelのバグだ!」私は叫んだ。

実際はそういうわけじゃない」とエドが言った。「Lotus 1-2-3のワークシートをインポートできるようにするために、そうする必要があったんだ」

「じゃあ、Lotus 1-2-3のバグってこと?」

「そう。だけどおそらくは意図的なものだ。Lotusは640Kのメモリに詰め込む必要があった。これはあんまり大きなものじゃない。1900年を無視すれば、与えられた年がうるう年かどうか判定するのは右端の2ビットが0かどうか見るだけで済む。そのほうがずっと早くて簡単だ。たぶんLotusの連中ははるか昔のふた月が間違っていたところで問題にはならないと考えたんだろう。一方でBasicの連中は、そのふた月にこだわってエポックを1日ずらしたんだ」
「あーっ!」私は声を漏らした。そして「1904年から計算する」というチェックボックスがオプションダイアログについている理由を調べ始めた。

その翌日はBillGレビューの日だった。

これで、もうお分かりですね。BillGレビューで1900年の1月と2月以外は日付・時刻の関数が動くと答えられた理由が。

この1900年うるう年問題はマイクロソフト公式にもアナウンスされています。「仕様です」ということですね。

https://docs.microsoft.com/ja-jp/office/troubleshoot/excel/wrongly-assumes-1900-is-leap-year

Excel全ての機能を使った人はいないと再三言っていますが、1904年から計算するのオプションは現在でも勿論あります。

《よもやまExcel-Tips》

図のリンク貼り付け

レポートのように綺麗にしたシートに表を貼り付けると、列幅がずれてレイアウトが崩れてしまった経験ないでしょうか。そんなときは表は別シートで作成し図のリンク貼り付けを使うとスマートに解決します。

例えばこのシートに…

この表をコピーすると

アァァ… 絵に書いたような悲劇に(例は分かりやすいように誇張してます)

こんなときは右クリックして「形式を選択して貼り付け」から「リンクされた図」または「図」を選択します。

ブラボー! 図になっていますので自由に配置が出来る上、リンクは継続されていて元データが変更されると反映されます。図の貼り付けの場合は反映されません。

また、書式がテーブル形式だとリンク貼り付けが出来ない(図はOK)といった制約があります。ちなみにこの機能、昔(リボンが無い時代)はSHIFTキーを押しながらメニューバーの編集を押すと表示されるという隠し?機能でした。


Joelの近況

Joel on Softwareの元になったブログ Joel on Software が最近更新されました。それによると、3度目の起業をしたようです。Microsoft退社後に

Glitch
Stack Overflow (技術系質問の最後の砦、お世話になっております)

と立ち上げたJoelですが、現在はHASH というサービスを立ち上げたようです。AIですね。今後も注目です。

《よもやまExcel-Tips》

最後のTipsはやや上級ですが、便利なテクニックです。例えば各支店の売上がシート別に入っていて、それを集計するシートを用意するとします。各支店のフォーマットは同一です。

普通に実行すると、以下のようになると思います。=東京!B2(シート名 +! + セル位置)を入れることで値が表示されますが別の支店はシートが違うため、改めて設定が必要になります。

そこで、INDIRECT(インダイレクト)を使います。これでシート名や名前(範囲に名前を設定して入力規則などに使えるが今回は割愛)を制御することが出来ます。

具体的には =INDIRECT($C3 & "!B2") とします。そうするとC3は支店名が入っているため=東京!B2 と同じ結果になります。結合したい文字列を””で括って&でつなげます。

C3でなく$C3になっているのはコピーした際にC列は固定したいためです絶対参照と相対参照についての説明は割愛します。

これで簡単にシート参照が出来ます。シート名をリストにして変更するとその支店の報告書に変わるといった使い方も可能です。

以上でExcel-Tipsの紹介も終了です。Excel三昧の特別編いかがだったでしょうか。意外とTipsが重厚になってしまったので機会があれば、また紹介したいと思います。Joelに感謝しつつ素敵なExcelまたは脱Excelライフを!

IT古典良書を読み解く

――――――――――――――――――――――――――――――――――

執筆者プロフィール:伊藤 慶紀
大手SIerにて業務用アプリケーションの開発に従事。
ウォーターフォールは何故炎上するのか疑問を感じ、アジャイルに目覚め、一時期、休職してアメリカに語学留学。
Facebookの勢いを目の当たりにしたのち、帰国後、クラウド関連のサービス・プロダクト企画・立ち上げを行う。
その後、ベンチャーに転職し、個人向けアプリ・WebサービスのPM、社内システム刷新など様々なプロジェクト経験を経てSHIFTに入社。趣味は将棋、ドライブ、ラーメン、読書など

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/