Any help is greatly appreciated.
I am trying to get form responses to move over to another sheet if cell in row 5 is greater than 0. The code I am using below moves it over but adds it under the last cell that has a formula in it. Is there a modified version of this code that i can tell it to ignore formula's in cell. Also only copy over rows A:E. Thanks
function moveToAppropriateSheet(e) {
// assumes source data in sheet named Form Responses 1
// target sheet of move to named TR Requested
// test column with yes/no is col 11 or K
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Query');
var r = s.getRange(s.getLastRow(),1,1,20);
var data = r.getValues();
if(data[0][4] >0) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Pending");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
targetSheet.getRange(targetSheet.getLastRow()+1,1,1,20).setValues(data);
s.deleteRow(row);
}
};
Edited in light of new information:
You want to copy only the first 5 columns of the row you copy in "Query" to the sheet "Pending".
You already have entries in "Pending", in columns F, G, H, ... You wish to add your copied row under the last entry in columns A:E
I've also assumed for simplicity's sake that you always copy 5 columns so I can check only column A to find the last row (in the subset A:E).
I also note that this is essentially a duplicate of this answer by Mogsdad.
If my assumptions are correct, then:
function moveToAppropriateSheet(e) {
// assumes source data in sheet named Form Responses 1
// target sheet of move to named TR Requested
// test column with yes/no is col 11 or K
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Query');
var r = s.getRange(s.getLastRow(),1,1,5); // Change 20 to 5 to copy only cols A:E
var data = r.getValues();
var targetSheet = ss.getSheetByName("Pending");
var lastRowIgnoringFormulae = 0;
var targetSpace = targetSheet.getRange("A:A").getValues();
var lastRow = targetSpace.filter(String).length;
if(data[0][4] >0) {
var row = r.getRow();
var numColumns = s.getLastColumn();
targetSheet.getRange(lastRow+1,1,1,5).setValues(data); // +1 to convert into R1C1 notation
s.deleteRow(row);
}
};
I hope I've helped.
Related
I have a code to add a array of content in a row but i need to add it in a specific range so the checkboxes in the first column are not read as information, so it can add up the row but in the same row that the checkbox it's in.
function criarRegistro() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("EQUIPAMENTOS NO LABORATÓRIO");
var destinyLog = ss.getSheetByName("EQUIPAMENTOS NO LABORATÓRIO");
sheet.activate();
var source = sheet.getRange("C2:G2");
var rangeLimpeza = sheet.getRange("C2:G2");
var values = source.getValues();
//rangeLimpeza.clearContent();
destinyLog.appendRow(values[0]);
ss.toast("Registro finalizado");
SpreadsheetApp.flush();
}
That's the code i'm using, basically i want to appendRow or copy the row information starting in B column, while in the A column i would have a preset of unmarked checkboxes.
You cannot use appendRow but you can calculate the correct destination range where the values should be copied and then use a basic getRange().setValues().
Rewriting and cleaning your function
function criarRegistro() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("EQUIPAMENTOS NO LABORATÓRIO");
var destinyLog = ss.getSheetByName("EQUIPAMENTOS NO LABORATÓRIO");
var source = sheet.getRange("C2:G2");
var values = source.getValues();
var nbOfCols = values[0].length; // how many columns do we need
var lastLineOfData = destinyLog.getDataRange().getNumRows() // how many rows are already present in the destination
destinyLog.getRange(lastLineOfData+1, 2, 1, nbOfCols).setValues(values) // we write after the last line, starting at the second column (B)
ss.toast("Registro finalizado");
SpreadsheetApp.flush();
}
My information is set in columns (A to E), info paste in 2 rows (A2:A3, B2:B3...). What I want to happen is when info set in last column E (E2:E3, E5:E6 and more), new info paste with a new row in column A (A5:A6, B5:B6).
My info is in the spreadsheet:
This code paste info doesn't work correctly:
function submitData1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form"); //Form Sheet
var datasheet = ss.getSheetByName("Job"); //Data Sheet
//Input Values
var values1 = [[formSS.getRange("B6").getValue()], [formSS.getRange("B7").getValue()]];
var sr = 1
var sc = 1
var nr = 2
var nc = 1
for (var i=1;i<1;i++)
var workingCell = datasheet.getRange(i,7);
{
if (workingCell ==null)
{datasheet.getRange(sr,datasheet.getLastColumn()+1,nr,nc).setValues(values1)
}
else {datasheet.getRange(datasheet.getLastRow()+1, sc, nr, nc).setValues(values1)
sc= sc+1}
}
}
Here is a sample replication code:
function submitData1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var datasheet = ss.getSheetByName("Job"); //Data Sheet
//Input Values
var values1 = [["Name X"], ["Job X"]];
var lastRow = datasheet.getLastRow();
var lastRow_ColCount = datasheet.getRange(lastRow,1,1,5).getValues().flat().filter(String).length;
Logger.log(lastRow);
Logger.log(lastRow_ColCount);
if(lastRow_ColCount==5){
//Add data on a new row, column A
datasheet.getRange(lastRow+2, 1,2,1).setValues(values1);
}
else{
//Add data on the next column in the same row
datasheet.getRange(lastRow-1, lastRow_ColCount+1,2,1).setValues(values1);
}
}
I used a fixed value for the input data during this replication.
Just replace the values from your original code that will be read from your form sheet
You can also remove the logs in the script, I just used them to debug the code
What it does?
Get the last row of the sheet, It will determine the last row that has a valid data
Get the data/values of the last row from column A to column E. Use Array.flat() to change 2-d array to 1-d array. Use Array.filter() to get non empty cells then count the data available in the last row.
If the current data available is 5, then the new data will be added on the new row, else the new data will be added on the next column
Output:
function CopyinData_AM_A() {
/* Edit the vars below this line for your needs */
var sourceSheet = "Students AM" ; // Enter the name of the sheet with the source data
var sourceRange = "B7:N77" ; // Enter the range of the cells with the source data
var targetSheet = "Students AM A" ; // Enter the name of the target sheet
var targetRange = "B7:N77" ; // Enter the range of cells you wish to copy data to. Note this must be same size as source range.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var values = sheet.getRange(sourceRange).getValues();
ss.getSheetByName(targetSheet).getRange(targetRange).setValues(values);
}
How would I add this into the above script? The action needs to occur after the data is copied into the sheet. I am only a VB coder. 'Students AM A' is a formula free sheet.
For each cell in ‘Students AM A'!N7:N77 then
If Ncell= ‘Menu!D14' then Hcell = ”O"
Check next cell
End
I'd have zero issue doing this in VB, I just started using google scripts about 3 months ago. Anyone recommend a good book to assist me in learning this google script stuff?
Once you have a value range, you can loop through the rows and compare the values against the reference value
You can use e.g. a for loop, a conditonal if statement and the == comparison operator
Sample to be merged with the rest of your function:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("Students AM");
var referenceSheet = ss.getSheetByName("Menu");
var referenceValue = referenceSheet.getRange("D14").getValue();
var sourceRange = "B7:N77";
var values = sourceSheet.getRange(sourceRange).getValues();
for (var i = 0; i < values.length; i++){
// values[i][12] correspond to the values in column N of each row
if(values[i][12] == referenceValue){
sourceSheet.getRange((sourceRange + i), 7).setValue("O");
}
}
For further reading:
getSheetByName()
getRange(a1Notation)
getRange(row, column)
getValue()
setValue()
A novice on app scripts, but managed to successfully build my own script through much research, but now my script is running into errors. Below is my current code:
function MyFunction() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Daily Sales');
var range = ss.getRange('B8:H83');
var data = range.getValues();
var OUrange = ss.getRange('K8:Q83');
var OUdata = OUrange.getValues();
var ts = sss.getSheetByName('Tracker');
ts.getRange(ts.getLastRow()+1, 1,data.length, data[0].length).setValues(data);
ts.getRange(ts.getLastRow()+1, 1,OUdata.length, OUdata[0].length).setValues(OUdata);
}
In the Daily Sales sheet I am copying values from columns B-H and K-Q and pasting them in the last row of the Tracker sheet starting at Column A. The Daily Sales values in Col. K-Q are pasted correctly below the B-H values, so happy with those results.
On the Tracker sheet these values are in Columns A-G. However I have since added formulas in Columns I and J based on the script data and a manual entry in Column H. These formulas are copied down the entire column within the sheet (i.e. row 5000). Since adding these formulas, the script is now pasting values in A5001.
I realize it is because of these formulas, but is there a way to update my script to paste in the last row of column A while maintaining those formulas in Columns I and J? Thanks in advance.
You could create a helper function that computes the first free row of a given column (NOT a column with formulas)
function MyFunction() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Daily Sales');
var range = ss.getRange('B8:H83');
var data = range.getValues();
var OUrange = ss.getRange('K8:Q83');
var OUdata = OUrange.getValues();
var ts = sss.getSheetByName('Tracker');
var values = data.concat(OUdata).filter(function (r) {return r[0]});
var fr = findFirstFreeRow(ts, 1) // second parameter represents column to check for first free row
ts.getRange(fr, 1,values.length, values[0].length).setValues(values);
}
function findFirstFreeRow(sheet, colNum) {
var v = sheet.getRange(1, colNum, sheet.getLastRow()).getValues(),
l = v.length,
r;
while (l >= 0) {
if (v[l] && v[l][0].toString().length > 0) {
r = (l + 2);
break;
} else {
l--;
}
}
return r;
}
See if that helps?
After deleting the extra empty rows from your 'Tracker' sheet, you can use the appendRow function to create a new row with the manual values (leaving the cells that need formulas blank).
After the manual values are in, you can then get the cells that need formulas and use setFormula on them.
For the sake of brevity, if you wanted column A,B,C,E,F to have manual values and column D to have a formula you would do:
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow(['A','B','C','','E','F']);
sheet.getRange(sheet.getLastRow(),4).setFormula('=FORMULA(HERE)');
I've spent hours trying to get this to work so any help is much appreciated I've got the code below copying from my main sheet to logs. However the code I'm trying to alter looks to column 10 for the sheet name. I'd like this just to default to the sheet logs any idea what needs changing to make this happen? Thanks in advance
function onEdit(e) {
// see Sheet event objects docs
// https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
var ss = e.source;
var s = ss.getActiveSheet();
var r = e.range;
// to let you modify where the action and move columns are in the form responses sheet
var actionCol = 9;
var nameCol = 10;
var target = SpreadsheetApp.openById('18L5-RGHBx41sMtvC1-7AoVCo6y3imvtELQFjkhPXtoY')
var targetsheet = target.getSheetByName('logs');
// Get the row and column of the active cell.
var rowIndex = r.getRowIndex();
var colIndex = r.getColumnIndex();
// Get the number of columns in the active sheet.
// -1 to drop our action/status column
var colNumber = s.getLastColumn()-1;
// if our action/status col is changed to yes do stuff
if (e.value == "Yes" && colIndex == actionCol) {
// get our target sheet name - in this example we are using the priority column
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
// if the sheet exists do more stuff
if (ss.getSheetByName(targetSheet)) {
// set our target sheet and target range
var targetSheet = ss.getSheetByName(targetSheet);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
// get our source range/row
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
// new sheets says: 'Cannot cut from form data. Use copy instead.'
sourceRange.copyTo(targetRange);
// ..but we can still delete the row after
r.setValue("Logged")
// or you might want to keep but note move e.g. r.setValue("moved");
}
}
}
It looks like you are trying to get a sheet by it's name.
The following code will return the sheet named Logs.
var targetSheet = SpreadsheetApp.getActive().getSheetByName('Logs');
Google Apps Script Documentation: getSheetByName(name)