在第一个计算实例上方添加一行 - Google电子表格

时间:2013-04-04 10:21:21

标签: google-apps-script google-sheets

我正在尝试编写一个脚本,这样我就可以在第一个计算的唯一值实例上面添加一行。

例如

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

我的问题: 脚本是否可以知道第一次出现的值的注释并在其上方添加一行?我感谢你提出的任何建议。

3 个答案:

答案 0 :(得分:2)

以下作品(见EXAMPLE):

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

}

答案 1 :(得分:2)

您的具体问题是:

  

我的问题:脚本是否可以知道。的注释   第一次出现一个值并在它上面添加一行?

通过使用布尔值的组合来指示您是否找到了您要查找的项目的任何,以及几个Range方法,您可以获得第一次出现。

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。因此,弄清楚第一个德国细胞的地址是不必要的。

脚本

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

预计您将拥有超过三种语言,并且为了可维护性,语言查找由对象iso639处理。 (假设您正在使用ISO 639-1 Language Codes。)因此,实际工作只需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)
};

答案 2 :(得分: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;
}

enter image description here