【誰得】Google Forms からGoogle Documentを生成
はじめに
暇つぶしにGoogleAppsScriptでいろいろ調べて遊んでいます.そこで作ってみたスクリプトを公開したいと思います.
作ったもの
- Google Formsで作成したアンケート等をGoogle Document形式に変換します.
機能詳細
- GoogleFormsのタイトル,質問,選択肢,セクションを取得して,それらしいGoogleDocumentを生成する.
使いどころ
- GoogleFormsでアンケートを作成したが,社内が未だに書面による決済のため,作成したGoogleFormsを印刷したい.(Formsでも印刷できるが,編集ができない)
- GoogleFormsでアンケートを実施したいが,スマホ等を所持していない可能性も考慮して,紙面でのアンケートも準備したい.
- GoogleFormsで印刷したら選択肢のプルダウンが多すぎて見るに堪えないので,プルダウンの選択肢は削除して印刷したい(どれだけニッチな場面なのか)
注意点
作成したFormsに編集権限がないと使えません.
使い方
自分のGoogleDriveのフォルダ内でGoogle Apps Scriptを新規作成して,以下のスクリプトをコピペ(Google Apps Scriptの配布の仕方がわかりませんでした).
スクリプト内の保存先フォルダーのIDを書き換える
生成したDocumentを保存したいフォルダをマイドライブ内のどこかに作成し,そこのフォルダに移動する.アドレスバーの以下の画像のようにアドレスの末尾がフォルダーIDなので,それをコピーして貼り付けてください.
- 読み込むフォームのIDを書き換える
読み込みたいフォームを開いて,フォルダーIDと同じような文字列がアドレスのところに表示されているので,それをコピーして貼り付け.
- 関数がmainになっていることを確認して実行
スクリプト
//保存先フォルダーのID const saveFolderId = 'ここに保存先フォルダーのID'; //読み込むフォームのID const formId = 'ここに読み込みたいフォームのID'; //各質問の先頭に付与するためのNumber var qNo = 1; //ファイルの保存 function saveDoc(doc,titleText){ var file = DriveApp.getFileById(doc.getId()); // 出力フォルダ var OutputFolder = DriveApp.getFolderById(saveFolderId); file.moveTo(OutputFolder); } //Docの最上部に表示する文字列を設定 //見出し,センタリング function setDocTitle(body, str){ var par = body.appendParagraph(str); par.setHeading(DocumentApp.ParagraphHeading.HEADING1); par.setAlignment(DocumentApp.HorizontalAlignment.CENTER); return body; } //追加されたセクションの処理 function setSectionTitle(body,str){ var par = body.appendParagraph(str); par.setHeading(DocumentApp.ParagraphHeading.HEADING2); par.setAlignment(DocumentApp.HorizontalAlignment.CENTER); return body; } function setContents(body, item){ const indent = ' '; var type = item.getType(); switch(type){ //チェックボックスの処理 case FormApp.ItemType.CHECKBOX: var res = String(qNo) + '.' + item.getTitle() +'\n\n'; qNo++; console.log('CHCECKBOX開始-' + item.getTitle()); var choices = item.asCheckboxItem().getChoices(); for( var i = 0; i < choices.length; i++) { res += indent + '□'+choices[i].getValue() + '\n'; } res += '\n'; body.appendParagraph(res); console.log('CHCECKBOX終了'); break; //複数選択方式のグリッドの処理 case FormApp.ItemType.CHECKBOX_GRID: console.log('CHCECKBOX_GRID開始-'+item.getTitle()); var res = String(qNo) + '.' + item.getTitle() +'\n\n'; qNo++; body.appendParagraph(res) var cols = item.asCheckboxGridItem().getColumns(); var rows = item.asCheckboxGridItem().getRows(); var cells = Array(rows.length+1); cols = [''].concat(cols); cells[0] = cols; for( var i = 1; i < rows.length+1; i++){ cells[i] = Array(rows[i-1]).concat(Array(cols.length-1).fill('□')); } body.appendTable(cells); console.log('CHCECKBOX_GRID終了'); break; //日付型の処理 case FormApp.ItemType.DATE: var res = String(qNo) + '.' + item.getTitle() + '\n'; qNo++; console.log('DATE開始-' + item.getTitle()); console.log('DATE終了'); break; case FormApp.ItemType.DATETIME: var res = String(qNo) + '.' + item.getTitle() + '\n'; qNo++; console.log('DATETIME開始-' + item.getTitle()); console.log('DATETIME終了'); break; case FormApp.ItemType.DURATION: console.log('DURATION開始-' + item.getTitle()); console.log('DURATION終了'); break; //単一選択形式のグリッドの処理 case FormApp.ItemType.GRID: console.log('GRID開始-'+item.getTitle()); var res = String(qNo) + '.' + item.getTitle() +'\n\n'; qNo++; body.appendParagraph(res) var cols = item.asGridItem().getColumns(); var rows = item.asGridItem().getRows(); var cells = Array(rows.length+1); cols = [''].concat(cols); cells[0] = cols; for( var i = 1; i < rows.length+1; i++){ cells[i] = Array(rows[i-1]).concat(Array(cols.length-1).fill('〇')); } body.appendTable(cells); console.log('GRID終了'); break; case FormApp.ItemType.IMAGE: console.log('IMAGE開始-' + item.getTitle()); console.log('IMAGE終了'); break; //プルダウンの処理 case FormApp.ItemType.LIST: var res = String(qNo) + '.' + item.getTitle() + '\n\n'; qNo++; console.log('LIST開始-' + res); var choices = item.asListItem().getChoices(); for( var i = 0; i < choices.length; i++) { res += indent + '・'+choices[i].getValue() + '\n'; } res += '\n'; body.appendParagraph(res); console.log('LIST終了'); break; //ラジオボタンの処理 case FormApp.ItemType.MULTIPLE_CHOICE: var res = String(qNo) + '.' + item.getTitle() + '\n\n'; qNo++; console.log('MULTIPLE_CHOICE開始-' + res); var choices = item.asMultipleChoiceItem().getChoices(); for( var i = 0; i < choices.length; i++) { res += indent + '・'+choices[i].getValue() + '\n'; } res += '\n'; body.appendParagraph(res); console.log('MULTIPLE_CHOICE終了'); break; //段落型の処理 case FormApp.ItemType.PARAGRAPH_TEXT: var res = String(qNo) + '.' + item.getTitle() + '\n\n'; qNo++; console.log('PARAGRAPH_TEXT開始-' + item.getTitle()); res += '(自由記述)'; res += '\n'; body.appendParagraph(res); console.log('PARAGRAPH_TEXT終了'); break; //均等目盛型の処理 case FormApp.ItemType.SCALE: var res = String(qNo) + '.' + item.getTitle() + '\n\n'; qNo++; console.log('SCALE開始-' + res); var llabel = item.asScaleItem().getLeftLabel(); var rlabel = item.asScaleItem().getRightLabel(); var lbound = item.asScaleItem().getLowerBound(); var rbound = item.asScaleItem().getUpperBound(); var line = ''; for(var i = 0; i < rbound-lbound; i++){ line += '----' + String(lbound + i + 1); } res += indent + llabel + ' | ' + String(lbound) + line + ' | ' + rlabel + '\n'; body.appendParagraph(res); console.log('SCALE終了'); break; case FormApp.ItemType.SECTION_HEADER: console.log('SECTION_HEADER開始-' + item.getTitle()); console.log('SECTION_HEADER終了'); break; //記述式の処理 case FormApp.ItemType.TEXT: var res = String(qNo) + '.' + item.getTitle() + '\n\n'; qNo++; console.log('TEXT開始-' + item.getTitle()); res += '(自由記述)'; res += '\n'; body.appendParagraph(res); console.log('TEXT終了'); break; //時刻の処理 case FormApp.ItemType.TIME: console.log('TIME開始-' + item.getTitle()); console.log('TIME終了'); break; case FormApp.ItemType.VIDEO: console.log('VIDEO開始-' + item.getTitle()); console.log('VIDEO終了'); break; //追加されたセクションの処理 case FormApp.ItemType.PAGE_BREAK: body = setSectionTitle(body,item.getTitle() + '\n'); console.log('PAGE_BREAK開始-' + item.getTitle()); console.log('PAGE_BREAK終了'); break; } } function main() { //読み込み先のFormsを指定 var f = FormApp.openById(formId); //フォームの上部にある説明文 var des = f.getDescription(); var formTitle = f.getTitle(); //フォームと同じタイトルでGoogle Docsを作成する var date = new Date(); const doc = DocumentApp.create(formTitle + '_'+Utilities.formatDate(new Date(), 'JST', 'yyyyMMdd')); var body = doc.getBody(); body = setDocTitle(body,formTitle + '\n'); body.appendParagraph(des + '\n\n\n'); //質問項目を取得 var itemList = f.getItems(); for(let i = 0; i < itemList.length; i++) { setContents(body,itemList[i]); } saveDoc(doc,formTitle); }
注意点
- フォーム内の画像は取り込めません
- 回答によるセクション移動には対応していません
- テスト機能は反映しません
- 必須回答は反映しません(これはそのうち対応するかも)
- 入力チェックも反映しません
- バグがあると思います.お気づきのことがあればお知らせいただけるとありがたいです.
- その他,私が思い至らず考慮漏れしれいる事項があると思います.
参考
ここに全部書いてある. developers.google.com