I'm trying to store a value using google cache services but it doesn't seem to increment like I want it to. Here's the code -
//Starts a new instance of cache
var cache = CacheService.getScriptCache();
//Puts the value 2 into foo key of Cache
cache.put('foo', 2);
//Grabs that value
var startMessageRow = cache.get('foo');
//stuff for an email I'm sending using this cached value
var messageDataRange = sheet.getRange(startMessageRow, 2)
var message = messageDataRange.getValues();
//Here's where I'm trying to increment it, but the value is staying at 2
cache.put('foo','startMessageRow'+1);
That last line of code is where I'm trying to increment the value by one each time this script runs, however the value is just stuck at two no matter what I try.
I found an easier way to do this. I just put a counter in a random cell and then I just add one to that value every time my script runs. Way easier than using the cache services!
var cellRange = s1.getRange("W726"); //set this string to be the corresponding cell for daily counter
var cell = cellRange.getValues(); //grabs the value from that cell
var startMessageRow = cell; //sets StartMessage Row to be equal to the value of counter
startMessageRow = parseInt(startMessageRow);//ints it
cell = parseInt(cell); //ints it
cell+=1; //increments
cell = cell+""; // strings it
cellRange.setValue(cell); // puts the new value in
Related
I've got a system that generates and automatically maintains lots of spreadsheets on a Drive account.
Whenever I add data to the sheet I run a 'format' method to pass over and make sure everything is ok.
This generally does things like:
set the default font and size across the sheet
set up the heading row
freeze rows
In addition, I have the code below to make sure the first two columns (index 0 and 1) in the sheet are autoresizing to fit their contents. when I run it though, this element doesn't seem to make a difference. The font, column freezes etc all work.
Other notes:
I only want those 2 columns to auto-resize
the amount of rows in a sheet can vary
this job is appended to the end of several in requestList
My code:
requestList.Requests.Add(new Google.Apis.Sheets.v4.Data.Request()
{
AutoResizeDimensions = new AutoResizeDimensionsRequest()
{
Dimensions = new DimensionRange()
{
SheetId = Convert.ToInt32(sheetId),
Dimension = "COLUMNS",
StartIndex = 0,
EndIndex = 1
}
}
});
var updateRequest = sheetService.Spreadsheets.BatchUpdate(requestList, spreadSheetId);
var updateResponse = updateRequest.Execute();
Could the order which I request the 'format' changes be affecting things maybe? Can anyone help?
As written in the documentation,
the start index is inclusive and the end index is exclusive.
So, For the first two columns, it should be
startIndex = 0,
endIndex = 2
Using the following code I cannot increment a value in google sheets to be plus one.
function incrementCellValuesByOne() {
// Increments the values in all the cells in the active range (i.e., selected cells).
// Numbers increase by one, text strings get a "1" appended.
// Cells that contain a formula are ignored.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeRange = ss.getActiveRange();
var cell, cellValue, cellFormula;
// iterate through all cells in the active range
for (var cellRow = 1; cellRow <= activeRange.getHeight(); cellRow++) {
for (var cellColumn = 1; cellColumn <= activeRange.getWidth(); cellColumn++) {
cell = activeRange.getCell(cellRow, cellColumn);
cellFormula = cell.getFormula();
// if not a formula, increment numbers by one, or add "1" to text strings
// if the leftmost character is "=", it contains a formula and is ignored
// otherwise, the cell contains a constant and is safe to increment
// does not work correctly with cells that start with '=
if (cellFormula[0] != "=") {
cellValue = cell.getValue();
cellValue =+cellValue
cell.setValue(cellValue + 1);
}
}
}
}
For example "personalDataDOB_3" needs to become "personalDaTaDOB_4" I'm looking for a fast way to do this as right now I need to replace the value by typing.
You want to modify "personalDataDOB_3" of a certain cell to "personalDaTaDOB_4". If my understanding is correct, how about this modification?
Modification points :
When the retrieved "personalDataDOB_3" is converted to the number using cellValue =+cellValue, NaN is returned. So even if 1 was added, the result is NaN.
If the format of strings you want to modify is always "personalDataDOB_#", how about separating the string by _?
In order to reflect above points, please modify your script as follows.
From :
if (cellFormula[0] != "=") {
cellValue = cell.getValue();
cellValue =+cellValue
cell.setValue(cellValue + 1);
}
To :
if (cellFormula[0] != "=") {
cellValue = cell.getValue();
var temp = cellValue.split("_"); // Added
temp[1] = Number(temp[1]) + 1; // Added
cell.setValue(temp.join("_")); // Modified
}
Note :
If the format of strings you want to modify is always changed, please tell me.
If I misunderstand your question, I'm sorry.
I have been checking out multiple codes on trying to update my Google Spreadsheet but have been unsuccessful when trying to do this with multiple cells. On my spreadsheet I have multiple tabs and when I update a row in column 2,3 or 4, I would like it to enter the date in column 5.
Thank you for your help.
Step 1.
In the Google Spreadsheet, click on "Script editor..." under the "Tools" menu.
Step 2.
Remove any sample script that might be in there and paste the following ...
// Sets the targetColumn on the edited row to the current date if the
// edited column in within columnBounds.
// Note: This will only handle single cell editing.
// Columns that need to be monitored for changes. Use CAPITAL letters.
var monitoredColumns = ['B', 'C', 'D'];
// Colum that will receive the date.
var targetColumn = 'E'
// To avoid adding the date in the title row, we need to consider the starting row.
var startingRow = 4
// onEdit() is a reserved function name that will be called every time the sheet will be edited.
function onEdit(e) {
var range = e.range;
// Row of the edited cell.
var row = range.getRow();
// Column of the edited cell.
var col = String.fromCharCode(64 + range.getColumn());
if (row < startingRow) {
// None of the monitored rows have been edited.
return;
}
if (monitoredColumns.indexOf(col) < 0) {
// Column B, C or D (2, 3 or 4) was not modified.
// Do not proceed any further.
return;
}
// Current spreadsheet.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// Date cell.
var dateCell = sheet.getRange(targetColumn + range.getRow());
// Set it to the current date.
dateCell.setValue(new Date());
}
Step 3
Adjust the values of monitoredColumns, targetColumn and startingRow
Step 4
Start entering some content in the cells.
I am building a spreadsheet that tracks work in progress as it moves through steps of a manufacturing process.
Each step of the process has a column with the total parts moved to each stage. To the left of this column is a column for number of parts moved to the stage (parts move through a few at a time).
My scrpit then takes the values in the "add" column, adds them to the "total" column, then reset the "add" column to "".
Here's the code:
function addColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// ss is now the spreadsheet the script is associated with
var sheet = ss.getSheets()[0]; // sheets are counted starting from 0
// sheet is the first worksheet in the spreadsheet
for (var i=4; i<500; i++ ) {
if(sheet.getRange(i,1).getValue()>0){ //Only run if order number not empty
//Breakout Column
var add = sheet.getRange(i,6);
var total = sheet.getRange(i,7);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
//CNC Column
var add = sheet.getRange(i,8);
var total = sheet.getRange(i,9);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
//CutSand Column
var add = sheet.getRange(i,10);
var total = sheet.getRange(i,11);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
//Lasered Column
var add = sheet.getRange(i,12);
var total = sheet.getRange(i,13);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
//To Finishing Column
var add = sheet.getRange(i,14);
var total = sheet.getRange(i,15);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
// Defective Column
var add = sheet.getRange(i,17);
var total = sheet.getRange(i,18);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
//Etsy Column
var add = sheet.getRange(i,20);
var total = sheet.getRange(i,21);
total.setValue(total.getValue() + add.getValue());
add.setValue("");
}
if(sheet.getRange(i,4).getValue()<1){i=500} //Once you find a blank order exit the loop
}
}
My code as written does accomplish this; it does exactly what I need. The problem is that since the code is accessing the spreadsheet on each loop it takes almost a full second per cell to run, and with 7 steps per order it can take minutes at a time to run through with lots of orders...
This is a pretty simple mathematical task, so there has to be a more efficient way of doing it, I just haven't been able to find the right keywords to describe what I need to do.
I am quite happy to learn whatever needs to be done, just need to know what direction to head.
Thanks in advance!
I would suggest to do something like this: (not tested)
function addColumns() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; // Refers to the first worksheet in the spreadsheet
var data = sheet.getDataRange().getValues(); // Acquires all values of the sheet
for (var i = 3; i < data.length; i++) { // Loop over every row
if (data[i][0].length > 0) { // Check if first column has a value
// Breakout
sheet.getRange(i+1,7).setValue(parseFloat(data[i][6]) + parseFloat(data[i][5]));
sheet.getRange(i+1,6).clear();
// Repeat code above for other columns
}
}
}
This code acquires all the data from the sheet instead of looping over a fixed amount of 500 rows. Assuming that your data starts at row 4, I've implemented this in the code above as well.
Variable data acquires all the data at one moment instead of trying to fetch values of every range (cell) all the time. I expect that this will save your script quite some time.
Because we acquire the data at once, the script sees the value as a string. Before we calculate the new value of the total column, we parse the value as a float (a number with decimals).
The code above is not tested as I don't have a sheet ready in the same format as you do but I think the logic is clear and if it doesn't work I suppose you should be able to adjust it to work for your sheet.
I have some cells (that are non-adjacenet). Each of these has a range name in the form "rLampnn" as below.
ss.getRangeByName("rLamp20").setValue(e.range.getValue());
ss.getRangeByName("rLamp19").setValue(e.range.getValue());
ss.getRangeByName("rLamp18").setValue(e.range.getValue());
I want to put the same value into several of them at once. (Each of them then has a conditional format which changes the cell colour depending on what was entered into them).
Is there a more efficient way (i.e. quicker) of setting the same value into a group of these cells rather than individual calls like above?
If you have many of them you could loop .setValue() using the nn index in the named ranges:
var fName = 'rLamp';
var howManyNamedRanges = 20;
// Assuming the first NamedRange is rLamp0
for (var i=0;i<howManyNamedRanges;i++) {
ss.getRangeByName(fName+i).setValue(e.range.getValue());
}
If the first named ranges is 1 or else you could change it to:
var fName = 'rLamp';
var firstNamedRange = 4;
var lastNamedRange = 20;
// Assuming the first NamedRange is rLamp[n]
for (var i=firstNamedRange;i<=lastNamedRange;i++) {
ss.getRangeByName(fName+i).setValue(e.range.getValue());
}