すいません、説明が下手なのでコードにしてみました。
修正した点、考慮した点を簡単に列記します。
- 合算シートの最終行が取得できていなさそうだったので
getLastRow()
を使用しています
- もともとのソースですと合算シートの行ごとにスプレッドシートを作成する流れになっていたため、
「発行」というキーワードがあり、一番初めに取得した顧客名を基準にスプレッドシートを作成しています。
逆に言うと制限として「発行」というキーワードが複数の顧客にまたがっているとスプレッドシートは作成されません。
合算シートがどの程度のボリュームかが検討がつかなかったので、1顧客ずつ作成する流れにしてしまいました。
- 1つの顧客情報の中に配列で内容?商品名?を格納するようにしました。
- 1つの項目ごとに
setValue()
で記載していたのを、setValues()
を使用して、
配列でまとめて記載する流れに変えました。
都度、GASにアクセスする流れは遅くなるので、なるべく一度に記載したほうがよいと思いました。
GAS
1function myfunction() {
2 Logger.log('--処理開始--');
3
4/*基本設定*/
5 var tmplId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //テンプレートIDの定義
6 var dstDirId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //保存先IDの定義
7
8/*コピー処理*/
9 var tmpl = DriveApp.getFileById(tmplId); //テンプレートIDからデータを取得
10 var dstDir = DriveApp.getFolderById(dstDirId); //IDからフォルダの場所を取得
11 var ss_act = SpreadsheetApp.getActiveSpreadsheet(); //アクティブなシートを取得
12
13 var ss_copyFrom = ss_act.getSheetByName('合算'); //アクティブなシート内の「合算」タブ内を参照
14 var LR_ssf = ss_copyFrom.getLastRow();
15 var Data =ss_copyFrom.getDataRange().getValues();
16 var n = 1;
17
18/*格納作業*/
19 var strage_userinfo = [];
20 for(var i=1; i<LR_ssf; i++){
21 if(Data[i][6] === '発行'){
22 //条件分岐用:明細発行有無
23
24 if(strage_userinfo[0] == undefined){
25 strage_userinfo.push(Data[i][1]); //顧客名
26 strage_userinfo.push(Data[i][2]); //郵便番号
27 strage_userinfo.push(Data[i][3]); //住所
28 strage_userinfo.push(Data[i][4]); //建物名等
29 strage_userinfo.push(Data[i][7]); //敬称
30 strage_userinfo[5] = [];
31 }
32
33 var strage_data = [];
34 if(strage_userinfo[0] === Data[i][1]){
35 strage_data.push(Data[i][18]); //内容
36 strage_data.push(Data[i][19]); //単価
37 strage_data.push(Data[i][20]); //数量
38 strage_data.push(Data[i][21]); //合計
39 }
40 strage_userinfo[5].push(strage_data);
41 }
42 }
43 //Logger.log(strage_userinfo);
44
45/*データ発行処理*/
46 var invoice = tmpl.makeCopy(strage_userinfo[0],dstDir); //指定フォルダにデータを作成し名称をB2から↓(i,2)の値とする。
47
48/*転記シート処理*/
49 var sst = SpreadsheetApp.open(invoice); //作成済みデータ開く
50 var t_sheets = sst.getSheets(); //sheetsの値を定義
51 var t_sheet = t_sheets[0]; //作成済みファイルは1シートしかないので0番目を取得
52
53 //顧客情報
54 var invoice_inforange = t_sheet.getRange('A1:I21');
55 var invoice_infoset = invoice_inforange.getValues();
56
57 invoice_infoset[0][1] = ('〒'+strage_userinfo[1]); //B1:郵便番号 を代入
58 invoice_infoset[1][1] = (strage_userinfo[2]); //B2:住所を代入
59 invoice_infoset[2][1] = (strage_userinfo[3]); //B3:建物名等を代入
60 invoice_infoset[4][1] = (strage_userinfo[0]); //B5:送付先名称を代入
61 invoice_infoset[4][3] = (strage_userinfo[4]); //D5:敬称を代入
62 invoice_infoset[0][8] = ("001"); //I1:請求IDを代入*ここどうしようか悩んでます。
63 invoice_infoset[20][2] = (strage_userinfo[0]); //C21:件名を代入
64
65 /*
66 var dt = new Date(); //現在の日付を取得
67 var y = dt.getFullYear();
68 var m = ("00" + (dt.getMonth()+1)).slice(-2);
69 var d = ("00" + dt.getDate()).slice(-2);
70 var today = y + "/" + m + "/" + d;
71 */
72 var today = new Date();
73 invoice_infoset[1][8] = (today); //I2:本日を代入
74
75 //Logger.log(invoice_infoset);
76
77 //出力データ
78 var invoice_datarange = t_sheet.getRange(27, 2, strage_userinfo[5].length, 8);
79 var invoice_dataset = invoice_datarange.getValues();
80 for(var t=0; t < invoice_dataset.length; t++){
81 invoice_dataset[t][0] = (strage_userinfo[5][t][0]); //B27:内容を代入
82 invoice_dataset[t][4] = (strage_userinfo[5][t][1]); //F27:単価を代入
83 invoice_dataset[t][6] = (strage_userinfo[5][t][2]); //H27:数量を代入
84 invoice_dataset[t][7] = (strage_userinfo[5][t][3]); //I27:合計を代入
85 }
86 //Logger.log(invoice_dataset);
87
88 //顧客情報を転記シートに記入
89 invoice_inforange.setValues(invoice_infoset);
90 //出力データを転記シートに記入
91 invoice_datarange.setValues(invoice_dataset);
92
93 Logger.log('--処理終了--');
94}
1顧客ずつスプレッドシートを作成するのではなく、
まとめて作成する場合にはさらに合算シート内でフラグを設けておいたほうがよいかと思いました。
あ… それとも月末とかにまとめて請求書発行するのであれば、別にフラグ関係なかったか…orz
いかがでしょうか?
まだ勉強中の身のため説明が下手ですいません。。。
追記(2018/08/09)
複数のスプレッドシートが作成できるようにしてみました。
格納作業のところで、顧客名ごとにデータをまとめる作業をしました。
もう少し効率のよい書き方があると思います。。。
データ発行処理のところで、顧客名ごとにスプレッドシートを作成しています。
GASに問い合わせする回数を減らすのがいずれもポイントなんだと思います。
簡単なテストしかしていないので適宜修正してください。
GAS
1function myfunction() {
2 Logger.log('--処理開始--');
3
4/*基本設定*/
5 var tmplId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //テンプレートIDの定義
6 var dstDirId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //保存先IDの定義
7
8/*コピー処理*/
9 var tmpl = DriveApp.getFileById(tmplId); //テンプレートIDからデータを取得
10 var dstDir = DriveApp.getFolderById(dstDirId); //IDからフォルダの場所を取得
11 var ss_act = SpreadsheetApp.getActiveSpreadsheet(); //アクティブなシートを取得
12
13 var ss_copyFrom = ss_act.getSheetByName('合算'); //アクティブなシート内の「合算」タブ内を参照
14 var LR_ssf = ss_copyFrom.getLastRow();
15 var Data = ss_copyFrom.getDataRange().getValues();
16 var n = 1;
17
18 //Logger.log(Data);
19
20/*格納作業*/
21 var strage_userinfo = [];
22 for(var i=1; i < LR_ssf; i++){
23 if(Data[i][6] == '発行'){
24 //条件分岐用:明細発行有無
25 if(strage_userinfo.length > 0){
26 //配列に1つ以上顧客情報がある
27 for(var a=0; a < strage_userinfo.length; a++){
28 var search_name = strage_userinfo[a].indexOf(Data[i][1]);
29 if(search_name >=0){
30 //顧客名が見つかった
31 var strage_data = [
32 Data[i][18], //内容
33 Data[i][19], //単価
34 Data[i][20], //数量
35 Data[i][21] //合計
36 ];
37 strage_userinfo[a][5].push(strage_data);
38 break;
39
40 }else if(search_name == -1){
41 //顧客名見つからない
42 if(a+1 == strage_userinfo.length){
43 //配列内には顧客名なし
44 var user_array =[
45 Data[i][1], //顧客名
46 Data[i][2], //郵便番号
47 Data[i][3], //住所
48 Data[i][4], //建物名等
49 Data[i][7], //敬称
50 []
51 ];
52 var strage_data = [
53 Data[i][18], //内容
54 Data[i][19], //単価
55 Data[i][20], //数量
56 Data[i][21] //合計
57 ];
58 user_array[5].push(strage_data);
59 strage_userinfo.push(user_array);
60 break;
61 }
62 }
63 }
64
65 }else{
66 Logger.log("配列なし");
67 //配列の中身が存在していない
68 var user_array =[
69 Data[i][1], //顧客名
70 Data[i][2], //郵便番号
71 Data[i][3], //住所
72 Data[i][4], //建物名等
73 Data[i][7], //敬称
74 []
75 ];
76 var strage_data = [
77 Data[i][18], //内容
78 Data[i][19], //単価
79 Data[i][20], //数量
80 Data[i][21] //合計
81 ];
82 user_array[5].push(strage_data);
83 strage_userinfo.push(user_array);
84 }
85 }
86 }
87 //Logger.log(strage_userinfo);
88
89/*データ発行処理*/
90 for(var v=0; v < strage_userinfo.length; v++){
91 Logger.log("--" + (v+1) +"枚目の処理--");
92 //スプレッドシートのコピー
93 var invoice = tmpl.makeCopy(strage_userinfo[v][0],dstDir); //指定フォルダにデータを作成し名称をB2から↓(i,2)の値とする。
94
95 //転記シート処理
96 var sst = SpreadsheetApp.open(invoice); //作成済みデータ開く
97 var t_sheets = sst.getSheets(); //sheetsの値を定義
98 var t_sheet = t_sheets[0]; //作成済みファイルは1シートしかないので0番目を取得
99
100 //顧客情報
101 var invoice_inforange = t_sheet.getRange('A1:I21');
102 var invoice_infoset = invoice_inforange.getValues();
103
104 invoice_infoset[0][1] = ('〒'+strage_userinfo[v][1]); //B1:郵便番号 を代入
105 invoice_infoset[1][1] = (strage_userinfo[v][2]); //B2:住所を代入
106 invoice_infoset[2][1] = (strage_userinfo[v][3]); //B3:建物名等を代入
107 invoice_infoset[4][1] = (strage_userinfo[v][0]); //B5:送付先名称を代入
108 invoice_infoset[4][3] = (strage_userinfo[v][4]); //D5:敬称を代入
109 invoice_infoset[0][8] = ("001"); //I1:請求IDを代入*ここどうしようか悩んでます。
110 invoice_infoset[20][2] = (strage_userinfo[v][0]); //C21:件名を代入
111
112 /*
113 var dt = new Date(); //現在の日付を取得
114 var y = dt.getFullYear();
115 var m = ("00" + (dt.getMonth()+1)).slice(-2);
116 var d = ("00" + dt.getDate()).slice(-2);
117 var today = y + "/" + m + "/" + d;
118 */
119 var today = new Date();
120 invoice_infoset[1][8] = (today); //I2:本日を代入
121
122 //出力データ
123 var invoice_datarange = t_sheet.getRange(27, 2, strage_userinfo[v][5].length, 8);
124 var invoice_dataset = invoice_datarange.getValues();
125 for(var t=0; t < invoice_dataset.length; t++){
126 invoice_dataset[t][0] = (strage_userinfo[v][5][t][0]); //B27:内容を代入
127 invoice_dataset[t][4] = (strage_userinfo[v][5][t][1]); //F27:単価を代入
128 invoice_dataset[t][6] = (strage_userinfo[v][5][t][2]); //H27:数量を代入
129 invoice_dataset[t][7] = (strage_userinfo[v][5][t][3]); //I27:合計を代入
130 }
131 //Logger.log(invoice_dataset);
132
133 //顧客情報を転記シートに記入
134 invoice_inforange.setValues(invoice_infoset);
135 //出力データを転記シートに記入
136 invoice_datarange.setValues(invoice_dataset);
137 Logger.log("--" + (v+1) +"枚目の処理終了--");
138 }
139
140 Logger.log('--処理終了--');
141}