Reputation: 36656
I have a filtered column. I want to copy its values, clear all the original values and paste only the content of the copied filtered ones.
I try to use a draft sheet for that, but it seems not to work. The paste repeats the filtered bulk over and over again.
(I had to add the +300
, otherwise I get a range mismatch error).
function main() {
_move(mailTab, 'F8:H', draftTab, 'A8:C');
}
function _move(fromSheet, fromRange, toSheet, toRange) {
var fromRange = fromRange + "300";
var toRange = toRange + "300";
toSheet.getRange(toRange).clearContent();
fromSheet.getRange(fromRange).copyTo(
toSheet.getRange(toRange), { contentsOnly: true, skipFilteredRows: true });
fromSheet.getRange(fromRange).clearContent();
}
Upvotes: 0
Views: 173
Reputation: 36656
I'm not sure how, why but this code fixes the problem.
It copies the filtered rows only.
I manually clear data after the first duplication chunk.
function _move(fromSheet, fromRange, toSheet, toRange) {
//var fromRange = fromRange + "300";
//var toRange = toRange + "300";
toSheet.getRange(toRange).clearContent();
fromSheet.getRange(fromRange).copyTo(
toSheet.getRange(toRange), { contentsOnly: true, skipFilteredRows: true });
_clearDestinationDups(toSheet, toRange);
fromSheet.getRange(fromRange).clearContent();
}
function _clearDestinationDups(toSheet, toRange){
var values = toSheet.getRange(toRange).getValues();
var i;
for (i = 1; i<values.length; i++){
if (values[i][0] == "") break;
}
toSheet.getRange(toRange).offset(i+1,0).clearContent();
}
Update:
I'm sure it copies all rows and ignores any filter. Try to apply a filter on your source data and you'll see -- all hidden rows will appear on the destination sheet.
My reply: I removed the filter in the source range, but the target range stays the same.
Upvotes: 0
Reputation: 14502
As far as I can tell skipFilteredRows
option works only with clear()
method.
https://developers.google.com/apps-script/reference/spreadsheet/range#clearoptions.
copyTo()
has no such option: https://developers.google.com/apps-script/reference/spreadsheet/range#copytodestination,-options
To copy/paste filtered data you need more complicated algorithm.
Something like this:
function main() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var range = "A2:B" + sheet.getLastRow();
var all_data = sheet.getRange(range).getValues();
var filter_column = 0;
var filter_criteria = getFilterCriteria(sheet, filter_column);
var filtered_data = all_data.filter(row => !filter_criteria.includes(row[filter_column].toString()));
Logger.log(filtered_data);
}
function getFilterCriteria(sheet, column) {
try {
return sheet.getFilter().getColumnFilterCriteria(column+1).getHiddenValues();
} catch(e) {
return [];
}
}
If you have a table like this
And if you will apply the filter that hides 1
:
You will get the filtered data
without 1
:
[[2.0, bbb], [, ], [2.0, ddd]]
Just like it looks in the filtered table:
Upvotes: 0
Reputation: 5163
From the documentation, skipFilteredRows
is not a valid advanced parameter, thus it does nothing. Also, since copyTo
always copies to a range of the same size, the filtered values are repeated.
A better way of copying filtered values is to check each row using isRowHiddenByFilter(i)
and copy them if the condition returns false.
Sample Code is in How to copy filtered spreadsheet data with Apps Script
Upvotes: 1