見出し画像

Googleフォームをより便利に

各選択肢に点数をふれない

アンケートを取るときに便利な「Googlフォーム」。
自動集計をしてくれるので、集計作業も簡単です。
しかし、下のような場合は不便です。

Aの選択肢を選んだ人に4ポイント
Bの選択肢を選んだ人に3ポイント
Cの選択肢を選んだ人に2ポイント
Dの選択肢を選んだ人に1ポイント
選択肢が異なると置換もめんどくさい

選択肢にポイントを振って、集計したい。
しかし、私の調べではできませんでした。

出番だよーGAS!!

ということで、今回は、
①Googleフォームで、同じ配点にしたい回答のアルファベットを付ける
②回答をスプレッドシートに出力する
②1文字切るスプレッドシートに回答をコピーする
④プログラムでアルファベットだけを残し、それ以外を削除する
⑤スプレッドシートの「検索と置換」で、アルファベットを点数に置換する
⑥集計する
というフローで集計できると構想しました。
ではでは、④をGASでプログラミングします。

作成した流れ

配列は神!

先頭の文字だけ残すメソッドあるだろうと探したところありました。
「sliceメソッド」
さすが配列。便利。

sliceメソッドを使えるように色々と工夫をしていきます。
1次配列でないとやってくれないとのこと。
1次配列にしてsliceメソッドを回しましょう。

このようなデータにアプローチします

スプレッドシートのデータは、基本的に
A列:タイムスタンプ
B列:名前
になるので、C列(配列だと2)からlength-1にsliceメソッドを行います。

function slice1() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(`入力シート`);
  const datas = sheet.getDataRange().getValues();  //シートすべてのデータを配列
  datas.shift(); //見出しを削除

  let newdatas = []; //スライスした配列を格納する配列

  for (let data of datas) {  //1次配列化
    for (let i = 2; i <= data.length - 1; i++) { //要素数回forで回す
      data[i] = data[i].slice(0, 1); //先頭の文字だけ残す
    }
    newdatas.push(data); //スライスした配列をnewdatasに格納
  }
}
こんな感じに先頭の文字だけになります。

この後は、スプレッドシートの「編集」の「検索と置換」を使います。
アルファベットを点数に置換します。
これで、集計ができるようになります。

縦型も欲しい

実は集計表があって、縦型の集計をする!!
うううう、Googleフォームは横型。
心配要りません。
貼り付ける際に、横型⇔横型に変換する貼り付け方もあります。。
しかし、作ってみたくなるのが人ってものです。

こちらの記事にあるアロー関数をそのまま使わせていただきます。

  const xych = Browser.msgBox("XY変換を行いますか?", Browser.Buttons.YES_NO);  //縦型にするかmsgBoxで聞く
  if (xych == `yes`) { //Yesだった場合実行
    const transpose = a => a[0].map((_, c) => a.map(r => r[c])); //transpose関数を定義
    newdatas = transpose(newdatas); //transpose関数を実行
    newdatas.shift(); //タイムスタンプ列を削除
  }
無事縦型になりました。

基データは残こす

元データを変更すると、ややこしくなりそうです。
新しいシートを作成して、貼り付けます。
 ①新しいシートを作成
 ②inputBoxでシート名を回収
 ③新しいシートに名前を付ける
 ④配列を1次配列にして、appendRowで新しいシートに貼り付ける
のプログラムを作りました。

  const newsheet = ss.insertSheet()  //新しいシートを挿入
  const name = Browser.inputBox(`シートの名前を入力してください`)  //inputBoxでnameを定義
  newsheet.setName(name)   //新しいシートに名前を付ける

  for (let newdata of newdatas) {  //1次配列化
    newsheet.appendRow(newdata)  //appendRowで新しいシートに貼り付ける
  }

ヘルプとメニューが便利

使い方を知らない方にプログラムが渡った時に説明するのは面倒です。
そんな時に、ヘルプがあると便利です。
今回のヘルプは、起動したときに表示させるようにします。

また、プログラムを実行する際に、Apps Scriptを押して実行するのは大変です。
メニューに、プログラムを実行するメニューを作成しましょう。

function onOpen()の中にコードを入れ込こみます。
スプレッドシートを開いた際に実行させることができるそうです。

起動時にヘルプがポップアップされるようになりました
アプリメニューが追加されました
//スプレッドシートを開いた際に実行する
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  const menu = ui.createMenu(`アプリメニュー`);  //menuにアプリメニューを定義
  menu.addItem(`変換`, `slice1`);  //slice1関数を変換メニューに設定
  menu.addToUi();  //menuを追加

  help();//ヘルプ関数を実行
}

//使い方ヘルプを表示させる
function help() {
  Browser.msgBox(`
このアプリはA1から入力したデータを先頭1文字に区切るアプリです。\\n
A列目は非表示、B列はそのまま、C列から先頭1文字になります。\\n
XYを変換することも可能です。
`);
}

完成したプログラム

function slice1() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(`入力シート`);
  const datas = sheet.getDataRange().getValues();
  datas.shift(); //見出しを削除

  let newdatas = []; //スライスした配列を格納する配列

  for (let data of datas) {  //1次配列化
    for (let i = 2; i <= data.length - 1; i++) { //要素数回forで回す
      data[i] = data[i].slice(0, 1); //先頭の文字だけ残す
    }
    newdatas.push(data); //スライスした配列をnewdatasに格納
  }

  const xych = Browser.msgBox("XY変換を行いますか?", Browser.Buttons.YES_NO);  //縦型にするかmsgBoxで聞く
  if (xych == `yes`) { //Yesだった場合実行
    const transpose = a => a[0].map((_, c) => a.map(r => r[c])); //transpose関数を定義
    newdatas = transpose(newdatas); //transpose関数を実行
    newdatas.shift(); //タイムスタンプ列を削除
  }

  const newsheet = ss.insertSheet()  //新しいシートを挿入
  const name = Browser.inputBox(`シートの名前を入力してください`)  //inputBoxでnameを定義
  newsheet.setName(name)   //新しいシートに名前を付ける

  for (let newdata of newdatas) {  //1次配列化
    newsheet.appendRow(newdata)  //appendRowで新しいシートに貼り付ける
  }

}

//スプレッドシートを開いた際に実行する
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  const menu = ui.createMenu(`アプリメニュー`);  //menuにアプリメニューを定義
  menu.addItem(`変換`, `slice1`);  //slice1関数を変換メニューに設定
  menu.addToUi();  //menuを追加

  help();//ヘルプ関数を実行
}

//使い方ヘルプを表示させる
function help() {
  Browser.msgBox(`
このアプリはA1から入力したデータを先頭1文字に区切るアプリです。\\n
A列目は非表示、B列はそのまま、C列から先頭1文字になります。\\n
XYを変換することも可能です。
`);
}

私が作ったものは下からコピーできます。
お使いください。