Google Sheet单元格输入触发App Script(onKeyUp)?实现城市前缀筛选
Google Sheets单元格输入触发脚本及城市前缀筛选方案
一、关于onKeyUp触发App Script的问题
Google Sheets没有原生的onKeyUp事件可以直接绑定到单元格输入(单元格的键盘交互事件并未暴露给App Script),但有两种可行替代方案:
方案1:使用onEdit简单触发器
适合不需要实时响应每一次按键输入的场景,当单元格编辑完成(失去焦点)时自动触发脚本:
- 无需额外授权,代码直接生效
- 触发时机为单元格内容确认后(如按回车、点击其他单元格)
方案2:结合HTML服务实现实时输入响应
如果需要每输入一个字符就触发筛选,可通过自定义侧边栏/对话框的输入框监听keyup事件,再联动修改Sheet的下拉列表:
- 需要手动打开侧边栏
- 能实现实时输入实时筛选的效果
二、修改筛选逻辑为“前缀匹配”
不管用哪种触发方式,核心是把原有的“包含匹配”改成“前缀匹配”,以下是两种方案的示例代码:
示例1:onEdit触发器实现前缀筛选
function onEdit(e) { // 指定触发筛选的目标列(比如第2列,即B列) if (e.range.getColumn() !== 2) return; const inputText = e.range.getValue().trim().toLowerCase(); const citySourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('城市列表'); // 获取所有非空城市数据 const allCities = citySourceSheet.getRange('A2:A').getValues().flat().filter(city => city !== ''); // 筛选以输入文本开头的城市(不区分大小写) const filteredCities = allCities.filter(city => city.toLowerCase().startsWith(inputText) ); // 更新目标单元格的下拉验证规则 const validationRule = SpreadsheetApp.newDataValidation() .requireValueInList(filteredCities, true) // true表示允许输入列表外的值,false则禁止 .setAllowInvalid(false) .build(); e.range.setDataValidation(validationRule); }
示例2:侧边栏实时前缀筛选
1. 编写App Script代码(GS文件)
// 打开城市筛选侧边栏 function showCityFilterSidebar() { const sidebarHtml = HtmlService.createHtmlOutputFromFile('CityFilterSidebar') .setTitle('城市前缀筛选'); SpreadsheetApp.getUi().showSidebar(sidebarHtml); } // 获取所有城市列表数据 function fetchAllCities() { const citySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('城市列表'); return citySheet.getRange('A2:A').getValues().flat().filter(city => city !== ''); } // 给指定单元格设置下拉列表 function updateCityDropdown(targetCellA1, filteredCities) { const activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const targetRange = activeSheet.getRange(targetCellA1); const validationRule = filteredCities.length > 0 ? SpreadsheetApp.newDataValidation().requireValueInList(filteredCities, true).build() : null; // 清空下拉规则 targetRange.setDataValidation(validationRule); }
2. 编写HTML侧边栏文件(命名为CityFilterSidebar.html)
<!DOCTYPE html> <html> <body style="padding: 1rem;"> <div> <label>输入城市前缀:</label> <input type="text" id="prefixInput" style="width: 100%; margin: 0.5rem 0;"> </div> <div> <label>目标单元格(如B1):</label> <input type="text" id="targetCell" value="B1" style="width: 100%; margin: 0.5rem 0;"> </div> <script> let allCities = []; // 页面加载时获取所有城市数据 window.addEventListener('load', async () => { allCities = await google.script.run.withSuccessHandler(data => data).fetchAllCities(); }); // 监听输入框keyup事件,实时筛选 document.getElementById('prefixInput').addEventListener('keyup', async () => { const inputText = document.getElementById('prefixInput').value.trim().toLowerCase(); const targetCell = document.getElementById('targetCell').value; // 前缀匹配筛选 const filtered = allCities.filter(city => city.toLowerCase().startsWith(inputText)); // 更新下拉列表 await google.script.run.updateCityDropdown(targetCell, filtered); }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者bsbak
相关产品推荐
相关产品推荐

