TypeError: невозможно прочитать свойство getBlob из undefined при попытке получить два разных изображения и вставить их в документ.

У меня есть скрипт Google Apps, который автоматически извлекает данные из Google Sheet и вставляет их в заранее указанный шаблон. Данные находятся с использованием уникальных тегов / идентификаторов.

Извлекаемые данные включают 3 подписи. Я могу извлечь только одну из этих подписей, прежде чем столкнусь с вышеупомянутой ошибкой: TypeError: Cannot read property 'getBlob' of undefined.

Этот код используется в двух разных функциях с одинаковыми переменными и именами. Я пытался изменить имена переменных, но это привело к тому же TypeError.

Таблицу можно найти здесь.

Скрипт находится здесь.

И заполняемый шаблон документа находится здесь .

Вот код.

function electInstallSignature(row, body){
  var signature = row[17];
  var sign = signature.substring(signature.indexOf("/") + 1);
  var sigFolder = DriveApp.getFolderById("16C0DR-R5rJ4f5_2T1f-ZZIxoXQPKvh5C");
  var files = sigFolder.getFilesByName(sign);
  var n = 0;
  var file;
  while(files.hasNext()){
    file = files.next();
    n++;
  } if(n>1){
    SpreadsheetApp.getUi().alert('there is more than one file with this name' + sign);
  }
  var sigElectInstaller = "%SIGNELECTINSTALL%";
  var targetRange = body.findText(sigElectInstaller); // Finding the range we need to focus on
  var paragraph = targetRange.getElement().getParent().asParagraph(); // Getting the Paragraph of the target
  paragraph.insertInlineImage(1, file.getBlob());// As there are only one element in this case you want to  insert at index 1 so it will appear after the text // Notice the .getBlob()
  paragraph.replaceText(sigElectInstaller, ""); // Remove the placeholder
}

function commEngineerSignature(row, body){
  var signature = row[35];
  var sign = signature.substring(signature.indexOf("/") + 1);
  var sigFolder = DriveApp.getFolderById("16C0DR-R5rJ4f5_2T1f-ZZIxoXQPKvh5C");
  var files = sigFolder.getFilesByName(sign);
  var n = 0;
  var file;
  while(files.hasNext()){
    file = files.next();
    n++;
  } if(n>1){
    SpreadsheetApp.getUi().alert('there is more than one file with this name' + sign);
  }
  var sigCommEngineer = "%SFCE%";
  var targetRange = body.findText(sigCommEngineer); // Finding the range we need to focus on
  var paragraph = targetRange.getElement().getParent().asParagraph(); // Getting the Paragraph of the target
  paragraph.insertInlineImage(1, file.getBlob());// As there are only one element in this case you want to  insert at index 1 so it will appear after the text // Notice the .getBlob()
  paragraph.replaceText(sigCommEngineer, ""); // Remove the placeholder
}

Как видите, код в обеих функциях одинаков, но работает только в функции electInstallSignature(row, body).

Ниже вы можете найти, где объявлены параметры row и body.

function chooseRowMethodI(templateId, rowNumber){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var dataRange = sheet.getDataRange();
  var values = dataRange.getValues();
  var data = sheet.getRange(2, 2, 10, 41).getValues();//starting with row 2 and column 1 as our upper-left most column, get values from cells from 1 row down, and 15 columns along - hence (2,1,1,15)
  var docTitle = sheet.getRange(2, 2, 10, 1).getValues();//this is grabbing the data in field B2
  var docTitleTagNumber = sheet.getRange(2, 5, 11, 1).getValues();
  var today = new Date();
  var dd = today.getDate();
  var mm = today.getMonth() + 1;
  var yyyy = today.getFullYear();
  today = dd + '/' + mm + '/' + yyyy;

  for(var i = 0; i < values.length; i++){
    for(var j = 0; j < values[i].length; j++){
      if(values[i][j] == response){
        Logger.log(i);
        var row = data[rowNumber];
        var docId = DriveApp.getFileById(templateId).makeCopy().getId();  
        var doc = DocumentApp.openById(docId);
        var body = doc.getActiveSection();
        //**************************  All Instruments data in here**********************
        instrumentDetails(body, row);
        electInstallSignature(row, body);
        commEngineerSignature(row, body);

        doc.saveAndClose();
        var file = DriveApp.getFileById(doc.getId());
        var newFolder = DriveApp.getFolderById("1Jylk3uO_WU0ClLQdm9y-mwRfHxlh2Ovn");
        newFolder.addFile(file); 
        var newDocTitle = docTitle[i - 1][0];
        var newDocTagNumber = docTitleTagNumber[i - 1][0];
        doc.setName(newDocTitle + " " + newDocTagNumber + " " + today);
      }
    }
  } 
}

Если это необходимо, я включил функцию, из которой все запускается (обратите внимание, что любой пользовательский интерфейс и код ввода выделены вкладками, чтобы избежать необходимости возвращаться к электронной таблице при каждом запуске кода).

var response = "FT101";

function chooseRow(){
//  var ui = SpreadsheetApp.getUi(); // Same variations.
//  var result = ui.prompt('Please enter the Tag number of the row you wish to print.', ui.ButtonSet.OK_CANCEL);
//  
//  // Process the user's response.
//  var button = result.getSelectedButton();
//  response = result.getResponseText();
//  if (button == ui.Button.OK) {
//    // User clicked "OK".
//    ui.alert('Your tag number is' + response + '.');
//  } else if (button == ui.Button.CANCEL) {
//    // User clicked X in the title bar.
//    ui.alert('You closed the dialog.');
//    return 'the end';
//  }

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var dataRange = sheet.getDataRange();
  var values = dataRange.getValues();
  var category = sheet.getRange(2, 3, 11, 1).getValues();//Needs to be verified to ensure correct cell is chosen by script
  var tags = sheet.getRange(2, 5, 11, 1).getValues();//Needs to be verified to ensure correct cell is chosen by script

  for(var i = 0; i < tags.length; i++){
    if(tags[i][0] == response && category[i][0] == "Instrument"){
      var templateId = "1N3o951ECS5CAVGE6UgqBiCPC7H7LiJbL7Cd59G1xTnA";
      chooseRowMethodI(templateId, i);
      return "";
    } else if(tags[i][0] == response && category[i][0] == "Motor" || tags[i][0] == response && category[i][0] == "Valve"){
      var templateId = "1cSPD23qFd-34-IIr5eJ5a5OgHp9YR6xav9T28Y4Msec";
      chooseRowMethodMV(templateId, i);
      return "";
    }
  }
}

person Ciaran Crowley    schedule 29.11.2019    source источник


Ответы (1)


Эта ошибка TypeError: Cannot read property 'getBlob' of undefined означает, что object, который вы пытаетесь getBlob получить, не имеет данных BLOB-объектов.

Единственная разница с функцией frist и второй - это первая строка: row[17] вместо row[35] это означает следующее:

  var signature = row[17];
  var sign = signature.substring(signature.indexOf("/") + 1);
  var sigFolder = DriveApp.getFolderById("16C0DR-R5rJ4f5_2T1f-ZZIxoXQPKvh5C");
  var files = sigFolder.getFilesByName(sign);
  var n = 0;
  var file;
  while(files.hasNext()){
    file = files.next();
    n++;
  } if(n>1){
    SpreadsheetApp.getUi().alert('there is more than one file with this name' + sign);
  }

Итак, вы, вероятно, никогда не обращаетесь к циклу while:

while(files.hasNext())

потому что у var files = sigFolder.getFilesByName(sign); никогда не было следующего, и, таким образом, поскольку file не инициализирован, это undefined.


Таким образом, вы получаете следующую ошибку:

file is undefined

Это означает, что вы никогда ничего не присваивали этой переменной, что происходит только в том случае, если вы никогда не обращались к while, что происходит только в том случае, если files никогда не было next.

Это происходит потому, что там вообще нет файлов, это означает, что на sigFolder нет файла с именем sign. Или что row[17] не содержит какой-либо существенной информации о имени файла, к которому вы хотите получить доступ.

Итак, проверьте это.

Также примите во внимание следующую документацию об итераторах, подобных тому, с которым вы работаете на files:

Когда вы делаете files.next(), вы получаете доступ к первому элементу итератора:

Итератор файлов

Общая документация по итераторам JavaScript:

Итераторы и генераторы на Javascript

person yuri    schedule 29.11.2019
comment
Спасибо за помощь Юрию. Это была моя простая глупая ошибка. У меня была выбрана неправильная строка, поэтому она не была определена. - person Ciaran Crowley; 29.11.2019