2

我正在尝试编写一个脚本,使我能够在唯一值的第一个计数实例之上添加一行。

例如。

    A
    German
    German
    German
    Italian
    Italian
    French
    French

运行脚本后,它应该类似于:

    A
    DE
    German
    German
    German
    IT
    Italian
    Italian
    FR
    French
    French

我所写的只是确定存在多少值:

function insertRowAbove() 
 {
 var report = SpreadsheetApp.getActive().getSheetByName('REPORT');

 var lang = report.getRange('A10:A').getValues();
 var positions = report.getRange('A10:A').getA1Notation();
 var DE = [];

 for (var i = 0; i < lang.length; i++)
 {
  if (lang[i] == 'German') 
  {
    DE++
    report.getRange('A1').setValue(DE);//now I know there are 3 German entries
  }
 }
}

我的问题:脚本是否有可能知道第一次出现的值的 A1notation 并在其上方添加一行?我感谢你任何明智的建议。

4

3 回答 3

2

以下作品(参见示例):

function insertRowAbove() {
 var report = SpreadsheetApp.getActive().getSheetByName('Insert Row Above');
 var values = report.getRange('B2:B').getValues();

 var prevVal = "null"; 
 var index = 1;
 while (index < values.length) {
   if (values[index].toString() != prevVal.toString()) {

     var header = 'unknown';
     if (values[index] == 'German')
       header = 'DE';
     else if (values[index] == 'Italian')
       header = 'IT';
     else if (values[index] == 'French')
       header = 'FR';

     report.insertRowBefore(index+1);
     report.getRange(index+1, 2).setValue(header);
     values = report.getRange('B2:B').getValues();
     index++;
   }
   prevVal = values[index];
   index++;
 }

}
于 2013-04-04T12:27:49.523 回答
2

您的具体问题是:

我的问题:脚本是否有可能知道第一次出现的值的 A1notation 并在其上方添加一行?

通过结合使用布尔值来指示您是否找到了您正在寻找的任何Range项目,以及几种方法,您可以获得第一次出现的 A1 表示法。

var column = 1; // this example is only using column A
var foundGerman = false;
var firstGerman = '';
...
if (lang[i] == 'German') {
  if (!foundGerman) {
    foundGerman = true;
    firstGerman = range.getCell(i, column).getA1Notation();
  }
  ...
}

之后,您将拥有包含“德语”的第一个单元格的 A1Notation。

但是,该函数insertRowsBefore()是一个Sheet方法,并且需要一个行号作为参数,而不是 A1Notation。因此,弄清楚第一个德国牢房的地址是什么是不必要的。

脚本

这是我的参赛作品!为了速度,明智的做法是使用尽可能少的应用程序脚本服务调用。在这个脚本中,所有的数据操作都是使用数组完成的,最终结果只写一次。

预计您将拥有超过三种您关心的语言,并且为了可维护性,语言查找由 Object 处理,iso639. (假设您使用的是ISO 639-1 语言代码。)因此,实际工作只需要 10 行代码!

function insertViaArray() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('REPORT');
  var values = sheet.getDataRange().getValues();
  var newValues = [];

  var iso639 = 
    {
      "German" : "DE",
      "Italian" : "IT",
      "French" : "FR"
    }

  var curLang = '';
  for (var i in values) {
    if (values[i][0] !== curLang) {
      curLang = values[i][0];
      newValues.push([iso639[curLang]]);
    }
    newValues.push([values[i][0]]);
  }
  sheet.getRange(1, 1, newValues.length, 1).setValues(newValues)
};

编辑脚本 V2

通过使用Array.splice()插入语言标签,我们可以进一步将代码减少到 8 行工作,并消除对并行newValues数组的需要。

function insertViaArrayV2() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('REPORT');
  var values = sheet.getDataRange().getValues();

  var iso639 = 
    {
      "German" : "DE",
      "Italian" : "IT",
      "French" : "FR"
    }

  var curLang = '';
  for (var i = 0; i < values.length; i++) {
    if (values[i][0] !== curLang) {
      curLang = values[i][0];
      values.splice(i, 0, [iso639[curLang]]);
    }
  }
  sheet.getRange(1, 1, values.length, 1).setValues(values)
};
于 2013-04-04T14:33:23.760 回答
1

这是一种有趣的练习,像往常一样,可能有很多方法可以让它发挥作用。

我不是假装我的方法更好,它只是不同,因此它可能值得在这里展示它;-)

function testFunction() {
  var sh = SpreadsheetApp.getActiveSheet();
  var data = sh.getRange('A10:A').getValues();
  var rowNum = 11;
  var previous = data[0][0];
  Logger.log(data)
 sh.insertRowBefore(10);
 sh.getRange(2,1).setValue(firstLetters(data[0][0]));
  for(n=1;n<data.length;++n){
  if(data[n][0].replace(/ /g,'')==previous.replace(/ /g,'')){
     previous = data[n][0] ; 
     ++rowNum ; 
     continue ; 
     }else if(firstLetters(data[n][0])){
     sh.insertRowBefore(rowNum+1);
     sh.getRange(rowNum+1,1).setValue(firstLetters(data[n][0]));
     ++rowNum
     previous = data[n][0]
     ++rowNum
     Logger.log(rowNum+'  '+firstLetters(data[n][0]))
     }else{
     break
     }
}
}

function firstLetters(name){
if (name==''){return false}
var str = name.toString().replace(/ /g,'').toUpperCase().substring(0,2);
if (str=='GE') {str='DE'};// handle german exception
if (str=='PO'){ str='PT'} ;//handle portuguese exception
return str;
}

在此处输入图像描述

于 2013-04-04T13:06:28.017 回答