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

时间:2019-11-15 12:12:37

标签: google-apps-script google-sheets google-sheets-api google-sheets-macros

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

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

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

我正在考虑使用“ 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”是在顶部添加最新数据的记录。我需要将“ Aux”选项卡中可变数量的X行复制到“ Hist_D”选项卡的第一行。但是在此之前,我需要在“ Hist_D”中添加(insertRowsBefore)相同数量的X行,以便不会覆盖旧信息。我现在的问题是,更改制表符时如何将X保留在numRowsI变量中。

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

2 个答案:

答案 0 :(得分:1)

使用这种非常方便的方法,可以支持@Mogsdad ref和AndyE before him

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

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

“ Blast”的值是B列中包含值的单元格数-隐式假定它是连续范围。

如果您使用getRange(row, column, numRows, numColumns)定义范围,则用“爆炸”代替“数字”。

答案 1 :(得分:1)

更新:

假设:

  • 对于要复制的每一行,您要复制所有包含内容的列,而不仅仅是I列。
  • 您希望将其复制到另一张纸的顶部,而不会覆盖以前的数据。

您可以尝试使用此功能:

Javascript Reader

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

为了不覆盖现有数据,必须添加到顶部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); } 的空白行数等于从Hist_D复制的行数(即等于{{ 1}})。您遇到了问题,因为Aux是Sheet类的方法,而不是Spreadsheet类的方法。

我希望这会有所帮助。