I'm trying to create a data snapshot on google sheets that will automatically run when a specific cell is edited. How should I do that? I'm not from coding background but so far I've found 2 sources and tried to combine them but when I tested it out, it's giving me error. I want to copy values from A2 to E2 of Snapshot sheet and append row every time B2 is changed. Please advise.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Snapshot");
var source = sheet.getRange("A2:E2");
var values = source.getValues();
if(e.range.getA1Notation() == 'B2'){
sheet.appendRow(values[0]);
}}
The B2 in Snapshot is a formula which displays the value of F1 in Receipt sheet. So, the onEdit is not triggered on change of name.
The name changes in F1
I tried the below code and it is working
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var rsht=ss.getSheetByName("Receipt");
var sheet = ss.getSheetByName("Snapshot");
var source = sheet.getRange("A2:E2");
var values = source.getValues();
if(e.range.getA1Notation() == 'F1'){
sheet.appendRow(values[0]);
}}
Related
I'm trying to calculate to cells but not working. This is my code :
function total() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sheet1");
var cell = sheet.getRange("A3");
var calculate = cell.setFormula("=SUM(A1+A2)");
return calculate
}
My cell is A1 AND A2 I want to put result in cell A3 by add "=total()".
not working but if run from script it work.
I want to put =total() in cell A3 and work without see my formula in sheet.
I wand to send copy of my sheet to people and he can read and edit it.
I don't need people to see my formulas.
or any another way to hide my formulas from people
You need to calculate the result in the script:
function total() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sheet1");
var values = sheet.getRange("A1:A2").getValues();
var value = values[0][0] + values[1][0];
return value;
}
Alternatively, you can
Calculate normally with formulas in another spreadsheet
Use IMPORTRANGE to import the data from that spreadsheet such that only values but not formulas are display in the cells
However, he cannot make changes to the range directly.
He need to first copy and paste by values.
Your custom formula is returning the return value of the function Range.setFormula(formula), which is a Range. And you want a number. For this you need the values of both cells "A1"and "A2".
Furthermore, if you are using this custom formula to set a value in cell "A3" and not a formula then you can just have the custom formula return the value.
Example:
function total() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sheet1");
var values = sheet.getRange("A1:A2").getValues();
var value = values[0][0] + values[1][0];
return value;
}
I'm trying to build a script that will allow me to copy and value paste a range from tab "robert" to tab "brendan". However, the range in "robert" is dynamic, so sometimes it will need to copy and paste A1:M3 or A1:M20. I'd also like it to append to the the first rows of the destination. So when run, the script looks for values on the source tab (robert), copies them, and pastes their values at the top of the destination (brendan) without overwriting existing data.
So far I've worked with the below script from a different thread:
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange('Robert!A1:M100');
source.copyTo(ss.getRange('Brendan!A4'), {contentsOnly: true});
source.clear();
}
The problem here is the script range is static, and it overwrites anything in the destination. I do like the clearing of the source though and the values paste. Any help would be greatly appreciated!
Define the range using variables. Use getLastRow() and getLastColumn() Instead of hard-coding it.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var robWs = ss.getSheetByName("Robert");
var brenWs = ss.getSheetByName("Brendan");
var robLr = robWs.getLastRow()
var robLc = robWs.getLastColumn()
//range starts at row 1 and column 1 (A1), you may need to change accordingly
var vals = robWs.getRange(1,1,lr,lc).getValues;
//paste range also starts at A1. you can find the lr on this sheet and start the range there
brenWs.getRange(1,1,lr,lc).setValues(vals);
function moveValuesOnly() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Robert');
var rg=sh.getActiveRange();//copies active range for source
var vA=rg.getValues();
dsh=ss.getSheetByName('Brendan');
dsr=4;//destination start row
dsc=1;//destination start col
dsa=2;//destination number of rows to append to
drg=dsh.getRange(dsr,dsc,rg.getHeight(),rg.getWidth());
var dvA=drg.getValues();
vA.forEach(function(r,i){
if(i<dsa){
r.forEach(function(c,j){
//only write data in destination for these rows if destination value is null
if(dvA[i][j]='') {
dvA[i][j]=c;
}
});
}else{
dvA[i][j]=c;
}
})
drg.setValues(dvA);
}
There are few queries which are somewhat similar but I'm unable to get a solution from those.
In my mainsheet I'm importing data from a webpage using Importdata function in the mainsheet. The data in the webpage changes every 5mins and so the cell value A50 changes every 5 mins in the mainsheet.
Now I want to write a google app scrip function that will copy the value from A50 of mainsheet to another sheet in the cell A1,A2,A3,A4,A5.......and so on and have a timestamp correspondingly in B1,B2,B3,B4,B5....and so on
You can use onEdit() trigger function to do this. When an edit happens in cell A50 check if cell and sheets are correct then read value and save into target sheet. Below code does that. Change the sheet names as shown in comment.
function onEdit(e) {
// check if active range is A50 or not
var rangeStr = e.range.getA1Notation();
if (rangeStr != 'A50') return;
// get Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get sheets
var mainSheetNames = ['main sheet name', 'main sheet name', 'main sheet name']; // change here
var mainSheet = e.range.getSheet();
if (mainSheetNames.indexOf(mainSheet.getName()) == -1) return;
var targetSheet = ss.getSheetByName('target sheet name'); // change here
// get value
var value = e.value;
// set values
targetSheet
.getRange(targetSheet.getLastRow() + 1, 1, 1, 2)
.setValues([[value, new Date().toLocaleString()]]);
}
I have recently started doing some work in Google Sheets, where previously I have been able to code functions in Excel, I am unable to get this working in Google Sheets Scripting.
I have two sheets
Sheet 1. Cells A1 - E5 contain values based on some selection criteria
Sheet 2. Register Sheet
What I need is when executing the script (via drawing and linked macro)
I need it to copy the range A1:E1
Go into Sheet 2, Go to the first Blank Cell in Column A, and then Paste Values.
I am using the following script, and I'm getting
coordinates of the target range are outside of the dimensions of the sheet.
function moveValuesOnly () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("PNG Sheet!A1:E1");
var destSheet = ss.getSheetByName("Project Codes");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}
Any assistance would be greatly appreciated.
Cheers
Graeme
You're receiving this error because you're attempting to select a range in the "Project Codes" sheet that does not exist. Use instead the appendRow() method, which will
paste the passed values into the first blank row, and
automatically resize your sheet.
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange("PNG Sheet!A1:E1");
var destSheet = ss.getSheetByName("Project Codes");
destSheet.appendRow(source.getValues()[0]);
source.clear();
}
At the moment this is the function I'm using but I have no way of testing if it will work in the spreadsheet until I publish the application.
function readSelection() {
//The commented lines aren't needed if the sheet is open already
//var sheetid = "sheet id here";
//var spreadsheet = SpreadsheetApp.openById(sheetid);
//SpreadsheetApp.setActiveSpreadsheet(spreadsheet);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
//sheet.setActiveSelection("B2:B22");
var activerange = sheet.getActiveRange();
var activecells = activerange.getValues();
return activecells;
};
I assume you mean highlighted == selected
The result depends on whether the cells are contiguous or not (non contiguous cell selection is available in the new spreadsheets features http://googleblog.blogspot.co.nz/2013/12/new-google-sheets-faster-more-powerful.html
For contiguous cells selected your code returns the values of the selection as an array, for non-contiguous cells your code will return the an array with the single value of the LAST selected item.
I suggest that this is a bug in the implementation of the new spreadsheet. If it is important to you, I suggest you raise an issue. For the old spreadsheets, you can only select contiguous cells (eg B2:B22) so it will work as you expect.
The easiest way to answer this Q is to run the code you have written! You don't have to publish anything just run the code in the script editor of the spreadsheet you are examining
and look at the log.
function readSelection() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var activerange = sheet.getActiveRange();
var activecells = activerange.getValues();
Logger.log(activecells)
return
};
There is no way to do this at the moment or to obtain the selected ranges from a script.
A request is pending and you can support it here : https://code.google.com/p/google-apps-script-issues/issues/detail?id=4056
by adding a star to the request.
If/when this function is implemented your code would look as follows:
function readSelection() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var activeranges = sheet.getSelectedRanges();
var activecells = [] ;'
for (var ar in activeranges)
activecells = activecells.concat(activeranges[ar].getValues()) ;
Logger.log(activecells)
return ;
}
note that selected ranges may overlap, so some cell contents could be added twice.