teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

実際に走らせているコードの一部を、掲載致しました。

2020/10/12 06:54

投稿

yoichiyy
yoichiyy

スコア55

title CHANGED
File without changes
body CHANGED
@@ -14,4 +14,188 @@
14
14
  フォームが同時に送信された場合、
15
15
  現在実行中のスクリプトが完了次第、準備ができるまで待ってもらうようなスクリプトを書く方法があればお教え下さい。
16
16
 
17
- どうぞよろしくお願い致します。
17
+ どうぞよろしくお願い致します。
18
+
19
+
20
+ ```
21
+ function tillDraft(){
22
+
23
+ var ss = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId());
24
+ var sheet = ss.getSheetByName("graph");
25
+ var ReferenceCell = sheet.getRange("s1"); //毎回VlookUPのために、値を更新する必要がある。
26
+ var EndCell = sheet.getRange("t1");
27
+ var ssID = "略";
28
+ var sheetID = sheet.getSheetId();
29
+ var driveID = "略";
30
+
31
+ ////////////////////
32
+ //追加変数と、追加回答処理部分
33
+ ////////////////////
34
+ var DataSheet = ss.getSheetByName("data");
35
+ const CValues = DataSheet.getRange('C:C').getValues(); 
36
+ var LastRow_Answered = CValues.filter(String).length; 
37
+
38
+ //返信済み打刻されている最終行。CValues(返信まち最終行)よりも、短い。
39
+ const CZValues = DataSheet.getRange('CZ:CZ').getValues(); 
40
+ var LastRow = CZValues.filter(String).length;  
41
+
42
+ //未処理の回答数をカウント
43
+ var mishori_count = LastRow_Answered - LastRow;
44
+ Logger.log(mishori_count)
45
+
46
+  //未処理カウントが1以上の場合、これが0になるまで(1になるまで?)繰り返し処理
47
+ if(mishori_count >0){
48
+ Logger.log("ifクリア");
49
+ for(var i = mishori_count; i >=1; i--){
50
+ Logger.log("ループ実行");
51
+ var toshibango = DataSheet.getRange(LastRow,1).getValues();
52
+ var yokonaga = DataSheet.getRange(LastRow-1,42,LastRow-1, 89).getValues();
53
+
54
+ DataSheet.getRange(LastRow,1).copyTo(DataSheet.getRange(LastRow+1,1)); //通し番号コピってます
55
+ DataSheet.getRange(LastRow-1,42,2,48 ).copyTo(DataSheet.getRange(LastRow,42,2, 48));//42列目〜89列目APからCK コピってます。
56
+ DataSheet.getRange(LastRow+1,104).setValue(new Date());//打刻
57
+
58
+ //最終行の回答番号を取得して、開始セルも終了セルもそれにする(つまり1枚のみPDF生成)
59
+ var LatestAnswer = DataSheet.getRange(LastRow+1,1).getValue();
60
+ Logger.log(LatestAnswer);
61
+ ReferenceCell.setValue(LatestAnswer);
62
+ EndCell.setValue(LatestAnswer);
63
+
64
+ ////////////////////
65
+ //以下、PDF生成から下書き作成まで
66
+ ////////////////////
67
+ var yourName = sheet.getRange("K1").getValue();
68
+ var gmailAddress = sheet.getRange("s3").getValue();
69
+ var filename = "結果_" + yourName +"様.pdf"
70
+ createPDF2(driveID, ssID,sheetID, filename); //下の関数を実行
71
+ createDraft2(gmailAddress, yourName, filename); //下の関数を実行
72
+
73
+ LastRow += 1
74
+ LastRow_Answered += 1
75
+
76
+ }
77
+ }
78
+ }
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+ function createPDF2(folderid, ssid, sheetid, filename){
97
+
98
+ // PDFファイルの保存先となるフォルダをフォルダIDで指定
99
+ var folder = DriveApp.getFolderById(folderid);
100
+
101
+ // スプレッドシートをPDFにエクスポートするためのURL。このURLに色々なオプションを付けてPDFを作成
102
+ var url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace("SSID", ssid);
103
+
104
+ // PDF作成のオプションを指定
105
+ var opts = {
106
+ exportFormat: "pdf", // ファイル形式の指定 pdf / csv / xls / xlsx
107
+ format: "pdf", // ファイル形式の指定 pdf / csv / xls / xlsx
108
+ size: "A4", // 用紙サイズの指定 legal / letter / A4
109
+ portrait: "true", // true → 縦向き、false → 横向き
110
+ fitw: "true", // 幅を用紙に合わせるか
111
+ sheetnames: "false", // シート名をPDF上部に表示するか
112
+ printtitle: "false", // スプレッドシート名をPDF上部に表示するか
113
+ pagenumbers: "false", // ページ番号の有無
114
+ gridlines: "false", // グリッドラインの表示有無
115
+ fzr: "false", // 固定行の表示有無
116
+ gid: sheetid // シートIDを指定 sheetidは引数で取得
117
+ };
118
+
119
+ var url_ext = [];
120
+
121
+ // 上記のoptsのオプション名と値を「=」で繋げて配列url_extに格納
122
+ for( optName in opts ){
123
+ url_ext.push( optName + "=" + opts[optName] );
124
+ }
125
+
126
+ // url_extの各要素を「&」で繋げる
127
+ var options = url_ext.join("&");
128
+
129
+ // optionsは以下のように作成しても同じです。
130
+ // var ptions = 'exportFormat=pdf&format=pdf'
131
+ // + '&size=A4'
132
+ // + '&portrait=true'
133
+ // + '&sheetnames=false&printtitle=false'
134
+ // + '&pagenumbers=false&gridlines=false'
135
+ // + '&fzr=false'
136
+ // + '&gid=' + sheetid;
137
+
138
+ // API使用のためのOAuth認証
139
+ var token = ScriptApp.getOAuthToken();
140
+
141
+ // PDF作成
142
+ var response = UrlFetchApp.fetch(url + options, {
143
+ headers: {
144
+ 'Authorization': 'Bearer ' + token
145
+ }
146
+ });
147
+
148
+ //
149
+ var blob = response.getBlob().setName(filename);
150
+
151
+ //}
152
+
153
+ // PDFを指定したフォルダに保存
154
+ folder.createFile(blob);
155
+ }
156
+
157
+
158
+
159
+ //////////////////////////////////////////
160
+ //CREATE DRAFT
161
+ //////////////////////////////////////////
162
+
163
+ function createDraft2(gmailAddress, yourName, filename){
164
+ //var accessToken = e.messageMetadata.accessToken;
165
+ //GmailApp.setCurrentMessageAccessToken(accessToken);
166
+ var attachedPDF = DriveApp.getFilesByName(filename).next();
167
+ var body = yourName + "様\n" +
168
+ "\n"+
169
+ "結果をお送りいたします。\n"+
170
+ "添付ファイルをご確認くださいませ。\n"+
171
+ "\n"+
172
+
173
+
174
+ GmailApp.createDraft(gmailAddress, "結果", body,{attachments:[attachedPDF]});
175
+
176
+ }
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+ ```

1

「フォームが同時に送信されるとエラーになる」という点についての説明詳細を記載致しました。

2020/10/12 06:54

投稿

yoichiyy
yoichiyy

スコア55

title CHANGED
File without changes
body CHANGED
@@ -1,17 +1,16 @@
1
1
  google formに回答があった時に、
2
2
  スクリプトが実行されるように設定(「スプレッドシートから フォーム送信時」)しています。
3
- 自動返信を送るスクリプトです。
4
-
5
- フォームを同時に送信されると、エラーになってしまいます。
6
3
 
7
- これ解決す方法として、
4
+ 自動返信メールスクリプトです。
8
- スクリプトのトリガーを、「フォーム送信時」ではなく、「5分ごと」にすることも検討しました。
9
5
 
6
+ 単にメールを送るだけでなく、
10
- ですが、この方法だと私のアカウントで5分おきにクリプトが実行されることになり、
7
+ スプレッドシーの値をコピーしたり、
11
- あまりにリソース使いぎているのではないかと思い躊躇しています。
8
+ その値をとにグラフ生成し、それをメールに添付したりするので
12
- *5分おき・・・1日に288・・・スクリプト試行が「リソースを使いぎだ」ということの根拠はないのですが、
9
+ あたり時間5秒程度かかりま
13
- いやいや、何かしらのリソースが各gogoleアカウントには割り当てられており、これはやはり影響があるだろうと予想しました。
14
10
 
11
+ このスクリプト実行の約5秒間の間に、
12
+ 次のフォームを受信してしまうと、そのままエラーになってしまいます。
13
+
15
14
  フォームが同時に送信された場合、
16
15
  現在実行中のスクリプトが完了次第、準備ができるまで待ってもらうようなスクリプトを書く方法があればお教え下さい。
17
16