copy data from specific cell in a sheet to another sheet - google-apps-script

There are few queries which are somewhat similar but I'm unable to get a solution from those.
In my mainsheet I'm importing data from a webpage using Importdata function in the mainsheet. The data in the webpage changes every 5mins and so the cell value A50 changes every 5 mins in the mainsheet.
Now I want to write a google app scrip function that will copy the value from A50 of mainsheet to another sheet in the cell A1,A2,A3,A4,A5.......and so on and have a timestamp correspondingly in B1,B2,B3,B4,B5....and so on

You can use onEdit() trigger function to do this. When an edit happens in cell A50 check if cell and sheets are correct then read value and save into target sheet. Below code does that. Change the sheet names as shown in comment.
function onEdit(e) {
// check if active range is A50 or not
var rangeStr = e.range.getA1Notation();
if (rangeStr != 'A50') return;
// get Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get sheets
var mainSheetNames = ['main sheet name', 'main sheet name', 'main sheet name']; // change here
var mainSheet = e.range.getSheet();
if (mainSheetNames.indexOf(mainSheet.getName()) == -1) return;
var targetSheet = ss.getSheetByName('target sheet name'); // change here
// get value
var value = e.value;
// set values
targetSheet
.getRange(targetSheet.getLastRow() + 1, 1, 1, 2)
.setValues([[value, new Date().toLocaleString()]]);
}

Related

Trigger when change is happening in specific sheet

I have a sheet with data that is imported through IMPORTRANGE to another sheet. When I make changes to Spreadsheet 1 >>> Spreadsheet 2 I have a script that copy the data from Copy to Paste. It is working all fine however I want to make sure that the script only runs when changes are made in the 'Copy' sheet and not any other. At the moment it runs independent on what sheet I make changes in.
Spreadsheet 1
Spreadsheet2
I tried onChange trigger two different ways...
This one makes the change but triggers when changes are made in any of the sheets
function Trigger2(e) {
var sheet = e.source.getActiveSheet();
if (sheet.getName() === 'Copy') {
copyInfo();
}
}
AND
(this does not work)
function Trigger2(e) {
var sheet = e.source.getActiveSheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
if( sheet.getActiveSheet().getName() !== "Copy" ) return;{
copyInfo();
}}
The copy code looks like this...
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
// get source range
var source = copySheet.getRange(2,1,12,8);
// get destination range
var destination = pasteSheet.getRange(2,1,12,8);
// copy values to destination range
source.copyTo(destination);
}
Copy Changes from one Sheet To Another after Imported Range Changes
Spreadsheet 2 Imports a range to Sheet1 from Spreadsheet 1 Sheet1 and when a change occurs in Spreadsheet 2 Sheet1 we copy data from Spreadsheet2 Sheet1 to Spreadsheet2 Sheet 2.
function onMyChange(e) {
//Logger.log(JSON.stringify(e));//useful during setup
//e.source.toast("Entry");//useful during setup
const sh = e.source.getSheetByName("Sheet1")
Logger.log(sh.getName());
if(e.changeType == "OTHER") {
let tsh = e.source.getSheetByName("Sheet2");
sh.getRange(2,1,12,8).copyTo(tsh.getRange(2,1));//Only need the upper left hand corner of the range. Thus you change change the size of the source data without having to change the target range.
}
}
One might be inclined to attempt to use e.source.getActiveSheet() unfortunately this does not necessary get the sheet that you have written unless in is SpreadsheetApp.getActive().getSheets()[0]. onChange event object always returns the most left sheet in the spreadsheet in this situation so it can't be used to identify the sheet that is being written to from the importRange function.
With this function you no longer require another function.
A simple if should work, but you're trying to compare the name to the wrong field. According to Google's documentation, the source field in the Event Object e returns the Spreadsheet object, which is the entire document.
Instead you can use the e.range field, which contains the exact range where the edit was made, and the Range class has a getSheet() method to get the parent Sheet.
So you can modify your sample to the following:
function Trigger2(e) {
var sheet = e.range.getSheet();
if (sheet.getName() === 'Copy') {//Edit: this will only work if sheet is the most left sheet in the spreadsheet
copyInfo();
}
}

How to copy a range of data to another google sheet using google apps script?

Source:
Destination:
Hi everyone,
I have 2 google sheets, Source & Destination. I want to copy a range of data from Source sheet to Destination sheet by using google apps script. So the data should appear at the last row of the Destination sheet. This is my code:
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Source");
var pasteSheet = ss.getSheetByName("Destination");
// get source range
var source = copySheet.getRange(3,1,1,10);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,1,10);
// copy values to destination range
source.copyTo(destination);
}
Seems like the script only allow me to do the copying within one google sheet (different tab) instead of 2 different google sheet. May I know how should I modified it so that the script able to find my destination google sheet and paste the data at the last row? Any help will be greatly appreciated!
Edit
I tried to use onEdit to triggered the script, however it seems like not working. Below is my script:
function onEdit(e) {
if (e.range.columnStart == 11 && e.range.rowStart == 3){
var ss = SpreadsheetApp.getActiveSpreadsheet();
const id ='1r5Hygl5ysahMi6DQ3duDR5L8c4aGX_0CJba7lXxnejw';
var copySheet = ss.getSheetByName("Sheet1");
var pasteSheet = SpreadsheetApp.openById(id).getSheetByName("Sheet1");
if (e.value == 'Submit'){
var source = copySheet.getRange(3,1,1,10);
const values = source.getValues();
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,1,10);
destination.setValues(values);
}
}
}
Source:
https://docs.google.com/spreadsheets/d/1jnOvE-Dc7y9o7GsgN9fjOXZWlUCwiJayugX5q4Y3CA0/edit#gid=0
Destination:
https://docs.google.com/spreadsheets/d/1r5Hygl5ysahMi6DQ3duDR5L8c4aGX_0CJba7lXxnejw/edit#gid=0
Use Range.getValues() and Range.setValues()
const id ='ID of paste Spreadsheet';
var pasteSheet = SpreadsheetApp.openById(id).getSheetByName("Destination");
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,1,10);
const values = source.getValues();
destination.setValues(values);
The method getSheetByName is used to define a sheet within a spreadsheet. To define a specific spreadsheet, you should use openById and associate the spreadhseet ID (https://docs.google.com/spreadsheets/d/{spreadsheet ID}/edit).
Define your source sheet as:
var copysheet = SpreadsheetApp.openById('enter id for Source').getSheetByName('Sheet 1')
Define your destination sheet as:
var pastesheet = SpreadsheetApp.openById('enter id for Destination').getSheetByName('Sheet 1')
If I understand correctly, your goal is the following:
/* Every time a user sets the value of cell K3 in source spreadsheet
to "submit". Copy all the values of row 3 and paste them into the
destination sheet under the last row. Then delete the source values
and set the value of K3 to "Clear" again. */
You need a installed trigger and a function to copy the values when triggered. So lets do that step by step.
Example:
First lets create a script that is bound to your source SS. Let's edit your copyInfo() function so that it takes the destination spreadsheet Id as parameter.
function copyTo(destinationSSId) {
// Open source SS at tab named "Source"
let copySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Source");
// Open destination SS at tab named "Destination"
let pasteSheet = SpreadsheetApp.openById(destinationSSId).getSheetByName("Destination");
// Get source values
let sourceValues = copySheet.getRange(3, 1, 1, 10).getValues();
// Set values to destination range
pasteSheet.getRange(pasteSheet.getLastRow() + 1, 1, 1, 10).setValues(sourceValues);
// Log the pasted values from the last row
console.log("Last row pasted: " + pasteSheet.getRange(pasteSheet.getLastRow(), 1, 1, 10).getValues()[0]);
}
Make a function to clear the source values and reset the "form".
function clearSubmission() {
let copySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Source");
copySheet.getRange(3, 1, 1, 10).clearContent()
copySheet.getRange(3, 11, 1, 1).setValue("Clear");
console.log("Source submitted and cleared.")
}
Set up the function to trigger.
function myTriggeredFunction(e) {
console.log(JSON.stringify(e.range), e.value)
if (e.range.columnStart == 11 && e.range.rowStart == 3) {
if (e.value == 'Submit') {
let destinationSSId = '{YOUR DESTINATION SS ID}';
copyTo(destinationSSId);
clearSubmission();
}
}
}
Install the trigger as "From spreadsheet - On edit" to run the function myTriggeredFunction by going to the "Triggers" tab in your project.

Trigger script editor when specific cell is changed (Google sheets)

I'm trying to create a data snapshot on google sheets that will automatically run when a specific cell is edited. How should I do that? I'm not from coding background but so far I've found 2 sources and tried to combine them but when I tested it out, it's giving me error. I want to copy values from A2 to E2 of Snapshot sheet and append row every time B2 is changed. Please advise.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Snapshot");
var source = sheet.getRange("A2:E2");
var values = source.getValues();
if(e.range.getA1Notation() == 'B2'){
sheet.appendRow(values[0]);
}}
The B2 in Snapshot is a formula which displays the value of F1 in Receipt sheet. So, the onEdit is not triggered on change of name.
The name changes in F1
I tried the below code and it is working
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var rsht=ss.getSheetByName("Receipt");
var sheet = ss.getSheetByName("Snapshot");
var source = sheet.getRange("A2:E2");
var values = source.getValues();
if(e.range.getA1Notation() == 'F1'){
sheet.appendRow(values[0]);
}}

Copy/Append dynamic range of rows to another sheet

I have asked if there is a way to loop an app script to copy header base information to multiple rows based on the amount of line items entered by a user:
Solution is using arrayformulas with an intermediary sheet "OrderKey" that can eventually be hidden.
I have updated a working solution thanks to Aurielle Perlmann (see below).
The SHEET system is very close to completion
See my example Sheet here:https://docs.google.com/spreadsheets/d/151h1XjB98NOBnO0otNaql3ASjK84CccZZ399dX4BMBM/edit#gid=0
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Custom Menu')
// creates a menu item "Submit Sales Order"
.addItem('Submit Sales Order', 'menuItem1')
.addToUi();
}
function menuItem1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var salesheet = ss.getSheetByName("salesOrder");
var source = ss.getSheetByName(" OrderKey");
// sets the 'OrderKey' Sheet as source
var target = ss.getSheetByName("Orders");
// sets 'Orders' sheet as the target for copying data to.
var sourceData = source.getSheetValues(2,1,source.getLastRow(),16);
// sets range to gather source 'OrderKey' data by finding last row, and Line 2 to Column 16
target.getRange(target.getLastRow()+1, 1, sourceData.length,16).setValues(sourceData);
// finds last row of target 'Orders' and writes to +1 row past last row up to column 16 using setValues of sourceData
// Following simply clears Sales Order Sheet so new data can be entered
salesheet.getRange('B4:B5').clearContent();
salesheet.getRange('B8').clearContent();
salesheet.getRange('G6:G8').clearContent();
salesheet.getRange('F10:G10').clearContent();
salesheet.getRange('A13:C76').clearContent();
salesheet.getRange('J13:J76').clearContent();
// Following gets seed number from cell I1, and increases value by +1 so next Sales Order ID is incremented by 1
var cell = salesheet.getRange("I1");
var cellValue = cell.getValue();
cell.setValue(cellValue + 1);
var lastID = salesheet.getRange("F1");
var nextID = salesheet.getRange("G1");
var lastIDValue = lastID.getValue();
nextID.setValue(lastIDValue + 1);
}
UPDATED.
I went ahead and added the formulas on your sheet for you, this formula only needs to be added to the very first line after the header and the rest will fill in automatically
the two formulas used are:
=arrayformula(if(istext(K2:K),salesOrder!B4,))
and
=ARRAYFORMULA(if(istext(salesOrder!A13:A),salesOrder!A13:A,))
the cell references change depending on which fields you are trying to import.
after doing that sheet - i added a script which I then attached to a button called "submit" which gets the last rows and appends the value onto a separate sheet you can use for archiving:
function testing(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName(" OrderKey");
var sheet2 = ss.getSheetByName("testing - aurielle");
var sourceData = sheet1.getSheetValues(2,1,sheet1.getLastRow(),14);
sheet2.getRange(sheet2.getLastRow()+1, 1, sourceData.length,14).setValues(sourceData);
}

Copy a row to new sheet based on value in a cell

I'm trying to create a Google Script that copies rows from one Google Sheet into different sheets based on the value of a cell.
The cell value are states in the United States. The master spreadsheet has data from a registration form that is being imported into it all the time. When a new registration happens (and the data is imported into the master sheet), I'd like the script to run and copy that row of data into the appropriate state sheet.
Here's where I'm at:
Get master sheet
Find the last row
Get the value of the cell in the column "state"
Copy that row into one of 50 different sheets depending on what state it is.
Run the script every time the master sheet is updated (via an API).
Any help would be appreciated. I'm definitely a newbie when it comes to scripting and this is just hurting my head.
Here's the code I have so far:
function myFunction() {
// Get Source Spreadsheet
var source = SpreadsheetApp.getActiveSpreadsheet();
// Get Source Sheet from Spreadsheet
var source_sheet = source.getActiveSheet();
// Get Active Range from Sheet
var lastRow = sheet.getLastRow();
// Get the Value of the State Cell
var cellValue = Range.getCell(lastrow,3);
// Copy Last Row to Appropriate State Sheet
if ( cellValue == 'Alaska') {
var target = SpreadsheetApp.openById("");
var target_sheet = target.getSheetByName("Sheet1");
target_sheet.appendRow(lastRow);
}
}
With this code:
// Get Active Range from Sheet
var lastRow = sheet.getLastRow();
The getLastRow() method returns an integer. Then further down in your code, you are using the lastRow variable as the data for appendrow() which won't work;
target_sheet.appendRow(lastRow);
The code should probably be something like this:
var target = SpreadsheetApp.openById("");
var target_sheet = target.getSheetByName("Sheet1");
var lastRowOfData = source_sheet
.getRange(source_sheet.getLastRow(), 1, 1, source_sheet.getLastColumn())
.getValues(); //Returns a two dimensional array
var oneD_Array = lastRowOfData.join().split(","); //Creates a one D array
target_sheet.appendRow(oneD_Array);
The appendRow() method takes a one dimensional array. The getValues() method returns a 2 Dimensional array, so it must be converted. Because you are only getting one row of data, it's easy to convert. The outer array only has one inner array. The one inner array has all the cell values of the row.
Here's the answer for what I came up with for the code:
function myFunction() {
// Get Source Spreadsheet
var source = SpreadsheetApp.getActiveSpreadsheet();
// Get Source Sheet from Spreadsheet
var source_sheet = source.getActiveSheet();
// Get Last Row
var lastRow = source_sheet.getLastRow();
// Get Last Column
var lastColumn = source_sheet.getLastColumn();
// Get Last Row of Data
var lastRowOfData = source_sheet.getRange(lastRow, 1, 1, lastColumn).getValues();
// Creates a one dimensional array
var oneD_array = lastRowOfData.join().split(",");
// Get the Value of the State Cell
var cellValue = source_sheet.getRange(2,7).getValue();
// Copy Last Row to Appropriate State Sheet
if ( cellValue == "New York" ) {
var target = SpreadsheetApp.openById("");
var target_sheet = target.getSheetByName("Sheet1");
target_sheet.appendRow(oneD_array);
}
}