How to use value of a cell once? - google-sheets

I have a certain cell (e.g. C1) that is computed by some formula and another cell (e.g. C2) that when a IF event happens, it takes the value of cell C1.
But, I only want to have C2's value be calculated one initial time and from then on, C2's value will stay the same and no longer depend on C1.
Is that possible, and if so, how can I do that?
If I wasn't clear enough, here is an example spreadsheet with the logic commented.

Found the answer: a simple copy script can do the job:
function simpleCopy() {
var sheet = SpreadsheetApp.getActiveSpreadsheet(); //access to the spreadsheet
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('testing enviroment')); //access to the sheet by name
var range = sheet.getRange('D1'); //assign the range you want to copy
var copy = range.getValues();
sheet.getRange('D2').setValue(copy) //new range you want to paste a value
}

Related

Make the column values static in Google sheets

I have two columns in google sheets. 1st column column A is the input column and the second column column B is the output column. I want the values in the second column to be static once I enter the values in the 1st column. (as the results in the second column are based on the values entered in the first column)
Here is a basic script that takes the value to the right of the edited cell and makes it "static":
function onEdit(e) {
var staticCell = e.range.offset(0,1); // Finds the cell to the right of the edited one
var staticVal = staticCell.getValue(); // Gets the value of that cell
staticCell.setValue(staticVal); // Sets the cell value to itself, removing the formula and making the cell "static"
}
Here is another script that does the same thing, but only works when column A is edited (specific to this question):
function onEdit(e) {
var staticCell = e.range.offset(0,1);
var staticVal = staticCell.getValue();
if(e.range.columnStart == 1){ // Checks to see if the edited cell is in column A
staticCell.setValue(staticVal);
} else {}; // If it is not in column A, nothing happens
}

Newbie: writing a script for google sheets that will run on all sheets

I am a real novice at this (not even). Have never written code in my life-just copied the following code off a website that explained how to do it. I a google doc that I need to be sorted according to Column C continuously as new data is added. This is the code I was given:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(3, 1, sheet.getLastRow() - 2, sheet.getLastColumn());
range.sort({column: 3, ascending: true});
}
It works partially, but I need it to be applied to all sheets/tabs in the document.
Thanks in advance!
Your code includes the line var sheet = SpreadsheetApp.getActiveSheet(); and the rest of you code is based on sheet - so it run only on one sheet, the one that is active when new data is inserted, so the one in which the edit is performed
If instead you want to perform the sorting on each edit in all sheets of the spreadsheet, you need the method getSheets() to retrieve all sheets of the spreadsheet as an array
Subsequently you need to loop through the array to apply the sorting function to each sheet
Sample:
function onEdit() {
var sheets = SpreadsheetApp.getActive().getSheets();
for (var i = 0; i < sheets.length; i++){
var sheet = sheets[i];
var range = sheet.getRange(3, 1, sheet.getLastRow() - 2, sheet.getLastColumn());
range.sort({column: 3, ascending: true});
}
}
Important:
The onEdit trigger only detects human-made edits like typing of text. If instead you want to fire the trigger on changing the document structure, such as e.g. inserting a new empty row (which is different from typing values into cells of an alreday existing empty row), you would need to replace the onEdit trigger, through the installable onChange trigger, see also here

Duplicate Sheet with Name of Cell Value

I am wondering if there is a way to duplicate a sheet I am working on and assigning that new duplicate sheet a name based on a cell value in the original sheet?
Right now I am simply using a script/button to clear content of cell values to start a new stock order (see below)
function newSalesOrder() {
var activeSheet = SpreadsheetApp.getActive();
var ranges = ["StockOrder!B4", "StockOrder!E8", "StockOrder!D9","StockOrder!A12:B41"];
for (var i = 0; i < ranges.length; i++) {
activeSheet.getRange(ranges[i]).clearContent();
}
}
So I would like to add the ability to duplicate the StockOrder! sheet, rename it to the Purchase Order Number value in Cell C4 for example.
If I understand correctly what you are trying to achieve, all you need to do is:
Save the content of a given cell into a String variable
This one is a bit tricky, the hierarchy in Google sheets is: SpreadSheet: Sheet: Range: Cell. So what you need to do to get the value of Cell C4 is:
var ss = SpreadsheetApp.openById('Insert ID here');
var name = ss.getName();
var sheet = ss.getSheetByName('Insert Sheet Name Here');
var range = sheet.getRange(3,4);
var newSheetName = range.getValue();
Of course, you do not need to use openById or getSheetByName methods. You can use getActiveSheet() or whatever you like.
Create a new sheet whose title is the saved String variable
var newSpreadSheet = SpreadsheetApp.create(newSheetName);
Hope this is gonna help:)

Run a script on a spreadsheet, or a specific sheet within a spreadsheet, and pull data conditionally to another sheet

This is my 2nd question, as the first one was solved by patt0, thanks!
I have an on edit working script that is checking everytime I edit a sheet and, if the value of any cell of the column no. 7 is changed to "RECEBER", it will pull the entire row to another sheet. At first, I tought that would work for me, but quickly found out that the onEdit has some limitations that aren't compatible with what I want to do.
Since I cannot rely on the onEdit, I want to run the script from a menu that was created (as suggested by patt0) whenever I want. This could be done all at once, to a whole spredsheet, and also sheet by sheet (I believe the solution to both will be similar, and both ways would be very handy for me).
here's the code I have (not working - was adapted from the previous on edit code):
This first part is storing the sheet name to check if it is between 1 and 31;
function mustBeCopied(sheetName) {
var sheetNumber = parseInt(sheetName);
if (sheetNumber <=31 && sheetNumber >=1)
return true;
return false;
}
This second part probably as some issues,as it was brought from the onEdit function.
function RECEBER() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // stores the active spreadsheet (where the script is being ran)
var s = ss.getActiveSheet(); // stores the Active sheet within the stored spreadsheet
var r = ss.getActiveRange(); // stores the range of rows in my document ?
if(mustBeCopied(s.getName()) && r.getColumn() == 7 && r.getValue() == "RECEBER") { // if mustBeCopied, when applied to the sheet defined in the s variable is satisfied, it will check on every row if the value "RECEBER" is in its 7th column.
var row = r.getRow(); // stores the row that satisfied the condition
var numColumns = s.getLastColumn(); // stores the last column on the sheet ?
var targetSheet = s.getSheetByName("money"); // sets the target sheet
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1); // gets range on the target sheet and adds one more row for the new data to be inserted
s.getRange(row, 1, 1, numColumns).copyTo(target); // writes the data into the target sheet, but I don't understand how..
}
}
I'm doing a step by step analysis to see if I'm understanding what's happening..
I'm sure this can be done quite easily, and am wiling to learn, but I can't seem to find solutions on the net.. I thought this would be already a discussed subject.
It would save me a lot of time every month if I could do this automatically. It would also decrease the risk of human error, as it would be handled by computer..
I hope someone can help me..
Thanks.
You have the Execution transcript (View -> Execution transcript) to observe the execution stack (any errors will be there).
The following code may be helpful:
/* CODE FOR DEMONSTRATION PURPOSES */
function onEdit(e) {
var targetSheet = e.source.getSheetByName('money'),
range = e.range,
s = range.getSheet(),
lastColumn = s.getLastColumn();
if (mustBeCopied(s.getName()) && range.getColumn() === 7 && e.value === 'RECEBER')
s.getRange(range.getRow(), 1, 1, lastColumn).copyTo(targetSheet.getRange(targetSheet.getLastRow() + 1, 1, 1, lastColumn));
}
Adjust as needed.

How do I get value of cell before it changes in Google spreadsheet?

This function seems not to be triggered until the cell is exited, as the value i'm getting is the post-change value. I need the pre-change value, but I only need it if in fact that particular column is edited.
Thank you
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
var columnNum = r.getColumn();
var msg;
if (columnNum == 11) {
var dateCell = s.getRange(r.getRow(), 11);
var v=dateCell.getValue();
msg = 'Value= ' + v;
Browser.msgBox (msg);
//dateCell.setValue(v);
}
}
This is a very old question, but in case anyone else needs the answer, it's quite easy to get both the old and new values of any edited cell with the event object:
function onEdit(e) {
let oldValue = e.oldValue;
let newValue = e.value;
console.log("The range's old value was: " + oldValue + ", and the updated value is: " + newValue);
}
Here are are the accessible properties of the Google Sheets event objects.
To the best of my knowledge, capturing the value of a cell before an edit is still not possible.
You might like to star this issue on the issue tracker; it is currently deemed a medium-priority enhancement request.
#AdamL Is there anyway to access the spreadsheets revision history programmatically?
Sorry this is beyond my noob abilities, but my question may hold the clue to a workaround for A B's issue.
#A B ANOTHER POSSIBLE WORKAROUND
You could set up a time based triggers to populate 2 arrays. 1 array from the current data in the column your checking for edits, and 1 array from a previous snapshot of the same data. Then by using a loop to test if any values have changed since your last trigger event, you can determine what value/values have changed(if any) If a value your testing for has changed then push the rowNumber() and colNumber() and getValue() of both previous and current instances of the same data to a new array, also include a timestamp new Date(). Have this new array data populate a new sheet or spreadsheet.
If used in conjunction with your onEdit function, yourll be able to see the before and after value changes, and the approximate time they occured.
Time based triggers can be set to run every minute, hour day etc

Resources