Google Apps ScriptでDocs APIを使って文字を一括で置き換える【GAS】
過去にSheets APIを使って高速化という記事を書きましたが、Google Apps Scriptからは使えるのはこれらのGoogle APIの一部がメソッドとして使えるようになってるものの、一部はメソッドとして用意されていません。よって、Drive APIなどもそうなのですが、サービスを追加する事で利用できるものがあったりします。
今回はGoogle Docs APIを使って文字を置き換えるものを、BatchUpdateにて一括でリクエストを送って見たいと思います。
今回利用するスプレッドシート等
- replaceAllTextで一括置き換え - Google Spreadsheet
- ReplaceAllTextRequest API - Google Docs API
今回のスクリプトは別途適当なDocumentファイルを複数用意してください。次項の事前準備にてファイルのリストと置き換える言葉リストを用意してから実行します。
事前準備
Google Apps Script側
今回はGoogle Docs APIを利用するので、スクリプトエディタに入って、以下の作業が必要になります。
- スクリプトエディタを開く
- エディタの左側、サービスの横の+をクリックする
- Google Docs APIを探して選択し、追加をクリック
これで、Docs APIの各種メソッドが利用する事ができるようになります。
図:Docs APIを追加する
データの準備
スプレッドシート側にデータの準備をします。
- filelistのシートにIDと別途用意したDocumentファイルのファイルIDを記述していく
- replacewordシートには、置き換える文字と置き換え後の文字を追加していく
今回、Documentには他の文字と混同しないように「§置き換える文字§」といった形で、§記号を使って文字を括って、これをまるごと置き換えるようにしています。同じ置き換える文字が文中に合ってもすべて、置き換わるので注意が必要です。
図:データの事前準備は大事です。
図:置き換える対象のドキュメントの中身
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
//ファイルの一覧を取得 function execreplace(){ //シートデータを取得する let sheet = SpreadsheetApp.getActiveSpreadsheet() let ss = sheet.getSheetByName("filelist").getDataRange().getValues(); let ss2 = sheet.getSheetByName("replaceword").getDataRange().getValues(); //リクエストオプションを構築する let options =[]; for(let k = 0;k<ss2.length;k++){ //レコードを一個取り出す let rec = ss2[k]; //一時配列を用意 let temparr = { replaceAllText: { replaceText: rec[1], containsText: { matchCase: true, text: rec[0] } } }; //配列に追加 options.push(temparr); } //ファイルIDを取得して置き換えを連続実行 for(let i = 1;i<ss.length;i++){ //レコードを一個取り出す let rec = ss[i]; //fileidを取得する let fileid = rec[1]; //置き換え関数を実行する let ret = docsbatch(fileid,options) } //終了メッセージ SpreadsheetApp.getUi().alert("置き換え完了") } //Docs APIを使ってバッチ処理 function docsbatch(fileid,options){ var result =Docs.Documents.batchUpdate({ requests: options }, fileid); return result; } |
- まずはreplacewordのシートの内容から、置き換えるリストを一括で作成します。
- その後、fileidを取得し置き換えるリストの配列をdocsbatchにわたす。
- docsbatch関数では、置き換えるリストでバッチアップデートを実行します。複数のファイルに対するバッチアップデートは出来ないようです。あくまでもファイル単位で実行
- Google Apps ScriptのreplaceTextメソッドで置き換える場合は1ワード単位で置き換えるの対して、一括で置き換えされるため、Docs APIのほうが早く処理を完了出来ます。
注意点
このDocs APIで100回くらい連続で実行してみたところ、以下のエラーが表示されてQuotaに引っかかりました。
1 |
GoogleJsonResponseException: 次のエラーが発生し、docs.documents.batchUpdate の呼び出しに失敗しました: Quota exceeded for quota metric 'Quota group for write operations' and limit 'Quota group for write operations per minute per user' of service 'docs.googleapis.com' for consumer 'project_number:xxxxxxxx'. |
Docs APIのQuotaはGCPの表示を見ると1分当たりでのリクエスト制限が掛けられており
- 読み取り - 3000回/1プロジェクト/1分, 300回/1プロジェクト/ユーザ/1分
- 書き込み - 600回/1プロジェクト/1分, 60回/1プロジェクト/ユーザ/1分
となってる。かなり上限が低い為、今回は1リクエスト11個の置き換えを100が1分以下で終わっていた為に、110のリクエストが送られてる。そのため、書き込みの1ユーザ1分の60回のリクエストに引っかかってしまったと思われる。
よって、実際に高速に動作するものの、Quota回避の為には、Utlities.sleepにて1000〜3000msのウェイトを入れなければならない。しかもさらにその上に600回の上限があるため、なかなか大規模に使うというのには向いていない。。
図:Quotaに引っかかってしまった