Google script for google sheets - Range copy paste special 'add' - google-apps-script

i'm really newbie at scripting, i used to do my work with microsoft office that have a special paste "add" feature and now for google sheet i can't really find it.
I will have a source range of C2:C102 and destination at same sheet D2:D102 i want the script (that i can run manually weekly) to copy all the range from source and sum it with the already existing data at D2:D102 (only values).
Here is a small example - Before after
I tried to use this code but ofc it just replaces the values.
function copyCells(){
var thisSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var SourceSheet = thisSpreadsheet.getSheetByName("test");
var SourceRange = thisSpreadsheet.getRange("C2:C102");
var destinationSheet = thisSpreadsheet.getSheetByName("test");
var destinationRange = destinationSheet.getRange("D2:D102");
SourceRange.copyTo(destinationRange, {contentsOnly: true});
}
Any help will be really appreciated :)

Haven't tested the code but try this.
grab values with getValues()
sum the values
copy back values with setValues()
function copyCells(){
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const SourceSheet = spreadsheet.getSheetByName("test");
const SourceRange = spreadsheet.getRange("C2:C102");
const SourceValues = SourceRange.getValues();
const destinationSheet = spreadsheet.getSheetByName("test");
const destinationRange = destinationSheet.getRange("D2:D102");
const destinationValues = destinationRange.getValues();
for (let i = 0; i < SourceValues.length; i++)
destinationValues[i][0] = parseFloat(destinationValues[i][0]) + parseFloat(SourceValues[i][0])
destinationRange.setValues(destinationValues);
}
REFERENCES
range.getValues()
range.setValues()

Related

copyTo(target) copies my functions but need it to copy values

So this might be a simple one for someone more skilled. The code works except it copies the functions rather than the values. The cells contain a LOT of functions and I'm using this to create a second version since the functions are UI data reliant and this is the easiest way to make a "Backup" in case we need to go back to an old forms data. I'm using the below code and it copies everything over, and creates the sheet with the right name, but I'm not sure how to get it to take the values and not the functions.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("AHA");
var nameSheet = sourceSheet.getRange(1, 15).getValue();
var target = SpreadsheetApp.openById('1634dptmmyJVtbYLeHKw57U_Wzi2k1JGnACndxFzddgM');
var targetSheet = sourceSheet.copyTo(target);
targetSheet.setName(nameSheet);
I've tried this,
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("AHA");
var nameSheet = sourceSheet.getRange(1, 15).getValue();
var target = SpreadsheetApp.openById('1634dptmmyJVtbYLeHKw57U_Wzi2k1JGnACndxFzddgM');
var targetSheet = sourceSheet.copyTo(target,SpreadsheetApp.CopyPasteType.PASTE_VALUES);
targetSheet.setName(nameSheet);
but it gives me the following error:
Exception: The parameters (SpreadsheetApp.Spreadsheet,SpreadsheetApp.CopyPasteType) don't match the method signature for SpreadsheetApp.Sheet.copyTo.
Any help or advice on another script I could use would be appreciated. Thanks.
Try this:
function copyvalues() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("AHA");
const vs = sh.getDataRange().getValues();
const name = sh.getRange(1, 15).getValue();
const tss = SpreadsheetApp.openById('1634dptmmyJVtbYLeHKw57U_Wzi2k1JGnACndxFzddgM');
const tsh = tss.insertSheet(name);
tsh.getRange(1,1,vs.length,vs[0].length).setValues(vs);
}

How to Ctrl+Shift+Down using Google app scripts

I am trying to write an Google App Script for a google sheet that I have. The number of values I have in column D will change every week, and I am trying to copy those values to paste into another sheet.
So far, I can't find any code that will do the equivalent of selecting D2, and doing a Ctrl + Shift + down + copy.
function ELATerminationTransfer() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('D2').activate();SpreadsheetApp.getSelection().getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.DOWN).activate};
Anyone know of a simple fix?
Try this:
function testSelection()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName('Source');
var destSheet = ss.getSheetByName('Destination');
// copy column values to destination sheet
sourceSheet
.getRange('D2:D')
.copyTo(destSheet.getRange('D2'), {contentsOnly:true});
}
You can select by this way
function myFunction(){
var cel = SpreadsheetApp.getActiveRange()
var end = cel.getNextDataCell(SpreadsheetApp.Direction.DOWN)
var rng = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(cel.getA1Notation()+':'+end.getA1Notation()).activate()
}

How to copy and paste as values Google Apps Script/Sheets from one spreadsheet to another?

So I have a huge spreadsheet with 9k rows and more than 30 columns. I want to copy this spreadsheet to another spreadsheet (Values only).
Previously I was using this code successfully, but due to the increase in data, the script now times out (1800s +). Is there a way to optimize this script or maybe an alternative option altogether?
function temp() {
var sss = SpreadsheetApp.openById('XYZ'); // sss = source spreadsheet
//var ss = sss.getSheets()[4]; // ss = source sheet
var ss = sss.getSheets(); // ss = source sheet
var id=4; //default number
for(var i in ss)
{
var sheet = ss[i];
if(sheet.getName()== "ABC")
{ id=i;
break;
}
}
console.log(id);
ss=sss.getSheets()[id];
//Get full range of data
var SRange = ss.getDataRange();
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
SpreadsheetApp.flush();
var tss = SpreadsheetApp.getActiveSpreadsheet(); // tss = target spreadsheet
var ts = tss.getSheetByName('ABC'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
}
I believe your goal is as follows.
You want to reduce the process cost of the script.
In this case, I would like to propose to use Sheets API. This has already been mentioned in the Yuri Khristich's comment. Also, when the benchmark is measured between Spreadsheet service (SpreadsheetApp) and Sheets API, when Sheets API is used for reading and writing the values for Spreadsheet, it was confirmed that the process cost could be reduced. Ref
When Sheets API is used for your script, it becomes as follows.
Modified script:
Before you use this script, please enable Sheets API at Advanced Google services. And please set the source Spreadsheet ID and the sheet names.
function temp() {
var sourceSpreadsheetId = "XYZ"; // Please set the source Spreadsheet ID.
var destinationSpreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
var sourceValues = Sheets.Spreadsheets.Values.get(sourceSpreadsheetId, "ABC").values;
Sheets.Spreadsheets.Values.update({values: sourceValues}, destinationSpreadsheetId, "ABC", {valueInputOption: "USER_ENTERED"});
}
References:
Benchmark: Reading and Writing Spreadsheet using Google Apps Script
Method: spreadsheets.values.get
Method: spreadsheets.values.update
Copy from one spreadsheet to another
function copyfromonetoanother() {
const sss = SpreadsheetApp.getActive();
const dss = SpreadsheetApp.openById("dssid");
const ssh = sss.getSheetByName('Sheet1');
const vs = ssh.getDataRange().getValues();
const dsh = dss.getSheetByName('Sheet1');
dsh.getRange(dsh.getLastRow() + 1,1,vs.length,vs[0].length).setValues(vs);
}
If you wish to select the source range:
function copyfromonetoanother() {
const sss = SpreadsheetApp.getActive();
const dss = SpreadsheetApp.openById("dssid");
const ssh = sss.getSheetByName('Sheet1');
const vs = ssh.activeRange().getValues();
const dsh = dss.getSheetByName('Sheet1');
dsh.getRange(dsh.getLastRow() + 1,1,vs.length,vs[0].length).setValues(vs);
}
This function appends to the bottom of the destination sheet
function appenddatatobottomofdestination() {
const sssId = "source spreadsheet id";
const sss = SpreadsheetApp.openById(sssId);
const dss = SpreadsheetApp.getActive();
const dssId = dss.getId();
const ssh = sss.getSheetByName('Sheet1');//Source sheet
const srg = ssh.getRange(1,1,ssh.getLastRow(),ssh.getLastColumn());
const dsh = dss.getSheetByName("Sheet1");//Destination sheet
var vs = Sheets.Spreadsheets.Values.get(sssId, `${ssh.getName()}!${srg.getA1Notation()}`).values;
const drg = dsh.getRange(dsh.getLastRow() + 1, 1, vs.length,vs[0].length);//appends to bottom of spreadsheet
Sheets.Spreadsheets.Values.update({values: vs}, dssId, `${dsh.getName()}!${drg.getA1Notation()}`, {valueInputOption: "USER_ENTERED"});
}

getsheetbyname with variable cell

I have a sheet called Audit with cell B1 corresponding to a specific shopID.
I have built a sheet with each shopID called ShopID+PrevAudit (555PrevAudit)
When they complete the audit they click a button that should copy values and format to the corresponding sheet i've created but I'm getting hung up on calling the correct sheet based on a B1 entry.
This is what I had been using but it was static and i want to make this easier on myself. I'm not sure why this is so difficult for me. Thanks for any help you can provide.
function copyaudit() {
var source = SpreadsheetApp.openById('SheetID');
var sourceSheet = source.getSheetByName('Audit');
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var tempSheet = source.getSheetByName('555PrevAudit');
var tempRange = tempSheet.getRange('A1:L51');
var destination = SpreadsheetApp.openById('SheetID');
sourceRange.copyTo(tempRange); // paste all formats?, broken references
tempRange.offset(0, 0, sourceValues.length, sourceValues[0].length)
.setValues(sourceValues); // paste all values (over broken refs)
}
Using a JS template string, you can generate the sheet name:
`${destID}PrevAudit`
To put it in context:
function copyaudit()
{
const range = 'A1:L51';
let spreadSheet = SpreadsheetApp.openById('SheetID');
let sourceSheet = spreadSheet.getSheetByName('Audit');
let sourceRange = sourceSheet.getRange(range);
// Get B1
let destID = sourceRange.getValues()[0][1];
let destSheet = spreadSheet.getSheetByName(`${destID}PrevAudit`);
sourceRange.copyTo(destSheet.getRange(range));
}

Copy filter data from one spreadsheet file to another - Google Apps Script

I'm currently working on a project where I need to copy data to another google sheet.
let me explain:
I'd created a function where I applied filter by text and it works. But the issue is that I can't copy only the filtered data to another sheet. I'd seen many stack conversations but nothing fit.
here is the code
function copyWithValues() {
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const sourceSheet = spreadSheet.getSheetByName('testo');
const sourceRange = sourceSheet.getDataRange();
const sourceValues = sourceRange.getValues();
const targetSpreadsheet = titleAsDate();
let rowCount = sourceValues.length;
let columnCount = sourceValues[0].length;
let targetSheet = targetSpreadsheet.getSheetByName('Sheet1').setName("Report");
let targetRange = targetSheet.getRange(1, 1, rowCount, columnCount);
targetRange.setValues(sourceValues);
}
Explanation:
The following solution is inspired by this answer.
The latter has one limitation though, it only works for transferring the filter data between sheets of the same spreadsheet.
We are going to use the exact same answer to copy the filter values from the source sheet and paste them to a temporary sheet temp_sheet of the source spreadsheet file.
Then we simply get the values of that temporary file and paste them to another spreadsheet file with the regular method of getting and setting the values as you have already implemented in your code.
Solution:
function copyWithValues() {
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const sourceSheet = spreadSheet.getSheetByName('testo');
const temp_sheet = spreadSheet.insertSheet('temp_sheet');
const sourceRange = sourceSheet.getFilter().getRange();
sourceRange.copyTo(
temp_sheet.getRange('A1'),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL,
false);
SpreadsheetApp.flush();
const sourceValues = temp_sheet.getDataRange().getValues();
const targetSpreadsheet = titleAsDate();
const rowCount = sourceValues.length;
const columnCount = sourceValues[0].length;
const targetSheet = targetSpreadsheet.getSheetByName('Sheet1').setName("Report");
const targetRange = targetSheet.getRange(1, 1, rowCount, columnCount);
targetRange.setValues(sourceValues);
spreadSheet.deleteSheet(temp_sheet);
}
where the helper function titleAsDate() is defined as:
function titleAsDate() {
const currentDate = Utilities.formatDate(new Date(), "GMT+8", "dd-MM-yyyy HH:mm:ss");
return SpreadsheetApp.create("Report of the " + currentDate);
}
based on your previous question.