Google Sheets - Sending Row to Another Spreadsheet - javascript

Written a Google Sheet where when a button is pressed a collated row of data is sent to a different Google Sheet. It was launched six months ago among colleagues that have full permissions to both sheets. The reason for this post was that 1 in 10 submissions goes missing and never arrives to be added to the secondary Google Sheet. Thus wondering if anyone had any ideas as to if there was an issue with my code.
sh.getRange("j7").setValue('=now()');
var range = sh.getRange('J7:R7'); //Fixed range of where the row/data is collated
var data = range.getValues();
var tss = SpreadsheetApp.openById('SHEET ID');
var ts = tss.getSheetByName('Main');
ts.getRange(ts.getLastRow()+1,1,1,9).setValues(data);
Many thanks for any ideas...

Try this:
function lfunko() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Enter Your Sheet Name");
sh.getRange("J7").setFormula('=now()');
var range = sh.getRange('J7:R7');
var data = range.getValues();
var tss = SpreadsheetApp.openById('SHEET ID');
var ts = tss.getSheetByName('Main');
ts.getRange(ts.getLastRow() + 1, 1, data.length, data[0].length).setValues(data);
}

Related

How do I fix a google script error that says coordinates of target range are outside the dimensions of the sheet when trying to archive? [duplicate]

I have been using a script in my google sheet that I found here:
copy data from one sheet to another in google app script and append a row, one small issue
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
// get source range
var source = copySheet.getRange(2,2,12,2);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,2,12,2);
// copy values to destination range
source.copyTo(destination);
// clear source values
source.clearContent();
}
When I am running it now it gives me an error:
The coordinates of the target range are outside the dimensions of
the sheet.
which wasn't coming up before. Does anyone have an idea why it is doing this?
Issue:
The error is in this line:
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,2,12,2);
pasteSheet.getLastRow() returns a row number which is at the very bottom of your sheet. Then you consider 12 rows range but the pasteSheet does not have 12 rows after the last row with content.
Solutions:
Add more rows in the pasteSheet:
or you can use insertRowsAfter:
pasteSheet.insertRowsAfter(pasteSheet.getLastRow(), 12)
Code snippet:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
// get source range
var source = copySheet.getRange(2,2,12,2);
// insert rows to make sure you have enough space
pasteSheet.insertRowsAfter(pasteSheet.getLastRow(), 12)
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,2,12,2);
// copy values to destination range
source.copyTo(destination);
// clear source values
source.clearContent();
}

Google Apps Script - Run Same Code on Dynamically Changing Tab Numbers

I would like the below code to run on how ever many tabs get created - after Sheet 7 (First 7 tabs always remain unchanged). Currently I use an array and must number them which works if you know exactly how many tabs get created - which I dont always know. So I currently create script for [7] then [8] etc etc. this does return an error when I say have [20] but Tab 20 doesnt exist.
function Company_ONE() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[7]; //SHEET 8
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheets()[7];
var lr = sheet.getLastRow();
var cell = SpreadsheetApp.getActive().getRange('AK3');
var criteria = SpreadsheetApp.DataValidationCriteria.CHECKBOX;
var rule = SpreadsheetApp.newDataValidation()
.requireCheckbox()
.build();
cell.setDataValidation(rule);
sheet.getRange('AK3').activate();
var destinationRange = sheet.getActiveRange().offset(0, 0, lr-3);
sheet.getRange('AK3').copyTo(destinationRange);
}
Explanation:
Use getSheet().slice(7) to get from 8th sheet onwards. See here how slice works.
Then you can use forEach() to iterate through every sheet (after sheet 7th).
I also removed some unnecessary lines of codes. For example, you use SpreadsheetApp.getActive() multiple times in the sheet or you define the same variables twice like ss or sheet.
Since you are interacting with the sheets iteratively you might need to use SpreadsheetApp.flush() to make sure all the pending changes are completed.
Solution:
function Company_ONE() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets().slice(7); // get 8th sheet onwards
sheets.forEach(sheet=>{
var lr = sheet.getLastRow();
var cell = ss.getRange('AK3');
var criteria = SpreadsheetApp.DataValidationCriteria.CHECKBOX;
var rule = SpreadsheetApp.newDataValidation()
.requireCheckbox()
.build();
cell.setDataValidation(rule);
sheet.getRange('AK3').activate();
var destinationRange = sheet.getActiveRange().offset(0, 0, lr-3);
sheet.getRange('AK3').copyTo(destinationRange);
SpreadsheetApp.flush();
});
}

Trying to do Dynamic Equity Split calculations in Google Sheets

new to using javascript in Google Sheets. I am trying to create a sheet that automatically calculates what business partners will receive based upon their dynamic split percentage and the incoming money. The percentage comes from one cell, but each payment made to the partners will be entered in a column. Here's what I have so far:
/**
* Creates a Date Stamp if a column is edited.
* Also performs dynamic split calculations
*/
//CORE VARIABLES
// The column you want to check if something is entered.
var COLUMNTOCHECK = 13;
// Where you want the date time stamp offset from the input location. [row, column]
var DATETIMELOCATION = [0,-1];
// Where the calculations will be performed for the Partners.
var PARTNERONELOCATION = [0, 1];
var PARTNERTWOLOCATION = [0, 2];
var PARTNERTHREELOCATION = [0, 3];
// Sheet you are working on
var SHEETNAME1 = 'Sheet1'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var partnerOnePercent = sheet.getRange("G2").getValue();
var partnerOnePaySource = sheet.getRange("M2").getValue();
var partnerTwoPercent = sheet.getRange("G3").getValue();
var partnerTwoPaySource = sheet.getRange("M2").getValue();
var partnerThreePercent = sheet.getRange("G4").getValue();
var partnerThreePaySource = sheet.getRange("M2").getValue();
//checks that we're on the correct sheet.
if(sheet.getSheetName() == SHEETNAME1 ) {
var selectedCell = ss.getActiveCell();
//checks the column to ensure it is on the one we want to cause the date and calculations to appear.
if( selectedCell.getColumn() == COLUMNTOCHECK) {
var dateTimeCell = selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
var partnerOneCell = selectedCell.offset(PARTNERONELOCATION[0],PARTNERONELOCATION[1]);
partnerOneCell.setValue((partnerOnePercent/100)*partnerOnePaySource);
var partnerTwoCell = selectedCell.offset(PARTNERTWOLOCATION[0],PARTNERTWOLOCATION[1]);
partnerTwoCell.setValue((partnerTwoPercent/100)*partnerTwoPaySource);
var partnerThreeCell = selectedCell.offset(PARTNERTHREELOCATION[0],PARTNERTHREELOCATION[1]);
partnerThreeCell.setValue((partnerThreePercent/100)*partnerThreePaySource);
}
}
}
The thing I would like it to do is when I enter a payment into the column (column 13), Is for the payment to be split into the partner location cells (var partnerOneCell, var partnerTwoCell, var partnerThreeCell) that are offset from the cell that the payment amount is typed in, and I only want it to be calculated by the percentages as they are at the moment the payment amount is entered. Any help would be appreciated.
Right now it is only calculating based upon cell M2 (row 2, column 13). I want it to be able to calculate based upon the amount I enter in any cell within that column, and only the cell I am currently updating. I think that this has something to do with getActiveRange or something, but I'm not familiar enough with these methods.
Edit: Upon testing, it also seems that row 3 column 14 is reflecting a calculation of partnerOnePaySource*partnerOnePercent with PaySource coming from row 3 column 13 (M3), though I'm not sure why.
Alright everyone, after reading over my code, I realized how I could use the getActiveCell method within the PaySource variables.
var partnerOnePercent = sheet.getRange("G2").getValue();
var partnerOnePaySource = ss.getActiveCell().getValue();
var partnerTwoPercent = sheet.getRange("G3").getValue();
var partnerTwoPaySource = ss.getActiveCell().getValue();
var partnerThreePercent = sheet.getRange("G4").getValue();
var partnerThreePaySource = ss.getActiveCell().getValue();
With this I was able to fix my problem and it now works.

Not working: Code to send email reminder based on date

Wazzup guys, thanks to this website, I was able to get a code that allows sending email reminders. Now, I wanted to send only reminders based on date, particularly when the Reminder date matches the date today. I found out this awesome post, but was still not able to make it work.
I tried several attempts to google similar cases, but to no avail. The code is actually working without the "based on date" condition, but I can't seem to work it out. I tried changing formats, used the "Utilities" in the script, but still nothing.
Below is how the sheet looks like and as well the code. So on the current data, I should be receiving an email reminder for the "Go to gym" task, but I don't get any (I've included my correct email in column A though).
Where could have this gone wrong? Hoping for your insights and guidance on this. Thanks!
var EMAIL_SENT = "Yes";
function sendEmails() {
var now = new Date().toLocaleDateString();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var startRow = 2;
var sheet = ss.getSheetByName ('Tasks')
var numRows = sheet.getLastRow();
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[0];
var message = row[2];
var ReminderDate = row[3];
var emailSent = row[4];
var subject = "Task reminder: "+row[1];
if (ReminderDate != now)
continue;
if (emailSent != EMAIL_SENT) {
message = "Good day! This is to remind you of a spefic task: "+ message +". \n\nThis reminder was triggered by the task monitoroing sheet: "+ ss.getUrl()
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 5).setValue(now);
SpreadsheetApp.flush();
}
}
}
Issue:
At Spreadsheet, when the date is used, the value retrieved by getValue() and getValues() is the date object. In your script, when row[3] of var row = data[i] is the date object, if (ReminderDate != now) is always false.
Modified script:
In order to avoid above issue, please modify as follows, because now of if (ReminderDate != now) is var now = new Date().toLocaleDateString();.
From:
var ReminderDate = row[3];
To:
var ReminderDate = row[3].toLocaleDateString();
Reference:
toLocaleDateString()

importing JSON to google sheets gives getRrange-error

I'm having troubles importing json data to google spreadsheets using google script. I have no java knowledge so sorry if the question is a bit stupid!
I do code a bit of VBA so I'm not completely unaccustomed to code.
I'm trying to pull the live exchange-rate from a cryptocurrency-exchange's API. I managed to get it to work with a different exchange's API, but here the json looks slightly different.
The JSON I can't get into google spreadsheets looks like this;
{"success":true,"message":"","result":{"Bid":0.00011437,"Ask":0.00011447,"Last":0.00011447}}
I have checked json on https://jsonlint.com/ and it checks out ok.
The code I use is this;
1 function pullJSON_XRP() {
2 var ss = SpreadsheetApp.getActiveSpreadsheet();
3 var sheets = ss.getSheets();
4 var sheet = ss.getActiveSheet();
5 Logger.log(sheets)
6 var url="https://bittrex.com/api/v1.1/public/getticker?market=BTC-XRP"; // JSON call URL
7
8 var response = UrlFetchApp.fetch(url);
9 var dataAll = JSON.parse(response.getContentText());
10 var dataSet = dataAll;
11 Logger.log(dataSet)
12 var rows = [],
13 data;
14 Logger.log(rows)
15
16 for (i = 0; i < dataSet.rows; i++) {
17 data = dataSet[i];
18 rows.push(data.result.Bid, data.result.Ask, data.result.Last); //JSON entities
19 }
20
21 dataRange = sheet.getRange(3, 1, rows.length, 3); // 4th Denotes total number of entites
22 dataRange.setValues(rows);
23 }
I get an error on row 21. The error message is in Swedish and remains in Swedish even though I changed my language on google but it reads something like: "Range coordinates or size invalid. At first at thought this was because dataRange = sheet.getRange(3, 1, rows.length, 3); mismatched the array for some reason. I have spent hours searching and testing but to no avail. I now suspect that my parsed json isn't being addressed correctly in rows.push(data.result.Bid, data.result.Ask, data.result.Last);
I have tried just using the ids data.Bid, data.Ask, data.Last but I still get the same error.
Any help would be so appreciated! =)
Thank you for taking the time!
Humbly,
Brian
This is a simple way:
function pullJSON_XRP() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheet = ss.getActiveSheet();
var url="https://bittrex.com/api/v1.1/public/getticker?market=BTC-XRP"; // JSON call URL
var response = UrlFetchApp.fetch(url);
var dataAll = JSON.parse(response.getContentText());
var values=[[ dataAll.result.Bid,dataAll.result.Ask,dataAll.result.Last]]
sheet.getRange("A3:C3").setValues(values)
}

Categories