Google Apps Script中ROUNDDOWN()与ROUNDUP()函数的替代方案问询
在Google Apps Script中替代ROUNDDOWN()和ROUNDUP()的方案
你说得没错,JavaScript原生的Math对象并没有直接对应Google Sheets里ROUNDDOWN()和ROUNDUP()的函数——尤其是当你需要处理负数小数位数(也就是向高位取整,比如到百位、千位这类场景)时,必须自己实现自定义函数来匹配Sheets的功能。
我帮你写了两个完美适配需求的自定义函数,直接加到你的代码里就能用:
// 完全匹配Google Sheets ROUNDDOWN()函数的行为 function rounddown(value, decimals) { const factor = Math.pow(10, decimals); // 负数场景也能匹配Sheets逻辑:比如ROUNDDOWN(-1.2, 0)返回-2,Math.floor正好符合 return Math.floor(value * factor) / factor; } // 完全匹配Google Sheets ROUNDUP()函数的行为 function roundup(value, decimals) { const factor = Math.pow(10, decimals); // 负数场景适配:ROUNDUP(-1.2, 0)返回-1,Math.ceil正好符合预期 return Math.ceil(value * factor) / factor; }
补充:你现有代码里的两个小问题
在使用这两个函数前,得先修复原代码里的两处细节问题,不然会导致功能异常:
处理二维数组的最小值/最大值
range.getValues()返回的是二维数组(即使是单列范围),直接用Math.min(data)会得到NaN。需要先把数组扁平化并过滤非数值内容:const flatData = data.flat().filter(val => typeof val === 'number' && !isNaN(val)); const minVal = Math.min(...flatData); const maxVal = Math.max(...flatData);Chart构建时的语法错误
chart.modify().build缺少括号,应该是build(),否则不会生成新的图表对象:chart = chart.modify() .setOption('vAxis.minValue', minVal) .setOption('vAxis.maxValue', maxVal) .build(); // 这里要加括号
修改后的完整代码
把这些调整整合后,你的最终代码应该是这样的:
// 替代Google Sheets ROUNDDOWN() function rounddown(value, decimals) { const factor = Math.pow(10, decimals); return Math.floor(value * factor) / factor; } // 替代Google Sheets ROUNDUP() function roundup(value, decimals) { const factor = Math.pow(10, decimals); return Math.ceil(value * factor) / factor; } function c_ScaleVerticalAxis(sheetName, chartTitle, rangeA1) { // 作者:Max Hugen // 日期:2021-08-09 // 用途:修改垂直轴的最小值与最大值以适配数值数据 // 参数:数值的A1样式范围,例如 "C6:C" const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName(sheetName); const range = sheet.getRange(rangeA1); const data = range.getValues(); const chart = c_GetChartByTitle(sheetName, chartTitle); if (!chart) { console.log(`未找到标题为${chartTitle}的图表`); return; } var margin = 0.1; // 数据最小值/最大值上下的边距 var decPlaces = 0; // 扁平化数组并过滤有效数值 const flatData = data.flat().filter(val => typeof val === 'number' && !isNaN(val)); if (flatData.length === 0) { console.log("指定范围内无有效数值"); return; } var minVal = Math.min(...flatData); if (minVal > 100000) { decPlaces = -5; } else if (minVal > 10000) { decPlaces = -4; } else if (minVal > 1000) { decPlaces = -3; } else if (minVal > 100) { decPlaces = -2; } else { decPlaces = -1; } minVal = rounddown(minVal*(1-margin), decPlaces); var maxVal = Math.max(...flatData); if (maxVal > 100000) { decPlaces = -5; } else if (maxVal > 10000) { decPlaces = -4; } else if (maxVal > 1000) { decPlaces = -3; } else if (maxVal > 100) { decPlaces = -2; } else { decPlaces = -1; } maxVal = roundup(maxVal*(1+margin), decPlaces ); chart = chart.modify() .setOption('vAxis.minValue', minVal) .setOption('vAxis.maxValue', maxVal) .build(); // 修复此处的括号 sheet.updateChart(chart); } function c_GetChartByTitle(sheetName, chartTitle) { // 作者:Tanaike // 日期:约2020年11月 // 用途:返回图表对象 const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName(sheetName); if (!sheet) return null; const charts = sheet.getCharts(); for (let i = 0; i < charts.length; i++) { var chart = charts[i]; if (chart.getOptions().get("title") == chartTitle) { return chart; } } return null; }
这样调整后,你的代码就能完美实现和Google Sheets原生ROUNDDOWN()、ROUNDUP()一致的取整效果,同时修复了数组处理和图表构建的问题。
内容的提问来源于stack exchange,提问作者maxhugen
相关产品推荐
相关产品推荐

