Google Script appendRow() fails - javascript

Everytime I try appendRow() I just get [Ljava.lang.Object;#4ed3710 in my spreadsheet.
function my() { //does not work
var ssMASTER = SpreadsheetApp.openById('1e4-----vQX');
var shMASTER = ssMASTER.getSheetByName('master_request');
var valuesMASTER = shMASTER.getDataRange().getValues();
var valuesPermaWrt = new Array();
valuesPermaWrt.push(["WhatEverItem"]);
Logger.log("writing:" + valuesPermaWrt); //Log: WhatEverItem
ssMASTER.appendRow([valuesPermaWrt]); //fails
}
I followed the solution from elias91:
var orderString = timeStamp + "," + ordNum + "," + clc + "," + orderRng.toString();
var orderValues = orderString.split(",");
from the Google Sheets: How to appendRow with 2d getValues array?
to create my failed version like here:
function blablaArray() { //does not work
var ssMASTER = SpreadsheetApp.openById('1e61------IuFV');
var shMASTER = ssMASTER.getSheetByName('master_request');
var valuesMASTER = shMASTER.getDataRange().getValues();
Logger.log("writing:" + valuesMASTER[0]);
//Log: [Timestamp, currently, scheduled in, Pin number]
var preappendMe = valuesMASTER[0].toString();
var appendMe = new Array();
var appendMe = preappendMe.split(",");
ssMASTER.appendRow([appendMe]); //fails
}
I know appendRow() is described here https://developers.google.com/apps-script/reference/spreadsheet/sheet#activate. But copy-pasting variables 10 times seems like a hack rather a programmatic solution, so I want it to be done through Array and not like here through each String variable.
function blablaSS() { //works fine
var ssMASTER = SpreadsheetApp.openById('1e61-----xAU');
var shMASTER = ssMASTER.getSheetByName('master_request');
var singularvalue = "ede";
ssMASTER.appendRow(["a man", singularvalue, "panama"]);
}

Try calling JSON.stringify() on your data before appending to the Google Sheet.
var valuesPermaWrt = new Array();
valuesPermaWrt.push(JSON.stringify(["WhatEverItem"]));
ssMASTER.appendRow(valuesPermaWrt);

Related

.length not working on array in Google Apps Script

I have this code. I want to loop through the array and create a new doc for each entry. If I manually set the loop length to the number of rows it works fine. I want to set it to loop for the length of the array. However the .length property always returns null. What am I missing. I have also tried for each loops with no luck.
function createDocument()
{
//var headers = Sheets.Spreadsheets.Values.get('fileID', 'A1:Z1');
var studentHistory = Sheets.Spreadsheets.Values.get('fileID', 'A2:Z200');
var templateId = 'fileID';
var documentId;
var dstFolder = DriveApp.getFolderById('folderID');
var length = studentHistory.length;
Logger.log(studentHistory);
Logger.log(length);
//Loop through rows in sheet
for (var i = 0; i < length; i++){
//Get values from sheet row
var date = studentHistory.values[i][0];
var studentName = studentHistory.values[i][1];
var dob = studentHistory.values[i][2];
var pcDoctor = studentHistory.values[i][3];
var address = studentHistory.values[i][4];
var fgName = studentHistory.values[i][5];
var mgName = studentHistory.values[i][6];
var phoneMom = studentHistory.values[i][7];
var phoneDad = studentHistory.values[i][8];
var empMom = studentHistory.values[i][9];
var empDad = studentHistory.values[i][10];
var livesWith = studentHistory.values[i][11];
var childrenInHome = studentHistory.values[i][12];
var childrenNotInHome = studentHistory.values[i][13];
var othersInHome = studentHistory.values[i][14];
var illnesses = studentHistory.values[i][15];
var illnessDetails = studentHistory.values[i][16];
var hospitalizations = studentHistory.values[i][17];
var hospDetails = studentHistory.values[i][18];
var trauma = studentHistory.values[i][19];
var traumaDetails = studentHistory.values[i][20];
var injuries = studentHistory.values[i][21];
var injuryDetails = studentHistory.values[i][22];
var medications = studentHistory.values[i][23];
var additionalComments = studentHistory.values[i][24];
var otherSchools = studentHistory.values[i][25];
//Make a copy of the template file
documentId = DriveApp.getFileById(templateId).makeCopy(dstFolder).getId();
//Change name of newly created document
DriveApp.getFileById(documentId).setName('SocialHistory_' + studentName + '_' + date);
var body = DocumentApp.openById(documentId).getBody();
//Insert values
body.replaceText('<<date>>', date);
body.replaceText('<<studentName>>', studentName);
body.replaceText('<<dob>>', dob);
body.replaceText('<<pcDoctor>>', pcDoctor);
body.replaceText('<<address>>', address);
body.replaceText('<<fgName>>', fgName);
body.replaceText('<<mgName>>', mgName);
body.replaceText('<<phoneMom>>', phoneMom);
body.replaceText('<<phoneDad>>', phoneDad);
body.replaceText('<<empMom>>', empMom);
body.replaceText('<<empDad>>', empDad);
body.replaceText('<<livesWithe>>', livesWith);
body.replaceText('<<childrenInHome>>', childrenInHome);
body.replaceText('<<childrenNotInHome>>', childrenNotInHome);
body.replaceText('<<othersInHome>>', othersInHome);
body.replaceText('<<illnesses>>', illnesses);
body.replaceText('<<illnessDetails>>', illnessDetails);
body.replaceText('<<hospitalizations>>', hospitalizations);
body.replaceText('<<hospDetails>>', hospDetails);
body.replaceText('<<trauma>>', trauma);
body.replaceText('<<traumaDetails>>', traumaDetails);
body.replaceText('<<injuries>>', injuries);
body.replaceText('<<injuryDetails>>', injuryDetails);
body.replaceText('<<medications>>', medications);
body.replaceText('<<additionalComments>>', additionalComments);
body.replaceText('<<otherSchools>>', otherSchools);
}
}
studentHistory.values is the array.
Therefore, try this instead to get the length:
var length = studentHistory.values.length;
Solution
I see you are using Advanced Google Services to call the Sheets API. This Apps Script class allows you to call the Google APIs directly from your script handling automatically the authorization process.
However it doesn't work as the built in Classes that are available for example inside the SpreadsheetApp wrapper.
Your request will return an HTTP-like response following these specifications:
{
"range": string,
"majorDimension": enum (Dimension),
"values": [
array
]
}
You will need to parse these responses in order to achieve the desired result.
Proposed modification
function createDocument()
{
//var headers = Sheets.Spreadsheets.Values.get('fileID', 'A1:Z1');
var studentHistory = Sheets.Spreadsheets.Values.get('fileID', 'A2:Z200');
var templateId = 'fileID';
var documentId;
var dstFolder = DriveApp.getFolderById('folderID');
var length = studentHistory.values.length;
...
Reference
Google Sheets API
Advanced Google Services

Google doc doesn't want to convert to a pdf after table data reaches 2000 lines

I want to convert a dynamically created document to a PDF. It works when there is not a lot of data in the doc. However if my table's lenght goes above a certain value it does not want to work. Does anyone know what I can do?
function myFunction() {
var tempFolder = DriveApp.getFolderById("FOLDER_ID");
var tempDoc = DriveApp.getFileById("tEMP_DOC_ID");
var tempFile = tempDoc.makeCopy(tempFolder);
var table = tableDat2.map(function(r) {
return [r[0].toString(), r[1], r[4], Number(r[7]).toFixed(2), Number(r[9]).toFixed(2), Number([10]).toFixed(2), Number(r[11]).toFixed(2)]
});
table.unshift(headingData[0]);
var DocUse = DocumentApp.openById("DOCUMENT_O_USE ID");
var body = DocUse.getBody();
var style = {};
style[DocumentApp.Attribute.FONT_SIZE] = 6;
body.replaceText("{shopName}", shopName);
body.replaceText("{Street}", street);
body.replaceText("{Suburb}", suburb);
body.replaceText("{City}", city);
body.replaceText("{Country}", country);
body.replaceText("{telephoneNumber}", telephoneNo);
body.replaceText("{email}", email);
body.replaceText("{orderDate}", orderDate);
body.replaceText("{sdd}", sDD);
body.replaceText("{rd}", rD);
body.replaceText("{parameter}", param);
body.replaceText("{order}", orderNo);
body.replaceText("{totalValue}", totalVal);
body.replaceText("{totalWeight}", totalWeight);
body.replaceText("{totalPallets}", totalPal);
body.appendTable([headingData[0]]);
var tab = body.appendTable(table);
tab.setAttributes(style);
DocUse.saveAndClose();
var pdfFolder = DriveApp.getFolderById("FOLDER'S ID");
var PDF1 = DocUse.getAs(MimeType.PDF);
var PDF = pdfFolder.createFile(PDF1).setName("Quotation of: " + shopName + "Order no: " + orderNo);
return PDF;
}

filter google calendar by regex using google app script

I only want to display certain entries in my google calendar.
I would like to use regular expressions for that (^([0-9]+day).
in my prototype I get full of mistakes:
TypeError: "0"
function myFunction() {
var cal = CalendarApp.getCalendarById("sl5something#gmail.com")
var now = new Date();
var events = cal.getEventsForDay(now)
for(var i = 0; i<events.length;i++){
title = events[i].getTitle()
var ar = title.match(/^([0-9]+day)/)
var preTitle = ar[0]; // <===== TypeError: "1"
var postTitle = ar[1];
if(preTitle){
Browser.msgBox(preTitle + ":" + postTitle)
}
}
}
this works as expected:
function myFunction() {
var cal = CalendarApp.getCalendarById("someEmail#gmail.com")
var now = new Date();
var events = cal.getEventsForDay(now)
for(var i = 0; i<events.length;i++){
title = events[i].getTitle()
var ar = title.match(/^([0-9]+day)(.*)/)
if(!ar) // <==== this helps
continue
var preTitle = ar[1]; // <===== no TypeError: "1"
var postTitle = ar[2];
Browser.msgBox(preTitle + " ### " + postTitle)
}
}

How to .setValue of a cell in spreadsheets being copied/named in a for loop?

I (with help) created a script that creates folders, copies a file 15 times, renames the file, and puts the new renamed files into the folders it created.
I am trying to edit the script so it uses .setValue to edit the new file it has copied, setting the "I9" cell of the new copied files to:
.setValue('=IMPORTRANGE("ID", "Question Details!C' + j + 3 + ':AX' + j + 3 + ')');
I don't know how to edit the newly created spreadsheets as its looping through and creating them. I'm not sure how to edit a sheet that is an "object" in the script. When I would run the script, it would say it couldn't get copySheet.getRange(1,9,1,1); of an object.
Now, I was trying to use "J" from the for loop in the new formula added to this cell so I can get it to increase dynamically according to the value of "J" and I can't get it to work. (This for loop is used to increase the number in the name of the sheet already) I'm sure that my syntax is way off. But, forgive me. I am still learning and really enjoy learning from the help on SO.
I also wondered if it made more sense to set it to loop through the these new folders/files afterwards and edit the "I9" cell in each? Not sure...
SCRIPT BELOW
The code that I tried to add in script is notated at the bottom of the script. I'm sure it's way off base, but I'm trying. Any help you guys could give me would be much appreciated!
Thanks!
Brandon
var folderIds = [];
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Data System Tool')
.addItem('Create Data System Folders', 'copyAndRenameTemplate')
.addToUi();
}
function copyAndRenameTemplate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var rangeOfFileNames = ss.getRange("B4:B");
var twoD_Array = rangeOfFileNames.getValues();
var arrayOfFileNames = twoD_Array.join().split(",");
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
Logger.log(folderType);
Logger.log(cell);
// throw new Error('Script Halted! Check out the logs!!');
var fldrNamesRng = theSheet.getRange(4,1,theSheet.getLastRow()-3,1);
Logger.log('fldrNamesRng: ' + fldrNamesRng);
var folderNames = fldrNamesRng.getValues();
Logger.log('folderNames: ' + folderNames);
var oneD_FolderNames = folderNames.join().split(",");
Logger.log('oneD_FolderNames: ' + oneD_FolderNames);
makeTheFolders(oneD_FolderNames);
putFilesIntoFolders(oneD_FolderNames);
};
function makeTheFolders(theFolderNames,cell) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
var i=0,
folderObj;
for (i=0;i<theFolderNames.length;i+=1) {
folderObj = DriveApp.createFolder(theFolderNames[i] + " " + cell);
folderIds.push(folderObj.getId())
};
};
function putFilesIntoFolders(arrayOfFolderNames,theFolderNames,cell) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
var file = DriveApp.getFileById("File to Copy");
var dest_folder = "";
var baseFileName = "",
newfile,
newFileName = "",
i=0,
j=0;
for (i=0;i<arrayOfFolderNames.length;i+=1) {
var source_folder = DriveApp.getFolderById("Folder that has File to be Copied");
dest_folder = DriveApp.getFolderById(folderIds[i]);
Logger.log('dest_folder' + dest_folder);
baseFileName = arrayOfFolderNames[i];
for (j=1; j<16; j+=1) {
var newFileName = baseFileName + " " + cell + " " + j.toString();
var fileCopy = file.makeCopy();
/* Code I tried */
// var copyID = fileCopy.getId();
// var copySs = DriveApp.getFileById(copyID);
// var copySheet = copySs.getSheets()[0];
// var copyCell = copySheet.getRange(1,9,1,1);
// copyCell.setValue('=IMPORTRANGE("ID", "Question Details!C' + j + 3 + ':AX' + j + 3 + ')');
var namedFileCopy = fileCopy.setName("_" + newFileName);
if (j<10) {
dest_folder.addFile(namedFileCopy);
source_folder.removeFile(fileCopy);
} else {
var namedFileCopy = fileCopy.setName(newFileName);
dest_folder.addFile(namedFileCopy);
source_folder.removeFile(fileCopy);
};
};
};
};
You've got the right idea, you just need to make sure you open the new (copied) spreadsheet as a Spreadsheet object so that you can use Spreadsheet methods on it.
Instead of:
var copySs = DriveApp.getFileById(copyID);
Use:
var copySs = SpreadsheetApp.openById(copyID);
By doing so, copySs will be a variable that represents a Spreadsheet object, and the other lines you already wrote will actually make sense!
var copySheet = copySs.getSheets()[0];
var copyCell = copySheet.getRange(1,9,1,1);
copyCell.setValue('=IMPORTRANGE("ID", "Question Details!C' + j + 3 + ':AX' + j + 3 + ')');

Storing information in cookies

Does anyone know powerfull class for storing information in cookies?
I just want write something like:
var cookieStorage = new cookieStorage(100); // 100 - time to store data
var apple = {size:10, color:'red',weight:100};
cookieStorage.set('MyApple',apple);
var restoredApple = cookieStorage.get('MyApple');
My implementation(without time to storing)
var cookieStorage = {
set: function (key, value) {
$.cookie(key, $.toJSON(value));
},
get: function (key) {
var json = $.cookie(key);
return $.parseJSON(json);
}
}
Here is cookie plugin
You can use the JSON library to achieve this. You can download JSON here: https://github.com/douglascrockford/JSON-js
I created a simple example for you. If you want to make it short, you can use JQuery-cookie.
function setCookie(){
var current = new Array();
var user = new Object();
user.FirstName = "Robby";
user.LastName = "Shaw";
current.push(user); //The test value
var exdate=new Date();
exdate.setDate(exdate.getDate()+5); //Expire in 5 days
var cname = "test"; //cookie name
var value = JSON.stringify(current); //Parse the array
document.cookie=cname+ "=" +escape(value)+ ";expires="+exdate.toGMTString();
}
function getCookie(){
var current = new Array();
if (document.cookie.length>0){
c_start=document.cookie.indexOf("test=");
if (c_start!=-1)
{
c_start=c_start + c_name.length+1
c_end=document.cookie.indexOf(";",c_start)
if (c_end==-1) c_end=document.cookie.length
current = JSON.parse(unescape(document.cookie.substring(c_start,c_end)));
alert(current[0].FirstName+","+current[0].LastName);
}
}
}

Categories