un4
@un4

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

GAS cannot read properties of undefined (reading 'length')エラーについて

Q&A

Closed

現在、あるスプレッドシートのシートから先頭行を除く全てのデータを別のスプレッドシートのシートに貼り付けようとしているのですが、実行するとcannot read properties of undefined (reading 'length')と表示され上手くいきません。 以下が実際のコードです。
function getValues(){
const to_url = "コピー先のスプレッドシートのURl";
const from_url = "コピー元のスプレッドシートのURL";
const to_sheet = SpreadsheetApp.openByUrl(to_url).getSheetByName("コピー先のシート名");
const from_sheet = SpreadsheetApp.openByUrl(from_url).getSheetByName("コピー元のシート名";
let values = from_sheet.getDataRange().getValues();
values.shift();
to_sheet.getRange(1, 1, to_sheet.length, to_sheet[0].length).setValues(to_sheet);}

コードを以下のように書き換えることで解決いたしました。

function getValues(){
    const to_url = "コピー先のスプレッドシートのURl";
    const from_url = "コピー元のスプレッドシートのURL";
    const to_sheet = SpreadsheetApp.openByUrl(to_url).getSheetByName("コピー先のシート名");
    const from_sheet = SpreadsheetApp.openByUrl(from_url).getSheetByName("コピー元のシート名";

        let values = from_sheet.getDataRange().getValues();
            const to_range = to_sheet.getRange(1, 1, values.length, values[0].length);
            to_range.setValues(values);
            to_sheet.deleteRow(1);
}
0

1Answer

コードを掲載する際にはちゃんとバッククォーテーションで囲ってあげてください…

エラーの内容の通りです。
恐らく最終行の
to_sheet.length, to_sheet[0].length
これらのどちらかが問題で、
to_sheetがundefinedになっているかも知れません。
Logger.log()などで中身を見てみてください。

仮に undefinedだった場合、to_sheetを取得している部分で、シート名が正しいかを確認してください。
const to_sheet = SpreadsheetApp.openByUrl(to_url).getSheetByName("コピー先のシート名");

0Like

Comments

  1. @un4

    Questioner

    回答ありがとうございます。
    Logger.log()で中身を確認したところ、to_sheet.lengthはnull、to_sheet[0].lengthだとcannot read properties of undefined (reading 'length')と表示されました。to_sheetを取得した部分ではシート名に問題はありませんでした。どうすれば良いのか分からず、よろしければ教えていただけませんか。
  2. ソースコードは複数行なので、三つのバッククオートで囲んであげてください…

    あ、よく見たらコードが根本的におかしいですね。
    `to_sheet`は配列ではないですよ。`getsheetbynamename`のドキュメントを参照してください。
    https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getsheetbynamename

    返り値は次のドキュメントに記載されているSheetというクラスのオブジェクトです。

    https://developers.google.com/apps-script/reference/spreadsheet/sheet


    さて、`values`に`from_sheet`の全データが格納されているので、これを`setValues()`でセットしなければいけません。
    最終行を次のように変えてみてください。

    ```
    to_sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
    ```
  3. @un4

    Questioner

    回答ありがとうございます。
    最終行をアドバイス通りに変えたところ、以下のようなエラーが表示されました。setValuesの後にgetValuesを使っているのが原因だと思うのですが、どのように修正すれば分からない状態で、お教えいただけないでしょうか。
    ```
    Exception: The parameters (number[ ]) don't match the method signature for SpreadsheetApp.Range.setValues.getValues
    ```
  4. 次からで良いですが、とりあえずエラーメッセージで調べる努力はしてみてください。

    setValuesに渡すのは2次元配列であるべきですが、なぜかvaluesが2次元配列になっていないっぽいですね。
    ※getValues()の返り値は2次元配列なはずです。

    valuesの中身を、shift()する前と後で確認してみてくれませんか?
  5. @un4

    Questioner

    valuesをshift()する前と後で確認したところ、行う前だと、取得したシートの全てのデータが2次元配列で取得され、shift()した後だと先頭行を除く全てのデータを2次元配列で取得されていました。
  6. まぁですよね...
    差し支えなければ、質問文の方にそのログ出力を追加していただけますか?
    また、念のためメソッドチェーンを辞めて処理を切り分けておいてください。

    ```
    const to_range = to_sheet.getRange(1, 1, values.length, values[0].length)
    to_range.setValues(values)
    ```
  7. @un4

    Questioner

    助言していただいた通りに処理を切り分け、shift()の部分を消して実行したところ無事実行完了いたしました。なぜshift()するとエラーになるのかはまだ分からないのですが、以下のコードのように対応いたしました。お忙しい中貴重なお時間をいただきまして、誠にありがとうございました。
    ```
    const to_range = to_sheet.getRange(1, 1, values.length, values[0].length);
    to_range.setValues(values);
    to_sheet.deleteRow(1);
    ```


  8. shiftを諦めて、後から先頭行を削除することで解決したとのこと、お疲れ様です。
    現状こちらが持つ情報で考える限りは、かなり不思議な現象な気がします。
    shiftを使っても原理的には問題ないように感じているので、解決した場合は記事などの形で投稿してみることも検討してみてください。
    (後、質問文に一応解決したコードの記載と、クローズをしておいてください。)
  9. @un4

    Questioner

    何から何まで大変お世話になりました。ありがとうございました。

Your answer might help someone💌