Spreadsheet isn't opened by openById() - javascript

maybe you can help me with my problem I tried to fix for hours. I have a function that should copy some values of cells of a row, if in column 6 of the row the value is being set to 6, to another spreadsheet. I already used ui.alert() to know where the function stops to work and it's when I overwrite the variable ss = SpreadsheetApp.getActiveSpreadsheet() with ss = SpreadsheetApp.openById('123456789'). I already made this in another Google Script and there it worked!
Here you can see my Code:
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
ui.createMenu('xyz')
.addItem('xyz', 'menuItem1')
.addToUi();
}
function menuItem1() {
var row = SpreadsheetApp.getActiveSheet().getActiveCell().getRow();
var col = 2;
var x = SpreadsheetApp.getActiveSheet().getRange(row, col).getValue();
var y = Browser.inputBox(titletranslation , 'Please enter the translation here', Browser.Buttons.OK_CANCEL);
if(y != "cancel" && y != "") {
var id ="123456789"
doc = DriveApp.getFileById(id).makeCopy(y)
doc.setSharing(DriveApp.Access.ANYONE_WITH_LINK,DriveApp.Permission.EDIT)
var url = doc.getUrl()
SpreadsheetApp.getActiveSheet().getRange(row, 5).setValue(url)
}
}
function onEdit(event){
var row = event.range.getRow()
var column = event.range.getColumn()
if(column == 6) {
if(ss.getActiveSheet().getRange(row, column).getValue() == 6) {
var x = ss.getActiveSheet().getRange(row, 1)
var y = ss.getActiveSheet().getRange(row, 2)
var z = ss.getActiveSheet().getRange(row, 3)
var xx = ss.getName()
var yy = ss.getActiveSheet().getRange(row,4)
ss = SpreadsheetApp.openById('123456')
ss.setActiveSheet(ss.getSheetByName('Need to be published'))
ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,1).setValue(x)
ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,2).setValue(y)
ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,3).setValue(z)
ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,4).setValue(xx)
ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,5).setValue(yy)
}
}
}
Hope you know what the problem is :)
Thanks in advance

The problem is the combination of
var x = ss.getActiveSheet().getRange(row, 1)
and
ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,1).setValue(x)
Lets transform it to:
var range1 = ss.getActiveSheet().getRange(row, 1);
var range2 = ss.getActiveSheet().getRange(ss.getActiveSheet().getLastRow() + 1,1);
range2.setValue(range1);
range1 (or x) is not a value, and thus using it as a parameter for the method setValue() is wrong, see the documentation.
If what you want is to assign the value of range1 to range2, the correct syntax would be
var value = range1.getValue();
range2.setValue(value);
You should change all lines where you use the method setValue() accordingly.

Related

GAS Function not setting value as intended in sheet

This is the Google Sheet, it can be copied: https://docs.google.com/spreadsheets/d/1ffIRGiGkiy5WFzSAvWNOY_3cqNXgTAOtO6o8vxS-BFU/edit?usp=sharing
The Function 'AddNewMembers' does not function, even if "isAdded == "No" it will not setValue(recruit_id)
function AddNewMembers(event){
event = {range: SpreadsheetApp.getActiveRange()}
CheckHandleSteamIDNotation(event)
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var recruitment_log = ss.getSheetByName('RL1');
var main_roster = ss.getSheetByName('Main Roster');
var isAdded = recruitment_log.getRange('R3').getValue();
if(isAdded == "No") {
var recruit_id = "'" + recruitment_log.getRange('J3').getValue();
main_roster.getRange('I100').setValue(recruit_id);
}
}
function CheckHandleSteamIDNotation(event)
{
let formSheet = SpreadsheetApp.getActiveSheet();
let header = formSheet.getRange(1,1,1,formSheet.getMaxColumns()).getValues();
let formRange = formSheet.getRange(formSheet.getLastRow(), 1, 1, formSheet.getMaxColumns());
let formValues = formRange.getValues();
for(let i = 0; i < header[0].length; i++)
{
if(header[0][i].includes("SteamID"))
{
formValues[0][i] = "'" + formValues[0][i];
}
}
formRange.setValues(formValues);
}
Since the provided script above contains var isAdded = recruitment_log.getRange('R3').getValue(); the value of R3 is currently set to "Yes" that is why the condition for the script below is not running.
if(isAdded == "No") {
var recruit_id = "'" + recruitment_log.getRange('J3').getValue();
main_roster.getRange('I100').setValue(recruit_id);
}
Try this modification:
function AddNewMembers(event) {
event = { range: SpreadsheetApp.getActiveRange() }
CheckHandleSteamIDNotation(event)
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var recruitment_log = ss.getSheetByName('RL1');
var main_roster = ss.getSheetByName('Main Roster');
//Gets all the data values on recruitment_log
var isAdded = recruitment_log.getRange(3, 1, recruitment_log.getLastRow(), recruitment_log.getLastColumn()).getValues();
//Gets the last row starting I17
var lastrow = main_roster.getRange(17, 9, main_roster.getLastRow() , 1).getValues().filter((x => x > 1)).length
//Sets the value on the last blank row
isAdded.map(x => x[17].toString().toLocaleLowerCase() == "no" ? "'" + main_roster.getRange(17 + lastrow,9).setValue(x[9]) : x)
}
I made modifications on your isAdded variable to the following to get the entire range of data on RL1 sheet.
var isAdded = recruitment_log.getRange(3, 1, recruitment_log.getLastRow(), recruitment_log.getLastColumn()).getValues();
This part of script was only used to get the current length of data for the New Operatives. Using .filter() method to filter out empty array elements, since getValues() gets blank cells if there is formatting applied on the spreadsheet.
var lastrow = main_roster.getRange(17, 9, main_roster.getLastRow() , 1).getValues().filter((x => x > 1)).length
Using ES6 .map() method to create a new array for the data that hasn't been added to the main roster sheet file.
isAdded.map(x => x[17].toString().toLocaleLowerCase() == "no" ? "'" + main_roster.getRange(17 + lastrow,9).setValue(x[9]) : x)
Screenshot:
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#description

Log changes on Google Script (Google Spreadsheets)

I'm looking to create a spreadsheet where it logs data and the changes you make on it.
For example in sheet, I used a Google Script to do it but instead of only logging in a particular row when you change the data on Sheet1, it copies all the data you changed since the beginning on Sheet 2. I only want to log a particular row each time I make a change.
Here's my code
* Retrieves all the rows in the active spreadsheet that contain Yes
* in the Include column and copies them to the Report sheet.
*/
function myFunction() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Sheet1");
var tarSheet = sSheet.getSheetByName("Sheet2");
var lastRow = srcSheet.getLastRow();
for (var i = 2; i <= lastRow; i++) {
var cell = srcSheet.getRange("B" + i);
var val = cell.getValue();
if (val == 'Yes') {
var srcRange = srcSheet.getRange("A" + i + ":D" + i);
var tarRow = tarSheet.getLastRow();
tarSheet.insertRowAfter(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":D" + (tarRow+1));
srcRange.copyTo(tarRange);
}
}
};
Can anyone please help?
Use onEdit(e)
function onEdit(e) {
var srcSheet = e.source.getActiveSheet();
if (srcSheet.getSheetName() !== 'Sheet1') { return; }
var row = e.range.rowStart;
var cols = 4;
var srcRange = srcSheet.getRange(row, 1, 1, cols);
var values = srcRange.getValues()[0];
if (values[1] == 'Yes') {
var tarSheet = e.source.getSheetByName('Sheet2');
tarSheet.appendRow(values);
}
}

Exception: Argument cannot be null: prompt Error in google Scripts

I have created a mail merge with a confirmation pop up in order to confirm the script has not been run recently, and also to double check the user intends to send emails. The script works perfectly, but annoyingly I receive the following error when run:
Stating; Exception: Argument cannot be null: prompt
I would like to get rid of this if possible. I attach my code.
//Creates a functional log of how many emails are sent and to how many branches
function confirmationWindow(){
var numberSent = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Validations').getRange('D3').getValue();
var numberOfVios = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Validations').getRange('D2').getValue();
var ui = SpreadsheetApp.getUi();
var ui = SpreadsheetApp.getUi();
ui.alert(
'You have succesfully sent ' + numberOfVios + ' violations, to ' + numberSent + ' branches.',)
}
function saveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Log');
var date = new Date()
var user = Session.getActiveUser().getEmail();
var range = ss.getRange("A:B")
var numberSent = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Validations').getRange('D2').getValue();
var branchNumber = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Validations').getRange('D3').getValue();
ss.appendRow([date,user,numberSent,branchNumber]);
}
var EMAIL_SENT = 'True';
function sendEmails() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Output');
var sheetI= SpreadsheetApp.getActive().getSheetByName('Input');
var sheetC = SpreadsheetApp.getActive().getSheetByName('Control');
var emailNum = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Validations').getRange('D3').getValue();
var startRow = 2;
var numRows = emailNum;
var dataRange = sheet.getRange(startRow, 1, numRows, 6);
sheetI.setTabColor("ff0000");
saveData()
var data = dataRange.getValues();
for (var i in data) {
var row = data[i];
var emailAddress = row[3];
var message = row[5] + "\n\nT\n\nT\n\nT";
var message = message.replace(/\n/g, '<br>');
var subject = row[4];
MailApp.sendEmail(emailAddress, subject, message,{htmlBody:message});
sheet.getRange(startRow + i - 18, 8).setValue(EMAIL_SENT);
sheetC.getRange(startRow + i - 18, 3).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
confirmationWindow()
}
function recentSend() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Log');
var lastR = sheet.getLastRow();
var recentRun = sheet.getRange('A' + lastR).getValue();
if(lastR=1){var recentlySent = 'False'}
var today = new Date().valueOf()
var recentDate = recentRun
var sec = 1000;
var min = 60 * sec;
var hour = 60 * min;
var day = 24 * hour;
var difference = today - recentDate
var hourDifference =Math.floor(difference%day/hour);
if (hourDifference > '12'){var recentlySent = 'False'}
else {var recentlySent = 'True'}
return(recentlySent)
}
function recentlySentTrue(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Log');
var lastR = sheet.getLastRow();
var recentUser = sheet.getRange('B' + lastR).getValue();
var recentQuant = sheet.getRange('C' + lastR).getValue();
var recentT = sheet.getRange('A' + lastR).getValue();
var recentSendLog = recentT.toString();
var recentTime = recentSendLog.slice(16,21)
var recentDate = recentSendLog.slice(0,11)
var ui = SpreadsheetApp.getUi();
var result = ui.alert(
'Are you sure you wish to send?',
'The user, ' + recentUser + ' ,recently sent ' + recentQuant + ' emails, at ' + recentTime + ' on ' + recentDate,
ui.ButtonSet.YES_NO);
if (result == ui.Button.YES) {
ui.alert(recentlySentFalse());
}
else {
}
}
function recentlySentFalse(){
var ui = SpreadsheetApp.getUi();
var ui = SpreadsheetApp.getUi();
var result = ui.alert(
'Are you Sure you wish to send?',
'Are you sure you want to send these violations?',
ui.ButtonSet.YES_NO);
if (result == ui.Button.YES) {
ui.alert(sendEmails());
} else {
}
}
function confirm(){
var recentlySent = recentSend();
if (recentlySent == 'True'){
recentlySentTrue()
}
else{recentlySentFalse()
}
}
Any help would be great.
Explanation:
Your ui.alert() calls that have function arguments such as recentlySentFalse() are not valid, since the functions do not have return statements, hence they return the default value of null. ui.alert() calls need at least a prompt message.
Solution 1:
Put the function call after the UI alert message:
if (result == ui.Button.YES) {
ui.alert('Sending message...');
recentlySentFalse();
}
Solution 2:
If you do not want excessive alerts, just remove ui.alert and call the function immediately.
if (result == ui.Button.YES) {
recentlySentFalse();
}
References:
Class UI | Apps Script

Trigger onEdit(e) does not trigger

When I've tried just to setValue("random") to some cell with this trigger it does work, but when I've tried to execute this code(for returning certain sheet names from selected spreadsheet) it doesn't work! When I run that chunk of code as separate function it does work and return sheets normally.
So, why it doesn't execute part of code from "//RETURNING JUST BUILDING LIST" part when I change value in D2 cell?
function onEdit(e) {
var range = e.range;
var rangeEdit = e.range.getA1Notation();
if(rangeEdit == "D2"){
//RETURNING JUST BUILDING LIST
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheetsByName("OVERVIEW").getRange('A2').setValue("OK")
var sRNG = ss.getSheetByName("KEYS").getRange('A1:A12').getValues();
for (var z=0; z<sRNG.length; z++)
if (sRNG[z][0] == ss.getSheetByName("OVERVIEW").getRange('G3').getValue()) {
var xyz = z + 1;
}
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = ss.getSheetByName("OVERVIEW").getRange(1, 8, 50, 1);
range.clear();
var shArray = [];
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var spreadSheetsInA =
SpreadsheetApp.openByUrl(ss.getSheetByName("KEYS").getRange('B' + xyz).getValue()).getSheets();
shArray = spreadSheetsInA.map(function(sheet) {
return [sheet.getName()];
});
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = ss.getSheetByName("OVERVIEW").getRange(1, 8, shArray.length, 1);
range.setValues(shArray);
var rDEL = 1
for (var xdel = 0; xdel<shArray.length; xdel++){
if(shArray[xdel][0].indexOf("Overview")>-1 | shArray[xdel][0].indexOf("Cashflow")>-1 | shArray[xdel][0].indexOf("Dates")>-1){
var delSHT = ss.getSheetByName("OVERVIEW");
delSHT.getRange('H' + rDEL).clear();
}
rDEL++
}
}
}
Even when I've tried this, it doesn't work...
function onEdit(e) {
var range = e.range;
var rangeEdit = e.range.getA1Notation();
if(rangeEdit == "D2"){
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheetsByName("OVERVIEW").getRange("A2").setValue("ok")
}
}
Basically, I just need to execute code if value in D2 in sheet Overview is changed!

My variable doesn't seem to be updating within a for loop

I'm working on a simple google script for a spreadsheet that will go down a column in the sheet and update the column next to it based on information pulled from links in the original column.
The problem is that the same output is being output regardless of the input column. My code is here:
function idThatSucka() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("F2:F20");
for (var y = 1; y <= range.getHeight(); y++) {
var logCell = ss.getRange("E"+y+":E"+y);
var url = ss.getRange("F"+y+":F"+y).getValue();
if (url){
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
var theLog = Logger.getLog();
var start = theLog.split('</title>')[0];
var output = start.split('Steam Community :: ')[1];
logCell.setValue(output);
}
}
}
I suspect that "url" might not be updating, but nothing I've tried so far has fixed the problem.
Try like this
function idThatSucka() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("F2:F20");
for (var y = 1; y <= range.getHeight(); y++) {
var url='';
var logCell='';
logCell = ss.getRange("E"+y+":E"+y);
url = ss.getRange("F"+y+":F"+y).getValue();
if (url){
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
var theLog = Logger.getLog();
var start = theLog.split('</title>')[0];
var output = start.split('Steam Community :: ')[1];
logCell.setValue(output);
}
}
}

Categories