Power Automate Desktopがなんとなく使える講座 #7 Excelで大量データの仕分けとページ設定

## RPAの繰り返し処理は時間がかかる
　RPAは、繰り返し処理を行うのは得意ですが、ループ回数が増えると処理時間がどんどん増えてきます。データを1件づつ処理する方法は、データ量が少ない場合はいいのですが、大量データを扱う場合はもっと早く終わらせたいと思うでしょう。ループする回数をできるだけ減らす工夫が必要になります。
 今回は、1,000件のデータを対象に、出身地ごとにシートを分ける処理を行います。1,000回ループさせる代わりに、出身地の数（都道府県の数、最大47回）のループで仕分けを行うようにします。

## アクセスキー
　Excelの各種操作は、主にリボンをマウスでクリックして行うことが多いと思いますが、マウスを使わずにリボン操作を行う方法があります。それがアクセスキーです。アクセスキーは、Altキーを一回押すと、以下のようにリボン上にアルファベットが表示されます。そのキーを押せば、リボンのアイコンをクリックしたのと同じ動作を行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f6c4050b-6bc3-8288-d593-e35223e433ba.png)
　例えば、前回使用した書式のコピーですが、**[Alt] → H → V → R** と順番に押していくと、キー操作だけで書式のコピーができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/9e2eb64b-d6d5-b70d-74c3-b6cb5e29e975.png)
※ 書式の貼り付け　**[Alt] → H → V → R** と、値の貼り付け **[Alt] → H → V → V** は、普段使いでも便利ですので、是非とも覚えておいてください。

### (注意)アクセスキーは常に一定ではない
　アクセスキーを使う場合に注意しなければならないのは、タブやリボンの項目設定によって、違う動きになることがあります。例えば、普通のシートで **[Alt] → P** とするとページレイアウトのリボンが表示されますが、クエリがかかった表データのシートでは、 **[Alt] → P → 1** という動作が必要になります。

## とにかくキー操作を使いまくる
　アクセスキーも、リボン上のボタン操作までしか行えず、別途ダイアログが開いた後は別の方法が必要です。複数のタブのあるダイアログでは **[Ctrl] + [Tab]** で切り替え、次の入力項目へは **[Tab]** で移動し、項目名右にアルファベットが書かれたダイアログ上の項目選択は [Alt] とアルファベットキーを押して選択します。
　ここで重要なのは、**キーの送信の遅延の調整が必要**ということです。早く処理を終わらせたいので、遅延は少なくしたいのですが、動作が完了する前に次のキーが送信されると思った動きになりません。また、ダイアログが開く動作には若干時間がかかります。キーの送信で操作を行いますが、ダイアログが開く前に次のキーを送信してしまう場合は、**「キー入力の間隔の遅延」**の値を調整する必要があります。キーの送信のステップを、大きな遅延が必要な処理と少なくてよい処理を分けるというのも、全体の速度アップのテクニックとなります。ＰＣのスペックや、Windows10のアップデートによって動作速度が変化する可能性がありますので、気持ち多めに設定した方が安心です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/8c01c14f-154e-df91-0f21-742a3f9f067f.png)

## デモ
　今回のフローの動作を先にお見せします。ショートカットキーとアクセスキーを使って、1,000件のデータの仕分けから印刷設定まで行っています。
<iframe width="560" height="315" src="https://www.youtube.com/embed/7Wcx4WO0akk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
　元のデータは以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ecacc35b-a2e2-737a-71fc-5538d86db463.png)
　出来上がったシートを印刷すると、以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/9c0dda0b-c32d-70cc-ba22-910caff14ed9.png)

## 処理のながれ
### フロー図
　フローは、以下のような流れになります。次回から2回に分けて、それぞれの処理に分けて説明していきます。
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ef9dbcc8-eaaa-dd3e-66a9-c0ffd90af7a2.jpeg)

### 使用したデータ
　元のエクセルファイルは [**ここ**](https://spumoni-my.sharepoint.com/:x:/g/personal/fukuyori_spumoni_onmicrosoft_com/Ee9tTO9F2ZFGkkqfFuhdWmcBA5naqE9AmFs5OUoCiUax8g?e=Bf6qm8) にあります。
　出来上がりのファイルは、 [**ここ**](https://spumoni-my.sharepoint.com/:x:/g/personal/fukuyori_spumoni_onmicrosoft_com/Eda4HfCGptJOhghR4cqBGF4BiqXOgz-Wq74auwcKXZUMLg?e=2LM4Ju) になります。

### Power Automate Desktopのステップ
　実際のフローは、以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/50503207-1b61-5c65-9e0b-f350269c7a4c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fc527051-4ceb-ae2e-879e-c53e3ff271ca.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/605d7f1e-e9cd-9ff6-7429-c7a26aca966f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6e11b3f7-c98f-1910-0996-7a7839e884c0.png)

### コード

```
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.DesktopDirectory SpecialFolderPath=> SpecialFolderPath
Excel.LaunchAndOpen Path: $'''%SpecialFolderPath%\\personal_information1000.xlsx''' Visible: True ReadOnly: False LoadAddInsAndMacros: False Instance=> ExcelInstance
# 出身地リストの作成
Excel.ActivateWorksheetByIndex Instance: ExcelInstance Index: 1
Excel.GetFirstFreeColumnRow Instance: ExcelInstance FirstFreeColumn=> FirstFreeColumn FirstFreeRow=> FirstFreeRow
Excel.ReadCells Instance: ExcelInstance StartColumn: 1 StartRow: 1 EndColumn: FirstFreeColumn - 1 EndRow: FirstFreeRow - 1 ReadAsText: False FirstLineIsHeader: True RangeValue=> ExcelData
Variables.RetrieveDataTableColumnIntoList DataTable: ExcelData ColumnNameOrIndex: $'''出身地''' ColumnAsList=> ColumnAsList
Variables.RemoveDuplicateItemsFromList List: ColumnAsList IgnoreCase: False NewList=> ColumnAsList
# 都道府県リストの読み込み
Excel.ActivateWorksheetByIndex Instance: ExcelInstance Index: 2
Excel.GetFirstFreeColumnRow Instance: ExcelInstance FirstFreeColumn=> FirstFreeColumn2 FirstFreeRow=> FirstFreeRow2
Excel.ReadCells Instance: ExcelInstance StartColumn: $'''B''' StartRow: 1 EndColumn: $'''B''' EndRow: FirstFreeRow2 - 1 ReadAsText: False FirstLineIsHeader: False RangeValue=> ExcelData2
Variables.RetrieveDataTableColumnIntoList DataTable: ExcelData2 ColumnNameOrIndex: 0 ColumnAsList=> TodoufukenList
# 出身地を都道府県リストの並び順にする
Variables.FindCommonListItems FirstList: TodoufukenList SecondList: ColumnAsList OutputList=> IntersectionList
# エクセル操作開始
UIAutomation.Windows.FocusByInstanceOrHandle WindowInstance: ExcelInstance
Excel.ActivateWorksheetByIndex Instance: ExcelInstance Index: 1
# フィルター ON
MouseAndKeyboard.SendKeys TextToSend: $'''{Control}({Shift}({L}))''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
LOOP FOREACH CurrentItem IN IntersectionList
    Excel.ActivateWorksheetByIndex Instance: ExcelInstance Index: 1
    Excel.Advanced.SelectCells Instance: ExcelInstance StartColumn: $'''I''' StartRow: 1 EndColumn: $'''I''' EndRow: 1
    # 出身地でフィルターをかける
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}({Down})''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''FE%CurrentItem%{Enter}''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    # コピーするテーブルを選択
    MouseAndKeyboard.SendKeys TextToSend: $'''{Control}({A})''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    Excel.Advanced.Copy Instance: ExcelInstance
    Excel.AddWorksheet Instance: ExcelInstance Name: CurrentItem WorksheetPosition: Excel.WorksheetPosition.Last
    Excel.Advanced.PasteAt Instance: ExcelInstance Column: $'''A''' Row: 1
    # 列幅を自動設定
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}()OCA''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    # ヘッダー・フッターの設定
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}()PSP''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''{Control}({Tab}){Control}({Tab})''' DelayBetweenKeystrokes: 150 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}({C}){Tab}''' DelayBetweenKeystrokes: 150 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''出身地別一覧（%CurrentItem%）{Tab}{Tab}{Enter}''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}({U}){Tab}''' DelayBetweenKeystrokes: 150 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''&[ページ番号]{Tab}{Tab}{Enter}''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''{Tab}{Tab}{Tab}{Tab}{Tab}{Tab}{Tab}{Tab}{Enter}''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    # タイトル行の設定
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}()PI{Alt}({R})''' DelayBetweenKeystrokes: 150 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''$1:$1{Return}''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    # 余白
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}()PM{Down}{Down}{Down}{Return}''' DelayBetweenKeystrokes: 250 SendTextAsHardwareKeys: False
    # 用紙の向き
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}()PO{Down}{Return}''' DelayBetweenKeystrokes: 250 SendTextAsHardwareKeys: False
    # ページ設定
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}()PSP''' DelayBetweenKeystrokes: 150 SendTextAsHardwareKeys: False
    MouseAndKeyboard.SendKeys TextToSend: $'''{Alt}({F})1{Tab}0{Enter}''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
    Excel.Advanced.SelectCells Instance: ExcelInstance StartColumn: $'''A''' StartRow: 1 EndColumn: $'''A''' EndRow: 1
END
Excel.ActivateWorksheetByIndex Instance: ExcelInstance Index: 1
# フィルター OFF
MouseAndKeyboard.SendKeys TextToSend: $'''{Control}({Shift}({L}))''' DelayBetweenKeystrokes: 100 SendTextAsHardwareKeys: False
Excel.CloseAndSaveAs Instance: ExcelInstance DocumentFormat: Excel.ExcelFormat.FromExtension DocumentPath: $'''%SpecialFolderPath%\\振り分け済み'''
```