質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

2回答

3222閲覧

【GAS】スプレッドシートからGoogleFromsへの問題の流し込みについて

tokutake

総合スコア7

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2020/04/10 00:09

スプレッドシートに書かれた項目をGoogle Formの問題として流し込みたいのですが,なぜか「from.addListItem()」を繰り返すたびに項目が減ってしまいます.

コード内の「 generateArray(values, column)」部分の記述が悪いことは想像できるんですが,具体的にどのように修正すればいいかご教授頂けないでしょうか.

GAS

1//Googleフォームへの書き出し 2function createEventForm(){ 3 4 const ss = SpreadsheetApp.getActiveSpreadsheet() 5 const dataValues = ss.getSheetByName('DB').getDataRange().getValues(); 6 const values = ss.getSheetByName('DB').getDataRange().getValues(); 7 const values2 = ss.getSheetByName('問題選定').getDataRange().getValues(); 8 const formTitle = values2[0][1]; //タイトル 9 const form = FormApp.create(formTitle); 10 const formFile = DriveApp.getFileById(form.getId()); 11 DriveApp.getFolderById('').addFile(formFile); 12 DriveApp.getRootFolder().removeFile(formFile); 13 //氏名欄の追加 14 15 form.addListItem() 16 .setTitle('学年を入力してください') 17 .setChoiceValues(generateArray(dataValues, 15)) 18 .setRequired(true); 19 20 form.addListItem() 21 .setTitle('クラスを入力してください') 22 .setChoiceValues(generateArray(dataValues, 16)) 23 .setRequired(true); 24 25 form.addListItem() 26 .setTitle('出席番号を入力してください') 27 .setChoiceValues(generateArray(dataValues, 17)) 28 .setRequired(true); 29 30 31 form.addTextItem().setTitle('氏名を入力してください').setRequired(true); 32 33 //セクション変更 34 form.addPageBreakItem().setTitle('問題'); 35 36 37 const q1 = ss.getSheetByName('問題選定').getRange('A3').getValue(); 38 const q2 = ss.getSheetByName('問題選定').getRange('A4').getValue(); 39 const q3 = ss.getSheetByName('問題選定').getRange('A5').getValue(); 40 const q4 = ss.getSheetByName('問題選定').getRange('A6').getValue(); 41 const q5 = ss.getSheetByName('問題選定').getRange('A7').getValue(); 42 const q6 = ss.getSheetByName('問題選定').getRange('A8').getValue(); 43 const q7 = ss.getSheetByName('問題選定').getRange('A9').getValue(); 44 const q8 = ss.getSheetByName('問題選定').getRange('A10').getValue(); 45 const q9 = ss.getSheetByName('問題選定').getRange('A11').getValue(); 46 const q10 = ss.getSheetByName('問題選定').getRange('A12').getValue(); 47 const q11 = ss.getSheetByName('問題選定').getRange('A13').getValue(); 48 const q12 = ss.getSheetByName('問題選定').getRange('A14').getValue(); 49 const q13 = ss.getSheetByName('問題選定').getRange('A15').getValue(); 50 const q14 = ss.getSheetByName('問題選定').getRange('A16').getValue(); 51 const q15 = ss.getSheetByName('問題選定').getRange('A17').getValue(); 52 53 54 //問題の追加 55 var i =1 56 for(i=1;i<16;i++){ 57 form.addMultipleChoiceItem() 58 .setTitle(eval('q'+i) +'の意味を答えなさい') 59 .setChoiceValues(generateArray(values2, 2)) 60 } 61 62 63 function msgbox() { 64  //メッセージをmsgへ格納 65  var msg = "問題作成ができました!指定のドライブに戻ってください" 66 //メッセージボックスを表示 67 Browser.msgBox(msg); 68 } 69 msgbox(); 70 71 72 73} 74 75 function generateArray(values, column){ 76 77 values.shift(); 78 return values.map(record => record[column]).filter(value => value); 79 80 } 81 82

スプレッドシートは添付写真のようになっています.
イメージ説明

Formはこのようになってしまいます.
本来であれば,クラスは「A」から,出席番号は「1」から始まるはずなのですが…
イメージ説明

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己満足パターン

  • eval をする必要がない。
  • eval するために 1 つずつ値をとっているが、既に取得済みの値のため無駄な時間が生じている。
  • コードでシャッフルすれば選択肢を別に持つ理由がない。

//問題選定改

titiletest
quizans
A3B3
A4B4
A5B5
A6B6
A7B7
A8B8
A9B9
A10B10
A11B11
A12B12
A13B13
A14B14
A15B15
A16B16
A17B17
B18
B19
B20
B21
B22

javascript

1const q252598 = () => { 2 const configSheet = "DB"; 3 const quizSheet = "問題選定改"; 4 const book = SpreadsheetApp.getActive(); 5 const config = book.getSheetByName(configSheet).getDataRange().getValues(); 6 const quiz = book.getSheetByName(quizSheet).getDataRange().getValues(); 7 const form = createFormInFolder(quiz[0][1],""); 8 [15,16,17].forEach(e=> addList(form,arrayColumn(config,e),true)); 9 addText(form,'氏名を入力してください',true); 10 const qs = arrayColumn(quiz,0); 11 qs.shift(); 12 addPageBreak(form,qs.shift()); 13 const choice = arrayColumn(quiz,1).slice(2); 14 qs.forEach(e=>addMultipleChoice(form,`${e}の意味を答えなさい`,shuffle(choice))); 15 book.toast("指定のドライブに戻ってください","問題作成完了",10); 16} 17const arrayColumn = (array, column) => array.map(e=>e[column]).filter(e=>e.toString() !== ""); 18const shuffle = (array) => { 19 let i, j; 20 let len = array.length; 21 if (len < 2) { return array;} 22 while (len) { 23 i = Math.floor(Math.random() * len--); 24 j = array[i]; 25 array[i] = array[len]; 26 array[len] = j; 27 } 28 return array; 29} 30const createFormInFolder = (title, folder) => { 31 const form = FormApp.create(title); 32 const formAsFile = DriveApp.getFileById(form.getId()); 33 DriveApp.getFolderById(folder).addFile(formAsFile); 34 DriveApp.getRootFolder().removeFile(formAsFile); 35 return form; 36} 37const addList = (form,dat,required = true) => { 38 const header = dat.shift(); 39 form.addListItem() 40 .setTitle(`${header}を入力してください`) 41 .setChoiceValues(dat) 42 .setRequired(required); 43} 44const addText = (form, title, required = true) => { 45 form.addTextItem().setTitle(title).setRequired(required); 46} 47//セクション変更 48const addPageBreak = (form,title) => { 49 form.addPageBreakItem().setTitle(title); 50} 51const addMultipleChoice = (form,title,choice) => { 52 form.addMultipleChoiceItem() 53 .setTitle(title) 54 .setChoiceValues(choice); 55}

4 回実行して 15.046 秒 13.899 秒 14.942 秒 15.924 秒
さほど早くならなかった。

投稿2020/04/11 15:10

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

添削パターン

javascript

1//Googleフォームへの書き出し 2function createEventForm(){ 3 4 const ss = SpreadsheetApp.getActiveSpreadsheet() 5 const dataValues = ss.getSheetByName('DB').getDataRange().getValues(); 6 const values = ss.getSheetByName('DB').getDataRange().getValues(); 7 const values2 = ss.getSheetByName('問題選定').getDataRange().getValues(); 8 const formTitle = values2[0][1]; //タイトル 9 const form = FormApp.create(formTitle); 10 const formFile = DriveApp.getFileById(form.getId()); 11 DriveApp.getFolderById('').addFile(formFile); 12 DriveApp.getRootFolder().removeFile(formFile); 13 //氏名欄の追加 14 15 form.addListItem() 16 .setTitle('学年を入力してください') 17 .setChoiceValues(generateArray(dataValues, 15)) 18 .setRequired(true); 19 20 form.addListItem() 21 .setTitle('クラスを入力してください') 22 .setChoiceValues(generateArray(dataValues, 16)) 23 .setRequired(true); 24 25 form.addListItem() 26 .setTitle('出席番号を入力してください') 27 .setChoiceValues(generateArray(dataValues, 17)) 28 .setRequired(true); 29 30 31 form.addTextItem().setTitle('氏名を入力してください').setRequired(true); 32 33 //セクション変更 34 form.addPageBreakItem().setTitle('問題'); 35 36 37 const q1 = ss.getSheetByName('問題選定').getRange('A3').getValue(); 38 const q2 = ss.getSheetByName('問題選定').getRange('A4').getValue(); 39 const q3 = ss.getSheetByName('問題選定').getRange('A5').getValue(); 40 const q4 = ss.getSheetByName('問題選定').getRange('A6').getValue(); 41 const q5 = ss.getSheetByName('問題選定').getRange('A7').getValue(); 42 const q6 = ss.getSheetByName('問題選定').getRange('A8').getValue(); 43 const q7 = ss.getSheetByName('問題選定').getRange('A9').getValue(); 44 const q8 = ss.getSheetByName('問題選定').getRange('A10').getValue(); 45 const q9 = ss.getSheetByName('問題選定').getRange('A11').getValue(); 46 const q10 = ss.getSheetByName('問題選定').getRange('A12').getValue(); 47 const q11 = ss.getSheetByName('問題選定').getRange('A13').getValue(); 48 const q12 = ss.getSheetByName('問題選定').getRange('A14').getValue(); 49 const q13 = ss.getSheetByName('問題選定').getRange('A15').getValue(); 50 const q14 = ss.getSheetByName('問題選定').getRange('A16').getValue(); 51 const q15 = ss.getSheetByName('問題選定').getRange('A17').getValue(); 52 53 54 //問題の追加 55 var i =1 56 for(i=1;i<16;i++){ 57 form.addMultipleChoiceItem() 58 .setTitle(eval('q'+i) +'の意味を答えなさい') 59 .setChoiceValues(generateArray(values2.slice(1), 2)) 60 } 61 62 function msgbox() { 63  //メッセージをmsgへ格納 64  var msg = "問題作成ができました!指定のドライブに戻ってください" 65 //メッセージボックスを表示 66 Browser.msgBox(msg); 67 } 68// msgbox(); 69 70 71 72} 73 74 function generateArray(values, column){ 75 76 return values.slice(1).map(record => record[column]).filter(value => value); 77 78 }

2回実行したところ、16.035, 17.588 秒でした。
msgbox はユーザがボタンを押すまでスクリプトの実行がおわらず、6 分の時間制限にかかるのでやめたほうがよいと思います。

// 問題選定

titiletest
quizcorrectchoice
A3B3C3
A4B4C4
A5B5C5
A6B6C6
A7B7C7
A8B8C8
A9B9C9
A10B10C10
A11B11C11
A12B12C12
A13B13C13
A14B14C14
A15B15C15
A16B16C16
A17B17C17
C18
C19
C20
C21
C22

//DB

学年クラス出席番号
012345678910111213141A1
2B2
3C3
D4
E5
F6
G7
H8
I9
J10
11
12
13
14
15
16
17
18
19
20

投稿2020/04/11 14:44

編集2020/04/11 15:13
papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問