愛用マクロを64bit版Excelに早急に対応させる必要が出てきたので、ソースコード上のWin32APIのDeclare文を64bit対応に自動変換プログラムを作ってみたので紹介する。
なお、Declare文の変更だけでは完全に64bit対応とはならないので、実際に使う人はちゃんと勉強してから使うこと。
はじめに
つい先日(2017-2018年頃)まで、Microsoftは「32bit版 Excelを推奨」としていた。
実際に推奨設定でインストールした場合、32bit版が入ったと認識している。
ところがココ最近は推奨設定でインストールすると「64bit版 Excel」がインストールされるようになってしまった。
64bit版Excelになると何が困るかというと、VBAでWin32APIを使用している場合にDeclare文
でコンパイルエラーが起こるのである。
--------------------------- Microsoft Visual Basic for Applications --------------------------- コンパイル エラー: このプロジェクトのコードは、64 ビット システムで使用するために更新する必要があります。Declare ステートメントの確認および更新を行い、次に Declare ステートメントに PtrSafe 属性を設定してください。 --------------------------- OK ヘルプ ---------------------------
解消方法については既にたくさんの情報が公開されているため割愛するが、既存の方法では一つ一つ書き換えていくのがとにかく「めんどくさい」のである。
特に「Office2007対応」が求められている場合は、宣言文が入れ子になりさらにめんどくさい。
というわけで、ソースコードを自動的に変換するプログラムを思いついたので即興で書いてみた。(開発時間4時間くらいなので、改善の余地はあると思うが自分のは完成したのでヨシ!)
サンプル
早速だが、今回用意した関数を使うと、ソースコード(文字列)は以下のように変換される。
変換前1
Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
変換後1
#If VBA7 Then Private Declare PtrSafe Function SetCursorPos Lib "user32" Alias "SetCursorPos" ( _ ByVal x As Long, _ ByVal y As Long _ ) As Long #Else Private Declare Function SetCursorPos Lib "user32" ( _ ByVal x As Long, _ ByVal y As Long _ ) As Long #End If
変換前2
Declare Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" (ByVal xPoint As Long, ByVal yPoint As Long) As LongPtr
変換後2
#If VBA7 Then #If Win64 Then Declare PtrSafe Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" ( _ ByVal Point As LongLong _ ) As LongPtr #Else Declare PtrSafe Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" ( _ ByVal xPoint As Long, _ ByVal yPoint As Long _ ) As LongPtr #End If #Else Declare Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" ( _ ByVal xPoint As Long, _ ByVal yPoint As Long _ ) As Long #End If
※Declareと関数名を元にtxtを探索しているので、どのような宣言方法になっていても変換できる。
※VBA7
とWin64
スイッチを判定しているので、変換後のソースに変換を掛けても大丈夫。
自動変換関数
まずはソースコード(テキストファイルデータ)を自動的に変換するための関数を作ってみた。
事前準備と使い方
64bit対応に際してはMicrosoftのサイトを良く読むこと
Win32API_PtrSafe.txt を入手して、マクロを記述したブックと同じ場所に保存すること
- ソースコードを
Const TESTFILE = "Win32API変換テスト.bas"
のように用意しておくこと - テスト実行は
TESTFILE
のファイルを用意してSample
を実行 - 基本的にはソースコードの文字列を
ConvertVBAcode関数
で変換するだけでOK - パラメータのインデント幅は定数
P_INDENT_LEVEL
で変えられる。 - パラメータの自動改行は関数
InsertDeclareIndent
で行っているので、これを消せばOK - ちなみに、コメントアウトされていても変換する。
- ついでに、無意味な改行の繰り返しは自動的に除去する。
- Private / Public / 未指定は保持される。
- Win32PI_PtrSafe.txtは全て網羅されているとは限らない。txtに記載されていないものは文法の置き換えだけで完全な対応とはならないので注意
ソースコード
標準モジュールを作成してそこにコピペすればOK
使用例
関数だけでは面白みがないので、実際に活用するフォームを二種類作ってみた。
左側のテキストボックスにDeclare文をコピペすれば、瞬時に右側に変換プログラムが表示される。
左側のテキストボックスに関数名を入れただけで、瞬時に右側にプログラムが生成される。
ソースコード
UserForm1を作成して貼り付けるだけでOK。
コントロール等の設置は不要。
参考
ツール
ちなみに、Declareの宣言文の作成であれば、こんなツールもある。
https://www.rondebruin.nl/win/dennis/windowsapiviewer.htm
ディレクティブで分岐できない(?)
1件づつ関数をポチポチしないといけない
Win32API_PtrSafe.txtよりは網羅されている印象
という感じです。
関連ツイート
ようやく身軽になったので早速VBAを書こう。
— ちゅん🐥えくせるちゅんちゅん (@KotorinChunChun) 2019年10月20日
早急にVBAの64bit対応が求められているので、Win32APIのDeclare文のコーディングを自動化するマクロを書こうと思う。
はてなブログに投稿しました #はてなブログ
— ちゅん🐥えくせるちゅんちゅん (@KotorinChunChun) 2019年10月20日
VBAでWin32APIの64bit対応自動変換プログラムを作ってみた - えくせるちゅんちゅんhttps://t.co/RiZZhRZS93
まとめ
とりあえず大量のAPIの置き換えはこれで楽に対処できそうだ。
しかし動かない部分が沢山あるはずなので、動作テストには時間がかかりそうである。
よほど巨大なデータを扱わない限り64bit版Excelを使うメリットはないので、社内のPCは32bit版をインストールするようにしたほうが幸せになれると思う。
2023/5/9追記:現在はExcelをインストールすると基本が64bitなので64bitを前提としたソースコードに作り変えることを推奨する。
またExcel2007は流石に古すぎるので完全に破棄しましょう。Office365 / Excel 2019最高やで!
2023/5/9追記:Excel2013まではサポートが終了した。Microsoft365こそが至高である。
以上
何か御座いましたらコメント欄、またはTwitterからどうぞ♪
それではまた来週♪ ちゅんちゅん(・8・)
2020/8/9追記:64bit化で何をすべきなのか解説しました。
2020/9/27追記:本記事のプログラムを、GitHubで公開しているアドインに統合しました。