PythonでPower BI Desktopのデータを更新し、ワークスペースへレポートを自動発行する。


## やりたいこと

Pythonにて、Power BI Desktopからデータ更新を実施し、Power BI Servicesへレポートを自動発行したい。以下のページを参考にするも、上手くいかないので、悪戦苦闘しました。

- [【参考】PythonでPower BI Desktopを自動更新する](https://qiita.com/oogaki_newmedia/items/56825d29f2eccbc82a84)


## 苦労した点

### PythonからのPower BI Desktopの起動

Power BI Desktopのインストールは、Microsoft storeからでインストールする方法とインストール版を用いてインストールする方法の２つの方法があると思います。

最終的には、ファイルをクリックして関連付けられたPower BI Desktopを起動する方法に落ち着いたので今回 直接は関係ないのですが、Power BI Desktop自体をPythonから起動しようとする場合は、インストール版を使う必要があると思います。

Microsoft storeからインストールした場合は、インストール先が以下の場所になりました。

```
c:¥Program Files¥WindowsApps
```
WindowsAppsは、フォルダの所有者がTrustedInstallerになっており参照不可でした。
TrustedInstallerはAdministratorよりも権限が強いようです。なので、PATHも通せませんでした。。。

ちなみにインストール版の場合は、以下の場所にインストールされました。

```
"C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe"
```

### 共有ワークスペースの選択時の予期しないエラー

レポート発行の際に、共有ワークスペースの選択→ボタン[選択]の押下→ボタン[置換]の押下と進むのですが、以下のエラーが出て全く上手く行きませんでした。

```
予期しないエラー
申し訳ありません。Power BIサービスへの接続中に問題が発生しました。もう一度お試し下さい。
```

最終的には、ボタン[置換]の選択方法を変えて上手く動くようになりました。

- OK

   ```python
   dialog = app[file_name + " - Power BI DesktopDialog"]
   dialog.child_window(title="置換", control_type="Button").click_input()
   ```

- NG

   ```python
   PBIDesktop_window['置換'].click()
   ```

### pywinautoのインストール

社内環境であったため、pywinautoのインストールをwhl ファイルを使用してPythonパッケージをインストールする方法で実施していました。しかし、以下の部分で、backend='uia'と指定するとエラーが発生して、backend='win32'と指定しないとエラーとなる現象が発生。

```
app = Application(backend='uia').connect(path=exe)
```

結局、pipでpywinautoを再インストールすることで、問題解消しました。


## コード

```python
import os
import sys
import time

from pywinauto import Application

def main(workbook):
    # exe名
    exe = 'PBIDesktop.exe'
    # ファイル名
    #file_name = '発行テスト用'
    file_name = os.path.splitext(os.path.basename(workbook))[0]
    # レポート発行先のワークスペース名
    workspace_name = "hogehogehoge"

    # ファイルを開く
    os.system('start "" "{0}"'.format(workbook))
    app = Application(backend='uia').connect(path=exe)
    time.sleep(15)

    try:
        # Windowを指定
        PBIDesktop_window = app.window(title_re = '.*Power BI Desktop')

        print("フォーカス Start")
        PBIDesktop_window.set_focus()
        print("フォーカス End")

        print("更新ボタン押下 Start")
        PBIDesktop_window['更新'].click()
        print("更新ボタン押下 End")
        time.sleep(30)

        print("保存ボタン押下 Start")
        PBIDesktop_window['save'].click()
        print("保存ボタン押下 End")
        time.sleep(30)

        print("発行ボタン押下 Start")
        PBIDesktop_window['発行'].click()
        print("発行ボタン押下 End")
        time.sleep(10)

        print(workspace_name + "をクリック Start")
        dialog1 = app[file_name + " - Power BI Desktop"]
        dialog1.child_window(title=workspace_name, control_type="DataItem", found_index=0).click_input()
        print(workspace_name + "をクリック End")
        time.sleep(5)

        print("選択ボタン押下 start")
        PBIDesktop_window['選択'].click()
        print("選択ボタン押下 End")
        time.sleep(5)

        print("置換をクリック Start")
        dialog2 = app[file_name + " - Power BI DesktopDialog"]
        dialog2.child_window(title="置換", control_type="Button").click_input()
        print("置換をクリック End")
        time.sleep(60)

        print("OKボタン押下 Start")
        PBIDesktop_window['OK'].click()
        print("OKボタン押下 End")

    except Exception as e:
        print(e)
    finally:
        app.kill()
        print("終了")


if __name__ == '__main__':
    try:
        file_path = sys.argv[1]
    except (IndexError):
        print('ファイルを指定してください。')
        sys.exit()

    main(file_path)
```

## 参考サイト

- [PythonでPower BI Desktopを自動更新する](https://qiita.com/oogaki_newmedia/items/56825d29f2eccbc82a84)
- [pywinauto の使い方メモ](https://qiita.com/nobu-maple/items/51901b2e27e4448f102b)
- [pywinautoの使い方をはじめから](https://harist.hatenablog.jp/entry/2020/03/22/154620)
- [Click a DataItem in a ListBox using Pywinauto](https://stackoverflow.com/questions/61520855/click-a-dataitem-in-a-listbox-using-pywinauto)
- [github pywinauto](https://github.com/pywinauto/pywinauto/blob/atspi/README.md)