自动将 Google 表格中单元格内容大写的脚本?

Script to automatically capitalize contents of a cell in Google Sheets?

我有一个点差sheet,可以输入股票代码。我希望它们始终全部大写,无论它们是如何输入的。这似乎需要一些脚本,因为除非存在该列的第二个副本,否则无法使用函数执行此操作,这是不可接受的。

我有一个有效的解决方案,但存在一个严重问题。代码如下:

function OnEdit(e) {
   var ss = e.source.getActiveSheet(),
       sheets = ['Trades', ''],
       ind = sheets.indexOf(ss.getName());
   if (ind === 0 && e.range.rowStart > 1 && e.range.columnStart >= 1 ) {
       e.range.setValue(e.value.toUpperCase());
   }
}

效果很好,我可以根据需要添加任意数量的标签和列来设置格式。不幸的是,它还大写了单元格内的 FORMULAS,这破坏了使用 importhtml() 函数的公式,因为它大写了所请求的 URL。

那么,有人知道一种方法可以完全按照上面的代码执行操作,但不触及单元格内的实际公式,只触及它们输出的文本吗?

编辑:感谢@ocordova 的评论,我认为我有一些东西可以很好地完成这项工作。不幸的是,它的行为很奇怪……它在某些列上部分起作用,而在其他列上则完全不起作用。这是我当前的代码(为清楚起见,与之前的代码略有不同):

function onEdit(e){ 
   var activeSheet = e.source.getActiveSheet(),
       sheets = ['NEW Trades', ''],
       sheetIndex = sheets.indexOf(activeSheet.getName());
  if (sheetIndex === 0 && e.range.rowStart > 1 && e.range.columnStart >0  && e.range.getFormula() == '') {
    e.range.setValue(e.value.toUpperCase());
  }
}

任何人都知道为什么某些列中的某些单元格会按预期大写,而那些相同列中的其他单元格不会,而其他列在任何地方根本不会大写?

编辑 2:我的问题似乎与数据验证有关或与之冲突。我试图大写的列由另一个 sheet 上的值列表提供。如果该值之前以小写形式存在,然后我对该列应用了数据验证,脚本将不会将该值大写。但是,如果我 select 来自数据验证列表的适当的大写 selection,然后以小写形式重新键入相同的值,脚本会启动并大写。非常奇怪和混乱。我对冲突的看法可能是错误的,但这对我来说就是这样。

编辑 3:它与数据验证无关,因为它在根本没有验证的简单列上的行为方式相同。如果我之前输入的值已经是小写的,那么再次输入小写将不会激活脚本。但是,如果我以大写形式键入值,然后以小写形式重新键入,脚本会将其大写。也许一些奇怪的情况与脚本何时被触发有关...?

如果单元格包含公式不想大写,可以使用方法getFormula()检查单元格是否包含公式

Returns the formula (A1 notation) for the top-left cell of the range, or an empty string if the cell is empty or doesn't contain a formula.

代码应如下所示:

if (ind === 0 && e.range.rowStart > 1 && e.range.columnStart >= 1  && e.range.getFormula() == '') {
  e.range.setValue(e.value.toUpperCase());
}

编辑:

如果我没听错的话,您输入的是完全相同的值,例如:如果单元格中的值为 México,并且您删除了全部或部分字符并立即再次键入 México,在这种情况下,旧值和新值相同,并且不会触发 OnEdit()。另一个例子是,如果您更改值的格式,那是另一种类型的事件。

如果您想知道该事件是如何被考虑的,您可以使用 installable on change trigger:

function triggerOnChange(e) {
  MailApp.sendEmail('john.doe@gmail.com', 'Testing triggerOnChange', JSON.stringify(e));
}

然后在脚本编辑器菜单中:Resources -> Current Project Triggers -> Add a new trigger -> ['triggerOnChange', 'From spreadsheet', 'On change']

关于如何更改公式结果的大小写,我认为@Rubén 的想法是正确的,但它只有在公式的第一个字符中包含 UPPER() 时才有效,而且因为你是使用公式 IMPORTHTML() 使用 UPPER() 会破坏它,也许其他一些函数如数组公式,除非你使用 INDEX():

=INDEX(UPPER(IMPORTHTML(url, query, index)))

另一个选项可能是正则表达式,但考虑到所有组合,我认为这有点冒险。

So, anyone know a way to do exactly what the above code does, but not touch the actual formulas inside the cells, only the text that they output?

考虑对 OP 方法稍作更改:不是将任何情况下的所有单元格内容都大写,而是根据以下条件进行大写:

  1. 如果单元格值(包括包含常量或公式的单元格值)不是字符串,则不执行任何操作。
  2. 如果单元格值为字符串
    • 并且单元格内容是常量,那么直接从脚本中改变大小写。
    • 单元格内容为公式,则将原公式嵌套在内置函数UPPER.

示例:

function onEdit(e) {
  var range = e.range;
  var value = range.getValue();
  var sheet = range.getSheet();
  var sheetName = sheet.getName();
  if (sheetName === 'Sheet1' && 
      range.getRow() > 1 && 
      range.getColumn() > 1 && 
      typeof value === 'string') {
    if(!range.getFormula()) {
      range.setValue(value.toUpperCase());
    } else {
      if(range.getFormula().substring(0,6).toUpperCase() == '=UPPER') {
        return;
      } else {
        range.setFormula('=UPPER(' + range.getFormula().substring(1) + ')');
      }
    }
  }
}

备注:

  • 为简单起见,未包含 ind 数组。
  • typeof e.value 总是 returns 'string',因此使用 range.getValue();