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
  • 64ビット環境サポート及びそれに伴うWindows APIコールの変更

最近の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から作り直す方が良いくらいの勢いだった)。