TypeError: Cannot read property 'length' of undefined エラーが解決できない。
Q&A
解決したいこと
GASで請求書のPDF化を試みていますが、
エラーを解決できずにいます。
発生している問題・エラー
TypeError: Cannot read property 'length' of undefined
該当するソースコード
newsheet.getRange(33,1,myTekiyo.length,myTekiyo[0].length).setValues(myTekiyo)
ソースコード全体
function Seikyusho() {
//プログラムA-1|スプレッドシートを設定
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();//変数spreadsheetに「アクティブなスプレッドシート」を設定
var sheet = spreadsheet.getSheetByName('シート4');//変数sheetに「シート4」シートを設定
var myRange = sheet.getDataRange().getValues();//スプレッドシートのデータを二次元配列として取得
//プログラムA-2|変数templateに「請求書フォーマット」シートを設定
var template = spreadsheet.getSheetByName('請求書');//変数sheetに「請求書フォーマット」シートを設定
var start= template.getRange('S4').getValue();//「請求書フォーマット」のセルS4の日付を取得
var startdate = dayjs.dayjs(start).subtract(1, 'd');//変数startの日付をMomentで設定(1日前を設定)
var end= template.getRange('S5').getValue();//「請求書フォーマット」のセルS5の日付を取得
var enddate = dayjs.dayjs(end).add(1, 'd');//変数endの日付をMomentで設定(1日後を設定)
//プログラムA-3|空の配列を設定
var torihiki = [];
//プログラムA-4|プログラム2の取引先(E列)をプログラム3の空配列に取得
for (var i=1; i<myRange.length; i++){
torihiki.push(myRange[i][4]);//配列torihikiにmyRange[i][4]を追加
}
//プログラム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 myTekiyo = [];//シート4のH列「ご注文の時間〜」格納用
var mySuryo = [];//シート4のN列「取引金額」格納用
//プログラムA-6-2|取引先ごとに、プログラム6-1で設定した配列に格納
for (var k=0; k<myRange.length; k++){
if (dayjs.dayjs(myRange[k][4]).isAfter(startdate) && dayjs.dayjs(myRange[k][4]).isBefore(enddate)){//myRange[k][2](納品日)がstartdateより後、かつenddateより前ならば
if (myRange[k][4] == torihiki_list[i]){ //myRange[k][4](取引先)とtorihiki_list[i]が一致すれば
myTekiyo.push([myRange[k][7]]);//配列myTekiyoにmyRange[k][7]を追加
mySuryo.push([myRange[k][9]]);//配列mySuryoにmyRange[k][9]を追加
}
}
}
//プログラムA-6-3|シートを追加して、シート名を各取引先に変更
var newsheet = template.copyTo(spreadsheet);//「請求書フォーマット」のシートをコピーする
newsheet.setName(torihiki[i]);//コピーしたシートの名前を「torihiki[i]」にする
//プログラムA-6-4|ID,摘要,納品日,取引金額を新しいシートの33行目以下に貼り付け
newsheet.getRange(33,1,myTekiyo.length,myTekiyo[0].length).setValues(myTekiyo);//セルC14以下に「摘要」情報を貼り付け
newsheet.getRange(33,9,mySuryo.length,mySuryo[0].length).setValues(mySuryo);//セルF14以下に「納品日」情報を貼り付け
//プログラムA-6-5|変数goukeiを0リセット
// var goukei = 0;
//プログラムA-6-6|14行目以降のC~Eを結合して、取引金額の合計値を算出
// for (var j=0; j<myID.length; j++){
// var row = j+14;//行のカウントアップ
// newsheet.getRange('C'+ row + ':E' + row).merge();//セルC~セルEの結合
// goukei = goukei + Number(myKingaku[j]);//取引先ごとの取引金額を算出
// }
//プログラムA-6-7|シートに請求書情報を入力
var today = dayjs.dayjs(new Date());
var hiduke = dayjs.dayjs(start);
var duedate = today.clone().add(15, 'd').format('YYYY/MM/DD');//請求日の期限を設定
var month = hiduke.clone().format('YYYY年MM月');//年月の取得
var formatteddate = today.clone().format('YYYY/MM/DD');
newsheet.getRange('A6').setValue(torihiki_list[i]);//請求書のセルB4に取引先を入力
newsheet.getRange('L6').setValue(formatteddate + '_' + Number(i+1));//請求書のセルL6に請求書IDを入力
newsheet.getRange('L8').setValue(new Date());//請求書のセルG4に請求日(今日の日付)を入力
// newsheet.getRange('C9').setValue(goukei + '円');//請求書のセルC9に合計金額を入力
newsheet.getRange('C17').setValue(duedate);//請求書のセルC11に請求日の期限を入力
Utilities.sleep(1000); //1秒待機(待機中に情報を更新)
SpreadsheetApp.flush(); //挿入したシートの情報更新
//プログラムA-6-8|PDF化
var ssId = spreadsheet.getId();//スプレッドシートIDを取得
var sheetId = newsheet.getSheetId();//取引先のシートIDを取得
var folderurl = newsheet.getRange('S3').getValue();//newsheetのセルJ2の値(PDF保管先のフォルダURL)
var myArray= folderurl.split('/'); //folderurlを「/」で区切る
var folderid = myArray[myArray.length-1];//変数folderidにフォルダIDを取得
var folder = DriveApp.getFolderById(folderid);//PDF保管先のfolderを設定
PDFexport(ssId, sheetId,torihiki_list[i],folder);//プログラムBを実行(5つの引数を渡す)
}
}
//プログラムB-0|PDF化
function PDFexport(ssId, sheetId, torihiki, row, folder) {
//プログラムB-1|PDF化の条件設定
var url = 'https://docs.google.com/spreadsheets/d/'+ ssId +'/export?';
var opts = {
exportFormat: 'pdf', // ファイル形式の指定
format: 'pdf', // ファイル形式の指定
size: 'A4', // 用紙サイズの指定
portrait: 'true', // true縦向き、false 横向き
fitw: 'true', // 幅を用紙に合わせるか?
sheetnames: 'false', // シート名を PDF 上部に表示するか?
printtitle: 'false', // スプレッドシート名をPDF上部に表示するか?
pagenumbers: 'false', // ページ番号の有無
gridlines: 'false', // グリッドラインの表示有無
fzr: 'false', // 固定行の表示有無
range : 'A1%3AG' + row, // 対象範囲「%3A」 = : (コロン)
gid: sheetId // シート ID を指定 (省略する場合、すべてのシートをダウンロード)
};
//プログラムB-2|PDF化のurl作成
var PDFurl = [];//urlという空配列を設定
for(optName in opts){
PDFurl.push(optName + '=' + opts[optName]);//opts配列の各要素を=でつないだものをurl配列に格納
}
var options = PDFurl.join('&');//urlの配列の各要素を&でつなぐ
//プログラムB-3|PDF化の条件設定
var token = ScriptApp.getOAuthToken();//アクセストークンを取得
var response = UrlFetchApp.fetch(url + options, {headers: {'Authorization': 'Bearer ' + token}}); //PDFのURLからアクセスする
var blob = response.getBlob().setName(torihiki + '.pdf');//PDFの名前を「取引先+.pdf」とする
var newFile = folder.createFile(blob);//PDFを所定のフォルダに保管する
newFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);//共有設定をする:「リンクを知っている人」が「閲覧可能」
}
自分で試したこと
newsheet.getRange(33,1,myTekiyo.length,myTekiyo[0].length).setValues(myTekiyo)
上記のセルの取得を"A1"のように直接指定を試みましたが、別のエラーが発生し解決に至っておりません。
調べた時にでてきた記事
https://techacademy.jp/magazine/26836
https://teratail.com/questions/264325
https://teratail.com/questions/135221
0