尝试使用宏制作脚本-代码太长

时间:2019-01-31 15:10:54

标签: google-sheets

首先,我必须说,我对Google App脚本的了解几乎为零。我尝试使用宏实用程序创建脚本,但是生成的代码太长。如果有人可以帮助我简化此代码,我将不胜感激。我在下面指出了主题的参数:

  • 我在电子表格中大约有50个标签(表格),尽管它们可以更多。 (简而言之,the spreadsheet that is attached有5个标签,其内容(简而言之,是相同的。)
  • 每个标签都包含单元格B8:L17中的数据(11列和10行数据)。
  • 在名为“索引”的选项卡上,是50个选项卡的名称。选项卡的名称必须以B2开头。在一个标签名和下一个标签名之间有9个空行。 (以上所有内容我都能够解决。)

我想做的-使用“间接”公式-如下: -将工作表1的数据复制到C2:M11的索引中。 -将工作表2上的数据复制到C12的索引:M21。 -将工作表3上的数据复制到C22:M31中的索引。 -将表4的数据复制到C32:M41的索引中。 -将工作表5的数据复制到C42:M51的索引中。 -等等。

感谢您的关注。

function INDIRECT() {
var s = SpreadsheetApp.getActive();
s.getRange("c2").setFormula('=INDIRECT("\'"&Index!b2&"\'!b8:l17")');
s.getRange("c2").offset(10, 0).activate();
s.getCurrentCell().offset(-10, 0).copyTo(s.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
s.getCurrentCell().offset(10, 0).activate();
s.getCurrentCell().offset(-20, 0).copyTo(s.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
s.getCurrentCell().offset(10, 0).activate();
s.getCurrentCell().offset(-30, 0).copyTo(s.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
s.getCurrentCell().offset(10, 0).activate();
s.getCurrentCell().offset(-40, 0).copyTo(s.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
}

1 个答案:

答案 0 :(得分:0)

在OP需要填充一个主片与其他片材的内容。

以下代码假定工作表的名称已填充在B列中(根据OP电子表格)。

等效的query公式(例如,在单元格C3中)如下所示:
 =query(Funda!$B$8:$L$17;" Select * ")

此代码不会产生自定义公式。这是可能只运行一次,通过主片的列B循环,并插入适当的查询到列C的基础上,在列B中列出的表名称的代码可能只运行一次的程序。除非有电子表格中的布局的变化,片或更多片相加,由代码插入查询公式将更新主片上的子片的所有更改。

function so54463600() {

  // setup spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var mastername = "Master"; // Change this sheet name to whatever you want
  var sheet = ss.getSheetByName(mastername);

  // The sheet data range
  var datarange = "$B$8:$L$17";

  // set the data and number of sheets in Column B
  var Bvals = sheet.getRange("B1:B").getValues();
  var Blast = Bvals.filter(String).length;
  var lastRow = sheet.getLastRow();
  //Logger.log("DEBUG: the last row = "+lastRow);//DEBUG

  // loop through the rows of column B
  for (var x = 0; x < lastRow; x++) {

    // action if the cell has contents
    if (Bvals[x][0].length != 0) {

      // Logger.log("DEBUG: x = "+x+", Value = "+Bvals[x][0]+", length: "+Bvals[x][0].length);//DEBUG

      // sample query: =query(Funda!$B$8:$L$17;" Select * ")
      var formula = "=query(" + Bvals[x][0] + "!" + datarange + ";" + '"' + " Select * " + '")';
      // Logger.log("DEBUG: the formula is "+formula);//DEBUG

      // Location to set query formula
      Logger.log("target range:" + sheet.getRange(x + 1, 3).getA1Notation());

      // set the formula
      sheet.getRange(x + 1, 3).setFormula(formula);
    }
  }
}

<强> REVISION 2019年2月4日
更新表名称编程

电子表格中的页数可以为50个或更多。表名称可以更改,片材可以被添加或删除。因此,为了保证在主片上示出的数据是完整和准确的,理想的是片材的名称来编程插入,而不是手动。

此修订版包含一个新的子例程buildsheetnames,并对原始代码进行了一些更改。认为这是一个完整的取代,而不是一个简单的附加组件。

采购表名称
片材名称与getSheets(),然后getName()
首先获得 用户按照适合他们的屏幕顺序组织工作表;只列出到“主”片材的片材权将被包括在由该例程中显示的名称。

包含用户定义的变量startingsheetNumber,以定义要在“主”列表上显示的第一张工作表。这是通过从左至右,开始计数为零计数的所有工作表获得。所述第一片材的“主”正确的计数值应分配给该变量。片材到的“主”右侧的其余部分将被自动包含。

function so54463600mk2() {

  // setup spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var mastername = "Master";
  var sheet = ss.getSheetByName(mastername);

  // The sheet data range
  var datarange = "$B$8:$L$17";

  // select the existing sheet data and clear the contents
  // do this in case a sheet is added or deleted; minimize chance of not detecting an error.
  var lastRow = sheet.getLastRow();
  var lastColumn = sheet.getLastColumn();
  //Logger.log("last row = "+lastRow+", last Column: "+lastColumn);
  var masterrange = sheet.getRange(2, 2, lastRow - 1, lastColumn - 1);
  masterrange.clear();


  // update the sheet names in column B
  // run the sub-routine buildsheetnames
  buildsheetnames(mastername);


  // set the data and number of sheets in Column B
  var Bvals = sheet.getRange("B1:B").getValues();
  var Blast = Bvals.filter(String).length;
  var lastRow = sheet.getLastRow();
  //Logger.log("DEBUG: the last row = "+lastRow);//DEBUG

  // loop through the rows of column B
  for (var x = 0; x < lastRow; x++) {

    // action if the cell has contents
    if (Bvals[x][0].length != 0) {

      // Logger.log("DEBUG: x = "+x+", Value = "+Bvals[x][0]+", length: "+Bvals[x][0].length);//DEBUG

      // sample query: =query(Funda!$B$8:$L$17;" Select * ")
      //var formula = "=query(" + Bvals[x][0] + "!"+datarange+";"+'"'+" Select * "+'")';
      var formula = "=query(" + "'" + Bvals[x][0] + "'!" + datarange + ";" + '"' + " Select * " + '")';
      // Logger.log("DEBUG: the formula is "+formula);//DEBUG

      // Location to set query formula
      Logger.log("target range:" + sheet.getRange(x + 1, 3).getA1Notation());

      // set the formula
      sheet.getRange(x + 1, 3).setFormula(formula);
    }
  }
}

function buildsheetnames(mastername) {

  // setup spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(mastername);

  // move the curcor to cell B2
  var row = 2;
  var column = 2;
  sheet.getRange(2, 2).activate();

  // get the list of sheets
  var sheetlist = ss.getSheets();
  // Logger.log("DEBUG: Number of sheets: "+sheetlist.length);//DEBUG

  // Displaying Sheet names on the master sheet
  // Instructions:
  // 1 - View the spreadsheet with sheets laid out at the bottom of the screen
  // 2 - Move the sheets into the order that you want; 
  // 2a - Sheets to the left of "Master" (or whatever sheet you define as "mastername") wouldn't be included in the sheet names written onto Master
  // 2b - Only the names of those sheets to the right of "Master" will be displayed.
  // 3 - Count ALL the sheets, from left to right of screen. The first sheet will be zero, the second sheet will be one, and so on. 
  // 4 - Stop when you reach the first sheet that you want the name displayed on Master
  // 5 - Update the count value for that sheet to the variable 'startingsheetNumber'.
  // 6 - Note: the variable "sheetrowseparation" is the number of rows between each name; 
  // 6a - This is the same as the number of data rows on each data sheet. 
  // 6b - If the number of data rows ever changes, then you can change this variable.
  var startingsheetNumber = 6;
  var sheetrowseparation = 10;

  // loop through the sheets
  if (sheetlist.length > 1) {

    for (var i = startingsheetNumber; i < sheetlist.length; i++) {
      //Logger.log("DEBUG: Sheet#: "+i+", Sheet name: "+sheetlist[i].getName());//DEBUG
      sheet.getRange(row, column).setValue(sheetlist[i].getName());
      row = row + sheetrowseparation;
    }
  }
  return;
}