0

私は最近、この質問をしました: リストボックスに myDrive 内のすべてのフォルダーを入力します。

私は答えを得ました (助けてくれた Serge insas に感謝します!) しかし、彼が作ったものを現在の UI に取り入れようとしています。リストボックスを作成しましたが、彼が作成した「function folderSelect」という関数以外はすべて、UI に移動しようとすると、スクリプトを実行すると「e undefined」エラーが発生します。また、ドロップダウン メニューでそのフォルダーを選択したときに、ドキュメントが生成されたときにそのフォルダーにそのドキュメントが保存されるようにする必要もあります。(このすべてについて非常に多くの質問をして申し訳ありません。ここに来る前に自分でやるべきことをやってみようとしていますが、自分が何をしているのかわからないときは難しいです。)

現在のプロジェクトの PasteBin: http://pastebin.com/GVSvfcqG

これが私がこれまでに持っているものです:

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

編集:

すべてを修正してくれた Serge insas に感謝します。彼はすべてを修正し、完璧に動作しました。次のようなことが必要な場合は、皆さんと共有したいと思います。スプレッドシート ドキュメントの行を作業ドキュメントにエクスポートし、特定のフォルダーに移動し、その作業ドキュメントの PDF を作成します。テンプレートで {A} {B} などを使用して、情報を配置する場所を作成します。

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

/*
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);  

}

4

1 に答える 1

1

あなたがしたようにこのコードを統合することはできません...handler関数は、ユーザーが特定のアクションを実行したときに実行される関数であり、オブジェクトcallBackElementを使用してその関数に値をもたらしeます (e はイベント情報を表します)。

メイン コードを取得e.parameterしようとすると、まだ定義されていない値を取得しようとし、エラーが発生します。

これがあなたのコードの正しい実装です。注意深く調べて、どのように機能するかを確認してください。

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

編集 :

あなたのコメントに続いて、ドキュメントを選択したフォルダーに移動し、同じフォルダーに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);// 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;
}
于 2013-08-09T14:14:52.470 に答える