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

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;
}

补充:你现有代码里的两个小问题

在使用这两个函数前,得先修复原代码里的两处细节问题,不然会导致功能异常:

  1. 处理二维数组的最小值/最大值
    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);
    
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:27:33