You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Apps Script:选择行号无法填充HTML输入框,报Uncaught eval错误

问题修复方案

核心问题分析

  1. HTML语法错误:select标签的id="rowNum"与onchange属性之间无空格,导致浏览器无法正确解析事件;同时重复绑定onchange(标签内+script内)引发冲突。
  2. 参数传递失效:调用google.script.run.setValue()时未传入选中行号,服务端函数无法获取有效参数。
  3. 前后端逻辑混淆:服务端模板直接调用依赖客户端localStorage的headerRowToInsert,但服务端无法读取客户端存储数据。
  4. 表格取值逻辑错误:getRange(e,1,LastRow,LastCol)会从第e行开始取LastRow行数据,不符合仅获取目标行的需求。
  5. 字段匹配逻辑缺陷:找到第一个匹配字段就返回整行数组,未正确收集所有匹配值。

修复后的代码

1. export_getRow.html(行号选择侧边栏)

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>

  <body>
    <p>Header row</p>  
    <select name="rowNum" id="rowNum" style="width:280px;height:30px;">
        <option value="none" selected>Please select a row</option>
        <?!= options ?>
    </select>

    <p>Select the row with the field title of the data to export.</p>

    <button onclick='prevPage()'>prev</button>
    <button onclick='nextPage()'>next</button>
    <button onclick='insertData()'>insert Data</button>

    <script>
      const headerRow = document.getElementById("rowNum");
      
      // 统一通过script绑定onchange事件,传递选中行号
      headerRow.onchange = function(){
        const selectedRow = headerRow.value;
        console.log(selectedRow);
        localStorage.setItem("selectRowNum", selectedRow);
        google.script.run.setValue(selectedRow);
      }      

      const valueToInsert = localStorage.getItem("selectObjToInsert");  
      console.log(valueToInsert);   

      function prevPage() {
        google.script.run.getSheetListforExport();
      }

      function insertData() {
        google.script.run.salesforceEntryPoint(valueToInsert, headerRow.value);
      }  

      function nextPage() {
        const selectedRow = headerRow.value;
        if(selectedRow !== "none"){
          google.script.run.setValue(selectedRow);
        } else {
          alert("Please select a row first!");
        }
      }
    </script>
  </body>
</html>

2. export_MatchingField.html(匹配字段输入框侧边栏)

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <!-- 直接使用服务端传入的匹配后数据 -->
    <? for(var i=0; i<value.length; i++){ ?>
    <div style="margin-top:5px;">
      <!-- 给input设置唯一ID,避免重复 -->
      <input type="text" id="textValue_<?=i?>" name='textValue' value="<?= value[i] ?>">
    </div>
    <? } ?>

    <button onclick='prevPage()'>Prev</button>

    <script>
      const textBoxes = document.querySelectorAll('[id^=textValue]');
      let textToWrite;
      for(let i = 0; i < textBoxes.length; i++){
        textToWrite = textBoxes[i].value;
        console.log(textToWrite);
      }

      function prevPage() {
        google.script.run.getRowNum();
      }    
    </script>
 </body>
</html>

3. matchField.gs(服务端逻辑)

function matchingField(selectedRow){
  // 先校验参数有效性
  if(!selectedRow || selectedRow === "none"){
    return [];
  }

  const ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const lastCol = ss.getLastColumn();
  // 仅获取选中行的整行数据(第selectedRow行,1行,所有列)
  const rowData = ss.getRange(selectedRow, 1, 1, lastCol).getValues()[0]; 

  const url = 'example.com';
  const response = UrlFetchApp.fetch(url, getUrlFetchOptions());
  const json = response.getContentText();
  const data = JSON.parse(json);
  const dataSobjectsField = data.fields;

  // 提取接口返回的字段名数组
  const sfFieldNames = dataSobjectsField.map(field => field.name);

  // 收集当前行中与接口字段匹配的值
  const matchedValues = rowData.filter(cellValue => sfFieldNames.includes(cellValue));
  
  return matchedValues;
}

function setValue(selectedRow){
  // 调用匹配函数获取结果
  const matchedValues = matchingField(selectedRow);
  const html = HtmlService.createTemplateFromFile('export_MatchingField');
  // 将匹配结果传入模板
  html.value = matchedValues;
  const sidebar = html.evaluate()
        .setTitle('DG Connector')
        .setWidth(400)
        .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi().showSidebar(sidebar);
}

额外说明

  • 移除了标签内重复的onchange绑定,统一通过script处理事件,避免冲突。
  • 修正了表格取值范围,仅获取选中行的数据,优化匹配逻辑返回所有匹配值。
  • 模板不再依赖客户端localStorage,通过服务端直接传递匹配后的数据,解决前后端数据隔离问题。
  • 给input设置唯一ID,避免DOM元素ID重复引发的潜在问题。

内容的提问来源于stack exchange,提问作者whytili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 02:06:52