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

时间:2016-08-08 02:25:14

标签: javascript google-apps-script google-sheets uppercase

我有一个电子表格,可以输入股票代码。我希望它们总是在所有大写中,无论它们是如何输入的。这似乎需要一些脚本,因为除非列的第二个副本存在,否则无法用函数执行此操作,这是不可接受的。< / p>

我有一个解决方案,有一个关键问题。代码如下:

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:我的麻烦似乎与数据验证有关,或与之相冲突。我试图大写的列由另一张纸上的值列表提供。如果该值先前以小写形式出现,然后我将数据验证应用于列,则脚本将不会将该值大写。但是,如果我从数据验证列表中选择适当的大写选择,然后以小写形式重新键入相同的值,则脚本将启动并进行大写。非常奇怪和混乱。我对这场冲突可能是错的,但那对我来说就是这样。

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

2 个答案:

答案 0 :(得分:2)

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

  

返回范围的左上角单元格的公式(A1表示法),,如果单元格为空或不包含公式,则返回空字符串。

代码应如下所示:

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)))

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

答案 1 :(得分:1)

  

所以,任何人都知道一种方法可以完全按照上面的代码进行操作,但是不要触摸单元格中的实际公式,只触及它们输出的文本?

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

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

    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始终返回'string',因此使用了range.getValue();