ReferenceError: calendarId is not defined - google-sheets

New to any form of coding.
I am trying to sync Google calendars to Google sheets to autogenerate events. I found this script online but continue to have errors.
This is my current code:
function scheduleShifts() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarID = spreadsheet.getRange("C4").getValue();
var eventCal = CalendarApp.getCalendarById(calendarId);
var signups = spreadsheet.getRange("A8:C20").getValues();
for (x=0; x<signups.length;x++){
var shift = signups[x];
var startTime = shift[0];
var endTime = shift[1];
var volunteer= shift[2];
eventCal.createEvent(volunteer, startTime, endTime);
}
}
The error code I keep getting is:
ReferenceError: calendarId is not defined
scheduleShifts # Code.gs:4
I can't seem to figure out how to correct it. Any suggestions?
Thanks!
Screenshot of Error

calendarID is not equal to calendarId. Take a look to the d/D.

Related

CopyTo Google sheets

I'm trying to get this code to work but keep getting a "TypeError: offset.copyTo is not a function". The script is supposed to take one value from sheet "Budget" and copy it into the next available row in column F on sheet "Projected".
I have tried playing around with syntax and other ways to copy but to now avail, any help would be greatly appreciated
function OffsetRecord() {
var sheet = SpreadsheetApp.openById("xx").getSheetByName("Budget");
var offset = sheet.getRange('I5').getValue();
var destSheet = SpreadsheetApp.openById("xx").getSheetByName("Projected");
var colF = destSheet.getRange('F:F').getValues();
var fcolF = colF.filter(function (e) {return e[0];});
var firstEmptyRowIncolF = fcolF.indexOf('')+1;
offset.copyTo(firstEmptyRowIncolF, {contentsOnly: true});
copyTo expects ranges as parameters, not values or column numbers, see here
Modify your code as following:
function OffsetRecord() {
var spreadsheet = SpreadsheetApp.openById("XX");
var sheet = spreadsheet.getSheetByName("Budget");
var offset = sheet.getRange('I5');//without ".getValue();"!
var destSheet = spreadsheet.getSheetByName("Projected");
...
firstEmptyRowIncolF = ...;
var destinationColumn = 1;
var range = destSheet.getRange(firstEmptyRowIncolF, destinationColumn);
offset.copyTo(range, {contentsOnly: true});
}

Google Sheets - Start Macro while cell is still open

I'm still SUPER new to Google Sheets, I've mostly just programmed in VBA before this.
The project I'm working on is for a D&D type game, wherein the DM will use Sheet to record damage dealt to the monster. Basically the DM types the damage, clicks the calculate button, then the code sums up the current damage to baddie.
The code works perfectly. The problem I'm having is a human one. There is a tendency to click the "calculate" button before closing the cell.
For instance, the DM types 31 in the cell and immediately clicks "calculate" before hitting enter. This prevents the damage from being recorded properly and I can't figure out the code to make the cell close first.
Here is my current code:
function DamageRecordEnemy1Copy1() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').activate();
var DamageLocation = spreadsheet.getRange('Q4');
var DamageLogLocation = spreadsheet.getRange('Q5');
var DamageLocationValue = DamageLocation.getValue();
var DamageLogLocationValue = DamageLogLocation.getValue();
var NewDamage = DamageLocationValue + DamageLogLocationValue;
DamageLocation.activate();
spreadsheet.getCurrentCell().setValue(NewDamage);
DamageLogLocation.activate();
spreadsheet.getCurrentCell().setValue("");
spreadsheet.getRange('A1').activate();
}
Any idea how to solve the issue? Much appreciated!
Thanks for the help everyone, here is what I ended up doing:
function onEdit(e){
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = e.range;
var DamageLocation = spreadsheet.getRange('Q4');
var DamageLogLocation = spreadsheet.getRange('Q5');
var DamageLocationValue = DamageLocation.getValue()
var DamageLogLocationValue = DamageLogLocation.getValue()
var allRows = [5];
var allColumns = [17, 20, 23, 26, 29, 32];
var EditRow = range.getRow()
var EditColumn = range.getColumn()
if (allColumns.indexOf(EditColumn) > -1)
{
if (allRows.indexOf(EditRow) > -1)
{
var BadDamage = spreadsheet.getRange(EditRow-1,EditColumn)
var BadDamageLog = spreadsheet.getRange(EditRow,EditColumn)
var DamageCalc = BadDamage.getValue() + BadDamageLog.getValue()
BadDamage.setValue(DamageCalc);
BadDamageLog.setValue("");
}
}
};
Replace the "button" with insert->checkbox then use the OnEdit function to check if that cell was set to true, execute your button code and set it back to false. The reason this will work is because Drawings are on it's own layer but the checkbox will force them to have the "hit enter" behavior.

Series of Basic Google Sheet functions combined

So I am new to Google Sheets. I am making an inspection report for a small company using Sheets. I would like to add a button to the bottom of the sheet which does the following script:
Duplicate original sheet
Rename sheet to a cell value +today's date. i.e Fred01011980
Email the sheet as a PDF to a recipient.
Finally clear the inputted values in the original master template sheet.
I have looked up how to do each of these and a few of them are straightforward, but I don't know how to combine them. Can I just add all of the functions individually together without any additional syntax needed? Any help on this would be really appreciated. Thank you.
I believe you can just create another function that calls your functions, like this:
function doAllStuff() {
doStuff();
doMoreStuff();
}
Here's how I did it:
function AllinOne() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var name = "Inspection";
var sheet = ss.getSheetByName("Inspection").copyTo(ss);
var newname = ss.getSheetByName("Inspection").getRange(2, 2).getValue();
var newnamedate = ss.getSheetByName("Inspection").getRange(3, 2).getValue();
var sheetx = ss.getActiveSheet()
var thisSheet = sheetx.getName();
var actualSheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName()
var sheetfinal = ss.getSheetByName("Inspection")
var old = ss.getSheetByName(newname+newnamedate);
if (old) ss.deleteSheet(old);
sheet.setName(newname+newnamedate); //copies the sheet and renames it to "store+date"
ss.setActiveSheet(sheet)
// below is pdf conversion
var originalSpreadsheet = SpreadsheetApp.getActive();
var sourcesheet = originalSpreadsheet.getActiveSheet();
var sourcerange = sourcesheet.getRange('A1:B176'); // range to get - here I get all of columns which i want
var sourcevalues = sourcerange.getValues();
var data = sourcesheet.getDataRange().getValues();
var newSpreadsheet = SpreadsheetApp.create(thisSheet); // can give any name.
var sheetnow = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
var sheetz = sourcesheet.copyTo(newSpreadsheet);
var destrange = sheetz.getRange('A1:B176');
destrange.setValues(sourcevalues);
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
var pdf = DriveApp.getFileById(newSpreadsheet.getId());
var theBlob = pdf.getBlob().getAs('application/pdf').setName(newname+newnamedate);
var folderID = "File_ID"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var newFile = folder.createFile(theBlob);
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
MailApp.sendEmail("Email","New Manager Inspection: "+newname+newnamedate, "A new Manager Inspection Report has been added to the Drive.");
ss.getSheetByName(name).getRangeList(["B176","B150:B164","B138:B146","B129:B134","B119:B125","B106:B115","B99:B102","B84:B95","B78:B80","B66:B74","B55:B62","B48:B51","B34:B44","B25:B30","B18:B21","B10:B14","B4:B7","B2","B16","B23","B32","B46","B53","B53","B64","B76","B82","B97","B104","B117","B127","B136","B148","B166"]).clearContent();
ss.setActiveSheet(sheetfinal);
SpreadsheetApp.getUi().alert("Report Submitted, Please do NOT Resubmit. Thank You");
}

Google Apps - Sheets - Column for Modified By

I'm needing a column on a Google Sheet that contains Modified By information. I will be sharing this sheet with other users in our Google Apps domain. Here is the script I currently have:
function onEdit(event)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actSht = event.source.getActiveSheet();
var actRng = event.source.getActiveRange();
var actUser = Session.getActiveUser().getEmail();
var index = actRng.getRowIndex();
var dateCol = actSht.getLastColumn();
var lastCell = actSht.getRange(index,dateCol);
var date = Utilities.formatDate(new Date(), "GMT-6", "MM/dd/yyyy HH:mm");
lastCell.setValue("Modified By: " + actUser + " - " + date);
}
That returns "Modified By: at 12/15/2014 12:33" in the last column. This applies to myself (the creator of the document) as well as another test user I shared the sheet with. Any suggestions?
Turns out the OnEdit function can't pull user info. I created a custom function instead of OnEdit() and then set an On Edit trigger that pointed to that function. Then everything worked as expected.

AdWords Countdown Script for AdGroups Error

I'm trying to implement the countdown script from https://developers.google.com/adwords/scripts/docs/tutorials/countdown-sale
The script works for single Ad Group but when trying to Multiple ad groups part of I keep getting following error:
TypeError: Cannot call method "setAdParam" of undefined. (line 9)
My full script is:
// Date to use to find out how many days are remaining.
var END_DATE = new Date('February 24, 2013');
// Change this to the Ad Group you set up with text ads with AdParams.
var AD_GROUP_NAMES = ['AdGroup1', AdGroup2'];
function main() {
var timeLeft = calculateTimeLeftUntil(END_DATE);
var adGroups = getAdGroups(AD_GROUP_NAMES);
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
var keywords = adGroup.keywords().get();
// We want to update {param1} to use our calculated days and {param2} for hours.
keywords.setAdParam(1, timeLeft['days']); // HERE COMES THE ERROR
keywords.setAdParam(2, timeLeft['hours']);
}
}
var DAY_IN_MILLISECONDS = 1000*60*60*24;
function calculateTimeLeftUntil(end) {
var current = new Date();
var timeLeft = {};
var daysFloat = (end - current) / (DAY_IN_MILLISECONDS);
timeLeft['days'] = Math.floor(daysFloat);
timeLeft['hours'] = Math.floor(24 * (daysFloat - timeLeft['days']));
return timeLeft;
}
function getAdGroups(names) {
var predicateValues = "['" + names.join("','") + "']";
Logger.log(predicateValues);
return AdWordsApp.adGroups()
.withCondition('Name IN ' + predicateValues)
.withLimit(names.length)
.get();
}
The issue is that you're trying to set the ad param to a keyword iterator, not individual keywords.
Instead of this
var keywords = adGroup.keywords().get();
// We want to update {param1} to use our calculated days and {param2} for hours.
keywords.setAdParam(1, timeLeft['days']); // HERE COMES THE ERROR
Try this:
var keywords = adGroup.keywords().get();
while (keywords.hasNext()) {
var keyword = keywords.next();
// and now
keyword.setAdParam(...);
}

Resources