<< えっちでよくないブラウザ | main | トライアスロン >>
2008.07.10 Thursday

Excelのバグ

たまにはExcelネタを。それもVBAのバグネタです。
つい先日、私自身がこれにハマりました。

まず「前提」の1つめ。
Excel VBAではプロパティを省略することが許されています。
プロパティを省略すると、そのオブジェクトの"既定のプロパティ"が指定されたものとします。
たとえばセルに値を代入するとき、セルの値はValueプロパティですから、本来なら次のように書くのがセオリーです。

Range("A1").Value = "tanaka"

これを、プロパティを省略して、次のように書いてもOKです。

Range("A1") = "tanaka"

次に「前提」の2つめ。
VBAの変数にはバリアント型という型があります。
バリアント型にセル(Rangeオブジェクト)を格納すると、変数を介してセルを操作できます。
次のコードで確認してみましょう。

Sub Sample1()
  Dim c
  Set c = Range("A1")
  c.Font.ColorIndex = 3
End Sub


以上の「前提」から、次のコードは何も問題がないように思えます。
選択したセル範囲(Selection)の各セルに対して、セルの値(数値とします)を10倍します。

Sub Sample2()
  Dim c
  For Each c In Selection
    c = c * 10
  Next c
End Sub


ところがコレ、まったく機能しませんし、エラーも発生しません。
いったい、どうしたことでしょう。

あれこれと試した結果、回避策はわかったのですが、そもそも原因は何なのでしょう。
調べてみたら、Excelのバグでした。
詳しくは、次のサポート情報(機械翻訳)に書かれています。

■XL98: Value プロパティがバリアント種類の For Each ループに unchange しました。
http://support.microsoft.com/kb/191176/ja


Excel 97とExcel 2007で確認しましたが、確かにおかしいです。

回避策は次の2点です。

・セルを格納する変数は、バリアント型ではなくObject型やRange型を使う

Sub Sample3()
  Dim c As Range
  For Each c In Selection
    c = c * 10
  Next c
End Sub


・代入される側のプロパティを省略しない

Sub Sample4()
  Dim c
  For Each c In Selection
    c.Value = c * 10
  Next c
End Sub


どうせプロパティを省略しないのなら「c.Value = c.Value * 10」と書くべきでしょうけど。
また、Microsoftのサポート情報では「For Eachループ内で発生する」ように書かれていますが、次のようなコードでも同じバグが発生します。

Sub sample5()
  Dim c
  Set c = ActiveCell
  c = c * 10
End Sub


これは、遭遇する機会の多いバグだと思います。十分に注意してくださいな。
コメント
バグというか、一瞬不思議な仕様ですね。加算代入演算子(+=)があれば良いのかな。(^^A)
  • 藤代千尋
  • 2008.07.10 Thursday 17:32
う〜む。でも、加算代入だけでなく、

Sub sample5()
  Dim c
  Set c = ActiveCell
  c = Now()
End Sub

Sub smaple6()
  Dim c
  For Each c In Selection
    c = Now()
  Next c
End Sub

なんてのもダメですからね。

こうした書き方がダメだという必然性を感じませんから、やっぱ、バグでしょう(^^;
  • 田中亨
  • 2008.07.10 Thursday 20:25
そうか。再代入で入れたものが入れ替わってしまうので、=Now() でもダメですね。

でも私的には“VBA の”仕様として正しく見えるのですが。今まで、これが元のエラーに出会ったことがないですし。(^^;)
#変数の型宣言無しや、オブジェクトしかいれないのに Variant 型を使ったりはしたことが無い。
  • 藤代千尋
  • 2008.07.11 Friday 01:25
普通に仕様かと。
「変数の型情報(オブジェクト型)に基づいて既定のプロパティを指定したものとする」が仕様かと思います。
「オブジェクトの〜」ではなく「オブジェクト“型”の〜」なのです。
だから、バグじゃないんです。仕様です。

VB言語の設計ミスというのなら、まだ理解できますが・・・。
バリアント型の変数はあくまでもバリアント型で、オブジェクト型として扱われると言語仕様的には複雑かなと思います。(使い勝手とは別ですが、実行効率に影響がでるかと思います)
仮に修正するとしても、過去に作られた膨大なマクロの資産に影響をおよぼすため絶対に変更できない仕様でしょう。
最近、VBA Excel を使っているので仕様を確認したりするのですが、16ビット時代のコンピュータの頃からの仕様やら何やら、ひどい仕様があるのは同意できます。
  • オガワ
  • 2013.03.09 Saturday 01:57
コメントする








 
この記事のトラックバックURL
トラックバック
excelのこと
楽天から検索された商品Microsoft Office Specialist問題集 Microsoft Office …¥ 2,100オススメ度:★★★★Microsoft Office Specialist 公認コースウェアよくわかるマスター 著者:富士通オフィス機器株式会社出版社:富士通エフ・…速効!パソコン講座エクセル¥ 53
  • WEBの情報缶!
  • 2008/07/10 7:31 AM
Calendar
   1234
567891011
12131415161718
19202122232425
262728293031 
<< March 2017 >>
Selected Entries
Categories
Archives
Recent Comment
Recent Trackback
Recommend
Recommend
Recommend
Recommend
Recommend
Links
Profile
Search this site.
Others
Mobile
qrcode
Powered by
30days Album
無料ブログ作成サービス JUGEM