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

Parcel下拉框联动获取Google Sheets对应最大Status值异常求助

问题:选择Parcel下拉框后,Status下拉框无法自动填充对应最大状态值

我有一个包含「Statuses」工作表的Google表格,同时用Apps Script开发了一个Web表单。需求是用户选择Parcel下拉框后,自动从Google表格中获取该Parcel对应的最大状态值,并填充到Status下拉框中。但实际测试时,选择表格中存在的Parcel选项后,Status下拉框并未填充对应的最大状态值(比如「Negotiating」)。


当前使用的Apps Script代码

function doGet(e) {
  var htmlOutput = HtmlService.createTemplateFromFile('DependentSelect');
  var subs = getDistinctSubstations();
  htmlOutput.message = '';
  htmlOutput.subs = subs;
  return htmlOutput.evaluate();
}

function doPost(e) {
  var parcel = e.parameter.parcel.toString();
  var substation = e.parameter.substation.toString();
  var comment = e.parameter.comment.toString();
  var status = e.parameter.status.toString();
  var date = new Date();
  
  addRecord(comment, parcel, date);
  addToStatuses(parcel, status, date);
  
  var htmlOutput = HtmlService.createTemplateFromFile('DependentSelect');
  var subs = getDistinctSubstations();
  htmlOutput.message = 'Record Added';
  htmlOutput.subs = subs;
  return htmlOutput.evaluate(); 
}

function getStatusOptions(parcel) {
  var maxStatus = getMaxStatusForParcel(parcel);
  var options = ["", "Outreach", "Negotiating", "Signed"];
  var dropdownHTML = options.map(option => {
    if (option === maxStatus) {
      return `<option value="${option}" selected>${option}</option>`;
    } else {
      return `<option value="${option}">${option}</option>`;
    }
  }).join("");
  
  return dropdownHTML;
}

function getDistinctSubstations() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var rdSheet = ss.getSheetByName("Raw Data"); 
  var subs = rdSheet.getRange('O4:O' + rdSheet.getLastRow()).getValues().flat().filter((sub, index, self) => self.indexOf(sub) === index && sub !== "");
  return subs;
}

function getParcels(substation) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var rdSheet = ss.getSheetByName("Raw Data"); 
  var lastRow = rdSheet.getLastRow();
  var substationValues = rdSheet.getRange('O4:O' + lastRow).getValues().flat();
  var parcelValues = rdSheet.getRange('A4:A' + lastRow).getValues().flat();
  var filteredParcels = [];
  
  for (var i = 0; i < substationValues.length; i++) {
    if (substationValues[i] === substation && parcelValues[i]) {
      filteredParcels.push(parcelValues[i]);
    }
  }
  
  return filteredParcels.filter(parcel => parcel !== "");
}

// 原逻辑存在问题的函数
function getMaxStatusForParcel(parcel) {
  var url = 'https://docs.google.com/spreadsheets...';
  var ss = SpreadsheetApp.openByUrl(url);
  var statusSheet = ss.getSheetByName("Statuses");
  var lastRow = statusSheet.getLastRow();
  var parcelValues = statusSheet.getRange('A4:A' + lastRow).getValues().flat();
  var statusValues = statusSheet.getRange('B4:B' + lastRow).getValues().flat();
  
  for (var i = 0; i < parcelValues.length; i++) {
    if (parcelValues[i] === parcel) {
      return statusValues[i];
    }
  }
  
  return ""; // 未找到匹配Parcel时返回空字符串
}

function addRecord(comment, parcel, date) {
  var url = 'https://docs.google.com/spreadsheets....';
  var ss = SpreadsheetApp.openByUrl(url);
  var dataSheet = ss.getSheetByName("Comments");
  var formattedDate = Utilities.formatDate(new Date(date), Session.getScriptTimeZone(), "MM/dd/yy");
  dataSheet.appendRow([parcel, comment, formattedDate]);
}

function addToStatuses(parcel, status, date) {
  var url = 'https://docs.google.com/spreadsheets....';
  var ss = SpreadsheetApp.openByUrl(url);
  var statusSheet = ss.getSheetByName("Statuses");
  var formattedDate = Utilities.formatDate(new Date(date), Session.getScriptTimeZone(), "MM/dd/yy");
  statusSheet.appendRow([parcel, status, formattedDate]);
}

function getUrl() {
  var url = ScriptApp.getService().getUrl();
  return url;
}

HTML代码

<!DOCTYPE html>
<html>
<head>
  <base target="_top">
  <style>
    body {
      font-size: 15px;
      background-color: #f0f8ff; /* 浅蓝色背景 */
    }
    .container {
      width: 50%;
      margin: 0 auto; /* 水平居中容器 */
      text-align: center; /* 容器内内容居中 */
      padding-top: 20px; /* 顶部留白 */
    }
    h1 {
      margin-top: 20px; /* 头部图片与标题间距 */
      font-size: 20px;
    }
    select {
      width: 100%; /* 下拉框占满容器宽度 */
      font-size: 15px; /* 下拉框字体大小 */
    }
    textarea {
      height: 80px;
      font-size: 15px; /* 文本域字体大小 */
    }
    input[type="submit"] {
      font-size: 15px; /* 提交按钮字体大小 */
    }
    .submit-message {
      color: red;
      font-size: 15px;
    }
  </style>
  <script>
    function getParcels(substation) {
      google.script.run.withSuccessHandler(function(parcels) {
        var parcelDropdown = document.getElementById("parcel");
        parcelDropdown.innerHTML = "";
        var option = document.createElement("option");
        option.value = "";
        option.text = "";
        parcelDropdown.appendChild(option);
        parcels.forEach(function(parcel) {
          var option = document.createElement("option");
          option.value = parcel;
          option.text = parcel;
          parcelDropdown.appendChild(option);
        });
      }).getParcels(substation);
    };
    
    function getMaxStatusForParcel(parcel) {
      var statusDropdown = document.getElementById("status");
      if (!parcel) {
        statusDropdown.innerHTML = '<option value=""></option>';
        return;
      }

      google.script.run.withSuccessHandler(function(maxStatus) {
        var options = ["", "Outreach", "Negotiating", "Signed"];
        var dropdownHTML = options.map(option => {
          if (option === maxStatus) {
            return `<option value="${option}" selected>${option}</option>`;
          } else {
            return `<option value="${option}">${option}</option>`;
          }
        }).join("");
        
        statusDropdown.innerHTML = dropdownHTML;
      }).getStatusOptions(parcel);
    }
    
    function validateForm() {
      var parcel = document.getElementById("parcel").value;
      var substation = document.getElementById("substation").value;
      var comment = document.getElementById("comment").value;
      var status = document.getElementById("status").value; // 获取状态值
      
      if (!parcel || !substation || !comment || !status) {
        document.getElementById("submit-message").innerText = "所有字段为必填项。";
        return false; // 阻止表单提交
      }
      
      return true; // 允许表单提交
    }
  </script>  
</head>
<body>
  <div class="container">
    <img src="https://i.imgur.com/16QsZja.png" alt="Header Image" style="width: 100%; max-width: 200px;">
    
    <h1>评论提交表单</h1>
    
    <? var url = getUrl(); ?>
    <form method="post" action="<?= url ?>" onsubmit="return validateForm()">
      <label>变电站</label><br>
      <select name="substation" id="substation" onchange="getParcels(this.value)">
        <option value=""></option>
        <? for (var i = 0; i < subs.length; i++) { ?>
          <option value="<?= subs[i] ?>"><?= subs[i] ?></option>
        <? } ?>
      </select><br><br>
      
      <label>Parcel</label><br>
      <select name="parcel" id="parcel" onchange="getMaxStatusForParcel(this.value)"></select><br><br>
      
      <label>状态</label><br>
      <select name="status" id="status"></select><br><br>
      
      <label>评论</label><br>
      <textarea name="comment" id="comment"></textarea><br><br>
      
      <input type="submit" name="submitButton" value="提交" /> 
      <span id="submit-message" class="submit-message"></span>      
    </form>
  </div>
</body>
</html>

问题分析与修复方案

核心问题

原getMaxStatusForParcel函数逻辑错误:找到第一个匹配的Parcel就直接返回对应的Status,而不是遍历所有匹配记录并筛选出优先级最高的状态值。

修复后的getMaxStatusForParcel函数

function getMaxStatusForParcel(parcel) {
  var url = 'https://docs.google.com/spreadsheets...'; // 替换为你的表格URL
  var ss = SpreadsheetApp.openByUrl(url);
  var statusSheet = ss.getSheetByName("Statuses");
  // 精准获取A4到最后一行的有效数据(排除前3行表头)
  var data = statusSheet.getRange(4, 1, statusSheet.getLastRow() - 3, 2).getValues();
  
  // 定义状态优先级,数值越高优先级越高
  var statusPriority = {
    "": 0,
    "Outreach": 1,
    "Negotiating": 2,
    "Signed": 3
  };
  var maxPriority = 0;
  var maxStatus = "";

  for (var i = 0; i < data.length; i++) {
    var currentParcel = data[i][0];
    var currentStatus = data[i][1];
    // 匹配Parcel且当前状态优先级高于已记录的最高优先级时更新结果
    if (currentParcel === parcel && statusPriority[currentStatus] > maxPriority) {
      maxPriority = statusPriority[currentStatus];
      maxStatus = currentStatus;
    }
  }
  
  return maxStatus;
}

额外检查点

  1. 表格权限:确保Google表格已设置正确的共享权限,允许Apps Script访问该表格
  2. 值匹配问题:检查Parcel值的大小写、空格是否完全一致(比如表格中是「Parcel_001」,表单中是「parcel_001」会导致匹配失败)
  3. 数据范围:使用getRange(4,1,statusSheet.getLastRow()-3,2)替代原范围获取方式,避免包含空行导致的无效数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:57:03