Power Automate DesktopでGoogleスプレッドシートは操作出来るのか?
現在、社内向けのGASの初心者講座を作成しています。その中でマクロの記録をリライトしていますが、この機能は結構やれることが狭い為、正直あまり積極的に勧められない。
その過程の中でPower Automate for DesktopでGoogleスプレッドシートって操作出来たっけ?という疑問が生じたので検証してみることにしました。
目次
今回利用するツール等
サンプルのGoogleスプレッドシートに対して適当な操作をしてみて果たして出来るのか?だけではなく、GASでウェブアプリを作成してそのウェブアプリも操作できるのか?また、REST APIならばどうなのか?といった一連の疑問を検証します。
マクロの記録に関しては以下のエントリーにまとめています。
スプレッドシートを直接操作してみる
個人的にやってみたけれど、しっくりこなかったというのが答え。doGetでエンドポイントだけ用意して叩き、実際の処理はGASで書く方が建設的と言えます。
レコーダーや要素指定で操作
Power Automate Desktopに備わってるWebページのリンクをクリックを使って、UI要素を追加しクリックを実現する操作を記録してみました。また同様にレコーダーを使ってChromeでの手作業の操作を記録してみました。
結論から言えば、まともに動作しません。
特にスプレッドシートのメニューからファイル→印刷を実行する流れを記録しただけなのですが、ファイルを開くまではオッケーでも「印刷」のクリックが動作せず。また、セルのクリックなども記録してみましたが、セルのエリア個別に認識してくれるわけではないのでほぼまともに操作ができません。
※また、Googleはあまり明確に記述していませんが原則RPAツールやスクレイピングツールでの自動操縦による操作を禁止してたりします。
図:スプシを見たまま操作は出来ない
キー送信で操作する
キー送信でフローを作成する
今時のウェブアプリはDOMで構成されていなかったり複雑すぎてブラウザ操作でコントロールができるとは思っていなかったので、前述の結果は想定の範囲内。VBAで他のアプリを操作の時にも使った「キーボード操作を送りつける手法」ならば行けるのでは?ということで、印刷するフローを構築してみました。ショートカットキーや方向キー、Tabキー、Enterなどを駆使します。
実際にCtrl+Pで印刷を実行し、PDFとして保存を実行するまでの間を作ってみましたが、こちらは操作が出来ました。ただしいくつかの注意点があります。
- 事前にBrowserインタンスとしてChromeを起動しておく。ただしログインの自動化はできませんのであらかじめログイン状態にしておく必要があります。
- ショートカットキーとして、キーの送信にてCtrl+Pを送信してからがスタート(Browserインスタンスに対して送信する)
- 印刷設定画面になるが、ここは何もせずに「次へ」をクリック。ただキー送信では出来ないので、Webページのリンクをクリックにて、UI要素を指定してクリックしてあげる
- 印刷ダイアログが出ますがここはUI要素指定はできません。キーの送信にてフォアグラウンドに対してTabキーを必要回数分用意して送信する。5回操作したらプリンター選択要素に飛ぶ。
- 送信先はPDFに送信を選びたいので、テキストをハードウェアキーとして送信にて「PDF」の文字列を送信する
- 再度、Tabキーで何度か移動させて保存ボタンまで移動し、Returnを送信する
- 保存先ダイアログはWindowsのコンポーネントなので、キー送信にてタイトルやクラスまたはその両方をもって、「名前をつけて保存」を指定し、Returnを送信する
同名があった場合に備えて名前をランダムにいれるようにする処理などを入れるとなお良いです。ですが、ここまでをみたように、キー送信でほぼ操作してるので、非常に煩雑。また一部はUI要素を指定したり、ウィンドウハンドルに対して操作したりが混在するので、フローを作成するといっても要求されるスキルがかなり高めになってしまう。
※セルの操作もショートカットキーを駆使することになるので、作るのが非常に面倒だと感じました。
図:とりあえず操作自体は出来ました
図:名前をつけて保存ダイアログの操作
フローのコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
WebAutomation.LaunchChrome.LaunchChrome Url: $'''ここに操作するスプシのURLを入れる''' WindowState: WebAutomation.BrowserWindowState.Maximized ClearCache: False ClearCookies: False WaitForPageToLoadTimeout: 60 Timeout: 60 PiPUserDataFolderMode: WebAutomation.PiPUserDataFolderModeEnum.AutomaticProfile BrowserInstance=> Browser MouseAndKeyboard.SendKeys.FocusAndSendKeysByInstanceOrHandle WindowInstance: Browser TextToSend: $'''{Control}{P}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False WebAutomation.Click.Click BrowserInstance: Browser Control: appmask['Web Page \'h ... id=0#gid=0\'']['Span \'次へ\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0 MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''PDF''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: True MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Return}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False MouseAndKeyboard.SendKeys.FocusAndSendKeysByTitleClass Title: $'''名前を付けて保存''' Class: $'''''' TextToSend: $'''{Return}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False # [ControlRepository][PowerAutomateDesktop] |
GASのウェブアプリは操作できるのか?
GASのウェブアプリ操作フローを作る
Googleスプレッドシートを直接RPAで操縦するのは正直現実的じゃありません。しかし、一定の入力や作業をGASで構築したウェブアプリであれば操縦は出来るのか?ということでチャレンジしてみました。予め用意しておいた掲示板アプリに書き込みをしてみます。
単純なjQuery UIのダイアログとW2UIのGridを使っただけのウェブアプリですが、Power Automate Desktopのレコーダーで作業を記録してみました。
GASのウェブアプリはiframeのサンドボックス環境なのでうまく要素を捉えて操縦できるかどうか?心配でしたが、実際にレコーダーで順番に操縦して記録してみたところ、こちらはバッチリ操縦できました。2019年頃にチャレンジした際にはできなかったことです。
ただ実際にこうした操縦をPADで作成するか?といったら、自分だったら操縦不要になる機能をGASでつけてPADを不要にすると思う・・・・作成者が装備してくれないケースで自身もGASが書けない時の自動化といった観点ならば、このPADでの自動操縦は意味があるかもしれない。
図:レコーダーでアプリの操縦を記録
図:無事に操縦できました
フローのコード
1 2 3 4 5 6 7 8 9 10 11 12 13 |
WebAutomation.LaunchChrome.LaunchChrome Url: $'''ここにウェブアプリのexecのURLを入れる''' WindowState: WebAutomation.BrowserWindowState.Maximized ClearCache: False ClearCookies: False WaitForPageToLoadTimeout: 60 Timeout: 60 PiPUserDataFolderMode: WebAutomation.PiPUserDataFolderModeEnum.AutomaticProfile BrowserInstance=> Browser @@source: 'Recorder' WebAutomation.Click.Click BrowserInstance: Browser Control: appmask['Web Page \'h ... t2Q6J/exec\'']['Div \'雑談\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True @@source: 'Recorder' WebAutomation.Click.Click BrowserInstance: Browser Control: appmask['Web Page \'h ... t2Q6J/exec\'']['Anchor \'新レス\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True @@source: 'Recorder' WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserInstance: Browser Control: appmask['Web Page \'h ... t2Q6J/exec\'']['Input text \'name\''] Text: 'とまと' UnfocusAfterPopulate: False Mode: WebAutomation.PopulateTextMode.Replace @@source: 'Recorder' WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserInstance: Browser Control: appmask['Web Page \'h ... t2Q6J/exec\'']['Text area \'wasabi5\''] Text: '楽しいトマト栽培' UnfocusAfterPopulate: False Mode: WebAutomation.PopulateTextMode.Replace @@source: 'Recorder' WebAutomation.PressButton.PressButton BrowserInstance: Browser Control: appmask['Web Page \'h ... t2Q6J/exec\'']['Input button \'レスを送信\''] # [ControlRepository][PowerAutomateDesktop] |
REST APIを叩いたらどうなるのか?
Google Apps Scriptを書くスキルは持っていない。けれど、Googleスプレッドシートの操縦を自動化したいとなった場合の3つ目の手段としては、Google Sheets APIを利用して、REST APIをPower Automate Desktopで叩く手法です。今回は簡便なAPIキーを利用して叩いて操縦してみたいと思います。
APIキーを生成する
Google Cloud上でAPI Keyを生成し、Power Automate Desktopのフローの変数に格納しておきます。
- Cloud Consoleを開いて自身のプロジェクトを表示する
- 左サイドバーより、APIとサービスを開く
- APIとサービスを有効にするをクリックする
- Sheetsで検索して、Google Sheets APIを有効化します。
- APIとサービスのトップページに戻り、次に認証情報をクリックする
- 上部にある認証情報を作成をクリッしてAPIキーをクリックする
- 自動的に生成される。APIキーの文字列をコピーする。
- ダイアログを一旦閉じて作成されたキーをクリックして中に入る
- 名前は適当に付けて、APIの制限ではキーを制限を選択。対象APIはGoogle Sheets APIのみを選択する
- 保存をクリックする
ここで取得したAPIキーをPower Automate Desktopのapikeyという変数ボックスの中に格納します。
図:Sheets APIを有効化
図:APIキーには制限をつけておきます
範囲を読み取るフローを作ってみる
各種変数にAPIキー、スプシのID、読み取り範囲、シート名の4つを整備する。そして、その後の「Webサービスの呼び出し」フローにて、以下の設定をします。
- URLはSheets APIに対してリクエストするURLを構築する。変数を組み込んで1つのURLにします
- メソッドはGETを指定
- コンテンツタイプはapplication/jsonを指定する
- 受け入れるの欄は「*/*」を指定する
- リクエストの答えは「WSResponse」に返ってくる
そして、レスポンス内容については、「JSONをカスタムオブジェクトに変換」フローを用いて、前述の「%WSResponse%」をJSONに指定する。変換結果は「ResponseObj」に格納されます。
実行をして成功すると、右サイドバーのWSResponseやResponseObjにシートのデータが返ってきます。
このようにGASでなくともREST APIだけでも十分操作が可能で、理解できれば割とスッキリなフローで操作が可能です。ハードルは若干高いですが、基本はリクエストURLをどうやって構築するか?に絞られ、読み取りだけじゃなく書き込みも可能です。
1 2 |
//Sheets APIリクエストURL https://sheets.googleapis.com/v4/spreadsheets/%ssid%/values/%sheetname%!%range%?key=%apikey% |
図:単純に範囲のデータをJSONとして読み取ってくれる
図:HTTPリクエストをするフローの中身
図:読み取り結果の表示
フローのコード
1 2 3 4 5 6 |
SET apikey TO $'''ここにAPI Keyを入力''' SET ssid TO $'''ここに操作するスプシのIDを入れる''' SET sheetname TO $'''ここに操作するシートの名前を入力''' SET range TO $'''ここに操作する範囲を指定(例:A1:R18)''' Web.InvokeWebService.InvokeWebService Url: $'''https://sheets.googleapis.com/v4/spreadsheets/%ssid%/values/%sheetname%!%range%?key=%apikey%''' Method: Web.Method.Get Accept: $'''*/*''' ContentType: $'''application/json''' ConnectionTimeout: 30 FollowRedirection: True ClearCookies: False FailOnErrorStatus: False EncodeRequestBody: False UserAgent: $'''Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.21) Gecko/20100312 Firefox/3.6''' Encoding: Web.Encoding.AutoDetect AcceptUntrustedCertificates: False ResponseHeaders=> HTTPHeaders Response=> WSResponse StatusCode=> StatusCode Variables.ConvertJsonToCustomObject Json: WSResponse CustomObject=> ResponseObj |
関連リンク
- 「Webブラウザ」アクションからChromeでGoogle Workspaceにログインしようとすると、 「ログインできませんでした」と表示されログインできない
- Power Automate DesktopからGoogleスプレッドシートを操作する方法
- PAD:Power Automate Desktop を使って Webブラウザを操作
- Power Automateで退勤時の定型業務を自動化してみた
- Power Automate 「Gmail のメールを Google スプレッドシートに記録する」テンプレートの利用方法
- TargetingIdeaService や TrafficEstimatorService のスクレイピング
- Power Automate Desktop「ブラウザー自動化」を使いこなす
- Read Google Sheets API With Power Automate for Desktop