GoogleSpreadSheetからGoogleFormを作るGAS

# 概要
選択肢やセクションの多いアンケートをFormで編集しながら作るのは面倒だし、ミスが発生しやすいと思ったので、SpreadSheetの情報をもとに生成できるツールを開発しました。

# 実現できること
1　プログラミングができないユーザが使用することを想定して、必要な変数はSpreadSheetから読み込むようにしています
2  記述式(メールアドレス形式も設定可能)、ラジオボタン、チェックボックス、プルダウンを設定できます
3　必須にするかを選択できます
4　ラジオボタン、チェックボックの場合、テキストボックスで入力できるようにできます
5　質問にはセクションを設定できます
6　原則、FormはSpreadSheetのあるドライブに保存されますが、保存先を設定できます

# 実現できていないこと
1　回答に応じてセクションを分岐させることはできませんでした。ループ処理を回すときの処理が複雑になりすぎて実装が難しかったです。必要な場合はできたフォームを手で修正せざるをえないです。
2　Formヘッダへの画像挿入、グリッド形式の質問などは職場での需要がなかったので実装していません。要望があれば別途、開発してみます

# SpreadSheetの画面イメージ
1　質問を入力する表
![質問シート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670115/1952bc86-cb10-ec5c-0226-c9c52460e9a8.png)

2　選択肢を入力する表
![選択肢シート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670115/50742ad0-bd9d-13bd-2c09-9631da64a958.png)

3　フォームの保存先を入力する表
　こちらは空白でも構いません。
![移動先.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670115/9261e41c-48db-35ba-5371-aefc1b69046c.png)

# ソースコード
```JavaScript
const createEventForm = (e) => {
  // 質問シート情報の取得
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const q_data = ss.getSheetByName('質問').getDataRange().getValues();
  const q_lastrow = ss.getSheetByName('質問').getLastRow();

  // 質問が1問も設定されていない場合、処理を終了する
  if (q_lastrow < 3) {
    Browser.msgBox("スプレッドシートには最低1問以上、質問を入力してください。",
                   Browser.Buttons.OK_CANCEL);
    return;
  }

  // タイトルと説明の設定
  const title = q_data[0][1]; //タイトル

  if (title == "") {
    Browser.msgBox("フォームの名称を入力してください。", 
                   Browser.Buttons.OK_CANCEL);
    return;
  }
  
  const form = setHeader(title);
```

```JavaScript
  // 選択肢シート情報の取得
  const s_data = ss.getSheetByName('選択肢').getDataRange().getValues();
  s_data.shift()

 // 質問の設定
  let j = 0; // 選択肢の列番号
  let selections = null;
  let section_prev = null;
  
  for (let i = 2; i < q_lastrow; i++) {     
    // セクションの切り替えを行う
    if(q_data[i][0] != section_prev && section_prev !== null) {
      form.addPageBreakItem().setTitle(q_data[i][0]);
    }
    
    section_prev = q_data[i][0];
        
    if (q_data[i][1] == 'ラジオボタン' || 
        q_data[i][1] == 'チェックボックス' || 
        q_data[i][1] == 'プルダウン') {
      selections = getSelections(s_data, j);

      if (!selections.length) {
        Browser.msgBox("質問に対応する選択肢を入力してください。", 
                       Browser.Buttons.OK_CANCEL);
        return;        
      }
    }
    
    // B列に指定した入力した内容に応じてフォームに入力項目を追加する
    if (q_data[i][1] == '記述式') {
      setTextQuestion(form, q_data[i][2], q_data[i][3], Boolean(q_data[i][4]));
    } else if (q_data[i][1] == 'メールアドレス') {
      setMail(form, q_data[i][2], q_data[i][3], Boolean(q_data[i][4]))
    } else if (q_data[i][1] == 'ラジオボタン') {
      setRadiobutton(form, q_data[i][2], q_data[i][3], 
                     Boolean(q_data[i][4]), Boolean(q_data[i][5]), selections);

      j++;
    } else if (q_data[i][1] == 'チェックボックス') {
      setCheckbox(form, q_data[i][2], q_data[i][3], 
                  Boolean(q_data[i][4]), Boolean(q_data[i][5]), selections);

      j++;
    } else if (q_data[i][1] == 'プルダウン') {
      setDropdownlist(form, q_data[i][2], q_data[i][3], 
                      Boolean(q_data[i][4]), selections);

      j++;
    }      
  }
```

```JavaScript
  // フォームの移動
  let dest = ss.getSheetByName('移動先').getRange(1, 2).getValue();

  if (dest) {
    dest = dest.replace('https://drive.google.com/drive/folders/', '')
    moveForm(form, dest);
  }

  Browser.msgBox("フォームの作成が完了しました。", Browser.Buttons.OK_CANCEL);
  return;
}
```