Excel VBAの密かな変化
最近、仕事でExcel 2013のVBAを使ってマクロを組むことがあります。VBAは久々に触りましたが、最近のプログラミング言語ではサポートされていることの多い無名関数やらジェネリック型はおろか、変数の宣言と同時の初期化や、ハッシュテーブル*1や、コードブロックごとの変数スコープすらサポートされておらず、10年以上前に第一線からは退いたVB6の時代から、VBAの言語自体は進化していないことに気づきました…。*2
ここでふとVBAのバージョン番号を見てみると、7.0になっていました。確かExcel 2000では6.0だったと思うので、いつの間にかメジャーバージョン番号が上がったことになります。そこで、VBA 6.xとVBA 7.0の違いについて調べてみました。
- 新しい型
64ビット整数を扱う型として、LongLong型が新設されています。同時にCLngLng関数も新設されています。
- 新しい条件付きコンパイル定数
VBAのバージョンが7か6.x以前か, および64ビット環境か32ビット環境かどうかを表す定数として、VBA7およびWin64というコンパイル定数が新設されています。
#If VBA7 Then ' VBA7用のコード #Else ' VBA6.x用のコード #End If
最近のWindowsは64ビット版があるため、それに伴いWin32 APIを呼ぶときに使用するポインタのサイズも32ビットから64ビットに変わっています。
両方の環境で実行できるようにするため、LongPtrという型が新設されています。Declareステートメントで外部のAPIを呼ぶ箇所は、それを使うように変える等が必要になります(他にPtrSafe属性も必要)。
ここでVB.NET経験のある方は注意が必要です。VB6→VB.NETになった時(2002年頃)にInteger型が16→32ビット, Long型は32→64ビットに変わったのですが、VBA 7では未だにInteger型: 16ビット, Long型: 32ビットです。VB.NETと同じ感覚で変換するとExcelが落ちると思います。
- 32ビット版Active XコントロールおよびCOMアドインとの非互換
(VBA7というより64ビット環境の問題ですが)32ビット版のActive Xコントロール等はサポートしていないようです。MSComCtl*3やMSComCtl2など結構使われていそうなものも、使えなくなってしまいます…。
こうして見ると、VBAの言語自体はほとんど変わっていないということが分かりました*4。VB6やVB.NETと違ってVBAは非エンジニア向けのものと言えるので、バージョン間の互換性を保つ必要が高い*5のは確かです。ただ変数の宣言と同時の初期化くらいはサポートしていると嬉しかったのですが…。
参考URL:
http://msdn.microsoft.com/en-us/library/ee691831(v=office.11).aspx
http://stackoverflow.com/questions/3072356/what-are-the-differences-between-vba-6-0-and-vba-7-0
*1:CreateObject("Scripting.Dictionary")で使うことはできますが、言語の標準機能というわけではない
*2:新しい言語に慣れている人がVBAを触ると、回りくどい書き方をする必要があるため、手枷をはめられた気分になりそうです。
*3:プログレスバーなど、標準のフォームには入っていないが使いたいコントロールが収録されている
*4:そもそもWindows APIをマクロから呼びまくるのはどうかと思いますが…。
*5:言語仕様変更による書き換えは、開発をメインでやっている人以外が行うには重い仕事です。VB6→VB.NETの書き換えはかなり大変でした(可能ならば1から作り直す方が良いくらいの勢いだった)。