I would like to have it that when a row is edited that it only copies the name phone and adds a timestamp of the edit on another tab in Google Sheets.
function onEdit(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Main');
var date = new Date();
var rowIdx = sheet.getActiveRange().getRowIndex();
var rowValues = sheet.getRange(rowIdx,1,1,sheet.getLastRow()).getValues();
Logger.log(rowValues);
var destValues = [];
destValues.push(rowValues[0][0]);// copy data from col A to col A
destValues.push(rowValues[0][2]);// copy data from col C to col B
destValues.push(rowValues[0][1]);// copy data from col B to col C
destValues.push(rowValues[0][3]);// copy data from col D to col D
var dest = SpreadsheetApp.getActive().getSheetByName('Updates');
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);
}
The above is working but i cannot figure out how to get the timestamp to show.
The outcome should display the roadname, phone and then C:C should have timestamp of change made.
I have updated the below sheet to show expected outcome
https://docs.google.com/spreadsheets/d/1V3Ne9L0kB97OkFKwlidx40yN__sx78aRik_Ujiej2Wc/edit#gid=1523701088
How I want it to look.
Result Image
Data source
Source Data
Your written explanation is inconsistent with your sample output which is inconsistent with your script. destValues.push()-you are pushing 4 (four) values onto the array (including "Phone Number", "Date Contacted" and "Clan Name") but your expected outcome only has three columns (excluding "Date Contacted" and "Phone number"), but the "Phone number" is in the "Clan Name" column.
REPLACE
destValues.push(rowValues[0][0]);// copy data from col A to col A
destValues.push(rowValues[0][2]);// copy data from col C to col B
destValues.push(rowValues[0][1]);// copy data from col B to col C
destValues.push(rowValues[0][3]);// copy data from col D to col D
var dest = SpreadsheetApp.getActive().getSheetByName('Updates');
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);
WITH
var date = new Date()
destValues.push(rowValues[0][0]);// copy data from col A to col A
destValues.push(rowValues[0][2]);// copy data from col C to col B
destValues.push(date);// copy data from col B to col C
var dest = SpreadsheetApp.getActive().getSheetByName('Updates');
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);
Related
I am trying to write a script that will look for a new entry from a Google Form into a Google Sheet and move data from specific cells to a separate spreadsheet. I have the following script and am having trouble with the rowValues variable. Below is the script as it is currently written.
function onEdit(){
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CopyFromSheet");
var rowId = sheet.getActiveRange().getRowIndex();
var rowValues (rowId);
Logger.log(rowValues);
var destValues = [];
destValues.push(rowValues[0][0]);// copy data from col A to col A
destValues.push(rowValues[0][1]);// copy data from col B to col B
destValues.push(rowValues[0][2]);// copy data from col C to col C
destValues.push(rowValues[0][5]);// copy data from col F to col D
destValues.push(rowValues[0][6]);// copy data from col G to col E
destValues.push(rowValues[0][7]);// copy data from col H to col F
destValues.push(rowValues[0][8]);// copy data from col I to col G
destValues.push(rowValues[0][21]);// copy data from col V to col H
destValues.push(rowValues[0][23]);// copy data from col X to col I
var dest=SpreadsheetApp.openById('SheetID#').getSheetByName('CopyToSheet');
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);
}
function onFormSubmit(e){
var destValues = [];
destValues.push(e.values[0]);
destValues.push(e.values[1]);
destValues.push(e.values[2]);
destValues.push(e.values[5]);
destValues.push(e.values[6]);
destValues.push(e.values[7]);
destValues.push(e.values[8]);
destValues.push(e.values[21]);
destValues.push(e.values[23]);
var dest=SpreadsheetApp.openById('SheetID#').getSheetByName('CopyToSheet');
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);
}
I'm trying to make a google sheet script that adds a row based on cell value, basically if I have in the Quantity (Column D) 7x laptops, I want the script to add 6 additional rows below if Column H is marked as "Yes" through data validation.
What I was able to find and to do is only duplicate that row but is without data validation and I would prefer to add the data validation and possible make each quantity split to 1 (instead of 7) after the duplication.
`function autoDup() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = sheet.getDataRange().getValues();
var newData = [];
for(var n in data){
newData.push(data[n]);
if(!Number(data[n][3])){continue};// if column 3 is not a number then do nothing
for(var c=1 ; c < Number(data[n][3]) ; c++){ // start from 1 instead of 0 because we have already 1 copy
newData.push(data[n]);//store values
}
}
sheet.getRange(1,1,newData.length,newData[0].length).setValues(newData).sort({column: 1, ascending: false});// write new data to sheet, overwriting old data
}`
Hope someone is able to help me.
Thank you,
Column D contains a qty and goods description. If Column H = "Yes", you want to insert a number of rows below Col D equal to the qty minus one. If Column H <> "Yes, then take no action.
Sample data - Before
Sample data - After
function so5925663201() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "59256632";
var sheet = ss.getSheetByName(sheetname);
var row = 7;
// get value of Column H
var colHValue = sheet.getRange(row,8).getValue();
if (colHValue === "Yes"){
//Logger.log("DEBUG: Col H = yes. do something")
// get value of Column D
var Value = sheet.getRange(row,4).getValue();
var searchterm = "x";
var indexOfFirst = Value.indexOf(searchterm);
//Logger.log("DEBUG: the first instance of 'x' is "+indexOfFirst);
// get the quantity and convert from a string to a number
var qty = Value.substring(0, indexOfFirst);
var qtynum = +qty;
// var newtype = typeof qtynum; // DEBUG
//Logger.log("DEBUG: the quantity is "+qtynum+", new type = "+newtype)
// This inserts rows after
sheet.insertRowsAfter(row, qtynum-1);
}
else{
//Logger.log("DEBUG: col H <> Yes. do nothing");
}
}
Im am trying to match 2 columns (A:B) in sheet1 with 2 columns in sheet2 (A:B) and if there is a match, copy contents of column C matching row in sheet1 to matching row in sheet2.
I've tried to adapt several scripts without success. The code below comes closest to my requirements, but with my limited knowledge of script I haven't been able to adapt it to my exact needs.
Sheet1
A B C
Week Rotation Working
Week1 11 In
Week1 5 In
Week1 4 In
Week1 3 In
Week1 3 Off
Week1 7 Off
Sheet2
A B C
Week Rotation Working
Week1 6
Week1 5
Week1 4
Week1 3
Week1 3
Week1 11 (In should be copied to here)
My code:
function MatchColumns(){
// gets spreadsheet A and the range of data
var sheetA
=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Testa");
var dataA = sheetA.getRange(2, 1, sheetA.getLastRow(),
2).getValues();
// gets spreadsheet B and the range of data
var sheetB =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test2");
var dataB = sheetB.getRange(2, 1, sheetB.getLastRow(),
1).getValues();
// Added
var res = [];
for (var b in dataB) {
for (var a in dataA) {
if (dataA[a][0] == dataB[b][0]) res.push([dataA[a][3]]);
}
if (b != res.length - 1) res.push([""]);
}
sheetB.getRange(2, 2, res.length, res[0].length).setValues(res);
Note that JavaScript is one of the many languages that use 0-base indexing. So res.push([dataA[a][3]]) is placing the 4th value from the row into the result array, i.e. Column D.
Your dataA and dataB variables don't actually include the column C data, as you initialized them with only 2 columns of data. So dataA[a][2] and dataA[a][3] are both undefined.
You probably don't want to collect these new values into an array via push, as this will lose the correlation between which row you matched in A & B, and which row you write into. To avoid losing existing information in column C, you need to read it from sheet 2 and assign to the specific index:
var destC = sheet2.getRange(2, 3, sheet2.getLastRow() - 1, 1).getValues();
/** Find matched rows */
...
destC[b][0] = dataA[a][2];
...
// Lastly, write values
sheet2.getRange(2, 3, destC.length, 1).setValues(destC);
Try using a nested for to iterate through the Values in Sheet1 and Sheet2 and compare them with
function MatchColumns(){
// gets spreadsheet A and the range of data
var sheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var dataA = sheetA.getRange(2, 1, sheetA.getLastRow() - 1, 2).getValues();
// gets spreadsheet B and the range of data
var sheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var dataB = sheetB.getRange(2, 1, sheetB.getLastRow() - 1, 2).getValues();
for (var x = 0; x < sheetA.getLastRow() - 1; x++){
for (var y = 0; y < sheetB.getLastRow() - 1; y++){
if (dataA[x][0] == dataB[y][0]){
if (dataA[x][1] == dataB[y][1]){
sheetB.getRange(y + 2, 3).setValue(sheetA.getRange(x + 2, 3).getValue());
}
}
}
}
}
This copies the value of column C in Sheet1 to column C in Sheet2 if the corresponding cells in columns and B match.
Background
I have some code which is supposed to copy certain rows from Sheet B into Sheet A based on integer values in cells E1,J1 and I1. E1 has date format. After rows are copied from Sheet B to A, I need to fill column 12 (Column L) with the date from E1 to newly added rows.
https://docs.google.com/spreadsheets/d/15pTVfcoxM2wQTMC-3iLzXVXIEEaZFYXaOf97amy4yRg/edit?usp=sharing
Problem
The last three rows of code is not working well. Even though I am trying to select range for same column 12 (column L), it seems to select multiple columns and an additional 2 rows than what I had expected.
function test() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("B");
var aa = sheet.getRange("E1");
var Date = aa.getValue();
var aa = sheet.getRange("J1");
var lastrow = aa.getValue();
var aa = sheet.getRange("I1");
var lastrowV = aa.getValue();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("A");
var range = sheet.getRange(2, 1, lastrowV, 11);
var data = range.getValues();
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("B");
sheet.getRange(lastrow, 1, data.length, 11).setValues(data); /* cell J1 gets updated after this*/
var aa = sheet.getRange("J1");
var lastrowN = aa.getValue() - 1;
range = sheet.getRange(lastrow, 12, lastrowN, 12);
range.activate();
sheet.getRange(lastrow, 12, lastrowN, 12).setValues(Date);
}
Background
The OP is attempting to insert a given date in the cell at the end of a row. However, the OP's definition of the range is faulty because it is selecting multiple columns (when only one column is required) and the number of rows is greater (by 2 (two)) than the number required. In addition, regardless of the range height, the OP is attempting to set a single value (rather than an array) into the range.
Problems
1) The definition of the datecolumn (Column L) included a value for the number of columns (probably a carry over from having defined the data range earlier).
Old range: getRange(lastrow,12, lastrowN, 12);. Delete the last parameter (number of columns) and the code behaves.
2) The code used this method setValues(Date) to populate the date column (8 rows in the OP's example data). the problem here is that the value assigned is the single value Date. not an array. This was addressed by creating and populating a temporary array datearray, and using this to update values in the date column.
3) In addition to the problems noted, the OP code is problematic in that a number of variables names were re-used with entirely different contexts (including "sheet" and "aa"), and some variables were declared multiple times. This made the code hard to read and debug. I took the opportunity to resolve as many of these as possible.
function so5473808801() {
// setup spreadsheet and sheets
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetB = ss.getSheetByName("B");
var sheetA = ss.getSheetByName("A");
// define key variables
// date
var daterange = sheetB.getRange("E1");
var datevalue = daterange.getValue();
// rows on SheetA
var Arows = sheetB.getRange("I1"); // = 9
var Alastrow = Arows.getValue();
// rows on sheet B
var Brows = sheetB.getRange("J1"); // = 3
var Blastrow = Brows.getValue();
// define the data range on Sheet A
var Adatarange = sheetA.getRange(2, 1, Alastrow, 11);
// Logger.log("DEBUG: The defined range on Sheet A is "+Adatarange.getA1Notation());//DEBUG
var Adatavals = Adatarange.getValues();
// define a target range on Sheet B and set values from A
var targetrange = sheetB.getRange(Blastrow, 1, Adatavals.length, 11);
// Logger.log("DEBUG: The target on sheetB = "+targetrange.getA1Notation()); // DEBUG
targetrange.setValues(Adatavals);
// set a range to update date on Sheet B
var daterows = (Alastrow - 1); // doesn't take 2 row header on B intoi account
var Bdaterange = sheetB.getRange(Blastrow, 12, daterows);
// Logger.log("DEBUG: The date range on sheet B = "+Bdaterange.getA1Notation());
// create an array to store multiple copies of datevalue
var datearray = [];
//populate the array
for (var i = 0; i < daterows; i++) {
datearray.push([datevalue]);
}
// set the date into Column L
Bdaterange.setValues(datearray);
}
I would like to create a Google Spreadsheets document that maintains:
Sheet 1 (All Entries): Unfiltered
Sheet 2 (1st Level Filter): Copies rows from Sheet 1 that Column B >/= 5000 OR Column C >/= 50000
Sheet 3 (2nd Level Filter): Copies rows from Sheet 1 that Column B >/= 5000 AND Column C >/= 50000
I created a sample doc for reference that's editable here.
Fairly limited programming/script experience.
In case you were looking for a script. This is what it'll look like although you'll have to do the mapping yourself. I haven't opened your doc but this will make it work if you need a script to do your bidding.
function sheetMaintain()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1 = ss.getSheetByName("Sheet1");
var s2 = ss.getSheetByName("Sheet2");
var s3 = ss.getSheetByName("Sheet3");
var r1 = s1.getDataRange();
var r2 = s2.getDataRange();
var r3 = s3.getDataRange();
var data1 = r1.getValues();
for (var i=0; i<r1.getLastRow(); i++)
{
if (data1[i][1]>=5000 || data[i][2]>=50000)
{
var colB = data[i][1];
var colC = data[i][2];
var lr2 = r2.getLastRow();
s2.getRange(lr2+1, 1).setValue(colB); //Mapping Col B value to Col A of Sheet 2
s2.getRange(lr2+1, 2).setValue(colC); //Mapping Col C value to Col B of Sheet 2
}
if (data1[i][1]>=5000 && data[i][2]>=50000)
{
var colB = data[i][1];
var colC = data[i][2];
var lr3 = r3.getLastRow();
s3.getRange(lr3+1, 1).setValue(colB); //Mapping Col B value to Col A of Sheet 3
s3.getRange(lr3+1, 2).setValue(colC); //Mapping Col C value to Col B of Sheet 3
}
}
}
if you'd like to not have any duplicates (from running the function time and again) in Sheet2 or Sheet3 I would also suggest you look into using the clear() function and set your Sheet2 and Sheet3 to clear before you parse through Sheet1 again.
I have added a formula to both sheets to achieve something like you may want
i.e. the first one below is the OR and the second is the AND
=filter('Sheet 1 - All Entries'!A:C,(('Sheet 1 - All Entries'!B:B>=5000) + ( 'Sheet 1 - All Entries'!C:C >=5000)))
=filter('Sheet 1 - All Entries'!A:C,(('Sheet 1 - All Entries'!B:B>=5000) * ( 'Sheet 1 - All Entries'!C:C >=5000)))
PS... I am not sure if a formula is sufficient for you or if you wanted this done through script