根据非空单元格的数量复制可变范围

Copy a variable range depending on the number of non-empty cells

从 google sheets 宏中,我试图复制可变范围的单元格,这取决于每次非空单元格的数量。在下面的句子中:

spreadsheet.getRange ('Orders! 1: 30'). copyTo (spreadsheet.getActiveRange (), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

我需要一个变量,而不是数字“30”,该变量是根据同一 sheet 的第一列中占用的行数定义的。

我正在考虑使用 "for" 函数从单元格 I1 扫描第 I 列中的行,直到它找到一个空行(或不大于 0)。但我不确定该怎么做。


在#Iamblichus 和#Tedinoz 的帮助下,我能够推进代码,但现在出现了一个相关的类似问题。

我需要将所选范围粘贴到不同的选项卡中,但其中相同的变量不再识别相同的数量。这是我的代码:

function Test() {
  var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getSheetByName("Aux");

  spreadsheet.getRange('I3:I').createFilter();
  var criteria = SpreadsheetApp.newFilterCriteria().setHiddenValues(['0']).build();
  spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(9, criteria);

  var valuesI = spreadsheet.getRange("I1:I").getValues();
  var numRowsI = valuesI.filter(String).length; 
  var firstRow = 1;
  var firstCol = 1;
  var numCols = sheet.getLastColumn();
  var originRange = sheet.getRange(firstRow, firstCol, numRowsI, numCols); 

  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Hist_D'), true);
  spreadsheet.getActiveSheet().insertRowsBefore(sheet.getActiveRange().getRow(), numRowsI);
  spreadsheet.getRange('A1').activate();
  originRange.copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
  originRange.copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Aux'), true);
  spreadsheet.getRange('T35').activate();
  spreadsheet.getActiveSheet().getFilter().remove();  
}

"Hist_D"是一条记录,最新的数据加在最前面。我需要将可变数量的 X 行从 "Aux" 选项卡复制到 "Hist_D" 选项卡的第一行。但在此之前,我需要在 "Hist_D" 中添加 (insertRowsBefore) 相同数量的 X 行,这样旧信息就不会被覆盖。我现在的问题是如何在更改选项卡时将数量 X 保留在 numRowsI 变量中。

通过公式 .insertRowsBefore 插入的行数约为 100(第一个选项卡中的总行数),而应为 20 左右(第一个选项卡中的非空行数)。根据我的解释,由于某种原因,变量 numRowsI 在更改选项卡时发生变化。

支持@Mogsdad ref and AndyE before him,因为这个非常方便的方法。

var Bvals = ss.getRange("B1:B").getValues();

var Blast = Bvals.filter(String).length;

"Blast" 的值是 B 列中包含值的单元格的数量 - 隐含的假设是它是一个连续的范围。

如果您使用 getRange(row, column, numRows, numColumns) 定义范围,则将 "Blast" 替换为 "numrows"。

更新:

假设:

  • 对于要复制的每一行,您想要复制包含内容的所有列,而不仅仅是第 I 列。
  • 您想将此复制到另一个 sheet 的顶部,而不覆盖以前的数据。

你可以试试这个:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var originSheet = ss.getSheetByName("Aux");
  var destSheet = ss.getSheetByName("Hist_D");  
  var valuesI = originSheet.getRange("I1:I").getValues(); // As far as I can see, you want to check column I, not B
  var numRowsI = valuesI.filter(String).length;
  var firstRow = 1;
  var firstCol = 1;
  var numCols = originSheet.getLastColumn();
  var originRange = originSheet.getRange(firstRow, firstCol, numRowsI, numCols);  
  destSheet.insertRows(1, numRowsI);
  var destRange = destSheet.getRange(firstRow, firstCol, numRowsI, numCols);
  originRange.copyTo(destRange, SpreadsheetApp.CopyPasteType.PASTE_VALUES);
}

这里的主要任务是找到特定列中包含内容的最后一个单元格,这可以使用 this 来实现(假设中间没有空白单元格,考虑到您的问题,这似乎是这样的)。

为了不覆盖现有数据而必须添加到顶部 Hist_D 的空白行数等于从 Aux 复制的行数(即等于numRowsI)。您遇到问题是因为 getRange 是 Sheet class 的方法,而不是 Spreadsheet class.

的方法

希望对您有所帮助。