0

我创建了一个自动填充 UI 的代码。当我在列表框中选择一个项目时,它会启动一个查找要填充的数据的函数。我认为问题来自层次结构:列表框在 grid1 中,grid1 在面板中。如何使用回调元素以及为什么......我真的不明白为什么要使用它并且谷歌文档并不完整。添加数据的单击按钮运行良好,但我不明白为什么 changehandler 变量是“未定义” 这是我的代码:

    var submissioSSKey = 'XXXXXX';//Change this key to your spreadsheet key
//creation de l'interface d'ajout des déchets

function addWasteData() {
  var app = UiApp.createApplication().setTitle('Ajout de déchet').setHeight(400).setWidth(500);
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var wasteListSheet = ss.getSheetByName("Registre déchets");
  //1. creation d'une grille pour structurer la app:
  var mypanel = app.createVerticalPanel().setId('mainPanel'); 
  var grid1 = app.createGrid(2, 3).setId('grid1').setStyleAttribute("border","3px double #CCCCCC");
  var grid2 = app.createGrid(3, 3).setStyleAttribute("border","1px solid #CCCCCC");
  var grid3 = app.createGrid(3, 3).setStyleAttribute("border","1px solid #CCCCCC");
  var grid4 = app.createGrid(3, 3).setStyleAttribute("border","1px solid #CCCCCC");

  //2.Labels informatifs
  grid1.setWidget(0, 0, app.createLabel('Déchet'))
  .setWidget(0, 1, app.createLabel('Quantité'))
  .setWidget(0, 2, app.createLabel('Unités'));

  grid2.setWidget(0, 0, app.createLabel('Prix'))
  .setWidget(0, 1, app.createLabel('€ / unit'))
  .setWidget(1, 0, app.createLabel('Traitement'))
  .setWidget(1, 1, app.createLabel('Transport'))
  .setWidget(1, 2, app.createLabel('Location'));

  grid3.setWidget(0, 0, app.createLabel('Dates'))
  .setWidget(1, 0, app.createLabel('Enlèvement'))
  .setWidget(1, 1, app.createLabel('Facture'))
  .setWidget(2, 1, app.createLabel('Entrée donnée'));

  grid4.setWidget(0, 0, app.createLabel('Codes'))
  .setWidget(0, 1, app.createLabel('déchet'))
  .setWidget(1, 0, app.createLabel('Regroupement'))
  .setWidget(1, 1, app.createLabel('Valorisation'))
  .setWidget(1, 2, app.createLabel('Élimination'));
  // text box et listes
  grid1
  .setWidget(1, 0, app.createListBox().setName('waste').setId('waste'))
  .setWidget(1, 1, app.createTextBox().setName('quantity').setId('quantity'))
  .setWidget(1, 2, app.createListBox().setId('unitListBox').setName('unit').addItem("tonnes").addItem("m³"));

  grid2.setWidget(2, 0, app.createTextBox().setName('Trait').setId('trait'))
  .setWidget(2, 1, app.createTextBox().setName('Transport').setId('transport'))
  .setWidget(2, 2, app.createTextBox().setName('Location').setId('location'));

  grid3.setWidget(2, 0, app.createDateBox().setId('enlevement').setName('enlevement'))
  .setWidget(2, 1, app.createDateBox().setId('facture').setName('facture'))
  .setWidget(2, 2, app.createDateBox().setId('inputdb').setName('inputdb'));

  grid4.setWidget(0, 2, app.createTextBox().setName('codedechet').setId('codedechet'))
  .setWidget(2, 0, app.createTextBox().setName('regroupement').setId('regroupement'))
  .setWidget(2, 1, app.createTextBox().setName('valorisation').setId('valorisation'))
  .setWidget(2, 2, app.createTextBox().setName('elimination').setId('elimination'));

  app.createTextBox().setName('info').setId('info');

  //3.définir la variable des éléments de la app pour modification dans le script
  var wasteListBox = app.getElementById("waste").setName('waste');
  var unitListBox = app.getElementById("unitListBox");
  var info = app.getElementById("info");
  var mybutton = app.createButton('Ajouter');
  //4. creation de serveur d'évènement
  // liste deroulante déchet
  var handlerList = app.createServerChangeHandler('selectListHandler');
  handlerList.addCallbackElement(wasteListBox); //est ce bon? c est ici que ça coince
  wasteListBox.addChangeHandler(handlerList);
  // envoi des données
  var handler = app.createServerClickHandler('insertDataWaste');
  handler.addCallbackElement(mypanel)  //ici ça fonctionne
  mybutton.addClickHandler(handler); 

  //Ajout de les données déchets au menu déroulant, texte box, etc:

  //Ajout des données dans la listbox
   numItemList1 = wasteListSheet.getLastRow()-1;//-1 pour exclure la dernière ligne qui est vide
  //get the item array
  list1ItemArray = wasteListSheet.getRange(2,1,numItemList1,1).getValues();
  //Add the items in ListBox
  for(var i=0; i<list1ItemArray.length; i++){
    wasteListBox.addItem(list1ItemArray[i][0])
  }

  //creation de l'interface et affichage
   mypanel.add(grid1)
  .add(grid2)
  .add(grid3)
  .add(grid4)
  .add(mybutton);
  app.add(mypanel);
  //return app;   <-- ne fonctionne pas :/
  SpreadsheetApp.getActiveSpreadsheet().show(app);
}

//test du fonctionnement du choix dans la liste en faisant apparaitre le le choix dans le text box traitement
  function selectListHandler(z)  {
  var app = UiApp.getActiveApplication();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var wasteListBox = z
  var wasteListSheet = ss.getSheetByName("Registre déchets");
  var traitBox = app.getElementById('trait')
  var transport = app.getElementById('transport');
  var location = app.getElementById('location');
  traitBox.setValue(rechercheDechet( wasteListBox,ss,wasteListSheet,11));
  return app;
}

//Insertion des donénes lors du clic sur le boutton de soumission
function insertDataWaste(o){
  var app = UiApp.getActiveApplication();
  var intitule = o.parameter.waste;
  var qty = o.parameter.quantity;
  var codeDechet = o.parameter.codedechet;
  var unit = o.parameter.unit;
  var trait = o.parameter.Traitement;
  var trans = o.parameter.Transport;
  var loc = o.parameter.Location;
  var fac = o.parameter.facture;
  var enlev = o.parameter.enlevement;
  var input = o.parameter.inputdb;
  var regr = o.parameter.regroupement;
  var valo = o.parameter.valorisation;
  var elim = o.parameter.elimination;
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Data"); //.getActiveSheet() supprimé
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 1, 13).setValues([[intitule,codeDechet,qty,unit,trait,trans,loc,fac,enlev,input,regr,valo,elim]]);
  return app;
}

和寻找功能:

function rechercheDechet(value,doc,sheet,column) {
  var sh = sheet;
  var ss = doc;
  var last = sh.getLastRow(); 
  var range = sh.getRange(2, 1, last-1, column).getValues(); 
   {
  for (var i = 0; i < range.length; i++) {
    if (range[i] == value) {
      return value;
    }
  }
  return;
}

}

谢谢你的帮助。

4

2 回答 2

1

Here is the solution by Serge Insas for search function, thanks to you. In the listbox, the items added that contains a "+" create a bug. I replaced it by words. Then it was working.

 function rechercheDechet(value,doc,sheet,column) {
      var sh = sheet;
      var ss = doc;
      var last = sh.getLastRow(); 
      var lastCol = sh.getLastColumn()
      var range = sh.getRange(2, 1, last-2, lastCol ).getValues(); // on prend toute la ligne de données
      for (var i = 0; i < range.length; i++) {
        if (range[i][0].toString().match(value) == value) { // on compare la 1ere colonne avec le nom
        Logger.log('trouvé '+value +'  i='+i)
          return range[i][10]; //et on prend la colonne prix (indice 0 dans le comptage dans une array >> 10 pour col 11) 
        }
      }
      return;
    }
于 2013-01-09T15:13:53.393 回答
0

将父小部件用作 CallBackElement 而不是特定的小部件要容易得多......

在您的代码中,我会像这样使用网格 1(您提出问题的地方)

  handlerList.addCallbackElement(grid1); //est ce bon? c est ici que ça coince

代替

handlerList.addCallbackElement(wasteListBox); //est ce bon? c est ici que ça coince

因为 wasteListBox 是您要填充的列表本身(我认为)......无论如何,作为一般规则,回调元素必须包含您想要获取值的小部件,因此层次结构中的较高层是最佳选择。为什么不使用 panel1 以确保您确定?

关于您对return app不工作的评论,这是正常的,并且在文档中有明确说明

EDIT1:我在您的代码中发现的另一个问题:搜索函数(rechercheDechet)返回一个称为value数组的变量,您通过将其分配给文本框来使用它......这不应该工作......

解释一下:当您使用getValues()二维数组读取电子表格中的范围时,然后在 for 循环中迭代数组的行以测试数组(一维)和字符串值之间的相等性(这将始终也失败了……)。最后,该函数返回一个与电子表格中的行(实际上是其中的一部分)相对应的数组。请注意,即使您只选择一列,该值仍将是 2D,要摆脱它,只需使用range[i][0]例如获取范围中的第一个单元格或range[i].toString()使其...一个字符串!

J'espère avoir été clair,希望足够清楚。我尝试了您的代码的副本,它似乎正在处理一些小的更改,尽管我的 SS 中没有任何数据可以显示;-)

EDIT2:还有另一个问题,它涉及selectListHandler(z)您使用服务器处理程序调用的函数:在这种情况下,变量z是所谓的event,即 UI 返回的编码数据。但是你使用z'原样'作为函数的第一个参数,rechercheDechet这应该是一个range......那里相当混乱......我建议你参考事件参数的文档示例或使用记录器来查看它内容Logger.log(e.parameter)。很难解释此答案范围内的所有内容

于 2013-01-08T17:16:54.627 回答