前提・実現したいこと
元ファイルにある「テンプレート」シートを使用し会社別請求書を作成してます。
スプレッドシートを指定したフォルダに複製し、会社別にシートを作成します。
シートは設定、データ、テンプレートが存在しています。
設定:日付データを入力
データ:A2〜Dまで一覧表
テンプレート:A3に会社名、A11〜Dのデータ最終行まで転記。
テンプレートシートをコピーし、シート名を会社名に変更、
会社名毎のデータをA11〜Dのデータ最終行まで転記したいです。
以下の通り作成しましたが、エラーとなりご教授ください。
ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
TypeError: Cannot read property 'length' of undefined myFunction @ XXXXX.gs:71
該当のソースコード
function myFunction() { const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); const sht_setting = spreadsheet.getSheetByName('x'); const vare = sht_setting.getRange('C2').getValue(); var OutputFileName = ('請求書(')+Utilities.formatDate(new Date(vare), 'JST', 'yyyy年M月)') //保存先となるフォルダの取得 const folder = DriveApp.getFolderById('XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); //複製するファイル(スプレッドシート)の取得 const file = DriveApp.getFileById('XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); let new_spreadsheet_id = file.makeCopy(OutputFileName, folder).getId(); let new_spreadsheet = SpreadsheetApp.openById(new_spreadsheet_id); //複製したスプレッドシートの内にあるシート(TEMPLATE)の取得 let template = new_spreadsheet.getSheetByName('テンプレート'); //複製したスプレッドシートの内にあるシート(DATA)の取得 let sheet = new_spreadsheet.getSheetByName('データ'); //プログラムA-1|スプレッドシートを設定 var myRange = sheet.getDataRange().getValues();//スプレッドシートのデータを二次元配列として取得 //プログラムA-2|変数templateに「請求書フォーマット」シートを設定 var start= template.getRange('F3').getValue();//「テンプレート」の日付を取得 var startdate = dayjs.dayjs(start);//開始日設定 var end= template.getRange('F4').getValue();//「テンプレート」の日付を取得 var enddate = dayjs.dayjs(end);//終了日設定 //プログラムA-3|空の配列を設定 var torihiki = []; //プログラムA-4|プログラム2の取引先(E列)をプログラム3の空配列に取得 for (var i=1; i<myRange.length; i++){ torihiki.push(myRange[i][1]);//配列torihikiにmyRange[i][]を追加 } //プログラムA-5|プログラム4の取引先名の重複を削除 var torihiki_list = torihiki.filter(function(value, i, self){ return self.indexOf(value) === i; }); //プログラムA-6|商品名ごとに繰り返す for (var i=0; i<torihiki_list.length; i++){ //プログラムA-6-1|空の配列を設定 var myID = [];//シート1のA列「ID」格納用 var myTekiyo = [];//シート1のB列「摘要」格納用 var myNouhin = [];//シート1のC列「納品日」格納用 var myKingaku = [];//シート1のD列「取引金額」格納用 //プログラムA-6-2|取引先ごとに、プログラム6-1で設定した配列に格納 for (var k=0; k<myRange.length; k++){ if (dayjs.dayjs(myRange[k][0]).isAfter(startdate) && dayjs.dayjs(myRange[k][0]).isBefore(enddate)){//myRange[k][2](納品日)がstartdateより後、かつenddateより前ならば if (myRange[k][1] == torihiki_list[i]){ //myRange[k][4](取引先)とtorihiki_list[i]が一致すれば myID.push([myRange[k][0]]);//配列myIDにmyRange[k][0]を追加 myTekiyo.push([myRange[k][2]]);//配列myTekiyoにmyRange[k][1]を追加 myNouhin.push([myRange[k][3]]);//配列myNouhinにmyRange[k][2]を追加 myKingaku.push("個");//配列myKingakuにmyRange[k][3]を追加 } } } //プログラムA-6-3|シートを追加して、シート名を各取引先に変更 var newsheet = template.copyTo(spreadsheet);//「請求書フォーマット」のシートをコピーする deleteSheetIfExist(spreadsheet,torihiki_list[i]); newsheet.setName(torihiki[i]);//コピーしたシートの名前を「torihiki[i]」にする //プログラムA-6-4|ID,摘要,納品日,取引金額を新しいシートの14行目以下に貼り付け console.log(newsheet); newsheet.getRange(11,1,myID[0].length,1).setValues(myID);//セルB14以下に「ID」情報を貼り付け newsheet.getRange(11,2,myTekiyo[0].length,1).setValues(myTekiyo);//セルC14以下に「摘要」情報を貼り付け newsheet.getRange(11,3,myNouhin.length,myNouhin[0].length).setValues(myNouhin);//セルF14以下に「納品日」情報を貼り付け newsheet.getRange(11,4,myKingaku.length,myKingaku[0].length).setValues(myKingaku);//セルG14以下に「取引金額」情報を貼り付け } } function deleteSheetIfExist(spreadsheet, name) { const sheet = spreadsheet.getSheetByName(name); if(sheet === null) return; spreadsheet.deleteSheet(sheet); }
試したこと
https://fastclassinfo.com/entry/gas_seikyusho/#Google_Apps_ScriptGAS
上記のサイトを参考にしました