При вызове метода или свойства openbyid для объекта spreadsheetapp произошла ошибка

Если коротко, то так сделать нельзя.

Скорее всего проблема в том, что функция вызывается как пользовательская функция.

В сущности, вопрос стоит внимания, потому что он является общим случаем недопонимания процесса.

И так, куда смотреть и что делать.

Способ запуска. От способа запуска зависит многое, т.к. один и тот же код может выполняться по-разному. Называется «смена контекста».

  • Как пользовательская формула (специальный ограниченный контекст)
  • При вызове из редактора (основной контекст)
  • При вызове из UI контейнера (расширенный основной контекст)
  • При вызове из триггера
  • При вызове из неустановленного дополнения
  • При вызове из неразрешенного дополнения
  • При вызове из опубликованного веб-приложения
  • При вызове опубликованного API
  • И еще много чего можно сменить настройками для одного и того же куска (простите) кода.

Распространенной ошибкой является предполагать, что код в редакторе какой-то не такой. На самом деле это уже полноценное приложение. Многие, кто активно использует скрипты, «не парятся» на тему «откуда это запустить», они просто выбирают в редакторе функцию и жмут кнопку запуска.

Вернемся к баранам. При запуске пользовательской формулы контекст кода строго ограничен. Вы не можете вызывать многие методы SpreadsheetApp, например, openById(). См. Custom Functions — Advanced — Using Apps Script services

Интересно, что это не означает, что так делать нельзя. Например, хак описан тут snippets/spreadsheet-get_error_value_formulas. Но это прям надо хорошо вкурить, чтоб оно взлетело.

I found this tutorial that fit my need perfectly.

Basically read csv from an email and export it to spreadsheet.

I modified it just a bit, but getting an error at the final copy function.

The script can fetch the email and csv attachment, the file successfully uploaded/copied to gdrive folder. Just missing the last step, opening the csv and paste the content into the spreadsheet.

Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp.
ToDrive @ Code.gs:53
VendorToDrive @ Code.gs:67

This is the code that I’m running

var fileTypesToExtract = ['csv', 'xlsx'];
//Name of the folder in google drive i which files will be put



function file_type(attachment){
  var fileName = attachment.getName();
  var temp = fileName.split('.');
  var fileExtension = temp[temp.length-1].toLowerCase();
  if(fileTypesToExtract.indexOf(fileExtension) !== -1) return true;
  else return false;
}
 


function VendorToDrive(){
  //build query to search emails
  var Googel_Sheet = SpreadsheetApp.openById("1fraXrYZ7NL4wGP_FXU8n2V-0jAYE0G8IqB5lfqVr0RA");//spread sheet ID
  var Market = Googel_Sheet.getSheetByName("Deal Stage");
  var Market_Data = Market.getDataRange().getValues();
  var query = 'label:zoho-deal-stage';


  var thread_s = GmailApp.search(query);
  
  

function ToDrive(threads) {
  // var root = DriveApp.getRootFolder();
  var mesg = threads[0].getMessages()[0];//get first message (most recent)
  
  var attachments = mesg.getAttachments(); //get attachments
    for(var k in attachments){
      var attachment = attachments[k];
       var isDefinedType = file_type(attachment);
      if(!isDefinedType) continue;
   

        var attachmentBlob = attachment.copyBlob();
        var file = { 
          "title": attachment.getName(), 
          "parents": [{"id": '1sCtaxcbelLl1OSten_hiJX5JuY95IiCl'}]//Folder ID 
            }; //creates a file 
         
          file = Drive.Files.insert(file, attachmentBlob, {
            "convert": true
          });// Adds File t Drive 

       var fileid = file.getId(); //works

       Logger.log(fileid);
        //Logger.log(SpreadsheetApp.openById(file.getId()));
        var attached_gs = SpreadsheetApp.openById(fileid);// Attached Google sheet data 

          var data2 = attached_gs.getSheets()[0].getDataRange().getValues();
          if( attachment.getName() == 'ID_Deal_Stage_Report.csv'){
            Market.getRange(1, 1, Market_Data.length, Market_Data[0].length).clear();

            Market.getRange(1, 1, data2.length, data2[0].length).setValues(data2);
            
          }

      }

  
}
ToDrive(thread_s);

  
}

The execution log said this line is the error

var attached_gs = SpreadsheetApp.openById(fileid);// Attached Google sheet data

I tried changing fileid with the actual fileid (string) but still gave the same error.

Google Docs Editors Help

Sign in

Google Help

  • Help Center
  • Community
  • Google Docs Editors
  • Privacy Policy
  • Terms of Service
  • Submit feedback

Send feedback on…

This help content & information

General Help Center experience

  • Help Center
  • Community

Google Docs Editors

My google sheets apps script has a doGet() function which takes an HTTP get request and parses the query parameters and puts them in a spreadsheet.

When I tested the app with a get request, I got a ‘500 Internal Error message’, I then tested the deployment and got the error message ‘ Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp. (line 9, file «Code») ‘.

So, it’s having a problem opening the sheet but I am certain I have the correct sheet ID looking at project settings. I thought it could be a google drive issue so I made an entirely new google account with a blank drive and a new spreadsheet but the same error appears!? I’m not sure what’s going on here, so any help would be much appreciated! Code below:

https://github.com/Conwon99/4th-Year-Project/blob/main/GoogleAppsScript

asked Jan 8, 2021 at 12:20

Connor Dorward's user avatar

2

As the comments indicate, the sheet ID in the code is not in the standard 44-character format thus error 500 was thrown by openById() method.

The solution is to use a valid file ID that points to a non-deleted Google Sheet.

I’m very new to coding of any kind and search as I might I wasn’t able to find a solution for this exception:

Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp. (line 16)

The script I’ve written copies each file from a list of file IDs, pastes entire contents as values into the copied files.

What I’ve already done is check if there was an authorisation required in oauthScope in my appscript.json and I think I’ve given sufficient authorisation (spreadsheet and drive). I don’t get any other permission prompts.

Any help or suggestions will be great (generally for what I’ve written, but importantly for the exception)

This is the script:

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");
}

P.S. The script runs fine otherwise and carries out the copy and archive despite the exception, but the last line which is a msgBox does not display the message. I do not know why.

@shengcopypaste

Hi, I follow your script and all the steps. But, may I know why when I check for the operation of Google Sheets by using my URL and it shows the error as below?
Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp. (line 11, file «Code»)
TypeError: Cannot read property ‘getLastRow’ of null (line 12, file «Code»)

Hope to hear from you soon. Thanks

@taltalp

Hi, Shengcopypaste,
Could you tell me which example code?
You mean this getLastRow?

We’re looking forward to hearing from you. Thank you.

@shengcopypaste

Hi, I think it’s because my sheet name was changed and not update with the new version deployment. I follow ESP32_GoogleSheets example code. My URL for Apps Script can function. Just I am not sure why my ESP 32 show this error : [HTTP] GET… failed, error: send header failed, but the HTTP URL link generated by ESP32 is still valid. Do you have any suggestions?

Hi! Trying to pull sensitive data from a spreadsheet only accessible by this user account, all of which used to work fine. However, things suddenly stopped working recently and I can’t get SpreadsheetApp.openById (or SpreadsheetApp.open(DriveApp.getFileById)) to function properly.

No matter where I call the function, I get one of the following errors:

We’re sorry, a server error occurred. Please wait a bit and try again.

Usually occurs when the openById is called outside of a function; I assumed it had something to do with scope errors.

Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp.

Happens when called inside a function, but doesn’t appear to trigger every time. That said, a super unhelpful «could not connect to server» popup displays without fail when the function is called…but it doesn’t halt execution. Instead, it just runs the whole thing (???) and then fails later on.

Any help would be much appreciated—I’m pulling from multiple sheets (all shared with the user account running the script), and I can’t figure out why this wouldn’t work. I’ve used openById without a hitch in other scripts…I dunno, thanks in advance.

EDIT: Turns out it was more user error than Apps Script error in this case…oops! I added an installable trigger to account for openById not being able to work with simple onOpen, but the error persisted. Turns out, I was accidentally feeding in an array rather than a string.

Google Help

  • Help Center
  • Community
  • Google Docs Editors
  • Privacy Policy
  • Terms of Service
  • Submit feedback

Send feedback on…

This help content & information

General Help Center experience

  • Help Center
  • Community

Google Docs Editors

У меня есть html, где пользовательские запросы добавляют и вводят данные. Javascript в теле html вызывает серверную часть. Я не могу подключиться к листу с сохраненным идентификатором или URL-адресом, чтобы добавить строку.

Я не могу обновить свою электронную таблицу, несмотря на комментарий @Serge insas, что openById «означает» открыт для чтения и записи «. Я делаю простую ошибку или это невозможно. Код, инициированный со стороны клиента, работает на сервере.

const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
var sheet = SpreadsheetApp.openById("[ssId]").getSheetByName('Sheet1');

const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
var sheet = SpreadsheetApp.openById("ssId").getSheetByName('Sheet1');

Оба получают ошибку: исключение: непредвиденная ошибка при получении метода или свойства openById для объекта SpreadsheetApp.

  const ssUrl = PropertiesService.getScriptProperties().getProperty('ssUrl');
  var sheet = SpreadsheetApp.openByUrl("ssUrl").getSheetByName('Sheet1');

Получает ошибку: Исключение: недопустимый аргумент: URL

ВЫШЕ ВАЖНАЯ ЧАСТЬ


/**
 *  this code is run from the javascript in the html dialog
 */
function addMbrCode(myAddForm)  {
//  removed logging 
  console.log("Beginning addMbrCode" );
  paragraph = body.appendParagraph('Beginning addMbrCode.');
  
  // Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp.
//  const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
//  var sheet = SpreadsheetApp.openById("[ssId]").getSheetByName('Sheet1');
//  var sheet = SpreadsheetApp.openById("ssId").getSheetByName('Sheet1');
  
// Exception: Invalid argument: url  
  const ssUrl = PropertiesService.getScriptProperties().getProperty('ssUrl');
  var sheet = SpreadsheetApp.openByUrl("ssUrl").getSheetByName('Sheet1');
  
  myAddForm =  [ fName, lName, inEmail, fallNum, winNum, sprNum];
  var fName = myAddForm[0];
  var lName = myAddForm[1];
  var inEmail = myAddForm[2];
  var fallNum = myAddForm[3];
  var winNum = myAddForm[4];
  var sprNum = myAddForm[5];
  
  var retCd = '';
  /**
   *  10 - successful add
   *  20 - duplicate - not added
   */  
  var combNameRng = sheet.getRange(2, 4, numRows).getValues();
  var inCName = (fName + '.' + lName).toString().toLowerCase();
  if (combNameRng.indexOf(inCName) > 0 )   {
    console.log("Alert: Not adding duplicate " 
                + fName + ' ' + lName + " retCd: " + 20 );
    paragraph = body.appendParagraph("Not adding duplicate " 
                                     + fName + ' ' + lName + " retCd: " + 20);
    retCd = 20;
    return retCd;
  }
  
  sheet.appendRow([fName.toString().toLowerCase()
                 , lName.toString().toLowerCase()
                 , 
                 , inEmail.toString().toLowerCase()
                 ]);
  const currRow = sheet.getLastRow().toString();

);

  retCd = 10;

  return retCd;
  
}

Если это имеет значение, вот javascript из тела моего html в диалоговом окне.

<script>
  document.querySelector("#myAddForm").addEventListener("submit", 
    function(e)
    {
      alert('begin addEventListener');
      e.preventDefault();    //stop form from submitting
      
      var retCd =  google.script.run.addMbrCode(this);   // client side validation

          document.getElementById('errMsg').textContent = 'Successful member 

      return false;  // do not submit - redisplay html
    }
  );
</script>

Удалены ненужные детали кода

Per @iansedano я создал объект / массив для использования вместо него и добавил обработчик успеха и обработчик сбоев. В любом случае я хочу снова увидеть html со своим сообщением. Это текущий сценарий. Ответ настолько собачий, что я не вижу предупреждений, Logger.log или console.log. Сумасшедшие покупатели, пользующиеся моим интернетом!

<script>   

  document.querySelector("#myRmvForm").addEventListener("submit", 
    function(e)
      // removed alerts and logging
      // removed client side validation for simplicity
      cSideValidate();

      // Then we prevent the form from being submitted by canceling the event
      event.preventDefault();
    });
       
  function cSideValidate()  {

    dataObj = [
      document.getElementById('fName').value,
      document.getElementById('lName').value,
      document.getElementById('email').value
    ];
    var retCd = google.script.run.withSuccessHandler(serverReply)
                .withFailureHandler(serverReply)
                .rmvMbrCode(dataObj);  // server side validation
  }
  
  function serverReply {
    // logic to set the correct message - this is an example
    document.getElementById('errMsg').textContent 
             = 'Successful delete using email.';
  }
  
</script>

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

Solution 1

This error is due to a change Google recently rolled out prohibiting the use of SpreadsheetApp.openByUrl() (or SpreadsheetApp.openById() in custom functions. 
You can still use this method from other contexts like a menu item, trigger, etc. Google had to roll out this change for security reasons and they won’t be able to revert back to the old behavior. So the only possible fix may very well be to rewrite the function as a ‘normal’ GAS-function and NOT a custom function.

The issue is listed in the issue tracker.

Solution 2

I actually discovered a nice and easy fix for this yesterday. Hopefully, this workaround works out for you.

Reading through the SpreadsheetApp documentation, I found a function that opens a spreadsheet by providing the corresponding File object.

Here is the section:
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#open(File)

The example shows that you can easily search for a file type in Google Drive (Spreadsheets in this case). However, instead of searching your entire Drive library, you could just use the ID of the file/spreadsheet by using DriveApp.getFileById(ID).

Here is the documentation for that function:
https://developers.google.com/apps-script/reference/drive/drive-app#getFileById(String)

All you need to do is this:

  1. Find the link of the spreadsheet in drive by right clicking the file and selecting «Get Link»
  2. Copy the link, which should look like this docs.google.com/spreadsheets/d/{ID}/edit#gid=0
  3. Get that ID portion of the URL
  4. Use this line SpreadsheetApp.open(DriveApp.getFileById(ID)) to retrieve your Spreadsheet object

You can do other processing after that once you have the object. Let us know if this helped.

Solution 3

I had a similar issue. I switched to using an installed trigger to run my script, instead of using a simple trigger.

https://developers.google.com/apps-script/guides/triggers/installable

Comments

  • So I have encountered a problem in the application I am writing using google spreadsheets and app-script. I have put together a step by step guid to reproduce it.

    Summary:
    any script that uses SpreadsheetApp.openByUrl() and SpreadsheetApp.openById() works OK when called from inside the script editor but gives errors when called from inside even the same spreadsheet that has that script inside it.

    Error Messages:

    Error
        You do not have permission to perform that action. (line ?).
        

    Steps to reproduce it:

    1. Make a new Google Spreadsheet
    2. Open its Script Editor ( Tools menu >> Script Editor… )
    3. Choose Blank Project
    4. Paste in this code

      function demo1() {
        return "cat";
      }
      
      function demo2() {
        return [["bob", "fred"], ["x", "y"]];
      }
      
      function demo3() {
        Logger.log("demo3-1")
        ss = SpreadsheetApp.openByUrl("[==URL==]")
        name = ss.getName()
        Logger.log("demo3-2 " + name)
        return name
      }
      
      function demo4() {
        Logger.log("demo4-1")
        ss = SpreadsheetApp.openById("[==id==]")
        name = ss.getName()
        Logger.log("demo4-2 " + name)
        return name
      }
      
    5. Change the «[==URL==]» and «[==id==]» to refer to your own document

    6. Save the script

    7. From the Run menu choose demo1. This will trigger a question about privileges. Grant it the privileges it asks for. ( asks for access to your Google Drive )

    8. Go back to the spreadsheet itself

    9. Set the following cells to have these formulae:

      A1 : =demo1()
      C2 : =demo2()
      F1 : =demo3()
      h1 : =demo4()
      

    Note that the first 2 work, so the spreadsheet is seeing the script project and able to run code from it ( so it has permission to run code from that script ) but the last two do not work and complain that it does not have permission to perform that action.

    So how do I fix this? Am I doing something wrong or is there an underlying problem ?

Recents

Related

  • При вызове веб сервиса произошла ошибка при создании описания сервиса произошла ошибка эдо
  • При вызове веб сервиса произошла ошибка при создании описания сервиса произошла ошибка url сервиса
  • При вызове веб сервиса произошла ошибка аутентификация пользователя не выполнена 1с
  • При вызове driverpackageinstall возвращена ошибка 536870141
  • При вызове driverpackageinstall возвращена ошибка 32 для пакета