無限不可能性ドライブ

『ニューラルネットワーク自作入門』に刺激されてExcelVBAでニューラルネットワークを作ってみたものの、やっぱり数学やらなきゃと思い少しずつやってきたのもあって、自分の知識の整理とかそういった感じです。

【VBA】VBAからPythonのコードを実行してみる(1)【Python】

VBAにないなら Python のを使えばいいじゃない

ExcelVBAを書いていて「この処理 Python で書けば楽なのに…」とか思うことってないでしょうか。
例えば、

 サブフォルダを含めてファイルの一覧を取得したいけどVBAでどう書いたっけ?
 Python なら os.walk で簡単に書けるのになぁ…VBAにも os.walk みたいな関数があればいいのに。。

とか。

今回はそんなときのために Excel VBA から Python のコードを実行する方法についてみていきたいと思います。
Windows環境でPythonの環境構築が終わっている前提です。)

(準備1)xlwings と pywin32 のインストール

まずは必要なものをインストールします。

xlwings

コマンドプロンプトを起動してpip インストールでインストールしましょう。

pip install xlwings

Pythonの対話モードなどでインストールの確認をします。

>>> import xlwings

エラーにならなければOKです。

pywin32

こちらも同様に。

pip install pywin32

インストールの確認(pywin32 でなく win32 です)

>>> import win32

ちなみに、Anaconda の入っている私の環境では両方ともインストール済みでした。

(準備2)xlwings.bas ファイルを探して Excel VBA にインポートする

xlwings のインストールが正常に完了していれば、xlwings.bas ファイルがどこかにあるはずです。
Windows の検索機能を利用するなどしてファイルの場所を特定しましょう。
なお、私の環境では以下のフォルダにありました。

C:\Users\xxxx\Anaconda3\pkgs\xlwings-0.10.2-py36_0\Lib\site-packages\xlwings

ファイルのありかがわかったら、Excel VBA にインポートします。
VBE を開いて「ファイルのインポート」で xlwings.bas をインポートしてください。
インポートすると標準モジュールに「xlwings」というモジュールが読み込まれます。

これでひととおりの準備が完了です。

ここまでできたら、ファイルをいったん保存しておきましょう。
今回は「xl2py.xlsm」というファイル名にしてみました。
ついでに、今後のコードを書くための標準モジュールも追加しておきましょう。

f:id:celaeno42:20181126231450p:plain

(お試し)簡単なコードで動作確認

まずは簡単なコードで動作の確認をしてみましょう。
A1セルのテキストをコピーしてA3セルに貼り付ける処理を作ってみます。
貼り付ける前に若干の加工もしてみましょう。

(お試し)Pythonコードの準備

VBAから呼び出す Python のコードを準備しましょう。
ファイル名は「copy_text.py」とし、先ほど作成した Excel ファイル(xl2py.xlsm)と同じフォルダに作成します。

【copy_text.py】

import xlwings as xw

def copyAddText():
    txt = xw.Range('A1').value
    txt += ', I am the Doctor.'
    xw.Range('B3').value = txt

xlwings を import し xw でアクセスできるようにしています。
copyAddText 関数の内容はそれほど説明することはないかと思います。
txt = xw.Range('A1').value で A1 セルの値を変数 txt に格納しています。
その後加工して B3 セルに格納しなおしています。

(お試し)VBAからの呼び出し

上記で作成した Pyhon コードを VBA から呼び出す処理を記述します。
今回は標準モジュールにコードを書いています。

VBA - 標準モジュール】

Option Explicit

Public Sub copyText()
    Call RunPython("import copy_text; copy_text.copyAddText()")
End Sub

RunPythonプロシージャ の引数に呼び出すPythonファイルと関数の情報を渡します。
引数の書き方は、[ "import pythonファイル名; pythonファイル名.関数名()" ] というような感じになっています。
拡張子の .py は不要です。
ちなみに RunPython プロシージャは先ほど Excel にインポートした xlwingsモジュール内に記述されています。

(お試し)VBAの実行

では、VBAを実行してみましょう。
Python のコードでは、A1 セルの値を取得していたので、実行前に A1 セルに「Hello」と入力しておきます。
f:id:celaeno42:20181125235350p:plain


VBAの「copyText()」を実行すると…
f:id:celaeno42:20181126232006p:plain

このようになります。
無事 Python のコードが実行されて、その結果が Excel のセルに反映されました!

次回はいよいよ「Pythonコードでのファイル一覧取得」についてみていきます。


※※ 私が10月から参加させていただいているノンプロ研のアドベントカレンダー3日目の記事です。 ※※
※※ ノンプロ研はこの12月で開始からちょうど1年だそうです。おめでたいですね! ※※
adventar.org