11
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

xlwingsでExcel VBAからPythonを実行&チュートリアルの補足

Last updated at Posted at 2016-06-10

Qiitaでxmlwingsというライブラリを使ってExcel VBAでPythonを動かすことができるという記事を見て、Quick Start + 補足をちょっと書いてみる
普段ブログで書いてるのでQiitaの方で補足書いてみるのも良いかなということで

xlwingsがv0.9以降で大きく変更が入っていたようで、現状のコードで動かないためv0.9以降について追記

開発環境

  • Windows 7 (32-bit)
  • Office 2010 SP-2

インストール

特に特殊なことはなくてpipでインストールするだけ

pip install xlwings

私の環境では下記の場所にインストールされる。後でExcel側からファイルをインポートする際に参照する場所
C:\Python27\Lib\site-packages\xlwings

サンプルを実行

サンプルコード

Excelから呼び出すpythonモジュール

  • xlwings v0.9以前
mymodule.py
import numpy as np
from xlwings import Workbook, Range

def rand_numbers():
    """ produces standard normally distributed random numbers with shape (n,n)"""
    wb = Workbook.caller()  # Creates a reference to the calling Excel file
    n = int(Range('Sheet1', 'B1').value)  # Write desired dimensions into Cell B1
    rand_num = np.random.randn(n, n)
    Range('Sheet1', 'C3').value = rand_num
  • xlwings v0.9以降

参考:https://docs.xlwings.org/en/stable/migrate_to_0.9.html

mymodule.py
import numpy as np
import xlwings as xw

def rand_numbers():
    """ produces standard normally distributed random numbers with shape (n,n)"""
    wb = xw.Book.caller()  # Creates a reference to the calling Excel file
    n = int(wb.sheets['Sheet1'].range('B1').value)  # Write desired dimensions into Cell B1
    rand_num = np.random.randn(n, n)
    wb.sheets['Sheet1'].range('C3').value = rand_num

Excel側にで書くVBAコード

v0.9以前はRAW文字列じゃない場合でも使用できていたが、現在のv0.9以降現在の版数では\を使用する場合はRAW文字列にするかパス区切り文字を/にしないとエラーするようになっている。

  • v0.9以前
ExcelVBA
Sub RandomNumbers()
    RunPython ("sys.path.append('C:\Temp'); import mymodule; mymodule.rand_numbers()")
End Sub
  • v0.9以降
ExcelVBA
Sub RundomNumbers()
    RunPython ("sys.path.append(r'C:\Temp'); import mymodule; mymodule.rand_numbers()")
'    RunPython ("sys.path.append('C:/Temp'); import mymodule; mymodule.rand_numbers()")
End Sub

このVBAのコードサンプルでは
RunPython ("import mymodule; mymodule.rand_numbers()")となっているのだがこれがチュートリアルのちょっとしたトラップなのかなと
mymodule.pyというファイルをどこに置けば良いのかというようなことが書かれているのだが、RunPythonimportの前に任意のパスを追加すればどこに置いても構わない。
今回はパスを通していないC:\Tempmymodule.pyを置いてみた。
Excel自体は、C:\Users\h_oki\Documents\booktest.xlsmで保存しておいて、モジュールは別の場所にまとめておきたかったけどテスト用にどこからでも読み込めるか確認したかったため上記のとおりとした。

補足

VBAとかExcelとかは関係なく、あくまでPythonのコードを実行しているだけなので、その後にパスを設定してあげることで任意の場所に置いてあるモジュールでも読み込める。
import sysはxlwingsの中で勝手に読み込まれるため特に記入する必要はない。
サンプルコードではパスの通った場所か直下に置かないと読み込めないが任意のパスに置きたい場合は、sys.path.append('/your/to/path')import mymoduleの前に書いてあげるだけで良い。
また、sys.path.append('/your/to/path')を追加しなくても環境変数PYTHONPATHに設定してある場所であれば問題はなさそう。

実行結果

なぜか画像がアップロードできなかったため省略させてください。
ただ、任意の場所に置いたmymodule.py(クイックスタートのコードそのもの)は実行できました。

参考記事

関連記事

xlwingsを使うぜ
ExcelからPythonスクリプトを実行し、結果をExcelにグラフ表示できるxlwingsで遊んでみた。

公式

xlwings公式
Quickstart

11
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?