" E"未定义的Google脚本错误 [英] "e" undefined Google Script error

查看:91
本文介绍了" E"未定义的Google脚本错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近问这个问题:
有一个列表框与myDrive中的每个文件夹一起填充



我得到了一个答案(感谢Serge insas的帮助!)但是我试图得到他所做的到我目前的用户界面。当我尝试将它移动到我的用户界面时,我创建了列表框以及除了他所做的功能之外的所有功能,function folderSelect在运行脚本时给我一个未定义的错误。我还需要确保当我在下拉菜单中选择该文件夹时,当文档生成时,它将该文档保存在该文件夹中。 (抱歉,我已经提出了很多关于这些问题的问题,我试图在我来这里之前自己做我需要做的事情,但当我不知道我在做什么时很难。)



当前项目的PasteBin: http://pastebin.com/GVSvfcqG



这是我到目前为止:

 函数getTemplates(){
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication()。setTitle('从模板生成');
//创建一个带有3个文本框和相应标签的网格
var grid = app.createGrid(5,2);
grid.setWidget(0,0,app.createLabel('Template name:'));
var list = app.createListBox();
list.setName('Templates');
grid.setWidget(0,1,list);
var docs = DocsList.getFolder(Templates)。getFilesByType(document);
for(var i = 0; i< docs.length; i ++){
list.addItem(docs [i] .getName(),docs [i] .getId());
}
grid.setWidget(1,0,app.createLabel('Row:'));
var row = app.createTextBox()。setName('row');
row.setValue(SpreadsheetApp.getActiveSpreadsheet()。getActiveRange()。getRow());
grid.setWidget(1,1,row);

///////////////////////////////这就是我想要实现到我的用户界面//////////////////////////////////////////////
var curFN = app.createTextBox()。setText('MyDrive /')。setName('curFN')。setId('curFN')。setWidth('400');
// var curFID = app.createTextBox()。setText('x')。setName('curFID')。setId('curFID')。setWidth('400');
var listFolder = app.createListBox().setName('list').setId('list')。addItem('请选择一个文件夹','x');
grid.setWidget(2,0,app.createLabel('Choose Folder:'));
grid.setWidget(2,1,listFolder);
var folders = DocsList.getRootFolder()。getFolders();
for(var i = 0; i< folders.length; i ++){
list.addItem(folders [i] .getName(),folders [i] .getId())
}
var handler = app.createServerHandler('folderSelect')。addCallbackElement(grid);
list.addChangeHandler(handler);

var currentFN = e.parameter.curFN;
var currentFID = e.parameter.list;
//Logger.log(currentFID);
var FolderList = app.getElementById('listFolder');
var curFN = app.getElementById('curFN');
// var curFID = app.getElementById('curFID');
// if(currentFID =='x'){currentFID = DocsList.getRootFolder()。getId(); curFN.setText( MyDrive /)};
var startFolder = DocsList.getFolderById(currentFID);
var folders = startFolder.getFolders();
FolderList.clear()。addItem('no other subFolder','x')。addItem('返回根目录','x');
if(folders.length> 0){FolderList.clear(); FolderList.addItem('请选择一个子文件夹','x')};
for(var i = 0; i< folders.length; i ++){
FolderList.addItem(folders [i] .getName(),folders [i] .getId())
}
curFN.setText(currentFN + DocsList.getFolderById(currentFID).getName()+'/');
if(currentFID == DocsList.getRootFolder()。getId()){curFN.setText('MyDrive /')};
curFID.setText(currentFID);

////////////////////////////////////////// ////////////////////////////////////////////////// /////////////////////////////////

var panel = app.createVerticalPanel();
panel.add(grid);
var button = app.createButton('Submit');
var handler = app.createServerClickHandler('generateDocument');
handler.addCallbackElement(grid);
button.addClickHandler(handler);

//将按钮添加到面板和面板到应用程序,然后在电子表格doc中显示应用程序应用程序
panel.add(button);
app.add(panel);
doc.show(app);






编辑:



感谢Serge insas提供的所有帮助,他解决了所有问题,并且它完美地工作,如果您需要以下内容,我想与大家分享:导出一行将电子表格文档转换为工作文档,将其放入特定文件夹并创建该工作文档的PDF。使模板在您要放置信息的地方使用{A} {B}等等。

  //// ////////////////////////////////////////////////// ////////////////////////////////////////////////// //////////////// 

/ *
模板生成器作者:Andre Fecteau - klutch2013@gmail.com
原始代码来自: kiszal@gmail.com(通过搜索模板在模板库中找到它是第一个。
主要帮助:Serge Insas在堆栈溢出(他完成了大部分工作)
链接1 :https://stackoverflow.com/questions/18147798/e-undefined-google-script-error
链接2:https://stackoverflow.com/questions/18132837/have-a-listbox-populate-with -every-folder-in-mydrive

如何使用:
首先:每列在{Template}中用{列字母}指定,例如列A,它将是{A}
第二:您可以更改此设置,但您的模板必须位于名为模板的文件夹中。此文件夹可以位于驱动器中的任何位置。
第三种:单击在这里生成文档!然后点击导出行到文档
第四:输入你想要导出的行。选择你的文件夹路径。点击提交。
注意第四步:如果您希望您的编号跳过标题行,请在第28行中添加+1。
这意味着如果在行框中键入2,它实际上会导出第3行。我解决了这个问题,因为它有时会令人困惑。

注意:第67行,您可以将模板一词编辑为您将模板保存到的任何文件夹。

随意根据需要编辑此代码并满足您的需求。这就是我对原始代码所做的。
所以我没有理由限制别人用这个代码做什么。
* /

//////////////////////////////////// ////////////////////////////////////////////////// //////////////////////////////////

function generateDocument(e){
var template = DocsList.getFileById(e.parameter.Templates);
Logger.log(template.getName());
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var row = Number(e.parameter.row)// + 1; //删除//旁边的这一行//跳过标题
Logger.log(row);
var currentFID = e.parameter.curFID;
Logger.log(currentFID);
var myDocID = template.makeCopy(Sheet.getRange('B'+ row).getValue()+' - '+ Sheet.getRange('E'+ row).getValue()+' - '+ Sheet .getRange('D'+ row).getValue()+' - '+ Sheet.getRange('X'+ row).getValue())。getId();
var myDoc = DocumentApp.openById(myDocID);
var copyBody = myDoc.getActiveSection();
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
row--; //减少行号以符合工作表
中的实际行号var myRow = SpreadsheetApp.getActiveSpreadsheet()。getRange(row +:+ row);
for(var i = 1; i< Sheet.getLastColumn()+ 1; i ++){
var myCell = myRow.getCell(1,i);
copyBody.replaceText({+ myCell.getA1Notation()。replace(row,)+},myCell.getValue());
}

myDoc.saveAndClose();
var destFolder = DocsList.getFolderById(currentFID);
Logger.log(myDocID);
var doc = DocsList.getFileById(myDocID); //再次获取文档,但是使用docsList这次...
doc.addToFolder(destFolder); //将其添加到所需文件夹
doc.removeFromFolder(DocsList.getRootFolder()); //我一步一步做到了更容易遵循
var pdf = DocsList.getFileById(myDocID).getAs(application / pdf);
destFolder.createFile(pdf); //这将在您的文件夹中创建pdf文件
var app = UiApp.getActiveApplication();
app.close();
返回应用程序;
}

///////////////////////////////////// ////////////////////////////////////////////////// /////////////////////////////////

函数getTemplates(){
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication()。setTitle('从模板生成');
//创建一个带有3个文本框和相应标签的网格
var grid = app.createGrid(5,2);
grid.setWidget(0,0,app.createLabel('Template name:'));
var list = app.createListBox();
list.setName('Templates');
grid.setWidget(0,1,list);
var docs = DocsList.getFolder(Templates)。getFilesByType(document); //将单词模板更改为您将模板保存到
的文件夹(var i = 0; i< docs.length; i ++){
list.addItem(docs [i]。的getName(),文档[I] .getId());
}

grid.setWidget(1,0,app.createLabel('Row:'));
var row = app.createTextBox()。setName('row');
row.setValue(SpreadsheetApp.getActiveSpreadsheet()。getActiveRange()。getRow());
grid.setWidget(1,1,row);
var curFN = app.createTextBox()。setText('MyDrive /')。setName('curFN')。setId('curFN')。setWidth('400');
var curFID = app.createTextBox()。setText(DocsList.getRootFolder()。getId())。setName('curFID')。setId('curFID')。setVisible(false);
var listF = app.createListBox()。setName('listF').setId('listF')。addItem('请选择文件夹','x');
grid.setText(2,0,'Type Path:')。setWidget(2,1,curFN).setText(3,0,'OR').setText(4,0,'Choose Path:' ).setWidget(4,1,LISTF).setWidget(3,1,curFID);
var folders = DocsList.getRootFolder()。getFolders();
for(var i = 0; i< folders.length; i ++){
listF.addItem(folders [i] .getName(),folders [i] .getId())
}

var handlerF = app.createServerHandler('folderSelect')。addCallbackElement(grid);
listF.addChangeHandler(handlerF);
var panel = app.createVerticalPanel();
panel.add(grid);
var button = app.createButton('Submit');
var handler = app.createServerClickHandler('generateDocument');
handler.addCallbackElement(grid);
button.addClickHandler(handler);
//将按钮添加到面板和面板到应用程序,然后在电子表格doc中显示应用程序应用程序
panel.add(button);
app.add(panel);
doc.show(app);
}

///////////////////////////////////// ////////////////////////////////////////////////// /////////////////

函数folderSelect(e) {
var app = UiApp.getActiveApplication();
var currentFN = e.parameter.curFN;
var currentFID = e.parameter.listF;
Logger.log(currentFID);
var listF = app.getElementById('listF');
var curFN = app.getElementById('curFN');
var curFID = app.getElementById('curFID');
if(currentFID =='x'){currentFID = DocsList.getRootFolder()。getId(); curFN.setText( MyDrive /)};
var startFolder = DocsList.getFolderById(currentFID);
var folders = startFolder.getFolders();
listF.clear()。addItem('No More Sub Folders!','x')。addItem('Go to Root','x');
if(folders.length> 0){listF.clear(); listF.addItem('Select Sub Folder','x')};
for(var i = 0; i< folders.length; i ++){
listF.addItem(folders [i] .getName(),folders [i] .getId())
}

curFN.setText(currentFN + DocsList.getFolderById(currentFID).getName()+'/');
if(currentFID == DocsList.getRootFolder()。getId()){curFN.setText('MyDrive /')};
curFID.setText(currentFID);
返回应用程序;
}

///////////////////////////////////// ////////////////////////////////////////////////// /////////////////////////////////////

function onOpen(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name:将行导出到文档,functionName:getTemplates}];
ss.addMenu(在这里生成文档!,menuEntries);

}

解决方案你不能像你所做的那样集成这段代码... handler 函数是一个函数,当某个操作由用户完成时执行 callBackElement 使用 e 对象为该函数赋值(e用于事件信息)。



如果您尝试在主代码中获取 e.parameter ,它将尝试获取尚未定义的值并生成错误你得到了。



这是我的代码在你的正确实现,请仔细检查它,看看它是如何工作的。

  function getTemplates(){
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication()。setTitle('从模板生成');
//创建一个带有3个文本框和相应标签的网格
var grid = app.createGrid(5,2);
grid.setWidget(0,0,app.createLabel('Template name:'));
var list = app.createListBox();
list.setName('Templates');
grid.setWidget(0,1,list);
var docs = DocsList.getFolder(Templates)。getFilesByType(document);
for(var i = 0; i< docs.length; i ++){
list.addItem(docs [i] .getName(),docs [i] .getId());
}
grid.setWidget(1,0,app.createLabel('Row:'));
var row = app.createTextBox()。setName('row');
row.setValue(SpreadsheetApp.getActiveSpreadsheet()。getActiveRange()。getRow());
grid.setWidget(1,1,row);
var curFN = app.createTextBox()。setText('MyDrive /')。setName('curFN')。setId('curFN')。setWidth('400');
var curFID = app.createTextBox()。setText('x')。setName('curFID')。setId('curFID')。setVisible(false);
var listF = app.createListBox()。setName('listF').setId('listF')。addItem('请选择一个文件夹','x');
grid.setText(2,0,'选择驱动器中的文件夹')。setWidget(2,1,curFN).setWidget(3,1,curFID).setWidget(4,1,listF);
var folders = DocsList.getRootFolder()。getFolders();
for(var i = 0; i< folders.length; i ++){
listF.addItem(folders [i] .getName(),folders [i] .getId())
}
var handlerF = app.createServerHandler('folderSelect')。addCallbackElement(grid);
listF.addChangeHandler(handlerF);
var panel = app.createVerticalPanel();
panel.add(grid);
var button = app.createButton('Submit');
var handler = app.createServerClickHandler('generateDocument');
handler.addCallbackElement(grid);
button.addClickHandler(handler);
//将按钮添加到面板和面板到应用程序,然后在电子表格doc中显示应用程序应用程序
panel.add(button);
app.add(panel);
doc.show(app);
}

函数folderSelect(e){
var app = UiApp.getActiveApplication();
var currentFN = e.parameter.curFN;
var currentFID = e.parameter.listF;
Logger.log(currentFID);
var listF = app.getElementById('listF');
var curFN = app.getElementById('curFN');
var curFID = app.getElementById('curFID');
if(currentFID =='x'){currentFID = DocsList.getRootFolder()。getId(); curFN.setText( MyDrive /)};
var startFolder = DocsList.getFolderById(currentFID);
var folders = startFolder.getFolders();
listF.clear()。addItem('no other subFolder','x')。addItem('返回Root','x');
if(folders.length> 0){listF.clear(); listF.addItem('请选择一个子文件夹','x')};
for(var i = 0; i< folders.length; i ++){
listF.addItem(folders [i] .getName(),folders [i] .getId())
}
curFN.setText(currentFN + DocsList.getFolderById(currentFID).getName()+'/');
if(currentFID == DocsList.getRootFolder()。getId()){curFN.setText('MyDrive /')};
curFID.setText(currentFID);
返回应用程序;

$ / code $ / pre

$ hr
$ b

编辑:



在您的评论之后,下面是将文档移动到所选文件夹并在同一文件夹中创建PDF文件的修改:

  function generateDocument(e){
var template = DocsList.getFileById(e.parameter.Templates);
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var row = e.parameter.row
var currentFID = e.parameter.listF;
var myDocID = template.makeCopy(Sheet.getRange('B'+ row).getValue()+' - '+ Sheet.getRange('E'+ row).getValue()+' - '+ Sheet .getRange('D'+ row).getValue()+' - '+ Sheet.getRange('X'+ row).getValue())。getId();
var myDoc = DocumentApp.openById(myDocID);
var copyBody = myDoc.getActiveSection();
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var myRow = SpreadsheetApp.getActiveSpreadsheet()。getRange(row +:+ row);
for(var i = 1; i< Sheet.getLastColumn()+ 1; i ++){
var myCell = myRow.getCell(1,i);
copyBody.replaceText({+ myCell.getA1Notation()。replace(row,)+},myCell.getValue());
}
myDoc.saveAndClose();
var destFolder = DocsList.getFolderById(currentFID);
var doc = DocsList.getFileById(myDocID); //再次获取文档,但是使用docsList这次...
doc.addToFolder(destFolder); //将其添加到所需文件夹
doc.removeFromFolder(DocsList.getRootFolder()); //我一步一步做到了更容易遵循
var pdf = DocsList.getFileById(myDocID).getAs(application / pdf);
destFolder.createFile(pdf); //这将在您的文件夹中创建pdf文件
var app = UiApp.getActiveApplication();
app.close();
返回应用程序;
}


I recently asked this question: Have a listbox populate with every folder in myDrive

I got an answer (Thanks to Serge insas for the help!) But I am trying to get what he made into my current UI. I have the listbox made and everything but the function that he made called, "function folderSelect" when I try and move it over to my UI gives me a "e undefined" error when I run the script. I also need to make sure that when I select that folder in the drop down menu, that when the document is generated, it saves that document in that folder. (sorry that I have asked so many questions about all of this. I try to give it a try myself doing what I need to do before I come here but it is hard when I have no idea what I am doing.)

PasteBin for current project: http://pastebin.com/GVSvfcqG

Here is what I have so far:

 function getTemplates() {
      var doc = SpreadsheetApp.getActiveSpreadsheet();
      var app = UiApp.createApplication().setTitle('Generate from template');
      // Create a grid with 3 text boxes and corresponding labels
      var grid = app.createGrid(5, 2);
      grid.setWidget(0, 0, app.createLabel('Template name:'));
      var list = app.createListBox();
      list.setName('Templates');
      grid.setWidget(0, 1, list);
      var docs = DocsList.getFolder("Templates").getFilesByType("document");
      for (var i = 0; i < docs.length; i++) {
        list.addItem(docs[i].getName(),docs[i].getId());
      }
      grid.setWidget(1, 0, app.createLabel('Row:'));
      var row = app.createTextBox().setName('row');
      row.setValue(SpreadsheetApp.getActiveSpreadsheet().getActiveRange().getRow());
      grid.setWidget(1, 1, row);

    ///////////////////////////////This is what i am trying to implement into my UI//////////////////////////////////////////////
       var curFN = app.createTextBox().setText('MyDrive/').setName('curFN').setId('curFN').setWidth('400');
  //var curFID = app.createTextBox().setText('x').setName('curFID').setId('curFID').setWidth('400');
  var listFolder = app.createListBox().setName('list').setId('list').addItem('please select a folder','x');
  grid.setWidget(2, 0, app.createLabel('Choose Folder:'));
  grid.setWidget(2, 1, listFolder);
  var folders = DocsList.getRootFolder().getFolders();
  for (var i = 0; i < folders.length; i++) {
    list.addItem(folders[i].getName(),folders[i].getId())
  } 
  var handler = app.createServerHandler('folderSelect').addCallbackElement(grid);
  list.addChangeHandler(handler);

  var currentFN = e.parameter.curFN;
  var currentFID = e.parameter.list;
  //Logger.log(currentFID);
  var FolderList = app.getElementById('listFolder');
  var curFN = app.getElementById('curFN');
  //var curFID = app.getElementById('curFID');
  //if(currentFID=='x'){currentFID=DocsList.getRootFolder().getId() ; curFN.setText('MyDrive/')};
  var startFolder = DocsList.getFolderById(currentFID);
  var folders = startFolder.getFolders();
  FolderList.clear().addItem('no other subFolder','x').addItem('Go back to Root','x');
  if(folders.length>0){FolderList.clear(); FolderList.addItem('please select a subFolder','x')};
  for (var i = 0; i < folders.length; i++) {
   FolderList.addItem(folders[i].getName(),folders[i].getId())
  } 
  curFN.setText(currentFN+DocsList.getFolderById(currentFID).getName()+'/');
  if(currentFID==DocsList.getRootFolder().getId()){curFN.setText('MyDrive/')};
  curFID.setText(currentFID);

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      var panel = app.createVerticalPanel();
      panel.add(grid);
      var button = app.createButton('Submit');
      var handler = app.createServerClickHandler('generateDocument');
      handler.addCallbackElement(grid);
      button.addClickHandler(handler);

      // Add the button to the panel and the panel to the application, then display the application app in the Spreadsheet doc
      panel.add(button);
      app.add(panel);
      doc.show(app);
    }


EDIT:

Thanks to Serge insas for all of his help he fixed everything and it works perfectly and i would like to share it with all of you if you ever need something that will: Export a row of a spreadsheet document into a work document, put it into a specific folder and create a PDF of that work document. to make the template use {A} {B} and so on where you want to put your information.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
Template Generator By: Andre Fecteau - klutch2013@gmail.com
Original Code From: kiszal@gmail.com (Found in the template gallery by searching "Templates" It is the first One.
Major Help from: Serge Insas On Stack Overflow (He did most of the work.)
Link 1: https://stackoverflow.com/questions/18147798/e-undefined-google-script-error
Link 2: https://stackoverflow.com/questions/18132837/have-a-listbox-populate-with-every-folder-in-mydrive

How To Use: 
First: each column is designated in your Template by {Column Letter} for example for column A it would be {A}
Second: You can change this, but your Template must be in a folder called "Templates." This folder can be anywhere in your drive.
Third: Click "Generate Documents Here!" Then click "Export Row to Document"
Fourth: Type in the row you want to export. Chose your Folder Path. Click Submit. 
NOTE ON FOURTH STEP: If you want your number to skip the header row add a +1 to line 28. 
This would mean if you typed "2" in the row box it actually exports row 3. I took this out because it can get confusing at times.

NOTE: Line 67 you can edit the word "Templates" to whatever folder you saved your Template into.

Feel free to edit this code as you wish and for your needs. That is what I did with the original code.
So there is no reason I should restrict what others do with this code.
*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function generateDocument(e) {
  var template = DocsList.getFileById(e.parameter.Templates);
  Logger.log(template.getName());
  var Sheet = SpreadsheetApp.getActiveSpreadsheet();
  var row = Number(e.parameter.row)//+1 ; // Remove the // in this line next to the +1 to skip headers
  Logger.log(row);
  var currentFID = e.parameter.curFID;
  Logger.log(currentFID);
  var myDocID = template.makeCopy(Sheet.getRange('B'+row).getValue()+' - '+Sheet.getRange('E'+row).getValue()+' - '+Sheet.getRange('D'+row).getValue()+' - '+Sheet.getRange('X'+row).getValue()).getId();
  var myDoc = DocumentApp.openById(myDocID);
  var copyBody = myDoc.getActiveSection();
  var Sheet = SpreadsheetApp.getActiveSpreadsheet();
  row--; // decrement row number to be in concordance with real row numbers in sheet
  var myRow = SpreadsheetApp.getActiveSpreadsheet().getRange(row+":"+row);
  for (var i=1;i<Sheet.getLastColumn()+1;i++){
    var myCell = myRow.getCell(1, i);
    copyBody.replaceText("{"+myCell.getA1Notation().replace(row,"")+"}", myCell.getValue());
  }

  myDoc.saveAndClose();
  var destFolder = DocsList.getFolderById(currentFID);
  Logger.log(myDocID);
  var doc = DocsList.getFileById(myDocID);// get the document again but using docsList this time...
  doc.addToFolder(destFolder);// add it to the desired folder
  doc.removeFromFolder(DocsList.getRootFolder());// I did it step by step to be more easy to follow
  var pdf = DocsList.getFileById(myDocID).getAs("application/pdf");
  destFolder.createFile(pdf);// this will create the pdf file in your folder
  var app = UiApp.getActiveApplication();
  app.close();
  return app;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function getTemplates() {
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var app = UiApp.createApplication().setTitle('Generate from template');
  // Create a grid with 3 text boxes and corresponding labels
  var grid = app.createGrid(5, 2);
  grid.setWidget(0, 0, app.createLabel('Template name:'));
  var list = app.createListBox();
  list.setName('Templates');
  grid.setWidget(0, 1, list);
  var docs = DocsList.getFolder("Templates").getFilesByType("document"); //Change the word "Templates" to whatever folder you saved your template into
  for (var i = 0; i < docs.length; i++) {
    list.addItem(docs[i].getName(),docs[i].getId());
  }

  grid.setWidget(1, 0, app.createLabel('Row:'));
  var row = app.createTextBox().setName('row');
  row.setValue(SpreadsheetApp.getActiveSpreadsheet().getActiveRange().getRow());
  grid.setWidget(1, 1, row);
  var curFN = app.createTextBox().setText('MyDrive/').setName('curFN').setId('curFN').setWidth('400');
  var curFID = app.createTextBox().setText(DocsList.getRootFolder().getId()).setName('curFID').setId('curFID').setVisible(false);
  var listF = app.createListBox().setName('listF').setId('listF').addItem('Please Select Folder','x');
  grid.setText(2,0,'Type Path:').setWidget(2,1,curFN).setText(3,0,'OR').setText(4,0, 'Choose Path:').setWidget(4,1,listF).setWidget(3,1,curFID);
  var folders = DocsList.getRootFolder().getFolders();
  for (var i = 0; i < folders.length; i++) {
    listF.addItem(folders[i].getName(),folders[i].getId())
  } 

  var handlerF = app.createServerHandler('folderSelect').addCallbackElement(grid);
  listF.addChangeHandler(handlerF);
  var panel = app.createVerticalPanel();
  panel.add(grid);
  var button = app.createButton('Submit');
  var handler = app.createServerClickHandler('generateDocument');
  handler.addCallbackElement(grid);
  button.addClickHandler(handler);
  // Add the button to the panel and the panel to the application, then display the application app in the Spreadsheet doc
  panel.add(button);
  app.add(panel);
  doc.show(app);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function folderSelect(e){
  var app = UiApp.getActiveApplication();
  var currentFN = e.parameter.curFN;
  var currentFID = e.parameter.listF;
  Logger.log(currentFID);
  var listF = app.getElementById('listF');
  var curFN = app.getElementById('curFN');
  var curFID = app.getElementById('curFID');
  if(currentFID=='x'){currentFID=DocsList.getRootFolder().getId() ; curFN.setText('MyDrive/')};
  var startFolder = DocsList.getFolderById(currentFID);
  var folders = startFolder.getFolders();
  listF.clear().addItem('No More Sub Folders!','x').addItem('Go back to Root','x');
  if(folders.length>0){listF.clear(); listF.addItem('Select Sub Folder','x')};
  for (var i = 0; i < folders.length; i++) {
    listF.addItem(folders[i].getName(),folders[i].getId())
  } 

  curFN.setText(currentFN+DocsList.getFolderById(currentFID).getName()+'/');
  if(currentFID==DocsList.getRootFolder().getId()){curFN.setText('MyDrive/')};
  curFID.setText(currentFID);
  return app;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function onOpen() {   
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [{name: "Export Row to Document", functionName: "getTemplates"}];  
  ss.addMenu("Generate Documents Here!", menuEntries);  

}

解决方案

You can not integrate this code the way you did... A handler function is a function that is executed when a certain action is done by a user and the callBackElement brings values to that function using e object (e comes for event information).

If you try to get e.parameter in the main code it will try to get a value that is not yet defined and generate the error you get.

Here is a correct implementation of my code in yours, please examine it attentively to see and understand how it works.

function getTemplates() {
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var app = UiApp.createApplication().setTitle('Generate from template');
  // Create a grid with 3 text boxes and corresponding labels
  var grid = app.createGrid(5, 2);
  grid.setWidget(0, 0, app.createLabel('Template name:'));
  var list = app.createListBox();
  list.setName('Templates');
  grid.setWidget(0, 1, list);
  var docs = DocsList.getFolder("Templates").getFilesByType("document");
  for (var i = 0; i < docs.length; i++) {
    list.addItem(docs[i].getName(),docs[i].getId());
  }
  grid.setWidget(1, 0, app.createLabel('Row:'));
  var row = app.createTextBox().setName('row');
  row.setValue(SpreadsheetApp.getActiveSpreadsheet().getActiveRange().getRow());
  grid.setWidget(1, 1, row);
  var curFN = app.createTextBox().setText('MyDrive/').setName('curFN').setId('curFN').setWidth('400');
  var curFID = app.createTextBox().setText('x').setName('curFID').setId('curFID').setVisible(false);
  var listF = app.createListBox().setName('listF').setId('listF').addItem('please select a folder','x');
  grid.setText(2,0,'Choose a folder in your drive').setWidget(2,1,curFN).setWidget(3,1,curFID).setWidget(4,1,listF);
  var folders = DocsList.getRootFolder().getFolders();
  for (var i = 0; i < folders.length; i++) {
    listF.addItem(folders[i].getName(),folders[i].getId())
  } 
  var handlerF = app.createServerHandler('folderSelect').addCallbackElement(grid);
  listF.addChangeHandler(handlerF);
  var panel = app.createVerticalPanel();
  panel.add(grid);
  var button = app.createButton('Submit');
  var handler = app.createServerClickHandler('generateDocument');
  handler.addCallbackElement(grid);
  button.addClickHandler(handler);
  // Add the button to the panel and the panel to the application, then display the application app in the Spreadsheet doc
  panel.add(button);
  app.add(panel);
  doc.show(app);
}

function folderSelect(e){
  var app = UiApp.getActiveApplication();
  var currentFN = e.parameter.curFN;
  var currentFID = e.parameter.listF;
  Logger.log(currentFID);
  var listF = app.getElementById('listF');
  var curFN = app.getElementById('curFN');
  var curFID = app.getElementById('curFID');
  if(currentFID=='x'){currentFID=DocsList.getRootFolder().getId() ; curFN.setText('MyDrive/')};
  var startFolder = DocsList.getFolderById(currentFID);
  var folders = startFolder.getFolders();
  listF.clear().addItem('no other subFolder','x').addItem('Go back to Root','x');
  if(folders.length>0){listF.clear(); listF.addItem('please select a subFolder','x')};
  for (var i = 0; i < folders.length; i++) {
    listF.addItem(folders[i].getName(),folders[i].getId())
  } 
  curFN.setText(currentFN+DocsList.getFolderById(currentFID).getName()+'/');
  if(currentFID==DocsList.getRootFolder().getId()){curFN.setText('MyDrive/')};
  curFID.setText(currentFID);
  return app;
}


EDIT :

Following your comment, here is the modification to move the document it the chosen folder and create the pdf file as well in the same folder :

function generateDocument(e) {
  var template = DocsList.getFileById(e.parameter.Templates);
  var Sheet = SpreadsheetApp.getActiveSpreadsheet();
  var row = e.parameter.row
  var currentFID = e.parameter.listF;
  var myDocID = template.makeCopy(Sheet.getRange('B'+row).getValue()+' - '+Sheet.getRange('E'+row).getValue()+' - '+Sheet.getRange('D'+row).getValue()+' - '+Sheet.getRange('X'+row).getValue()).getId();
  var myDoc = DocumentApp.openById(myDocID);
  var copyBody = myDoc.getActiveSection();
  var Sheet = SpreadsheetApp.getActiveSpreadsheet();
  var myRow = SpreadsheetApp.getActiveSpreadsheet().getRange(row+":"+row);
  for (var i=1;i<Sheet.getLastColumn()+1;i++){
    var myCell = myRow.getCell(1, i);
    copyBody.replaceText("{"+myCell.getA1Notation().replace(row,"")+"}", myCell.getValue());
  }
  myDoc.saveAndClose();
  var destFolder = DocsList.getFolderById(currentFID);
  var doc = DocsList.getFileById(myDocID);// get the document again but using docsList this time...
  doc.addToFolder(destFolder);// add it to the desired folder
  doc.removeFromFolder(DocsList.getRootFolder());// I did it step by step to be more easy to follow
  var pdf = DocsList.getFileById(myDocID).getAs("application/pdf");
  destFolder.createFile(pdf);// this will create the pdf file in your folder
  var app = UiApp.getActiveApplication();
  app.close();
  return app;
}

这篇关于&QUOT; E&QUOT;未定义的Google脚本错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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