WinAppDriverを利用してExcelを保存する場合の注意点。
Windows Application Driverを利用して、起動中のエクセルを保存するときに
はまったのでまとめておきます。
(環境設定については、いろいろな記事が出てるのでここでは割愛します。)
環境
- VisualStudio2017Community
- Office 2016
エクセル操作
テンプレートの取得
GitHubのUIRecorderのページからWinAppDriverのテンプレートプロジェクトを取得します。
WinAppDriver/Tools/UIRecorder/UIRecorderTemplate at master · Microsoft/WinAppDriver · GitHub
XPathの取得
WinAppDriverUiRecorderを起動してエクセルのXPathを取得します。
通常保存時にはこのような保存ダイアログが表示されます。
開いたディレクトリにそのまま保存する場合には問題ありません。
ただし保存先を変更しようとファイル名にC:\temp\hoge.xlsxなどをSendKeyで入力する必要がありますが、
実行するとファイル名にはC:]temp]hoge.xlsxと入力されてしまいます。
この原因はこちらのブログで紹介されているようにキーボードの問題のようです。
この問題(2018/1現在)は解消していないようなので、別の方法で入力します。 同僚の方に相談したところアドレスバーのパスは/でも行けると教えてもらったので
- アドレスバーをクリック
- SendKeyでc:/tempと打つ
- SendkeyでEnterを打つ
という感じで操作します。
保存時ダイアログのアドレスバーをクリックするコードです。
string xp1 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Book1 - Excel\"][@ClassName=\"XLMAIN\"]/Window[@Name=\"名前を付けて保存\"][@ClassName=\"#32770\"]/Pane[@ClassName=\"ReBarWindow32\"]/Pane[@ClassName=\"Address Band Root\"]/ProgressBar[@ClassName=\"msctls_progress32\"]/Pane[@ClassName=\"Breadcrumb Parent\"]/ToolBar[@Name=\"アドレス: ドキュメント\"][@ClassName=\"ToolbarWindow32\"]"; var winElem1 = MyDesktopSession.FindElementByXPath(xp1); if (winElem1 != null) { winElem1.Click(); } else { Console.WriteLine($"Failed to find element {xp1}"); return; }
ちょっとXPathが長いですが、注目するのは最後の
/ToolBar[@Name=\"アドレス: ドキュメント\"][@ClassName=\"ToolbarWindow32\"]"で
Nameの部分に表示時のパスがついてきてしまいます。
Excel起動時にパスが異なると動かないので[@Name=\"アドレス: ドキュメント\"]の部分は削除します。
アドレスバーのクリックからパスの入力までやるこんな感じのコードになります。
string xp1 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Book1 - Excel\"][@ClassName=\"XLMAIN\"]/Window[@Name=\"名前を付けて保存\"][@ClassName=\"#32770\"]/Pane[@ClassName=\"ReBarWindow32\"]/Pane[@ClassName=\"Address Band Root\"]/ProgressBar[@ClassName=\"msctls_progress32\"]/Pane[@ClassName=\"Breadcrumb Parent\"]/ToolBar[@ClassName=\"ToolbarWindow32\"]"; var winElem1 = MyDesktopSession.FindElementByXPath(xp1); if (winElem1 != null) { winElem1.Click(); } else { Console.WriteLine($"Failed to find element {xp1}"); return; } string xp2 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Book1 - Excel\"][@ClassName=\"XLMAIN\"]/Window[@Name=\"名前を付けて保存\"][@ClassName=\"#32770\"]/Pane[@ClassName=\"ReBarWindow32\"]/Pane[@ClassName=\"Address Band Root\"]/ProgressBar[@ClassName=\"msctls_progress32\"]/ComboBox[@Name=\"アドレス\"][@ClassName=\"ComboBox\"]/Edit[@Name=\"アドレス\"][@ClassName=\"Edit\"]"; var winElem2 = MyDesktopSession.FindElementByXPath(xp2); if (winElem2 != null) { winElem2.SendKeys("c:/work"); winElem2.SendKeys(Keys.Enter); } else { Console.WriteLine($"Failed to find element {xp2}"); }