Pythonの応用 - PyXLL

提供: MochiuWiki : SUSE, EC, PCB

概要

PyXLLは、開発者がExcelの機能をPythonコードで拡張できるようにするExcelアドインである。
Pythonを生産的で柔軟なExcelワークシートのバックエンドにして、Excelのユーザインターフェイスを使用して情報インフラの他の部分とやり取りできるようにする。

PyXLLを使用する場合、Pythonディストリビューション (Anaconda、EnthoughtのCanopy、CPython 2.3〜3.10ディストリビューション等) を使用してPythonコードをExcelで実行できる。

PyXLLは独自の完全なPythonディストリビューションを実行するため、NumPy、Pandas、SciPy等の全てのサードパーティのPythonパッケージにアクセスでき、Excelからそれらを呼び出すことができる。

PyXLLの使用例を以下に示す。

  • 既存のPythonコードを呼び出してExcelで計算を実行する。
  • データ処理および分析
  • データベース等の外部システムからデータを取り込む
  • 大規模なデータセットを照会してExcelでサマリーレベルのデータを表示する。
  • Excelユーザに内部ライブラリやサードパーティライブラリを公開する。


デコレータ構文 (@xl_func等) のシンタックスに対応している必要がある。(Python 2.4以降が必要)
非同期関数のコルーチンシンタックスに対応している必要がある。(Python 3.5.1以降が必要)

※注意 1
Windowsストア経由でインストールされたPythonは使用できないため、Pythonの公式WebサイトからPythonをインストールすることが推奨される。
WindowsストアアプリまたはUWPアプリケーションのインストール方法では、必要なファイルにアクセスできないからである。

※注意 2
Microsoft Excel for Windows 2003が最小サポートバージョンである。
Office 365またはExcel 2016以降が推奨される。

PyXLLの機能の詳細を知りたい場合は、公式ドキュメントを参照すること。


対応バージョン

PyXLLの対応バージョン情報は以下の通りである。

PyXLLバージョン

  • 最新バージョン: PyXLL Version 5.11.2
  • サポート対象: PyXLL Version 5.x系列


Pythonバージョン

  • Python 2.3以降
  • Python 2.4以降 (デコレータ構文のサポート)
  • Python 3.5.1以降 (非同期関数のコルーチンシンタックスのサポート)
  • Python 3.14 (2026/1 最新) まで対応


Excelバージョン

  • Microsoft Excel for Windows 2003以降
  • Office 365
  • Excel 2016以降 (推奨)



PyXLLの制限事項

WindowsとExcelの互換性

PyXLLはWindows向けに設計されており、Windows上のMicrosoft Excelで動作する。
Windows向けに最適化されているため、Windows以外のプラットフォームでは機能が制限されたり、互換性の問題が発生したりする可能性がある。

Windows for ARM64はサポートされていない。

MacOSとLinuxはサポートされていない。
例えば、Linux上で開発する場合は、KVMでGPUパススルーした仮想マシンでWindowsを実行することが推奨される。

導入

PyXLLを使用したスプレッドシートをエンドユーザに導入する場合は、最小限の依存関係でPythonがインストールされているか、スプレッドシートにバンドルされているPythonランタイムが必要である。
つまり、PyXLLを利用したスプレッドシートを使用するユーザは、Pythonをインストールする必要がある。

学習曲線

PyXLLを効果的に使用する場合、PythonのシンタックスとExcelのオブジェクトモデルに精通していることが必要となる。


PyXLLの料金

年間契約

1ユーザ $299 / 年 (料金には、VAT、GST、売上税は含まれない)
また、マルチユーザライセンスの割引がある。

いつでもユーザを追加することが可能である。

月額契約

1ユーザ $29 / 月 (料金には、VAT、GST、売上税は含まれない)

いつでもキャンセル可能です。

個人ユーザに最適である。
いつでもユーザを追加することが可能である。


PyXLLのインストール

pipコマンドを使用して、PyXLLパッケージをインストールする。
condaまたは仮想環境を使用している場合は、コマンドを実行する前に有効にする必要がある。

pip install pyxll


PyXLLパッケージのインストールが完了した後、PyXLL Excelアドインをダウンロードしてインストールする。
"Do you have a PyXLL license key?" と尋ねられた場合、"n" と入力することにより、30日間の無料試用版が自動的に有効になる。

pyxll install


画面の指示に従ってインストールを完了する。
"Have you already downloaded the PyXLL add-in?" と尋ねられた場合は、"n" と入力すると、インストーラが必要なライブラリを全て自動的にダウンロードする。

必要であれば、PyXLLの公式Webサイトにアクセスして、PyXLLをダウンロードしてインストールする。
上記のWebサイトからダウンロードする場合、使用するPythonとExcelのバージョンを選択すること。

※注意 1
ダウンロードページからPyXLLをダウンロードしている場合は、パスが求められた時にエクスプローラからコマンドプロンプトにZIPファイルをドラッグ&ドロップすることができる。

※注意 2
Pythonはx86版とAMD64版の両方がサポートされているが、アーキテクチャが異なるExcelを混在させることは不可能である。
例えば、MS Office x86とPython AMD64を混在させることはできない。

PyXLLアドインが正常にインストールされた場合、Excelを起動すると自動的にアドインが読み込まれる。
また、PyXLLアドインがインストールされたフォルダには、PyXLLアドインとその設定ファイルと共にいくつかのサンプルが含まれている。


PyXLLアドインのインストールフォルダ

PyXLLをインストールする場所を覚えていない場合は、pyxll statusコマンドを使用して確認する。
または、ExcelのPyXLLメニューの[About]オプションを選択して確認する。

PyXLLのインストールフォルダには、以下に示すファイルがある。

  • pyxll.cfg
    PyXLLの構成ファイルであり、独自のPythonモジュールをロードするためにこれを変更する必要がある。
    インストールされた構成ファイルの例には、使用可能な設定のドキュメントが含まれている。
    PyXLLの設定オプションの詳細については、ユーザガイドの[Configuring PyXLL]セクションを参照すること。

  • exampleフォルダ内のExcelワークブックの例とコードの例
    このフォルダには、PyXLLアドインの使用方法を理解するために役立つ例がある。
    サンプルは全てデフォルトのPyXLL設定で読み込まれるため、examplesワークブックを開いて試すだけである。

  • ログファイル
    デフォルトの設定では、ログファイルのパスはPyXLLドメインのインストールフォルダ内のlogsフォルダに設定されている。
    logsフォルダには、PyXLLのログファイルがあり、Excelのワークシート関数やマクロを実行する時にスローされる例外のPythonスタックトレースの全データを含め、全てのエラーがこのファイルに記録される。
    そのため、問題が発生した場合は、最初にこのファイルを見る必要がある。

    設定ファイルの[LOG]セクションでvebosity = debugと設定することにより、デバッグロギングを有効にして不具合の詳細を知ることができる。
     [LOG]
     verbosity = debug
    



PyXLLの設定ファイル (pyxll.cfg)

PyXLLの動作は、インストールフォルダ内の設定ファイル (pyxll.cfg) で制御される。
この設定ファイルを編集することにより、Pythonの実行環境、ロードするモジュール、ログの詳細レベル等を設定できる。

[PYTHON]セクション

[PYTHON]セクションでは、Python環境に関する設定を行う。

  • pythonpath
    Pythonモジュールを検索するパスを追加する。
    複数のパスを指定する場合は、改行で区切る。
    相対パスと絶対パスの両方を指定できる。
     [PYTHON]
     pythonpath =
        c:\path\to\your\code
        .\relative\path
    

  • modules
    PyXLLが読み込むPythonモジュールを指定する。
    複数のモジュールを指定する場合は、改行で区切る。
    指定されたモジュールは、Excel起動時に自動的にロードされる。
     [PYTHON]
     modules =
        my_module
        excel_functions
    

  • executable
    使用するPythonインタープリタのパスを指定する。
    特定のPythonバージョンや仮想環境のPythonを使用する場合に設定する。
     [PYTHON]
     executable = c:\Python312\python.exe
    


[LOG]セクション

[LOG]セクションでは、ログに関する設定を行う。

  • verbosity
    ログの詳細レベルを設定する。
    設定可能な値: debug, info, warning, error
    デバッグ時は debug を設定することが推奨される。
     [LOG]
     verbosity = debug
    

  • path
    ログファイルの出力先を指定する。
    デフォルトでは、PyXLLインストールフォルダ内のlogsフォルダに出力される。


設定ファイルの例

pyxll.cfgの設定例を以下に示す。

 [PYTHON]
 pythonpath =
    c:\path\to\your\code
    .\relative\path
 
 modules =
    my_module
    excel_functions
 
 executable = c:\Python312\python.exe
 
 [LOG]
 verbosity = debug



PyXLLのサンプル

PyXLLアドインのインストールフォルダに、examples.xlsxというサンプルワークブックが存在する。
このワークブックには、PyXLLの機能の一部を示す例がいくつか含まれている。

独自のモジュール (.pyファイル) を追加する場合は、pyxll.cfgファイルにあるモジュールリストに追加する必要がある。

examplesフォルダだけでなく、他のフォルダにあるモジュールも追加できる。
その場合、pyxll.cfgファイルのpythonpathキーに独自のフォルダのパスを追加する。

独自のPython関数をワークシート関数としてExcelに公開する方法を知りたい場合は、公式ドキュメントのワークシート関数を参照する。

PyXLLの他の機能について知りたい場合は、公式ドキュメントのユーザーガイドを参照する。


PyXLLの基本的な使い方

PyXLLでは、Pythonのデコレータを使用してExcel関数、マクロ、メニューを定義する。
主要なデコレータは以下の通りである。

  • @xl_func
    Excelのワークシート関数を定義する。

  • @xl_macro
    Excelのマクロを定義する。

  • @xl_menu
    Excelのメニューアイテムを定義する。



@xl_funcデコレータ

@xl_func デコレータは、Python関数をExcelのワークシート関数として公開するために使用する。

基本的な使い方

最も簡単な使用方法は、関数に @xl_func デコレータを付けるだけである。

 from pyxll import xl_func
 
 @xl_func
 def hello(name):
    return "Hello, %s" % name


この関数は、Excelのワークシート上で =hello("World") のように呼び出すことができる。

型署名 (Type Signature) の使い方

型署名を使用することにより、引数と戻り値の型を明示的に指定できる。
これにより、ExcelとPython間の型変換を制御できる。

 from pyxll import xl_func
 
 @xl_func("int x, float y, bool z: float")
 def basic_pyxll_function_2(x, y, z):
    if z:
       return x
    return y


型署名の書式は、"<引数の型> <引数名>, ...: <戻り値の型>" である。

主な型の指定:

  • int: 整数
  • float: 浮動小数点数
  • bool: 真偽値
  • str: 文字列
  • var: 任意の型
  • numpy_array: NumPy配列
  • dataframe: Pandasデータフレーム


カテゴリの指定

category パラメータを使用することにより、Excel関数の挿入ダイアログでのカテゴリを指定できる。

 from pyxll import xl_func
 
 @xl_func(category="My Category")
 def my_function(x):
    return x * 2


揮発性関数 (Volatile Function)

volatile=True を指定することにより、Excelの再計算時に毎回実行される揮発性関数を定義できる。

 from pyxll import xl_func
 
 @xl_func(volatile=True)
 def current_time():
    import datetime
    return datetime.datetime.now()


マクロシート関数 (Macro Sheet Function)

macro=True を指定することにより、マクロシート関数を定義できる。
マクロシート関数は、Excelのワークシートに対して操作を行うことができる。

 from pyxll import xl_func, xlcAlert
 
 @xl_func(macro=True)
 def show_message(message):
    xlcAlert(message)
    return "OK"



@xl_macroデコレータ

@xl_macro デコレータは、Excelのマクロを定義するために使用する。
マクロは、Excelのリボンやボタンから実行できる。

基本的な使い方

最も簡単な使用方法は、関数に @xl_macro デコレータを付けるだけである。

 from pyxll import xl_macro, xlcAlert
 
 @xl_macro
 def popup_messagebox():
    xlcAlert("Hello")


このマクロは、Excelのマクロダイアログから実行できる。

ショートカットキーの設定

shortcut パラメータを使用することにより、マクロにショートカットキーを割り当てることができる。

 from pyxll import xl_macro, xlcAlert
 
 @xl_macro(shortcut="Alt+F3")
 def macro_with_shortcut():
    xlcAlert("Shortcut pressed!")


マクロからワークシートを操作する

マクロ内では、PyXLLが提供するExcel操作関数を使用してワークシートを操作できる。

 from pyxll import xl_macro, get_active_object
 
 @xl_macro
 def clear_range():
    xl = get_active_object()
    xl.Range("A1:C10").Clear()



@xl_menuデコレータ

@xl_menu デコレータは、Excelのメニューバーにカスタムメニューアイテムを追加するために使用する。

基本的な使い方

最も簡単な使用方法は、メニュー名と関数に @xl_menu デコレータを付けるだけである。

 from pyxll import xl_menu, xlcAlert
 
 @xl_menu("Hello!")
 def on_hello():
    xlcAlert("Hello!")


このメニューアイテムは、PyXLLメニューに追加される。

サブメニューの作成

menu および sub_menu パラメータを使用することにより、メニューの階層を作成できる。

 from pyxll import xl_menu, xlcAlert
 
 @xl_menu("My Item", menu="Tools", sub_menu="Operations")
 def operation_callback():
    xlcAlert("Operation executed!")


この例では、[Tools] - [Operations] - [My Item]という階層のメニューが作成される。

メニューアイテムの無効化

メニューアイテムを動的に無効化するには、関数が特定の値を返すように定義する。

 from pyxll import xl_menu, xlcAlert
 
 @xl_menu("Conditional Menu")
 def conditional_menu():
    # メニューが有効かどうかを判定
    if some_condition():
       xlcAlert("Menu executed!")
    else:
       return False  # メニューを無効化



Excel連携機能 : Pandasデータフレーム

PyXLLは、Pandasデータフレームとの緊密な連携機能を提供する。
Excelの範囲をPandasデータフレームとして読み込んだり、データフレームをExcelに書き込んだりすることができる。

データフレームを引数として受け取る

型署名で dataframe を指定することにより、Excelの範囲をPandasデータフレームとして受け取ることができる。

 from pyxll import xl_func
 import pandas as pd
 
 @xl_func
 def process_dataframe(df: pd.DataFrame) -> pd.DataFrame:
    df['new_column'] = df['value'] * 2
    return df


データフレームのパラメータ指定

型署名でデータフレームのパラメータを指定することにより、インデックスや列ヘッダの扱いを制御できる。

 from pyxll import xl_func
 
 @xl_func("dataframe<index=True, columns=1>: dataframe")
 def analyze_data(df):
    return df.describe()


パラメータの意味を以下に示す。

  • index=True
    最初の列をインデックスとして扱う
  • columns=1
    最初の行を列ヘッダとして扱う


データフレームを返す

Python関数がPandasデータフレームを返す場合、自動的にExcelの範囲に変換される。

 from pyxll import xl_func
 import pandas as pd
 
 @xl_func("int rows, int cols: dataframe")
 def create_dataframe(rows, cols):
    data = [[i * j for j in range(cols)] for i in range(rows)]
    df = pd.DataFrame(data, columns=[f"Col{i}" for i in range(cols)])
    return df


データフレームの実用例

以下の例では、Excelから受け取ったデータを集計してデータフレームで返している。

 from pyxll import xl_func
 import pandas as pd
 
 @xl_func("dataframe: dataframe")
 def group_by_category(df):
    # カテゴリごとに集計
    result = df.groupby('category').agg({
       'value': ['sum', 'mean', 'count']
    })
    return result



Excel連携機能 : NumPy配列

PyXLLは、NumPy配列との連携機能を提供する。
Excelの範囲をNumPy配列として読み込んだり、NumPy配列をExcelに書き込んだりすることができる。

NumPy配列を引数として受け取る

型署名で numpy_array を指定することにより、Excelの範囲をNumPy配列として受け取ることができる。

 from pyxll import xl_func
 import numpy as np
 
 @xl_func
 def matrix_multiply(a: np.ndarray, b: np.ndarray) -> np.ndarray:
    return np.dot(a, b)


NumPy配列の型指定

型署名でNumPy配列の要素の型を指定することができる。

 from pyxll import xl_func
 
 @xl_func("numpy_array<float>: numpy_array<float>")
 def normalize_array(arr):
    import numpy as np
    return arr / np.sum(arr)


指定可能な型を以下に示す。

  • int
    整数
  • float
    浮動小数点数
  • bool
    真偽値
  • object
    オブジェクト型


NumPy配列を返す

Python関数がNumPy配列を返す場合、自動的にExcelの範囲に変換される。

 from pyxll import xl_func
 import numpy as np
 
 @xl_func("int rows, int cols: numpy_array<float>")
 def create_matrix(rows, cols):
    return np.random.rand(rows, cols)


NumPy配列の実用例

以下の例では、線形回帰を行っている。

 from pyxll import xl_func
 import numpy as np
 
 @xl_func("numpy_array<float> x, numpy_array<float> y: numpy_array<float>")
 def linear_regression(x, y):
    # 線形回帰の係数を計算
    coeffs = np.polyfit(x.flatten(), y.flatten(), 1)
    # 予測値を計算
    predictions = np.polyval(coeffs, x.flatten())
    return predictions.reshape(-1, 1)



高度な機能 : RTD関数

RTD (Real-Time Data) 関数は、リアルタイムで更新されるデータをExcelに表示するための機能である。
株価、センサーデータ、ログデータ等のリアルタイムデータの表示に使用される。

基本的なRTD関数

型署名で rtd を指定することにより、RTD関数を定義できる。
RTD関数は、ジェネレータまたは非同期ジェネレータとして定義する。

 from pyxll import xl_func
 import random
 import time
 
 @xl_func(": rtd")
 def random_numbers():
    while True:
       yield random.random()
       time.sleep(5)


この関数は、5秒ごとにランダムな数値を生成してExcelセルを更新する。

非同期RTD関数

非同期RTD関数を使用することにより、ブロッキングせずにリアルタイムデータを更新できる。

 from pyxll import xl_func
 import asyncio
 import random
 
 @xl_func(": rtd")
 async def async_random_numbers():
    while True:
       yield random.random()
       await asyncio.sleep(5)


非同期RTD関数は、await を使用して非同期的に待機できる。

RTD関数の実用例

以下の例では、APIから株価データを取得してリアルタイムで更新している。

 from pyxll import xl_func
 import asyncio
 import aiohttp
 
 @xl_func("str symbol: rtd")
 async def stock_price(symbol):
    url = f"https://api.example.com/stock/{symbol}"
    while True:
       async with aiohttp.ClientSession() as session:
          async with session.get(url) as response:
             data = await response.json()
             yield data['price']
       await asyncio.sleep(60)  # 1分ごとに更新



高度な機能 : 非同期関数

PyXLLは、非同期関数をサポートしている。
非同期関数を使用することにより、ブロッキングせずにExcelから外部APIを呼び出したり、データベースにアクセスしたりできる。

基本的な非同期関数

async キーワードを使用して非同期関数を定義する。

 from pyxll import xl_func
 import asyncio
 
 @xl_func
 async def async_function():
    await asyncio.sleep(1)
    return "Done"


非同期HTTPリクエスト

非同期関数を使用して、外部APIからデータを取得できる。

 from pyxll import xl_func
 import aiohttp
 
 @xl_func
 async def fetch_data(url: str) -> str:
    async with aiohttp.ClientSession() as session:
       async with session.get(url) as response:
          return await response.text()


複数の非同期処理の並行実行

asyncio.gather を使用して、複数の非同期処理を並行実行できる。

 from pyxll import xl_func
 import asyncio
 import aiohttp
 
 @xl_func
 async def fetch_multiple_urls(url1: str, url2: str, url3: str) -> str:
    async with aiohttp.ClientSession() as session:
       tasks = [
          session.get(url1),
          session.get(url2),
          session.get(url3)
       ]
       responses = await asyncio.gather(*tasks)
       results = []
       for response in responses:
          results.append(await response.text())
       return ", ".join(results)



型変換の仕組み

PyXLLは、ExcelとPython間で自動的に型変換を行う。
型変換の仕組みを理解することにより、より効果的にPyXLLを使用できる。

ExcelからPythonへの型変換

Excelの値は、下表に示すPythonの型に変換される。

ExcelからPythonへの型変換
Excelの型 Pythonの型
数値 int または float
文字列 str
真偽値 bool
エラー値 ExcelError
空セル None
範囲 list (1次元) または list of list (2次元)


PythonからExcelへの型変換

Pythonの値は、下表に示すExcelの型に変換される。

PythonからExcelへの型変換
Pythonの型 Excelの型
int, float 数値
str 文字列
bool 真偽値
None 空セル
list 1次元範囲
list of list 2次元範囲
numpy.ndarray 範囲
pandas.DataFrame 範囲 (ヘッダー付き)


カスタム型変換

カスタム型変換を定義することにより、独自の型変換ロジックを実装できる。
詳細は、公式ドキュメントの型変換を参照すること。


エラー

ファイアウォールやプロキシサーバが原因でpipコマンドが使用できない

PyXLLアドインをインストールする場合、pipコマンドおよびpyxll installコマンドを使用する代わりに、手動でダウンロードしてインストールする。

pyxllコマンドが認識されない

pip install pyxllコマンドを実行する時、pyxllコマンドが認識されない場合がある。
これは、Pythonスクリプトフォルダがシステムパス上に存在しないことが原因である。

この時、python -m pyxll install コマンド および pyxll install コマンドを実行する。

Excelの起動時にpythonXXX.dll not foundエラーが発生する

使用しているPythonのバージョンが、PyXLLアドインがビルドされたPythonのバージョンと異なることが原因である。

コマンドラインインストーラを使用している場合は、PyXLLをダウンロード済みかどうかを尋ねられた時に "n" を入力して、正しいバージョンをダウンロードする。
PyXLLアドインを手動でダウンロードする場合は再度ダウンロードするが、ダウンロードフォームで正しいPythonのバージョンを選択するように注意すること。

その他の問題のトラブルシューティング

エラーが発生した時、PyXLLのログファイル (デフォルトでは、PyXLLのインストールフォルダ下のlogsフォルダ) に書き込まれる。

ログファイルの場所を確認する場合は、pyxll status コマンドの使用、あるいは、PyXLLメニューの[About]オプションを確認する。

または、PyXLLの公式WebサイトにあるFAQを確認すること。