通过处理程序传递数据(例如,数组值)而不使用ScriptProperties的另一种方法

时间:2014-06-21 15:50:53

标签: google-apps-script google-sheets

我构建了一个应用程序,我在其中使用ScriptProperties将数据从处理程序存储到其but(e)函数。这很好用,直到其他人开始同时使用相同的电子表格。经常发生这样的情况:一个人花时间考虑从复选框菜单中选择哪个项目而另一个人使用相同的功能,更改存储在scriptProperties中的数据并影响第一人使用该功能。 使用另一种方法通过处理程序传递信息的最佳方法是什么? 这里有一个theese函数的示例(我使用ScriptProperties传递letterSpreadsheetIdrecipientArray的值):

function letter(letterSpreadsheetId){
  ScriptProperties.setProperty('letterSpreadsheetId', letterSpreadsheetId); // different people may have different letterSpreadsheetId;
  ScriptProperties.setProperty('letter', 1); // to be used in another function
  var activeSheet = ss.getActiveSheet();
  var app = UiApp.createApplication().setHeight(400).setWidth(600);
  var panel = app.createVerticalPanel(); // you can embed that in a form panel
  var label = app.createLabel("Choose a receiver").setStyleAttribute("fontSize", 18);
  app.add(label);  
  var sheet = SpreadsheetApp.openById(letterSpreadsheetId).getSheetByName("receivers");
  var recipientArray = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();  
  var item3Panel = app.createHorizontalPanel();
  item3Panel.add(app.createLabel("receiver"));
  var listBox = app.createListBox().setName('item3');  
      for(var i = 0; i < (recipientArray.length); i++){
           listBox.addItem(recipientArray[i][1]);
    }
  item3Panel.add(listBox);
  var recipientArrayStr = JSON.stringify(recipientArray);
  ScriptProperties.setProperty('recipientArr', recipientArrayStr);
  var handlerBut = app.createServerHandler("butAnswerLetter").addCallbackElement(panel);
  var but = app.createButton("submit").setId("submitButton2").addClickHandler(handlerBut);
  panel.add(item1Panel)
       .add(item2Panel)
       .add(item3Panel)
       .add(but)
       .add(app.createLabel().setId("answer"));  
  var scroll = app.createScrollPanel().setPixelSize(600, 400).setTitle("My title 1");
  scroll.add(panel);
  app.add(scroll);
  ss.show(app);
}

function butAnswerLetter(e){
  var letterSpreadsheetId = ScriptProperties.getProperty('letterSpreadsheetId');
  var recipient = e.parameter.item3;
  ScriptProperties.setProperty('recipient', recipient);
  var recipientArrayRecovery = ScriptProperties.getProperty('recipientArr');
  var recipientArray = JSON.parse(recipientArrayRecovery);
  for(var i=0;i<recipientArray.length;i++){
    if(recipient == recipientArray[i][1]){
        var usedRecipientArray = recipientArray[i];
    }
  }

1 个答案:

答案 0 :(得分:2)

你有两种可能性(我知道),要么使用userProperties而不是脚本属性,因为它们与用户相关联,但它需要用户登录和授权,或者 - 这将在每种情况下都有效,即使应用程序是匿名访问的,使用几乎可以在任何小部件上编写的标记。

语法很简单,这是一个小代码示例:

function doGet(){
  var app = UiApp.createApplication().setTitle('test_TAG');
  var list = app.createListBox(true).setVisibleItemCount(5).setPixelSize(30,450).setName('list');
  var handler = app.createServerHandler('show').addCallbackElement(list);
  list.addChangeHandler(handler);
  var data = [];
  for(var n = 0;n<20;n++){
    list.addItem(n+' ');
    data.push('available value = '+Number(n+1));
  }
  list.setTag(data.toString());
  app.add(list);
  return app
}

function show(e){
  var app = UiApp.getActiveApplication();
  var data = e.parameter.list_tag.split()
  var selected = e.parameter.list;
  app.add(app.createTextBox().setText(selected).setPixelSize(200,20));
  app.add(app.createTextArea().setText(data.join()).setPixelSize(200,300));
  return app;
}

testable here


修改

遵循Zig的相关评论:

我忘了提及hidden widget(或者设置为隐藏的textBox /区域,当你想检查它包含的东西时用于调试!)当然也可用... 关于有多个窗口显示同一个应用程序的用户的评论也值得一提!

总而言之,你有三种可能性!

(感谢Zig Mandel)