プロが教える店舗&オフィスのセキュリティ対策術

VBAを使っていて

http://blog.goo.ne.jp/mumbai/e/dc90cf94fc40baebf …

#If VBA7 Then
Debug.Print "EXCELは2010以上です。"
#Else
Debug.Print("EXCELは2007以下です。")
#End If

というように、#IFというようなものが出てきます。

これの使用方法を知りたいのですが検索して調べたところ、

https://msdn.microsoft.com/ja-jp/library/tx6yas6 …

このページに書かれてあるように
#があるとコンパイル時にif文の評価を行うのに対し、
#がないとif文も含めてコンパイルした後に、プログラムを実行する時にif文の評価を行う
といったことが書かれてあります。

それで試してみたのですが


#If VBA7 Then
aa=0
#Else
aa=1
#End If


というコードを実行するとaa=0が代入されます。

一方で

If VBA7 Then
aa=0
Else
aa=1
End If
というコードを実行するとVBA7がemptyになっており
aa=1が代入されます。

これはVBA7という変数がコンパイル時にのみ有効で
実行時には存在しないためだからでしょうか?

質問者からの補足コメント

  • 納得しました
    ありがとうございます。

    No.1の回答に寄せられた補足コメントです。 補足日時:2016/06/26 23:28

A 回答 (2件)

少しだけですが、


#If VBA7 Then
aa=0
#Else
aa=1
#End If
の『VBA7』は条件付きコンパイル中で使える定数です。
あらかじめVBAの中に組み込まれています。

で、
If VBA7 Then
aa=0
Else
aa=1
End If
とした場合の『VBA7』は一般的な単なる変数です。

VBEでツール→オプションの編集タブにある「変数の宣言を強制する」に
チェックを入れてあると
「コンパイルエラー :変数が定義されていません」になるはずです。
でチェックを入れていない場合はVariant型として定義されますので
Empty値の初期値は、False、0、"" のいずれかになりますから
If VBA7 Then → False → aa=1 となるわけです。
この回答への補足あり
    • good
    • 0

せっかく#1さんが解説した後で、こちらが訳の分からないようなことを書くのはおこがましいと思われるかもしれませんが、



私は、#IF ダイレクティブをみて、

語学などで使う用語で メタ言語と呼ばれるものがありますが、それだなと思いました。つまり、メタ言語というのは、言葉を言葉で規定するということです。

この「メタ」という概念をプログラミングに置き換えると、VBAの一般の記述があり、それを「一つ上の段階から定義したり規定させること」ができるものと解釈できます。

あまり良い例が思いつきませんでしたが、

ひとつは、バージョンや32bit, 64bit で切り分けなくてはならない場合と、

もうひとつは、プロジェクト全体として、環境の違いにより、致命的なエラーを回避する必要がある時

だと思います。

ただ、よくよく考えてみると、Option Explicit で変数の宣言を強制するとか、32bit と64bit の違いによるプログラムの違いとかでないと、それほど重要な位置にとなるものは少ないのではないでしょうか。

だから、もし、これを同じVBAのステージで行うなら、例えば、バージョンなら、Val(Application.Version) などで、Version を取るのが普通です。

>これはVBA7という変数がコンパイル時にのみ有効で
>実行時には存在しないためだからでしょうか?

と言われれば、否定はしないけれども、VBA7は変数ではありませんね。条件付きコンパイル定数というわけで、予め組み込まれているわけですが、後々、気がついたことですが、VBA7 は、Excel 2010 以降とそれ以外を分けるものになっているわけで、こういう区分けは、あまり意味があるとは思えません。

Option Explicit
#If VBA7 Then
 Dim ret As Long 'Office 2010以降はこちらです。
#Else
 Dim ret As Integer '2007だと、こちらになる
#End If
Sub Test1()
 MsgBox TypeName(ret)
End Sub

そのコードをコンパイルで巻き込むとエラーを出すので、回避するためが中心で、それ以上に重宝するとも言えません。

それに、どこまでこの条件付きコンパイル定数が登録されているのかは、分かりません。せいぜい、64bit と32bit を分けるWin32 APIの区分けぐらいだけです。

Excel2003とそれ以降のファイルの違いで、リボン・コントロールイベントとクラスイベントの区分けを#IFダイレクティブで区分けできるとも言えません。せいぜい、コードエラーを出さないだけでしかありませんでした。
例:
http://oshiete.goo.ne.jp/qa/9317937.html
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!