GoogleスプレッドシートからGoogleフォームを作成する

# はじめに
従妹に卒業論文を作成するために、250個以上ある質問をGoogleフォームに起こしたいと言われた。
普段は記事を書かないが、同じように困っている人がいるかもしれないので残しておく。
スクリプトの内容について言及しない。

# 手順
- Googleスプレッドシートを作成する。 
フォーマットは以下の画像のようにする。「_FORM」「_BEGIN」「_END」を設けて、その間に諸々を記載すれば良い。
https://github.com/mi-ni-mi-mi/chores/blob/master/GAS/sheet2form/sheet2form_example.csv
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777640/767e357c-1712-4fcc-8d7f-4f9906128132.png)




- Apps Scriptを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777640/7e162adf-3146-164c-90b6-d82d22631e76.png)

- 以下のコード（sheet2form.gs）をコピペして保存（Ctrl+S）する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777640/fab8fe32-3839-ee30-d0f8-07e7a3923446.png)

```javascript:sheet2form.gs
function sheet2form() {

  //配列からキーワードに一致する要素のインデックスを返す
  function findIndex(values, keyword) {
    for (let i = 0; i < values.length; i++) {
      if (values[i][0] == keyword) { //1列目のみ
        return i + 1;
      }
    }
  }

  //シート全体を二次元配列に格納する
  const sheet = SpreadsheetApp.getActive().getActiveSheet();
  let values = sheet.getDataRange().getValues();

  //「_FORM」、「_BEGIN」、「_END」のセルを探す
  const formNum = findIndex(values, "_FORM");
  const beginNum = findIndex(values, "_BEGIN");
  const endNum = findIndex(values, "_END");

  //フォームファイル作成
  let date = new Date();
  let fileName = 'フォーム_' //ファイル名が未指定の場合のための初期値
    + date.getFullYear()
    + ('0' + (date.getMonth() + 1)).slice(-2)
    + ('0' + date.getDate()).slice(-2) + "_"
    + ('0' + date.getHours()).slice(-2)
    + ('0' + date.getMinutes()).slice(-2)
    + ('0' + date.getSeconds()).slice(-2);
  let form = FormApp.create(fileName);
  const formID = form.getId();

  //フォームの設定を読み込む
  for (let i = formNum; i < beginNum - 1; i++) {
    let method = values[i][1];

    if (method == "フォームファイル名") {
      DriveApp.getFileById(formID).setName(values[i][3])
    }
    else if (method == "メールアドレス") {
      form.setCollectEmail(values[i][3] == "収集する");
    }
    else if (method == "フォームタイトル") {
      form
        .setTitle(values[i][3])
        .setDescription(values[i][4]);
    }
    else if (!method) {
      //空行なら何もしない
    }
    else {
      Browser.msgBox(method + "：不明なメソッドです。");
    }
  }

  //フォームの内容を読み込む
  for (let i = beginNum; i < endNum - 1; i++) {
    let method = values[i][1];

    //セクションを追加するか否か
    let section;
    if (values[i][0] == "次のセクション") {
      section = form.addPageBreakItem();
    };

    if (method == "セクションタイトル") {
      section
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (method == "タイトル") {
      let item = form.addSectionHeaderItem();
      item
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (method == "記述式") {
      let item = form.addTextItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (method == "段落") {
      let item = form.addParagraphTextItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (method == "ラジオボタン") {
      let item = form.addMultipleChoiceItem();
      let list = [];
      for (let j = 6; j < 2006; j++) { //選択数の上限は2000個
        let value = values[i][j];
        if (value) {
          list.push(values[i][j]);
        } else {
          continue;
        }
      }
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        .setChoiceValues(list).showOtherOption(values[i][5] == "その他あり")
        ;
    }
    else if (method == "チェックボックス") {
      let item = form.addCheckboxItem();
      let list = [];
      for (let j = 6; j < 2006; j++) { //選択数の上限は2000個
        let value = values[i][j];
        if (value) {
          list.push(values[i][j]);
        } else {
          continue;
        }
      }
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        .setChoiceValues(list).showOtherOption(values[i][5] == "その他あり");
      ;
    }
    else if (method == "プルダウン") {
      let item = form.addListItem();
      let list = [];
      for (let j = 5; j < 2005; j++) { //選択数の上限は2000個
        let value = values[i][j];
        if (value) {
          list.push(values[i][j]);
        } else {
          continue;
        }
      }
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        .setChoiceValues(list)
        ;
    }
    else if (method == "均等目盛") {
      var item = form.addScaleItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        .setBounds(values[i][5], values[i][6])
        .setLabels(values[i][7], values[i][8])
    }
    else if (method == "日付") {
      let item = form.addDateItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        .setIncludesYear(values[i][5] == "年を含む")
        ;
    }
    else if (method == "日付と時刻") {
      let item = form.addDateTimeItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (method == "時刻") {
      let item = form.addTimeItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (method == "持続時間") {
      let item = form.addDurationItem();
      item
        .setRequired(values[i][2] == "必須")
        .setTitle(values[i][3])
        .setHelpText(values[i][4])
        ;
    }
    else if (!method) {
      //空行なら何もしない
    }
    else {
      Browser.msgBox(method + "：不明なメソッドです");
    } 
  }
}
```

- 「実行」をクリックする。
- 「権限を確認」をクリックする。
- アカウントを選択する。
- 「詳細」をクリックする。
- 「無題のプロジェクト（安全ではないページ）に移動」をクリックする。
- 「許可」をクリックする。
- 「実行完了」を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777640/79c26cff-be97-6cff-2c02-db8b4bbf25ad.png)
- Googleドライブのルートフォルダにフォームが作成されたことを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777640/60479ef5-896e-8ef1-bbbd-6959c46210ab.png)

以上

# 資料
スクリプトとスプレッドシートはGitHubにアップロードしている。
https://github.com/mi-ni-mi-mi/chores/tree/master/GAS/sheet2form