得到"未定义"在尝试从电子表格中获取值时

时间:2015-05-29 17:00:49

标签: javascript google-apps-script google-sheets google-spreadsheet-api google-form

我得到一个"未定义"我尝试从电子表格中的单元格中获取值时出错。问题是,如果我为不同的单元格执行相同的命令,我将获得该单元格中的值。这两个单元格之间的唯一区别在于产生价值的方式。

正确显示的单元格中的值直接来自与该电子表格关联的Google表单。调用时未显示的值是根据我在Google表单中创建的脚本生成的。

表单脚本(在表单提交时触发):

// This code will set the edit form url as the value at cell "C2".

function assignEditUrls() {
    var form = FormApp.getActiveForm();
    var ss = SpreadsheetApp.openById("my-spreadsheet-id")
    var sheet = ss.getSheets()[0];

    var urlCol = 3; // column number where URL's should be populated; A = 1, B = 2 etc
    var formResponses = form.getResponses();

    for (var i = 0; i < formResponses.length; i++) {
        var resultUrl = formResponses[i].getEditResponseUrl();
        sheet.getRange(2 + i, urlCol).setValue(resultUrl); 
    } 
    SpreadsheetApp.flush();
 }

表格(已更改为HTML)

<table>
    <tr> <!-- Row 1 -->
        <td>Timestamp</td> <!-- A1 -->
        <td>Name</td> <!-- B1 -->
        <td>Edit form URL</td> <!-- C1 -->
    </tr>
    <tr> <!-- Row 2 -->
        <td>5/26/2015 14:04:09</td> <!-- A2: this value came from the form submittion-->
        <td>Jones, Donna</td> <!-- B2: this value came from the form submittion-->
        <td>https://docs.google.com/forms/d/1-FeW-mXh_8g/viewform?edit2=2_ABaOh9</td> <!-- C2: this value came from the the script in the form -->
    </tr>
</table>

电子表格中的脚本(在表单提交时触发)

function onFormSubmit(e) {

    // This script will get the values from different cells in the spreadsheet 
    // and will send them into an email.

    var name = e.range.getValues()[0][1]; // This will get the value from cell "B2".
    var editFormURL = e.range.getValues()[0][2]; // This will get the value from cell "C2".

    var email = 'my-email@university.edu';
    var subject = "Here goes the email subject."
    var message = 'This is the body of the email and includes'
                  + 'the value from cell "B2" <b>'
                  + name + '</b>. This value is retrieved correctly.' 
                  + '<br>But the value from cell "C2" <b>'+ editFormURL
                  + '</b> show as "undefined".';

    MailApp.sendEmail(email, subject, message, {htmlBody: message});
}

电子邮件如下所示:

参议员:my-email@university.edu

主题:这是电子邮件主题。

体:

这是电子邮件的正文,包含来自单元格&#34; B2&#34;的值。 琼斯,唐娜。正确检索此值。

但来自细胞的价值&#34; C2&#34; 未定义显示为&#34;未定义&#34;。

问题:

我做错了什么?

3 个答案:

答案 0 :(得分:2)

你最有可能在比赛中遇到比赛。

  1. 用户提交表单。这是我们的主要活动。

  2. 提交表单后,将触发与该事件关联的所有触发器。

      表单脚本中的
    • assignEditUrls()

    • 电子表格脚本中的
    • onFormSubmit()

    如果您为此事件设置了其他脚本,它们也会触发。这里的复杂之处在于,所有这些触发器都是独立,或多或少同时触发,但没有保证执行顺序。电子表格触发器可以在表单触发器之前运行!这是一个问题。

  3. 每个触发器将以特定于其定义的格式接收事件信息。 (请参阅Event Objects。)由于C2实际上不是表单提交的一部分,因此它不会出现在电子表格函数接收的事件对象中。这是你的第二个问题,但由于你知道值相对于表单输入的偏移量,你可以使用range.offset()来获取它。

    额外的皱纹与文档和电子表格的共享方式有关;每个单独的脚本调用都将收到自己的电子表格副本,该副本最终与其他副本同步。一个脚本对电子表格所做的更改不会立即对所有其他用户可见。这就产生了三个问题。

    怎么做?

    您可以尝试协调两个相关触发器功能的操作。如果它们在同一个脚本中,那么Lock Service可以帮助解决这个问题。

    您可以只使用一个触发器功能来执行这两个操作。

    或者您可以通过等待C2填充电子表格功能来容忍任何延迟。这个代码片段可以做到这一点......

    ...
    var editFormURL = null;
    var loop = 0;
    while (!editFormURL) {
      editFormURL = e.range.offset(0,2).getValue(); // This will get the value from cell "C2".
      if (!editFormURL) {
        // Not ready yet, should we wait?
        if (loop++ < 10) {
          Utilities.sleep(2000); // sleep 2 seconds
        }
        else throw new Error( 'Gave up waiting.' );
      }
    }
    
    // If the script gets here, then it has retrieved a value for editFormURL.
    ...
    

    一个奖励问题:因为您正在使用getValues(),复数s,您正在检索二维信息数组。您没有看到问题,因为当您将这些值视为字符串时,javascript解释器将数组强制到您希望的字符串中。但它仍然是一个问题 - 如果您想要一个值,请使用getValue()

答案 1 :(得分:1)

获取正确的行,然后使用您的网址对该列进行硬编码:

var ss = SpreadsheetApp.openById("my-spreadsheet-id")
var sheet = ss.getSheets()[0];

var rowForLookup = e.range.getRow();
var columnOfUrl = 24; //Column X
var theUrl = sheet.getRange(rowForLookup, columnOfUrl).getValue();

答案 2 :(得分:1)

所以这段代码是我在实施你的建议后最终得到的。感谢Sandy Good和Mogsdad。

txtTotalSalary.Text = SASO.ToString();