如何让它等到用户输入日期然后关闭对话框并将值写入其目的地?

Posted

技术标签:

【中文标题】如何让它等到用户输入日期然后关闭对话框并将值写入其目的地?【英文标题】:How can I get it to wait until the user enters the date and then it closes the dialog box and writes the value to its destination? 【发布时间】:2021-06-19 16:51:22 【问题描述】:

问题来了:

我让这些代码运行没有错误,但总的来说,它们不会按预期工作。

意图是一旦用户勾选了A列中的一个框,在onEdit基础上运行的代码应该打开一个对话框让用户输入日期。然后代码更改行列中的一个值,日期将写在它旁边。 一旦用户输入日期并点击添加,对话框应该会自动关闭。

我不确定函数的顺序以及如何让 onEdit 函数等到用户输入日期以使对话框消失并继续将日期写入其目的地。

感谢您的关注。

function onEdit() 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('DB');
  var dbData = sheet.getRange(2, 1, sheet.getLastRow(), 39).getValues();
  var ItemNumberSheet = ss.getSheetByName("To ORDER");
  var ItemNoRow = ItemNumberSheet.getActiveCell().getRow();//Getting row from active cell
  var ItemNoCol = 4;
  var ItemNo = ItemNumberSheet.getRange(ItemNoRow, ItemNoCol).getValue();
  var orderTicked = ItemNumberSheet.getRange(ItemNoRow, 1).getValue();
  var dbRow = 1;

  if (ss.getActiveSheet().getName() == 'To ORDER' && 
  ItemNumberSheet.getRange(ItemNoRow, 1).getValue() == true && ItemNoRow > 6 && ItemNo != '') 
    for (var a = 0; a < dbData.length; a++) 
      var row = dbData[a];
      if (dbData[a][0] != '') 
        if (orderTicked == true && dbData[a][2] == ItemNo) 
          dbRow = a + 1;
          break;
        
      
    
    showDatePicker(); //This is calling the dialog box
    sheet.getRange(dbRow + 1, 31).setValue(AddRecord());//This is supposed to write the date to the destination
    sheet.getRange(dbRow + 1, 32).setValue("Yes");
    sheet.getRange(dbRow + 1, 38).setValue(new Date());
    sheet.getRange(dbRow + 1, 39).setValue(Session.getEffectiveUser().getEmail());
    SpreadsheetApp.flush();
    ItemNumberSheet.getRange(ItemNoRow, 1).setValue("false");
  

这是输入/对话框功能:

function showDatePicker() 
  var template = htmlService.createTemplateFromFile("DatePicker");

  var html = template.evaluate();
  html.setTitle("Enter an Order Date");
  //SpreadsheetApp.getUi().showSidebar(html);
  SpreadsheetApp.getUi().showModalDialog(html, "New Title for the window");


function AddRecord(orderdate)
  return orderdate;

现在这是 html + 脚本:

<!--https://developers.google.com/speed/libraries-->
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">   
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
    <script>
    $( document ).ready(function() 
      $("#orderdate").datepicker();
    );
    function AddRecord()
      var orderdate = document.getElementById("orderdate").value;
      google.script.run.AddRecord(orderdate);
      document.getElementById("orderdate").value = '';
    
    </script>
  </head>
  <body>
    Order Date:<input type="text" id="orderdate" /> 
    <input type="button" value="Add" onclick="AddRecord()" />
  </body>
</html>

【问题讨论】:

【参考方案1】:

修改点:

showModalDialog运行时,进程从当前函数中释放。我认为这可能是您的问题的原因。 而且,当我看到你的脚本时,我认为AddRecord()"Yes"new Date()Session.getEffectiveUser().getEmail()setValues 放在一起。 在这种情况下,可以使用uncheck()。 为了通过 javascript 执行将 dbRowonEdit 发送到 AddRecord,我使用了 PropertiesService。

当以上几点反映到你的脚本中时,它变成如下。

修改后的脚本:

Google Apps 脚本方面:

请修改onEditAddRecord如下。

function onEdit() 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('DB');
  var dbData = sheet.getRange(2, 1, sheet.getLastRow(), 39).getValues();
  var ItemNumberSheet = ss.getSheetByName("To ORDER");
  var ItemNoRow = ItemNumberSheet.getActiveCell().getRow();//Getting row from active cell
  var ItemNoCol = 4;
  var ItemNo = ItemNumberSheet.getRange(ItemNoRow, ItemNoCol).getValue();
  var orderTicked = ItemNumberSheet.getRange(ItemNoRow, 1).getValue();
  var dbRow = 1;
  if (ss.getActiveSheet().getName() == 'To ORDER' &&
    ItemNumberSheet.getRange(ItemNoRow, 1).getValue() == true && ItemNoRow > 6 && ItemNo != '') 
    for (var a = 0; a < dbData.length; a++) 
      var row = dbData[a];
      if (dbData[a][0] != '') 
        if (orderTicked == true && dbData[a][2] == ItemNo) 
          dbRow = a + 1;
          break;
        
      
    
    PropertiesService.getScriptProperties().setProperty("key", dbRow);
    showDatePicker();
  


function AddRecord(orderdate) 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('DB');
  var ItemNumberSheet = ss.getSheetByName("To ORDER");
  var ItemNoRow = ItemNumberSheet.getActiveCell().getRow();
  var v = PropertiesService.getScriptProperties().getProperty("key");
  var dbRow = v ? Number(v) : 1;
  sheet.getRange(dbRow + 1, 31, 1, 2).setValues([[orderdate, "Yes"]]);
  sheet.getRange(dbRow + 1, 38, 1, 2).setValues([[new Date(), Session.getEffectiveUser().getEmail()]]);
  ItemNumberSheet.getRange(ItemNoRow, 1).uncheck();

HTML & Javascript 方面:

从:
google.script.run.AddRecord(orderdate);
到:
google.script.run.withSuccessHandler(google.script.host.close).AddRecord(orderdate);
通过这个修改,当点击按钮时,对话框可以关闭。

注意:

根据您的问题,我无法理解执行onEdit 函数的方法。当您使用onEdit 作为简单触发器时,会发生错误,因为SpreadsheetApp.getUi().showModalDialog() 不能由简单触发器运行。请注意这一点。而且,当您可能将onEdit 与可安装的OnEdit 触发器一起使用时,请将函数名称从onEdit 重命名为其他人并重新安装。因为当onEdit函数名作为可安装触发器时,函数运行了2次。也请注意这一点。 在这个修改后的脚本中,它假设您在脚本中创建的dbRow 是您期望的正确值。请注意这一点。

参考资料:

uncheck() Class google.script.run Class PropertiesService

【讨论】:

un - 吓坏了 - 可信!谢谢!现在,是时候让我深入了解参考资料了。 @Antonio Santos 感谢您的回复。我很高兴你的问题得到了解决。也谢谢你。

以上是关于如何让它等到用户输入日期然后关闭对话框并将值写入其目的地?的主要内容,如果未能解决你的问题,请参考以下文章

如何等到对话框真正关闭

Datepicker:单击按钮时如何弹出日期选择器并将值存储在变量中[关闭]

如何在 linux 系统上用 PHP 启动后台进程并将用户 ajax 输入重复写入其标准输入

创建一个网页,它要求一些输入并将其写入文件[关闭]

如何让phantomJS webdriver等到加载特定的HTML元素然后返回page.source?

如何获取 ValueProvider 的值并将其写入 BigQuery 表?