So I am using google sheets with google scripts to sort some data and then put it into a new sheet. I have been using the .valueOf() method to grab the data from an array that grabbed all the data using sheet.getDataRange().getValues(); and has worked perfectly with grabbing everything in all the other places besides my column containing the dates in the "dd/mm/yyyy" order. It grabs it but then puts it into my new sheet in the form of some massive number (which I think could possibly be seconds or milliseconds). I don’t want a time stamp, I want to reverse whatever that time stamp thingy is.
Example: Original Date and After grabbing date and moving to new sheet
Below I have posted the code I am using. Any help or advice is greatly appreciated!
Code: https://pastebin.com/snn3jDcH
line where I grab the date:
for(var i = 1; i < data.length; i++) {
test = data[i][2].valueOf().substring(0,5);
if(test === "ES014")
{
DateStore[count] = data[i][0].valueOf();
NameStore[count] = data[i][1].valueOf();
NumStore[count] = data[i][2].valueOf();
QuantityStore[count] = data[i][3].valueOf();
count++;
}
Sorry about the formatting, but it wouldn't let me post unless I did it this way. No clue why but sorry! Thank you for this long read!
Instead of sheet.getDataRange().getValues(); and then doing valueOf()
Simply only do sheet.getDataRange().getDisplayValues(); and I think valueOf() is not necessary.
For further informations check this out
https://developers.google.com/apps-script/reference/spreadsheet/range#getdisplayvalues
Related
I am currently trying to get App Script to read a ranges of cells from different sheets in a workbook, but I keep getting "Range not found (line 30). I have a bit of experience with Javascript, but App Script is fairly new to me, so some tips and where to find good documentation or tutorials would really help as well.
function getvalues(values2) {
var sheet = SpreadsheetApp.getActiveSheet().getRange(values2)
var raw_values = []
for (var i = 0; i < sheet.length; i++) {
raw_values.push(sheet[i])
}
return raw_values
}
Edit
Here is what the value2 is. They're ranges separated by commas, and each range is from a different sheet in the workbook.
January!W22:W35,February!W22:W35,March!W22:W35,April!W22:W35,May!W22:W35,June!W22:W35,July!W22:W35,August!W22:W35,September!W22:W35,October!W22:W35,November!W22:W35,December!W22:W35
According to the docs, getRange() doesn't seem to specify a comma separated list of ranges as a valid argument. The error is most likely because the function is trying to interpret the entire string as a single range.
You may need to retrieve each range separately and then aggregate them in some way.
I've included an example of how you might do this.
let myRanges = "January!W22:W35,February!W22:W35,March!W22:W35"
function getvalues(values2) {
let raw_values = []
values2.split(",").forEach(a1range => {
let range = SpreadsheetApp.getActiveSheet().getRange(a1range)
console.log(range.getValues())
// get the values from the range and push them to raw_values
})
return raw_values
}
getvalues(myRanges)
Additionally, it looks like getRange() will return a Range object, which doesn't directly contain the values from the range, but has the methods getValue() and getValues() to return the values from the selected cells. getValues appears to return a multidimensional array representing the rows/columns from your range, so you'll need to do some extra processing depending on how you need your data formatted.
https://developers.google.com/apps-script/reference/spreadsheet/range#getValue()
Considering that, it would probably also be a good idea to change the function name to something other than getvalues to avoid confusion.
I am new in Apps Script, and had never a chance previously to write in JavaScript.
So, I have a dataset in one sheet in Google about personal information of clients (ID, name, mail, contact). I have another dataset in another Sheet about clients payment (date of payment of the first installment, date of payment of the second installment and amount.
The last sheet that is in focus is the third one relating to unpaid bills.
Now, what I want is to copy columns about personal information from the first sheet into the third one. Here condition would be to copy only information about clients where difference between date of payment of the second installment and today() is greater than 45. Here is what I have tried:
function Neplacena2Novi() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sheetFrom=ss.getSheetByName("Podaci o polaznicima"); //Data entry Sheet
var sheetTo=ss.getSheetByName("Neplaceni racuni"); //Data Sheet
var condition=ss.getSheetByName("Uplate novoupisani");
var range1=ss.getRangeByName("Prva rata");
var range2=ss.getRangeByName("Druga rata");
var startRow=3;
var endRow=ss.getLastRow();
function Neplacena2Novi(){
for var(i=startRow; i<(endRow+1)< i++) {
var startDate=new Date(condition.getRange(range1+1).getValue());
var endDate= new Date(condition.getRange(range2+1).getValues());
var difference=parseInt(endDate-startDate)/1000); //Dates are in format dd.mm.yyyy.
if(difference>45){
var values=sheetFrom.getRange(2, 1, sheetFrom.getLastRow(), 4).getValues();
sheetTo.getRange(3,1,1184,4).setValues(values);
}
}
var ui = SpreadsheetApp.getUi();
var potvrda = ui.alert("Odredili ste lica koja treba da se pozovu.");
}
function DugmeDodajKlijenta (){
var ui = SpreadsheetApp.getUi();
}
This code works but I didn't get anything in sheet! And I didn't now how to include today() function in formula for difference. But what I really want is to make a condition where difference would be today()-startDate().
Can someone please help me?
The code is not working because endDate is not a primitive value but a 2D array. Use Range.getValue() instead of Range.getValues(), like this:
const startDate = new Date(condition.getRange(row, startDateColumn).getValue());
const endDate = new Date(condition.getRange(row, endDateColumn).getValue());
...but that is not enough to make the code work. There is a syntactical error in the for loop line, and the i variable is not referenced in the loop. The whole thing is very inefficient because it reads and writes data row by row instead of doing just one read and just one write.
The new Date() calls are superfluous unless the "dates" in the spreadsheet are not numeric dates but text strings that just look like dates. The parseInt() call is also superfluous (plus, it is missing the radix parameter.)
JavaScript dates internally contain the number of milliseconds that have elapsed since 1 January 1970 0:00 UTC. To get the difference between two dates in days, try (endDate-startDate) / 1000 / 60 / 60 / 24. Note that there are many caveats — see Date.
The whole loop could be replaced with Range.getValues().filter(). It looks like the code should best be totally rewritten.
It is unclear why you would need a script in the first place, since the same can be done with a spreadsheet formula using e.g. filter() or query(). The personal info can be added to the missing payments data with a lookup e.g. arrayformula(vlookup()).
I'm relatively new to scripting and I have spent hours getting myself to this point... so any help from here is much appreciated.
I am creating a sheets doc that calculates and generates quotes for a tradie friend of mine.
Each time He calculates a Quote on the Spreedsheet, I want to save all the data + recall it later.
On another occasion, he'll input new values into the cells & want to save all again, with a new quoteID and values, from the same spreadsheet.
Effectively, I need a saved copy of the values that can then be recalled by a particular ID later on if he wants to "regenerate" that quote..
Basically, I have an 3 arrays + 3 single cells that I want to get all values for (nailed this part)
// custom menu function
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Save Data','saveData')
.addToUi();
}
// function to save data
function saveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var writesheet = ss.getSheetByName("Saved Quotes");
var houselabour = ss.getRange("Calculating the Quote!A7:B38").getValues();
Logger.log(houselabour);
var tradelabour = ss.getRange("Calculating the Quote!E7:F38").getValues();
var materials = ss.getRange("Calculating the Quote!H7:K38").getValues();
var quoteid = ss.getRange('Calculating the Quote!B2').getValue();
var surname = ss.getRange('Calculating the Quote!B1').getValue();
var datecreated = ss.getRange('Calculating the Quote!C2').getValue();
var s1 = houselabour.toString();
var s2 = tradelabour.toString();
var s3 = materials.toString();
writesheet.appendRow([quoteid,surname,datecreated,s1+s2+s3]);
}
//function to recall data
function recallData()
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activequoteid = ss.getActiveCell("Customers").getValue();
//input values from saved data (by quoteid) into Calculating the Quote Spreadsheet... ???
Ideally, I would input these values (quoteid, surname, datecreated) into a new sheet (writesheet) and then i've made the array data into string so i can input it into a single cell (this cell doesn't need to be read, just re-called to fill in the original table later)
Later on, I want to recall the same values I originally extracted back into the original quote generator - "Calculating the Quote" sheet.
2 things: Is it possible, instead of converting the 3 arrays I have to strings, to just log them somewhere without necessarily displaying them in the sheet anywhere? It is essential that the code that runs on a dropdown menu selection "save data" saves the array data and then the next time it is run it does not overrride the original but saves as another
I have a few solutions in my head
1) name each result of the Save Data function something unique (saved as array)...
- i do not know how to do this!
- if i dont print it out anywhere, where does it go???
2) append a row on the save quotes spreadsheet with the string instead of array, then when recalling the data with a new function, convert the object from .getValues
- i also do not know how to do this
... I also feel like there's a super easy solution to this that i'm just completely missing.
Your help is much appreciated
I`m trying to replace old values with new values using setValues in Google sheet script.
The data is in the below link...
https://docs.google.com/spreadsheets/d/1pSUVkxM9FhSNgizedHbY2MnYGTnC2iiYLfrWsoPmDks/edit?usp=sharing
I`m basically trying to remove first 14 characters and the last 12 characters under "Tracker" column
Below is the code I tried..
function URLReplacement() {
var ss = SpreadsheetApp.getActive().getSheetByName("transformer");
var rng = ss.getRange("G:G");
var data = rng.getValues();
for (var items in data)
{
var newer = data[items][0].substring(14)
// Turn these strings into an array
var newerr = newer.split(" ")
// Turn this into 2 dimensional array to use setValues
ss.getRange("G:G").setValues([newerr])
Logger.log([newer]);
}
}
But now, I get errors with the setValues statement
Saying the range I set there do not match the data
What am I doing wrong here..?
Can anyone please provide me with suggestions / advice?
You want to convert from IMAGE_SUFFIX_"http://google.com"<xxxnouse>" to http://google.com at the column "G".
The format of IMAGE_SUFFIX_"http://google.com"<xxxnouse>" is constant.
If my understanding is correct, how about this modification? The reason of your error is that [newer] is not 2 dimensional array for using setValues(). If this error was removed, the header is removed by overwriting the empty value. So I would like to modify as follows.
Modification points:
When getLastRow() is used, the data size retrieved by it can be reduced from that retrieved by "G:G". By this, the process cost can be reduced.
Header is not retrieved by getRange(2, 7, ss.getLastRow(), 1).
From the format of IMAGE_SUFFIX_"http://google.com"<xxxnouse>", split() was used for parsing this value.
The converted data was put by setValues(). By this, the process cost can be also reduced.
Modified script:
function URLReplacement() {
var ss = SpreadsheetApp.getActive().getSheetByName("transformer");
var rng = ss.getRange(2, 7, ss.getLastRow(), 1); // Modified
var data = rng.getValues();
var convertedData = data.map(function(e) {return e[0] ? [e[0].split('"')[1]] : e}); // Added
rng.setValues(convertedData); // Added
}
Note:
In your shared sample Spreadsheet, the sheet name is "Sheet1". But your script uses "transformer" as the sheet name. Please be careful this.
If the format of actual values in your Spreadsheet is different from your shared Spreadsheet, this might not be able to be used.
References:
split()
setValues()
If this was not the result you want, I apologize.
Quick look where I normally bother people tells me here is the new place to ask questions!
I have been making a script to create documentation generated from spreadsheet data which was in turn generated from a Google form. (Hope that makes sense...)
Anyway, I have been very successful with a lot of searching and bit of help but now I want to make my script homogeneous so I don't need to tinker with it when I want to setup new forms etc.
I have the getRowData function going from Googles script tutorials but instead of calling the row data from the normalised Headers i would like these to be generic i.e. Column1, Column2 etc.
I've pasted the tutorial function below, it passes the data to another function which normalizes the headers to use as objects, I was thinking thats where I could make them generic but I'm not sure how to get started on it...
Any help would be greatly appreciated!!
Thanks,
Alex
// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - columnHeadersRowIndex: specifies the row number where the column names are stored.
// This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData(sheet, range, columnHeadersRowIndex) {
columnHeadersRowIndex = columnHeadersRowIndex || range.getRowIndex() - 1;
var numColumns = range.getEndColumn() - range.getColumn() + 1;
var headersRange = sheet.getRange(columnHeadersRowIndex, range.getColumn(), 1, numColumns);
var headers = headersRange.getValues()[0];
// Browser.msgBox(headers.toSource());
return getObjects(range.getValues(), normalizeHeaders(headers));
// return getObjects(range.getRowIndex);
}
If you want to get the columns using their index, why parse them to object at all? Just use the plain getValues!
var values = sheet.getDataRange().getValues();
var row2 = values[1];
var cell_in_col4 = row2[3];
It looks like you are missing "var" when declaring your columnHeadersRowIndex variable.