xlwingsトラブルシューティング

xlwingsを使用していて発生したエラーと対処法を紹介します。随時更新。
# 「コンパイル エラー: Sub または Function が定義されていません。」
**現象**
[公式ドキュメント - RunpPython](https://docs.xlwings.org/ja/latest/vba.html#call-python-with-runpython)に従い、`RunPython`関数を実行しようとすると「コンパイル エラー: Sub または Function が定義されていません。」というエラーメッセージが表示される。
![Sub または Function が定義されていません。.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/8ef30f71-5f47-490d-f171-5871f74ac665.jpeg)

**原因・対処法**
原因は`RunPython`関数が未定義となっているため。
xlwingsアドインをインストールし、`RunPython`関数呼び出し元Excelブックの**参照設定にxlwingsを追加**すれば、`RunPython`関数を使えるようになる。`RunPython`関数を使う場合には、他の人にもわかるよう、アドインで定義された関数であることを次のように明示した方がよいでしょう:

```VB:RunPython関数呼び出し元ブックのモジュール
Sub HelloWorld()
    xlwings.RunPython ("import hello; hello.world()")
End Sub
```
（参照設定が必要なことは[RunpPython](https://docs.xlwings.org/ja/latest/vba.html#call-python-with-runpython)ではなく、[別のところ](https://docs.xlwings.org/ja/latest/addin.html#installation)に書いてあるのでわかりにくいですね。なぜ[スタンドアローンのアドイン](https://docs.xlwings.org/ja/latest/addin.html#alternative-standalone-vba-module)を勧める記事（[e.g. 1](https://celaeno42.hatenablog.com/entry/2018/12/03/191854), [e.g. 2](https://qiita.com/katzhide/items/60d0336b322105bf8fe9), [e.g. 3](https://qiita.com/0yan/items/dbeed1be6d2effd49a87)）が多いのだろうと考えていましたが、公式ドキュメントが悪いということで納得しました。）


# 「オブジェクトが必要です」
**現象**
UDF（ユーザー定義関数）を`@xw.sub`デコレーターで作成した場合はポップアップ上に、`@xw.func`デコレーターで作成した場合は数式を入力したセルに、「オブジェクトが必要です」と表示される。

**原因・対処法**
1. xlwingsのアドインがインストールされていない　→　アドインをインストール
2. VBAの参照設定でxlwingsにチェックが入っていない　→　チェックを入れる。呼び出し元のファイルで参照設定されていることを確認（別のファイルで参照設定していないか）。

# UDFの戻り値がゼロ & デバッグもできない
**現象**
UDFの戻り値がゼロ。デバッガー画面にも行けない。

**原因・対処法**
原因は、```Application.CommandBars("Standard").Controls(1).Enabled``` の値が `True` になっていて、`xlwings_udfs`モジュールにあるVBA関数（Python関数のラッパー）の1行目のIF文で`Exit Function`で終わるため。

```vb:xlwings_udfsモジュール
Function hello(name)
    If (Not Application.CommandBars("Standard").Controls(1).Enabled) Then Exit Function
    #If App = "Microsoft Excel" Then
        If TypeOf Application.Caller Is Range Then On Error GoTo failed
        hello = Py.CallUDF("test", "hello", Array(name), ThisWorkbook, Application.Caller)
        Exit Function
    #Else
        hello = Py.CallUDF("test", "hello", Array(name))
        Exit Function
    #End If
failed:
    hello = Err.Description
End Function
```
VBAを適当なブレークポイントで止めて、イミディエイトウィンドウ上で以下を実行:

```vb:イミディエイトウィンドウ
Application.CommandBars("Standard").Controls(1).Enabled = True
```
`Application.CommandBars("Standard").Controls(1)`はExcel 2003以前の標準ツールバー（説明は[リンク先](https://www.wanichan.com/pc/excel/2003/12/475.html)）の新規作成ボタンのこと。`Application.CommandBars("Standard").Controls(1).Enabled`の値を`True`にすることに害は無いと思う、たぶん。何でxliwngsのUDFの最初のIF文でこれを使っているかは不明。


# 「別のプログラムでのOLEの操作が完了するまで待機します」

**現象**
xlwingsで処理を実行中にExcelから「別のプログラムでのOLEの操作が完了するまで待機します」というメッセージが表示される。消してもしばらく経つとまた表示される。

**原因・対処法**
原因は、Excelから他のプロセスに呼び出した処理に時間がかかっているため。一定時間が経つと、上記の警告メッセージが表示される。

UDFの場合は以下のように呼び出す前に`Application.DisplayAlerts=False`を実行する。

```VB
Function vba_hogehoge()
    Application.DisplayAlerts = False
    call hogehoge 'xlwingsで定義したUDF
    Application.DisplayAlerts = True
End Function
```

# 「EOFError: Ran out of input when using Python」

**現象**
xlwingsをインポートしようとすると上記エラーが表示される。アドインのインストール`xlwings addin install`やUDFも使えなくなる。


**原因・対処法**
原因は、`%userprofile%\AppData\Local\Temp\gen_py\3.x\dicts.dat`(3.xはPythonのバージョン)のファイルサイズが0バイトになっているため。エクスプローラーまたは以下のコマンドで`gen_py`フォルダーを削除すればエラーが表示されなくなる。

```powershell:Powershell
> Remove-Item --recursive $env:USERPROFILE\Appcata\Local\Temp\gen_py
```

https://stackoverflow.com/questions/61298673/eoferror-ran-out-of-input-when-using-python

# リボンにxlwingsタブが表示されない

**現象**
xlwingsのアドインをインストールしているにも関わらず、リボンにxlwingsタブが表示されない。


**原因・対処法**
原因は、非表示のExcelプロセス（ゾンビ プロセス）が残っているため。`Ctrl+Shift+Esc`でタスク マネージャーを起動し、バックグラウンド プロセスのExcelを右クリックし「タスクの終了」で終了してください。

# 「could not load xlwings32-0.21.4.dll from either of the following folders」

**現象**
xlwingsリボンの`Import Functions`ボタンを押すと、「could not load xlwings32-0.21.4.dll from either of the following folders」
というエラーが表示される。
![xlwings_trouble.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239172/3d2f2278-6381-4896-ab66-675b3996bb76.jpeg)


**原因・対処法**
原因は、インストールしているxlwingsパッケージのバージョンとxlwingsアドインのバージョンが異なっているため。
PowerShellで`xlwings addin update`を実行し、アドインをアップデートする。

# 「ImportError: DLL load failed while importing win32api: 指定されたプロシージャが見つかりません。」

**現象**
以下の環境で確認

- OS: Windows 10 Pro
- python: Anaconda3-2020.11

`pip install`でpywin32をアップデートすると（`--force`オプションを付けてxlwingsのアップデートした場合を含む）、xlwingsのExcelアドインのインストール（`xlwings addin install`）の際に、上記エラーメッセージが表示され、アドインをインストールできない。


**原因・対処法**
原因は、インストール時にpywin32のdllが置き換えれず、パッケージとdllのバージョンがずれてしまうため。PowerShellで`python c:\programdata\anaconda3\scripts\pywin32_postinstall.py --install`を実行して、パッケージに合ったdllをインストールする。

https://stackoverflow.com/questions/58612306/how-to-fix-importerror-dll-load-failed-while-importing-win32api


# Excelアドインの一覧にxlwingsアドインが表示されない
**現象**
xlwingsアドイン自体はインストールされているものの、開発]リボン -> [Excelアドイン]ボタン で開けるExcelアドインの一覧に、xlwingsアドインが含まれていない。

**原因・対処法**
原因は良くわからないが、まれに発生。
対処法は、同画面の[参照]ボタンを押し、[ファイル名]に以下を入力し、[開く]ボタンを押す。
%appdata%\microsoft\excel\xlstart\xlwings.xlam