エクセル奇譚

このページの内容は Excel 97 を想定しています。
トラブルについては よくある質問と回答 も参照ください。

誤差アラカルト

DATEDIF 疑惑

ここはどこ…

マクロあります

ワレモノ注意

せまいよ〜こわいよ〜

幽霊リンクバスターズ

メモリーを買えばいいの?

見ないで!

パスワード忘れました! 〜弱いパスワードとの付き合い方〜

幽霊プロジェクトの怪

メニューとツールバーの神隠し


誤差アラカルト

「Excel は小数の計算を正確にはできません。
例えば、セルに 0.1 という数値が表示されているとします。これは 0.1 に見えるのですが、実際には 0.1 よりもちょっとだけ大きい数値だったり、ちょっとだけ小さい数値だったりすることがあるのです。

そのような数値に対して四捨五入、切り上げ、切り捨てをしたり、比較をしたりするとどうなると思いますか? 0.1 を小数点以下1桁に切り捨てても 0.1 のままですが、もし、0.1 よりちょっとだけ小さい数値だとしたら、小数点以下1桁に切り捨てたら 0 になってしまいます。

では実際に Excel 97 で試してみましょう。
セルに =1.2-1.1 と入力してみてください。結果は 0.1 になります。
次に =ROUNDDOWN(1.2-1.1,1) と入力してみてください。ROUNDDOWN 関数は切り捨てをする関数です。 この式は 1.2-1.1 の結果を小数点以下1桁で切り捨てる計算をします。いかがでしょう。0.1 になりましたか?
=1.2-1.1 の結果は 0.1 と表示されていますが、実際には 0.1 よりちょっとだけ小さい数値になっているわけです。

正確に計算したい場合は、小数は使わずに整数で計算することをおすすめします。
例えば、今の計算も、100倍した整数で計算すれば誤差を気にする必要はありません。=ROUNDDOWN((120-110)/10,0) は 120-110 の結果を 10 で割って小数部分を切り捨てます。桁は違いますが必要とする結果は得られますよね」

誤差の例をいくつか見てみましょう。セルにこんな数式を入力してみてください。

=0.1+0.2-0.3+0
=0.5-0.4-0.1+0

Excel 95 までは、=0.1+0.2-0.3 だけで良かったのですが、Excel 97 では、これは 0 になります。ところが、これに 0 を足すと誤差が見えてきます。ちょっと不思議でしょう?

次は時間計算の例です。

=IF(VALUE("12:30")+VALUE("0:25")=VALUE("12:55"),TRUE,FALSE)

時刻データも小数です。12時30分 に 25分を足しても 12時55分 ちょうどにはなりません。
もう一つ、時間を15分単位に切り捨てる例です。

=FLOOR(VALUE("16:00")-VALUE("14:00"),VALUE("00:15"))

FLOOR 関数は指定単位に切り捨てる関数ですが、時刻データのような小数を扱う場合は期待する結果にならない場合があります。この式では15分単位に切り捨てていますが、2時間 ではなく 1時間45分 に余分に切り捨てられてしまいます。

今度は、四捨五入と切り上げの結果を比較してみます。

=ROUNDUP(0.25,1)-ROUND(0.25,1)+0

どちらの関数の結果も 0.3 になり、答えは 0 になりそうな気がしますが、そうはなりません。「約0.3」で計算していることを承知していれば、この結果も不思議ではありません。

掲示板に書いた誤差関係のコメントを抜き出してみました。こちらです。


DATEDIF 疑惑

日付間隔を計算する DATEDIF 関数ですが、実はなかなか油断のできない奴だって知っていました?

=DATEDIF("1996/4/30","1997/3/1","MD")

=DATEDIF("1995/2/1","1996/3/1","YD")

カレンダーを見ながら数えてみてください。


DATEDIF(A1,B1,"MD") の代わりの例です。

=IF(A1>B1,#NUM!,IF(DAY(B1)>=DAY(A1),DAY(B1)-DAY(A1),B1-MIN(DATE(YEAR(B1),MONTH(B1)-1,DAY(A1)),B1-DAY(B1))))

DATEDIF(A1,B1,"YD") の代わりの例です。

=IF(A1>B1,#NUM!,B1-DATE(YEAR(B1)-IF(DATE(YEAR(B1),MONTH(A1),DAY(A1))>B1,1,0),MONTH(A1),DAY(A1)))

DATEDIFの仕様についての掲示板のログの抜粋です。角田 さん、SIMO さん ありがとうございました!
DATEDIF の謎に迫る!


ここはどこ…

Excel を使っていて「なんか変」と思ったら、まずチェックするのが、コントロールパネルの地域の設定です。日本以外になっていると正しく動きません。


マクロあります

Excel 97 ではマクロを含むブックを開く際に、警告メッセージが表示されるようになりましたが、 マクロなんて作った覚えがないのに、メッセージが表示されることがあります。その原因と対策です。

1. マクロウィルスに感染した

マクロウィルスに感染したのかもしれません。自分で判断できない人は、詳しい人に見てもらいましょう。

2. マクロが残っている

操作ミス等でマクロができてしまい、まだ残っているのかもしれません。

(以下の操作を行う前に、念のため、ファイルのバックアップを作成しておくことをおすすめします)

まず、[ツール]-[マクロ]-[Visual Basic Editor] で Visual Basic Editor を起動します。
プロジェクトウィンドウに、開いているブックやアドインが表示されています。その項目にぶら下がっているのがマクロを記述する場所で「モジュール」と言います。

このプロジェクトウィンドウを見ると、VBAProject (Book1) と VBAProject (Book2) の 2 つのブックが開いていることがわかります。括弧の中がブック名です。まず、問題のブックを見つけてください。

VBAProject (Book1) の中にある Sheet1、Sheet2、Sheet3 はワークシートのモジュールです。また、ThisWorkbook はブックのモジュールです。項目の左に表示されているアイコンがモジュールの種類を表しています。
これらのモジュールは削除することはできませんし、その必要もありません。しかし、モジュールの中のコードはすべて削除しなければいけません。
あらかじめ Visual Basic Editor のメニュー [ツール]-[オプション][編集] の [モジュール全体を連続表示] をチェックしておきます。その後、各モジュールをダブルクリックするとコード記述用のウィンドウが開きますので、もしコードが表示されたらすべて削除します。なお、このウィンドウには簡単な操作で自動的にコードが記述される機能がありますので、コードの削除後は余計な操作は行わないようにします。

VBAProject (Book2) の中にある Class1、Module1、UserForm1 はブックの初期状態では存在しないもので、後から追加されたモジュールです。項目の左に表示されているアイコンがモジュールの種類を表しています。
これらはマクロウィルスの可能性もありますので、どのようなものか自分で判断できない場合は、詳しい人に見てもらってください。
自分で不要なものであると判断できる場合は、モジュールを選択し [ファイル] メニューから [(モジュール)の削除](Excel 2000 の場合は [(モジュール)の解放])を実行します。エクスポートの問い合わせがありますが、モジュールを別ファイルに保存しておきたい場合は [はい]、特に必要がなければ [いいえ] を選択します。

3. 非表示オブジェクトの再表示

ワークシート、名前定義、図形オブジェクトは非表示になっている場合もあるので再表示して確認します。これにはマクロを使用する必要があります。以下にサンプルコードを書きます。

新規ブックを作成し、Visual Basic Editor を起動、プロジェクトウィンドウで新規ブックを選択し、メニュー [挿入]-[標準モジュール] でモジュールを挿入、以下のコードをコピー貼り付けします。 オブジェクトを表示したいブックをアクティブにしてから、[ツール]-[マクロ]-[マクロ] で ShowAllObject マクロを実行します。

表示したオブジェクトを再度非表示にするには1つ1つ手作業で操作する必要があります。ご注意ください。

Sub ShowAllObject()
    Dim o As Object
    Dim oo As Object
    Dim iRet As Long
    For Each o In Sheets
        If o.Visible = False Then
            iRet = MsgBox("非表示シートがあります。" & o.Name & Chr(10) & _
                "表示しますか?", vbOKCancel Or vbDefaultButton2 Or vbExclamation)
            If iRet = vbOK Then
                o.Visible = True
            End If
        End If
    Next
    For Each o In Sheets
        For Each oo In o.DrawingObjects
            If oo.Visible = False Then
                iRet = MsgBox("非表示オブジェクトがあります。 " & o.Name & Chr(10) & _
                    "表示しますか?", vbOKCancel Or vbDefaultButton2 Or vbExclamation)
            End If
            If iRet = vbOK Then
                o.Visible = True
            End If
        Next
    Next
    For Each o In Names
        If o.Visible = False Then
            iRet = MsgBox("非表示の名前定義があります。 " & o.Name & Chr(10) & _
                "表示しますか?", vbOKCancel Or vbDefaultButton2 Or vbExclamation)
            If iRet = vbOK Then
                o.Visible = True
            End If
        End If
    Next
End Sub
4. 名前定義や図形オブジェクトにマクロが登録されている

Excel の以前のバージョンではマクロに名前を定義して実行していました。そのため名前定義もチェックされます。
[挿入]-[名前]-[定義] で不要な名前定義があれば削除します。

図形オブジェクトへのマクロ登録も確認します。
[編集]-[ジャンプ][セル選択] で [オブジェクト] を選択すると、シート内のすべてのオブジェクトを選択できます。不要なオブジェクトがないか確認します。また、オブジェクトを選択した状態で TAB キーを押すと、一つ一つ選択して行くことができます。
グループ化されている場合はグループ内の個々のオブジェクトもチェックします。グループの解除は、オブジェクトを右クリックして [グループ化]-[グループ解除] を選択します。

5. 日本語の名前定義

Excel 97 では日本語の名前定義を使っていると、マクロ警告のメッセージが表示される場合があります。
以下の文字が問題になる可能性があります。この他にもあります。

頁 項 順 頗 領 頚 頬 頭 頸 題 額 顔 願 類 風 飛 食 飢 飯 飲 飴 飼 飽 飾 報 へ 付 勘 忘 様 濘 痘 秘 釘 闘 高 貸

なお、Excel 2000 や Excel 97 の最近のバージョンでは、この問題は発生しないようです。

6. 参照設定

VBA の参照設定が原因である可能性もあります。Visual Basic Editor のプロジェクトウィンドウでプロジェクトを選択し、メニュー [ツール]-[参照設定] で確認ができます。リスト先頭の2つのライブラリは解除できません。
参照設定のダイアログボックスで解除できないものがある場合は、マクロを使って解除します。サンプルマクロ です。

プロジェクト名を変更することで、マクロ関係のデータが更新され、現象が発生しなくなる場合もあります。Visual Basic Editor のプロジェクトウィンドウでプロジェクトを選択し、メニュー [ツール]-[(プロジェクト名)のプロパティ] でプロジェクト名を変更できます。

7. その他

マクロを作成しなくても、マクロに関係するデータがファイルに作成される場合があります。
例えば、Visual Basic Editor を開いた状態で新規作成し保存したファイルと、開いていない状態で新規作成し保存したファイルとでは、サイズが異なることがあります。これは、マクロ関係のデータが自動的にファイルに作成されるためです。
マクロ実行時のアクティブブックにマクロ関係のデータが作成される場合もあります。(メニューのカスタマイズ等、そのブックとは全く無関係の処理であっても、作成されることがあります)
このようなデータまで完全に削除したい場合は、新規にファイルを作り直すしかないと思います。


ワレモノ注意

Excel ファイルが壊れて開くことができなくなることがあります。

Word や Access で Excel ファイルを開くことでデータだけは取り戻すことができる場合があります。

Excel のセルに ='C:\My Documents\[Book1.xls]Sheet1'!A1 という数式を入力してデータを取り出すことができる場合があります。

ファイルが壊れる原因にはいろいろあるようです。バックアップを必ず取るようにしましょう。

また、フロッピーディスクから直接ファイルを開いているとファイルを破壊してしまう可能性が高いです。ファイルを開いている状態でフロッピーディスクを入れ替えたりする場合です。


せまいよ〜こわいよ〜

セルに 123 と入力して、表示形式を文字列に設定します。

列幅を少しずつ狭くして行くと、123 --> 120 --> ## --> # --> 0 --> (空白) と変化します。

列幅には余裕を持たせるようにしましょう。ワークシートの表示は環境に依存するのて、送り先の環境では 120 と表示されてしまうかもしれません。


幽霊リンクバスターズ

リンクを削除したのに、ファイルを開く際に「このシートにはリンクが設定されています」というメッセージが表示されることがあります。この現象は「幽霊リンク」と呼ばれたりします。

1. リンクの確認

まず、[編集]-[リンクの設定] で、どのようなリンクが残っているのか確認します。

以下の診断ツールのリンク検索も使ってみてください。(ただし、このツールはブック内のすべての要素を検索するわけではありません)

  エクセル ワークブック診断

Excel 2002 ではリンク解除等の機能が追加されました。

  ファイルを開く際に、"このブックには更新できないリンクが 1 つ以上含まれています。" エラーが表示される場合の対処方法
  http://support.microsoft.com/default.aspx?scid=kb;ja;882122

2. 非表示オブジェクトの再表示

シート、名前定義、図形オブジェクトは非表示になっている場合もあるので再表示して確認します。これにはマクロを使用する必要があります。「マクロあります」の「3. 非表示オブジェクトの再表示」を参照してください。

3. 数式の検索

[編集]-[検索] を使い、数式にリンクが残っていないか確認します。

検索する文字列 には以下のものを指定します。

ブック名([編集]-[リンクの設定] で表示されます)
' \ [ ] ! などの記号(リンク式にはこうした記号が含まれています)
#REF! などのエラー値

その他の設定は以下のようにします。

対象: 数式
大文字と小文字を区別する: オフ
完全に同一なセルだけを検索する: オフ

ブック内のすべてのワークシートを選択して検索を実行することもできます。(ただし、どれか 1つのシートで見つかった場合、検索を続けても他のシートは検索されません。検索を終了し、他のシートをアクティブにしてからもう一度検索を実行します)

4. 名前定義

名前定義の数式にリンクがあるかもしれません。各シートごとに [挿入]-[名前]-[定義] で調べます。なお、「名前の定義」ダイアログボックスには非表示の名前や、他シートのシートレベルの名前は表示されないので注意してください。以下の診断ツールでも、非表示の名前やシートレベルの名前を確認することができます。

  エクセル ワークブック診断 (ブックを選択、[診断]ボタンをクリックしてから、[名前...]に移動してください)

5. オブジェクト

図形やグラフ内のオブジェクトの数式またはマクロ登録にリンクがあるかもしれません。

数式は、オブジェクトを選択し数式バーで確認します。
マクロ登録は、オブジェクトを選択、右クリック、[マクロの登録] を選択し、確認します。

[編集]-[ジャンプ][セル選択] で [オブジェクト] を選択すると、シート内のすべてのオブジェクトを選択できます。また、オブジェクトを選択した状態で TAB キーを押すと、オブジェクトを一つ一つ選択して行くことができます。
グループ化されている場合はグループ内の個々のオブジェクトもチェックします。グループの解除は、オブジェクトを右クリックして [グループ化]-[グループ解除] を選択します。
埋め込みグラフやグラフシートのデータ系列、データ系列のラベル、その他の図形オブジェクトもチェックしてください。

6. リンク元に自ブックを指定する

リンク式がどこにもない場合、[編集]-[リンクの設定][リンク元の変更]でリンク元を自ブックに変更するとリンクが解消することがあります。

それでも解消されない場合、[リンク元の変更]、[今すぐ更新]、[リンク元の変更]、[今すぐ更新]、[リンク元の変更]、[今すぐ更新] のように、リンク元を自ブックに変更する操作を数回繰り返すと解消することがあります。

7. その他

どうしても幽霊リンクが解消されない場合、ファイルが壊れている可能性もあります。ファイルを作成し直す方が良いかもしれません。


メモリーを買えばいいの?

「メモリ不足です」というメッセージは「パソコンにメモリーを買い足してください」という意味ではありません。

Excel を操作していると、「メモリ不足です」というメッセージが表示されることがあります。また、ヘルプの「Excel の仕様」を読むと、「使用可能メモリに依存」と書かれている項目があります。それで、「メモリーを追加すれば良いんだな」「メモリーを追加すれば大きなファイルが扱えるのだな」と思い、物理メモリーを買いに行ってしまう人がいます。 これは間違いです。パソコンに物理メモリーを追加しても、Excel での問題が解決されるとは限りません。

メモリ不足のメッセージが表示されるのは主に以下の場合です。

たくさんのデータを処理している
たくさんのセル書式を使用している
ファイルが壊れている
その他

以下の 2つのことをおすすめします。

1. なるべく大きなファイルは作らない

たくさんのデータやセル書式は、ファイル破壊の原因になります。特に、複雑なワークシートを、一つのファイルにたくさん含めることは危険です。

2. 事前に最大データ量で動作確認をする

Excel ファイルのデータ量の上限は、データや数式の種類、セル書式の複雑さによって異なります。20MB のファイルで扱えるものもあれば、100KB のファイルで扱えなくなってしまうものもあります。
事前に最大データ量で動作確認をしておかないと、使っているうちに突然ファイルが開けなくなったり、動作が不安定になる危険性があります。大きなファイルを扱う場合にはご注意ください。


見ないで!

セルを見られないようにしたい、シートを隠したい、ファイルを開けないようにしたい、VBA のコードを見られないようにしたい… そういう要望がありますが、ファイルを渡してしまったら基本的に無理だと思ってください。

エクセルには以下のパスワードを使った保護機能があります。

1. シート保護
2. ブック保護
3. ファイルの読み取りパスワード
4. ファイルの書き込みパスワード
5. VBA プロジェクト保護

この中でファイルを暗号化するのは「ファイルの読み取りパスワード」だけです。「読み取りパスワード」でもすべてのデータが暗号化されるわけではなく、例えば、ブックの中の VBA のコードは暗号化されません。
結局、保護されるのは「読み取りパスワード」をかけたファイルの中の一部のデータだけで、その他のデータは保護されません。エクセル上で見えない、変更できないというだけです。パスワードがなくてもファイル形式の知識があればデータの取り出しや変更が可能です。

シート保護は元々マクロで無効にできるように作られている機能です。
シート保護とブック保護は勝手に解除されてしまうバグが知られています。
インターネットを検索するといろいろなプロテクト解除ツールが見つかり、誰でも入手することができます。

では、エクセルのセキュリティ(?)について、ちょっと体験してみましょう。
[ツール]-[保護]-[シートの保護] で xls というパスワードでシートを保護します。そして [ツール]-[保護]-[シート保護の解除] で now というパスワードを入力してみてください。解除できると思います。

これはバグではありません。シート保護とブック保護のパスワードは 2 バイトのデータに要約されます。違うパスワードでも要約した結果が同じなら、解除できてしまうのです。
このことは秘密の情報でもありません。マイクロソフトが出している「Excel デベロッパーズキット」という本に書いてあることです。

エクセルの将来のバージョンでこれらの保護が無効になる可能性もゼロではありません。実際に、Excel 5.0/95 のブック保護は Excel 97 以降では一部無効になってしまいます。(非表示にしたモジュールシートが表示されます)


パスワード忘れました! 〜弱いパスワードとの付き合い方〜

Ctrl キーと Shift キーを押しながら、メニューの [ツール]-[保護]-[すべての保護を強制解除] を実行するとすべての保護が解除できます… というのは嘘です。ごめんなさい。でも、本当にそんな機能があったらどうでしょうか。便利だと思いますか?

パスワードなしでプロテクトが解除できたら、パスワード機能自体が無意味になります。私は他の人の作ったソフトの機能を無意味にしようとは思いませんので、解除方法を知りたい方はご自分で調べてください。

もし誰にでもプロテクトが解除できると考えるなら、パスワードを使う理由もないはずです。解除されないことを期待して掛けたプロテクトを、今度はパスワードなしで解除したいと考えるのは筋が通っていません。気持ちはわかりますけど。

そんなわけで、提案です。

・パスワードを使わずに保護だけをする。
・短いパスワードを使う。
・忘れる心配のない特定のパスワードを使う。

パスワードを使用する上でやってはいけないことばかりですが、エクセルのプロテクトには期待しない、パスワード管理もファイルのバックアップも面倒という人には、悪くないやり方だと思います。


幽霊プロジェクトの怪

ブックを閉じても Visual Basic Editor のプロジェクトウィンドウにプロジェクトが残ってしまう現象を幽霊プロジェクトと呼んだりします。幽霊プロジェクトが保護されている場合は、Excel 終了時にパスワード入力のダイアログボックスが表示されます。

簡単な再現方法は、適当なモジュールでオブジェクト型の Public 変数を定義、ブックへの参照をセットしておいてそのブックを閉じる、というものです。

Public wb As Object
Sub Test()
    Set wb = Workbooks.Add
    wb.Close False
End Sub
これは、変数 wb にブックへの参照が残っているためなので、Set wb = Nothing としたり、[実行]-[リセット] でプロジェクトをリセットして変数を初期化すれば消えます。

このオブジェクト参照の解放のし忘れを Outlook Express と Excel がするようです。通常使うメーラーが Outlook Express のとき、Excel で [ファイル]-[送信]-[メールの宛先] を実行すると、ブックの中には MailEnvelope ストリームというデータが作成されます。このストリームのあるファイルを開くと内部的にブックへの参照が作成されるようです。ところが、メールの宛先が表示されている状態でブックを閉じればこの参照は解放されますが、表示されていない状態で閉じると解放されないようなのです。そして、プロジェクトだけが残ってしまいます。
一度、 MailEnvelope ストリームが作成されると自動的に削除されることはなく、ストレージエディタ等のツールで強制的に削除するか、ファイルを作成し直すしかないようです。(このツール(stgdir.lzh)を使い、 stgdir ファイル名 /d MailEnvelope を実行すると削除できますが、おすすめはしません)
通常使うメーラーを Outlook Express 以外にするとこの現象は発生しません。


メニューとツールバーの神隠し

ふと気が付くとメニューやツールバーがすべて初期化されて、ユーザー定義のツールバーもすべて消えていることがあります。

メニューとツールバーは Excel.xlb などの XLB ファイルに保存されます。XLB ファイルは Excel 起動時に読み取られ、終了時に上書きされます。(ファイル名と保存場所はバージョンや環境によって異なります)
メニューやツールバーがすべて初期化された原因としては、何らかの理由で XLB ファイルの読み取りができなかったことが考えられます。例えば、別の Excel が XLB ファイルの上書き中であったり、上書きの最中にハングアップしてしまったような場合です。その状態で新しく Excel を起動すると、XLB ファイルを読み取ることができずに、初期化された状態になります。

このような場合は、慌てて Excel を終了しないようにしてください。この時点ではまだカスタマイズした内容は XLB ファイルに残っている可能性があります。Excel を終了してしまうと、初期化された状態で XLB ファイルを上書きするので、今度は本当に変更内容はすべて消えてしまいます。

落ち着いて、XLB ファイルを検索して、念のため別のフォルダにコピーしてから、Excel で開いてみてください。カスタマイズした内容が残っていれば、消えていたメニューやツールバーが復活するはずです。

XLB ファイルの検索方法は、サポート情報などを参照してください。

[XL2000] メニューバーやツールバーの表示、非表示、またはリセットの方法
  http://support.microsoft.com/default.aspx?scid=kb;ja;825052
QA [Excel 2002] ツール バーやメニュー バーの設定を初期の状態に戻すには
  http://support.microsoft.com/default.aspx?scid=/directory/worldwide/ja/kblight/T009/3/05.asp


[戻る]