Using Google Apps Script for Google Sheet, this formula works to copy and paste visible row 77 :
function copyRow77() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var lRow = sheet.getLastRow();
var lCol = sheet.getLastColumn();
var range = sheet.getRange(77,1,1, lCol);
sh.insertRowsAfter(lRow, 1);
range.copyTo(sh.getRange(lRow+1, 1, 1, lCol), {contentsOnly:false});
}
}
But when row 77 is filtered, it doesn't work anymore...
Maybe an idea ?
As AsyntuBU stated:
You can use getFormulasR1C1, that will adapt to other rows/columns when copied. You can start at that. This is in no way an answer to your question, but to your comment where getFormulas wont adapt to new rows/columns
Related
Currently, I have a basic spreadsheet: https://docs.google.com/spreadsheets/d/1nlLdD48PfqrhyQzmJrhx_Tlw73C194YUqKeRkXoCOLg/edit?usp=sharing, and I have made a script that flattens the values of the formulas in the spreadsheet:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1'); // or whatever name
var range = sheet.getRange("A2:C"); // assuming data appears in A2-C
range.copyTo(range, {contentsOnly: true});
}
The issue with my current script is that it flattens all formula, even if the row is hidden by the filter, is there a way I can edit my script so that it will only flatten visible cells?
I found this operation for google app script isRowHiddenByFilter, but I am not sure how I could put it into my current script.
P.S. I will likely use this for different filters, so am not looking for a workaround. For example, if you look at my example spreadsheet, I wouldn't want the app script to specify "background-colour = white" etc)
You can loop through all rows and query either it is hidden before copying
Sample
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1'); // or whatever name
var firstRow = 2;
var firstColumn = 1;
var lastColumn = 3;
var range = sheet.getRange(firstRow, firstColumn, sheet.getLastRow() - firstRow + 1, lastColumn - firstColumn +1); // assuming data appears in A2-C
var rowHeight = range.getHeight();
for (var i = 0; i < rowHeight; i++){
if(!sheet.isRowHiddenByFilter((firstRow+i))){
var row = sheet.getRange((firstRow+i), firstColumn, 1, lastColumn - firstColumn +1);
row.setValues(row.getValues());
}
}
}
This sample copies the non-hidden rows one by one, thus it makes more sense to use the method setValues() instead of copyTo()
Ive been working on automatically sorting my data (ascending based on 2nd row 1st column data) and I found some tips through searching online but encountered an error which seems I cant find an answer through the net.
so heres the scenario:
I have 2 sheets, Sheet1 & Sheet2, the data from sheet1 is linked through sheet2 although sheet2 has additional columns,
this is sheet1
and this is sheet2
notice that the Column lastname and code in both sheets are thesame, the difference is the column Gender (Formatted on drop-down list) & Bdate(cell formatted as date)
I found a script that seems to work but I does not properly work completely, here is the output after I run the script.
notice the columns that inside the red box, it seems gender and bdate didnt follow the auto sort.
here is my code:
function autosortOnEdit() {
var sheetNames = ["Sheet1", "Sheet2"];
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheetNames.forEach(function(name) {
var sheet = ss.getSheetByName(name);
var range = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn() -1);
range.sort({column: 1, ascending: true});
});
}
my observation is I think this script does not work on cells that are formatted like the example above.
I want to sort this automatically based on column A "last name".
how can i make this script work even on formatted cells?
Thanks in Advance, I will continue searching through the net.
Not sure how to use range.sort({column: 1, ascending: true}); or how does it work, but whenever I want to sort sheet values, I do the following:
function myFunction()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var rows = sheet.getLastRow();
var columns = sheet.getLastColumn();
var sortedValues = sheet.getRange(2, 1, rows-1, columns).getValues().sort();
sheet.getRange(2, 1, rows-1, columns).setValues(sortedValues);
}
Try this instead of your code, hope this helps as it is successfully sorting all the values when I tested.
EDIT
To apply the same to all sheets inside a spreadsheet, you can get sheet names and iterate it in for loop one by one. Check the code:
function myFunction()
{
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var currentSheetName, currentSheet;
for(var i=0; i<sheets.length; i++)
{
currentSheetName = sheets[i].getName();
currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(currentSheetName);
var rows = currentSheet.getLastRow();
var columns = currentSheet.getLastColumn();
var sortedValues = currentSheet.getRange(2, 1, rows-1, columns).getValues().sort();
currentSheet.getRange(2, 1, rows-1, columns).setValues(sortedValues);
}
}
I want to take the last response from a Google Form and copy it to the same range on another sheet.
The second sheet has some data in columns A & B (a login and password) that I want to assign as somebody completes the registration form.
I want the data from column B to H from the form response sheet to be copied to column C to I on the sheet that contains the login/password columns when a response is received.
I know I am missing the code to take the range from the last row, but I know NO coding at all and my current script is compiled from things I've found around the web and the reference material.
Any advice would be greatly appreciated.
function onEdit(e) {
var spreadsheet = SpreadsheetApp.openById("sheetid");
var sheet = spreadsheet.getSheets()[0];
var lastrow = sheet.getLastRow();
var range = sheet.getRange(2,2,1,7);
values = range.getValues();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var SSsheet = ss.getSheets()[1];
var ssRange = SSsheet.getRange(2,3,1,7);
ssRange.setValues(values);
}
Try using copyTo(destination). It copies the data from a range of cells to another range of cells. Both the values and formatting are copied.
// The code below will copy the first 5 columns over to the 6th column.
var sheet = SpreadsheetApp.getActiveSheet();
var rangeToCopy = sheet.getRange(1, 1, sheet.getMaxRows(), 5);
rangeToCopy.copyTo(sheet.getRange(1, 6));
}
You can also try using copyValuesToRangecopyValuesToRange.
For additional code samples, you may also refer to this forum.
function onEdit(e) {
var spreadsheet = SpreadsheetApp.openById("ID");
var sheet = spreadsheet.getSheets()[0];
var lastRow = sheet.getLastRow();
var range = sheet.getRange("A"+(lastRow)+":G"+(lastRow));
var values = range.getValues();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var SSsheet = ss.getSheets()[1];
var getRow = SSsheet.getLastRow() + 1;
var ssRange = SSsheet.getRange(getRow, 1, values.length, values[0].length);
ssRange.setValues(values);
Try with this,
this code copies the last value you want from a certain range and pastes it in the last available row of the other sheet.
The code it's the same only in the place where you are going to copy it, specify it to be the size of what I want to copy. I hope it helps you :D
I know it has been asked and answered here many times, but I can not make it work. I am trying to copy a row values (no formulas) from one sheet to another sheet on googlesheets using Google Apps Script. Very basic, but somehow it is giving me hard time.
I have:
SourceSheet
SourceWorksheet
TargetSheet
TargetWorksheet
I am trying to Copy row values (no formulas) from SourceWorksheet(A2:K2), to a new row (after last used row) on TargetWorksheet. It will be again from (A:K) but row number will be different, each time it will create a new row after last row.
Any help would be really appreciated!
EDIT
I found this code below, but not sure how to modify it to read the range i mentioned above instead of all the rows from source worksheet, and I need to modify it so it finds last row on target worksheet then creates new row each time to write the values ( so it doesn't overwrite any data on target)
function myFunction() {
var source = SpreadsheetApp.openById('xxxxxx');
var sourcesheet = source.getSheetByName('sheet1');
var target = SpreadsheetApp.openById('xxxxx')
var targetsheet = target.getSheetByName('sheet1');
var targetrange = targetsheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn());
var rangeValues = sourcesheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn()).getValues();
targetrange.setValues(rangeValues);
}
To add a line to the last row of a form, use the sheet.appendRow() method.
In your example, var targetRange would not be needed. You could simply use targetSheet.appendRow(rangeValues) where the rangeValues = the range you're copying (as an array)
function myFunction() {
var source = SpreadsheetApp.openById('xxxxxx');
var sourcesheet = source.getSheetByName('sheet1');
var target = SpreadsheetApp.openById('xxxxx')
var targetsheet = target.getSheetByName('sheet1');
var rangeValues = sourcesheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn()).getValues();
targetSheet.appendRow(rangeValues);
}
Sorry for my english. ^^
Erm, i´ve found a script to copy from a sheet to an other Sheet.
My problem is: its copy with rows.
I want to copy columns and add 2 columns to lastcolumn on script running.
It becames a problem, because columns has no a1notification. A=1, B=2, etc.
copyTo wants A1notification.
Heres my script:
function Archiv() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.openById("sheetid");
var source_sheet = ss.getSheetByName("sheetname");
var target_sheet = target.getSheetByName("sheetnametarget");
var source_range = source_sheet.getRange("D4:E89");
var last_col = target_sheet.getLastColumn();
target_sheet.insertColumnAfter(last_col);
var target_range = target_sheet.getRange(">>>>(lastcol+1)<<<<4:>>>>>(lastcol+2)<<<<89");
source_range.copyTo(target_range, {contentsOnly:true});
}
The script have to run every Monday to archive the content of 2 Columns.
I hope you can understand my wish.
I have tested many things, but nothing helps. :(
Many thanks in advance.
Sebastian
You can use another range selection mode that will makes things very simple, see this doc, using integers for row and column numbers.
Your code could become like this :
function Archiv() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.openById("sheetid");
var source_sheet = ss.getSheetByName("sheetname");
var target_sheet = target.getSheetByName("sheetnametarget");
var source_range = source_sheet.getRange("D4:E89");
var last_col = target_sheet.getLastColumn();
while(target_sheet.getMaxColumns()<=last_col+2){// add columns only if necessary
target_sheet.insertColumnAfter(last_col)}
var source_values = source_range.getValues();
var target_range = target_sheet.getRange(4,last_col+1,source_values.length,2);// row Nr4, starting on last column+1, 2 columns width and 89-4 rows heigth
target_range.setValues(source_values);
}
I used getValues() and setValues() instead of copyTo() that returned an error : target and source must be in the same spreadsheet