Как мне обработать исключение, возникающее при использовании SpreadsheetApp.openById () - PullRequest
1 голос
/ 18 июня 2020

Я новичок в программировании любого вида и поиске, поскольку я не смог найти решение для этого исключения:

Исключение: Неожиданная ошибка при получении метода или свойства openById на объекте SpreadsheetApp. (строка 16)

Написанный мной сценарий копирует каждый файл из списка идентификаторов файлов, вставляет все содержимое как значения в скопированные файлы.

То, что я уже done - проверить, требуется ли авторизация в oauthScope в моем приложении. json, и я думаю, что я дал достаточную авторизацию (электронная таблица и диск). Я не получаю никаких других запросов на разрешение.

Любая помощь или предложения будут отличными (обычно для того, что я написал, но, что важно, для исключения)

Это сценарий:

function copyPasteValues()
{
  //Define destination archive folder
  var Destination = DriveApp.getFolderById("ID");

  //Open correct sheet in the Archiving Center file and get ID range
  var AllFileID_ss = SpreadsheetApp.openById("ID_2"); *------- no error on this one*
  var AllFileID_sheet = AllFileID_ss.getSheetByName("Sheets_to_be_archived");
  var FileID = AllFileID_sheet.getRange("B2:B10").getValues();

  //Select the correct file to archive and create a copy
  for (var i=0; i<FileID.length;i++)
  {
    if (FileID != "-")
    {
      var archfile = SpreadsheetApp.openById(FileID[i]); *------------ exception being thrown here (line 16)*
      var archcopy = DriveApp.getFileById(FileID[i]).makeCopy("Archive "+archfile.getName(), Destination);
      var copyId = archcopy.getId();
      var sheetNumber = archfile.getSheets().length;

      //Select correct sheets in copy, and paste values
      for (var j=0; j<sheetNumber;j++)
      {
        var values = archfile.getSheets()[j].getDataRange().getValues();
        SpreadsheetApp.openById(copyId).getSheets()[j].getRange(archfile.getSheets()[j].getDataRange().getA1Notation()).setValues(values);
      }    
    }
  }

  Browser.msgBox("Archiving is done");
}

PS В противном случае сценарий работает нормально и выполняет копирование и архивирование, несмотря на исключение, но последняя строка, которая является msgBox, не отображает сообщение. Не знаю почему.

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Как вы, @Oleg Valter, правильно заметили, я пытался передать то, что, как я думал, будет строковым значением, но на самом деле это массив, в openbyID (id). Ваш комментарий ниже прояснил это.

Я вижу, у вас есть предположение, что ограничение диапазона столбцом даст вам только столбец, но программы работают не так - они очень глупы. Вы сказали скрипту получить вам список строк, где каждая строка представляет собой список (массив) только с одним элементом, и это то, что он вернул

Я изменил эту часть скрипта, как показано ниже, и она сработала :

var AllFileID = AllFileID_sheet.getRange("B2:B10").getValues();

  //Select the correct file to archive and create a copy
  for (var i=0; i<AllFileID.length;i++)
  {
    var FileID = AllFileID[i][0] *----this is the change to pick out the value from the array*
    if (FileID != "-")
    {
      var archfile = SpreadsheetApp.openById(FileID); *---works!*

Большое спасибо!

0 голосов
/ 18 июня 2020

Согласно документации , openById(id) подпись метода ожидает строку в качестве параметра. Ваша переменная FileID содержит массив массивов значений, возвращаемых вызовом метода getValues() (см. docs ), поэтому доступ к элементу из него по индексу [i] возвращает массив, а не значение .

Условие FileID != "-" всегда оценивается как true в вашем скрипте, поскольку вы выполняете строгое сравнение , которое проверяет неравенство в вашем случае. Он возвращает true, как только возникает несоответствие типов: "object" !== "string".

const whatGetValuesReturns = [
  [1, 2, 3, 4, 5],
  [6, 7, 8, 9, 10]
];

const whatOpenByIdExpects = "string";

for(var i = 0; i < whatGetValuesReturns.length; i++) {
  const whatEachIterationOfLoopGets = whatGetValuesReturns[i];
  
  const typeOfWhatIsExtracted = typeof whatEachIterationOfLoopGets;
  
  console.log(
  `Expected ${whatOpenByIdExpects}, 
got ${typeOfWhatIsExtracted} with values:
${whatEachIterationOfLoopGets.join(" ")}`
  );
  
}

Основываясь на обсуждении, мне нужно пояснить, что, когда вы ограничиваете getRange() одним столбцом (вне примечания: B:B будет столбцом ссылка, B2:B10 - это диапазон ячеек) он по-прежнему возвращает экземпляр Range, который, в свою очередь, имеет определенный метод getValues(), который всегда возвращает матрицу значений:

const singleColumn = [
  [1],
  [2],
  [3],
  [4]
];

for(const row of singleColumn) {
  const value = row[0]; //<-- since we have only one, first index is used
  console.log(value);
}
...