无法从Web应用程序调用Google Script API函数(TypeError:无法读取未定义的属性“运行”) [英] Cannot call Google Script API Functions from Web App (TypeError: Cannot read property 'run' of undefined)

查看:288
本文介绍了无法从Web应用程序调用Google Script API函数(TypeError:无法读取未定义的属性“运行”)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个谷歌应用程序脚本可以正常工作数月,并且它突然停止工作。我想知道Google是否弃用了我的代码的某些部分。



这是指向该文件的链接:点击这里查看Google电子表格文件

尝试从HTML文件调用Google脚本函数时,Google脚本代码显然失败。这是失败的代码行。

  google.script.run.importCSVData(id); 

这些行失败并且出现以下错误:


TypeError:无法读取未定义的属性'run'

就像我说的,我有这个代码正常工作几个月,它突然停止工作。

(仅供参考...此代码的目的是将CSV文件上载到标签Archivo Plano ADN要运行该代码,必须从上面的菜单中选择Importar Archivo CSV - >Importar Archivo ...,当提示选择文件时,选择任何.csv文件。 )






我的Google电子表格文件有三个代码文件(Code.gs,CodeImport.gs和Picker .html)



让我给你每个代码:

Code.gs:

  function onOpen(){

var me = Session.getEffectiveUser();
if(me.getEmail()==alejandro.sardi@crusardi.net){
var ui = SpreadsheetApp.getUi();
ui.createMenu('Protected Ranges')
.addItem('Remove Protection','menuItem1')
.addItem('Copy Protected Ranges To Another Sheet','menuItem2')
.addItem('将SM受保护的范围复制到所有SA工作表','menuItem3')
.addToUi();

ui.createMenu('Importar Archivo CSV')
.addItem('Importar Archivo ...','showPicker')
.addToUi();

ui.cre
} else {
SpreadsheetApp.getUi()//或DocumentApp或FormApp。
.createMenu('Importar Archivo CSV')
.addItem('Importar Archivo ...','showPicker')
.addToUi();
}

}

CodeImport.gs:

 函数importCSVData(id){
try {
var file = DriveApp.getFileById(id);
var csvData = Utilities.parseCsv(file.getBlob()。getDataAsString(ISO-8859-1),;);
var sheet = SpreadsheetApp.getActiveSpreadsheet()。getSheetByName(Archivo Plano ADN);
sheet.getRange(A:U)。clear();
sheet.getRange(G:G)。setNumberFormat('@ STRING @');
Logger.log(yes);

sheet.getRange(1,1,csvData.length,csvData [0] .length).setValues(csvData);

file.setTrashed(true);

SpreadsheetApp.getUi()。alert(Archivo Importado conéxito);
$ b $ catch(e){
MailApp.sendEmail(Session.getEffectiveUser()。getEmail(),错误报告jaja - sonríelea la vida!,
\\ \\ r \\\
Message:+ e.message
+\r\\\
File:+ e.fileName
+\r\\\
Line:+ e.lineNumber);



function showPicker(){
var html = HtmlService.createHtmlOutputFromFile('Picker.html')
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi()。showModalDialog(html,'Select File');


函数getOAuthToken(){
DriveApp.getRootFolder();
return ScriptApp.getOAuthToken();
}

函数finishedImport(){
SpreadsheetApp.getUi()。alert(Archivo importado exitosamente);


函数senderror(e){
MailApp.sendEmail(Session.getEffectiveUser()。getEmail(),Error report jaja - sonríelea la vida!,
\r\\\
Message:+ e.message
+\r\\\
File:+ e.fileName
+\r\\\
Line:+ e 。电话号码);
}

最后,Picker.html文件:

 <!DOCTYPE html> 
< html>
< head>
< link rel =stylesheethref =https://ssl.gstatic.com/docs/script/css/add-ons.css>
< script type =text / javascript>
var DIALOG_DIMENSIONS = {
width:600,
height:425
};
var pickerApiLoaded = false;

函数onApiLoad(){
gapi.load('picker',{
'callback':function(){
pickerApiLoaded = true;
}
});
google.script.run.withSuccessHandler(createPicker)
.withFailureHandler(showError).getOAuthToken();


函数createPicker(令牌){

if(pickerApiLoaded&&&token){

// var docsView = new google.picker.DocsView()
//.setIncludeFolders(true)
//.setMimeTypes('application/vnd.google-apps.folder')
//.setSelectFolderEnabled(true );

var uploadDocsView = new google.picker.DocsUploadView()
.setIncludeFolders(true)
//.setMimeTypes('application/vnd.google-apps.folder')
//.setSelectFolderEnabled(true);

var picker = new google.picker.PickerBuilder()
//.addView(docsView)
.addView(uploadDocsView)
//.setAppId (\"AIzaSyCZDa4JKKIOv2AF3QyrG8DnVOXmz27054o )
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.hideTitleBar()
.setSize(DIALOG_DIMENSIONS.width - 2,DIALOG_DIMENSIONS.height - 2)
.setOAuthToken (令牌)
.setCallback(pickerCallback)
.setOrigin('https://docs.google.com')
.build();

picker.setVisible(true);
$ b $}其他{
showError('无法加载文件选择器');
}
}

/ **
*从
*响应对象中提取所选文档的元数据的回调函数。有关响应对象的详细信息,请参阅
* https://developers.google.com/picker/docs/result
*
* @param {object} data响应对象。
* /
函数pickerCallback(data){
try {
var action = data [google.picker.Response.ACTION];
if(action == google.picker.Action.PICKED){
var doc = data [google.picker.Response.DOCUMENTS] [0];
var id = doc [google.picker.Document.ID];
//显示Google云端硬盘文件夹的ID
//document.getElementById('result').innerHTML = id;
document.getElementById('result')。innerHTML =Importando ...
google.script.run.importCSVData(id);
//google.script.run.deleteImportedFile(id);
google.script.host.close();
} else if(action == google.picker.Action.CANCEL){
//document.getElementById('result').innerHTML =Cerrando1 ...
google.script .host.close();
//document.getElementById('result').innerHTML =Cerrando2 ...

}
} catch(e){
document.getElementById( 'result')。innerHTML = e;
google.script.run.senderror(e);
}
}

function showError(message){
document.getElementById('result')。innerHTML ='Error:'+ message;
}
< / script>
< / head>

< body>
< div>
< p id ='result'>< / p>
< / div>
< script type =text / javascriptsrc =https://apis.google.com/js/api.js?onload=onApiLoad>< / script>
< / body>
< / html>


解决方案

您需要使用Google加载Google文件选取器API Loader库。



替换:

 < script type = text / javascriptsrc =https://apis.google.com/js/api.js?onload=onApiLoad>< / script> 

附带:

 < script type =text / javascriptsrc =https://www.google.com/jsapi>< / script> 
< script> google.load(picker,1,{callback:function(){pickerApiLoaded =!0}});< / script>

请记住在进行此更改后发布新版本的Web应用程序。



更新:Google Apps脚本团队的Erik说:问题的原因是Picker API加载到google.picker时,它现在正在覆盖google.script,所以google.script。



他们发布了备用解决方案 - 在加载Picker API时手动保留并恢复google.script:

 窗口.script = google.script; 
gapi.load('picker','1',{callback:function(){
google.script = window.script;
// ...
}} );


I had a google apps script working fine for months and it suddenly stopped working. I'm wondering if Google deprecated some part of my code or something.

This is the link to the file: Click here to view Google Spreadsheet File

The google script code is apparently failing when trying to call a google script function from an HTML file. This is the line of code that fails.

google.script.run.importCSVData(id);

The lines fails and catches the following error:

TypeError: Cannot read property 'run' of undefined

Like I said, I had this code working fine for months and it suddenly stopped working.

(FYI... The purpose of this code is to upload a CSV file into the tab "Archivo Plano ADN". To run this code, one must simply select "Importar Archivo CSV" --> "Importar Archivo..." from the upper menu. When prompted to select file, select any .csv file. The csv file must be separated by ;)


My Google Spreadsheet File has three code files ("Code.gs", "CodeImport.gs" and "Picker.html")

Let me give you the code of each:

Code.gs:

function onOpen() {

  var me = Session.getEffectiveUser();
  if (me.getEmail() == "alejandro.sardi@crusardi.net") {
    var ui = SpreadsheetApp.getUi();
    ui.createMenu('Protected Ranges')
    .addItem('Remove Protection', 'menuItem1')
    .addItem('Copy Protected Ranges To Another Sheet', 'menuItem2')
    .addItem('Copy SM Protected Ranges to all SA sheets', 'menuItem3')
    .addToUi();

    ui.createMenu('Importar Archivo CSV')
      .addItem('Importar Archivo...', 'showPicker')
      .addToUi();

    ui.cre
  } else {
    SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
      .createMenu('Importar Archivo CSV')
      .addItem('Importar Archivo...', 'showPicker')
      .addToUi();
  }

}

CodeImport.gs:

function importCSVData(id) {
try {  
    var file = DriveApp.getFileById(id);
    var csvData = Utilities.parseCsv(file.getBlob().getDataAsString("ISO-8859-1"),";");
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archivo Plano ADN");
    sheet.getRange("A:U").clear();
    sheet.getRange("G:G").setNumberFormat('@STRING@');
    Logger.log("yes");

    sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);

    file.setTrashed(true);

    SpreadsheetApp.getUi().alert("Archivo Importado con éxito");

  } catch (e) {
    MailApp.sendEmail(Session.getEffectiveUser().getEmail(), "Error report jaja - sonríele a la vida!", 
      "\r\nMessage: " + e.message
      + "\r\nFile: " + e.fileName
      + "\r\nLine: " + e.lineNumber);
  }
}

function showPicker() {
  var html = HtmlService.createHtmlOutputFromFile('Picker.html')
      .setWidth(600)
      .setHeight(425)
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi().showModalDialog(html, 'Select File');
}

function getOAuthToken() {
  DriveApp.getRootFolder();
  return ScriptApp.getOAuthToken();
}

function finishedImport() {
  SpreadsheetApp.getUi().alert("Archivo importado exitosamente");
}

 function senderror(e) {
   MailApp.sendEmail(Session.getEffectiveUser().getEmail(), "Error report jaja - sonríele a la vida!", 
      "\r\nMessage: " + e.message
      + "\r\nFile: " + e.fileName
      + "\r\nLine: " + e.lineNumber);
 }

And finally, Picker.html file:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
  <script type="text/javascript">
    var DIALOG_DIMENSIONS = {
        width: 600,
        height: 425
    };
    var pickerApiLoaded = false;

    function onApiLoad() {
        gapi.load('picker', {
            'callback': function() {
                pickerApiLoaded = true;
            }
        });
        google.script.run.withSuccessHandler(createPicker)
            .withFailureHandler(showError).getOAuthToken();
    }

    function createPicker(token) {

        if (pickerApiLoaded && token) {

            //var docsView = new google.picker.DocsView()
                //.setIncludeFolders(true)
                //.setMimeTypes('application/vnd.google-apps.folder')
                //.setSelectFolderEnabled(true);

            var uploadDocsView = new google.picker.DocsUploadView()
                .setIncludeFolders(true)
                //.setMimeTypes('application/vnd.google-apps.folder')
                //.setSelectFolderEnabled(true);

            var picker = new google.picker.PickerBuilder()
                //.addView(docsView)
                .addView(uploadDocsView)
                //.setAppId("AIzaSyCZDa4JKKIOv2AF3QyrG8DnVOXmz27054o")
                .enableFeature(google.picker.Feature.NAV_HIDDEN)
                .hideTitleBar()
                .setSize(DIALOG_DIMENSIONS.width - 2, DIALOG_DIMENSIONS.height - 2)
                .setOAuthToken(token)
                .setCallback(pickerCallback)
                .setOrigin('https://docs.google.com')
                .build();

            picker.setVisible(true);

        } else {
            showError('Unable to load the file picker.');
        }
    }

    /**
     * A callback function that extracts the chosen document's metadata from the
     * response object. For details on the response object, see
     * https://developers.google.com/picker/docs/result
     *
     * @param {object} data The response object.
     */
    function pickerCallback(data) {
    try {
        var action = data[google.picker.Response.ACTION];
        if (action == google.picker.Action.PICKED) {
            var doc = data[google.picker.Response.DOCUMENTS][0];
            var id = doc[google.picker.Document.ID];
            // Show the ID of the Google Drive folder
            //document.getElementById('result').innerHTML = id;
            document.getElementById('result').innerHTML = "Importando..."
            google.script.run.importCSVData(id);
            //google.script.run.deleteImportedFile(id);
            google.script.host.close();
        } else if (action == google.picker.Action.CANCEL) {
        //document.getElementById('result').innerHTML = "Cerrando1..."
           google.script.host.close();
        //document.getElementById('result').innerHTML = "Cerrando2..."

        }
        } catch (e) {
          document.getElementById('result').innerHTML = e;
          google.script.run.senderror(e);
        }
    }

    function showError(message) {
        document.getElementById('result').innerHTML = 'Error: ' + message;
    }
  </script>
</head>

<body>
    <div>
        <p id='result'></p>
    </div>
    <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>

解决方案

You need to load the Google File Picker using the Google API Loader library.

Replace:

<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>

with:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>google.load("picker", "1", {callback:function(){pickerApiLoaded =!0}});</script>

Remember to publish a new version of the web app after making this change.

Update: Erik from the Google Apps Script team says " the cause of the problem is that when the Picker API loads into google.picker, it is currently overwriting google.script, so google.script.run() calls start failing."

They have posted an alternate solution - manually preserve and restore google.script when loading the Picker API:

window.script = google.script;
gapi.load('picker', '1', {callback: function() {
  google.script = window.script;
  // ...
}});

这篇关于无法从Web应用程序调用Google Script API函数(TypeError:无法读取未定义的属性“运行”)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆