I wrote a google script to create and paste the values from a cell in one sheet to another (same spreadsheet). The code consists of following two steps:
(works): If a cell of specific columns of one sheet are edited, then the next adjacent cell gets a value based on the edit.
(does not work): Paste the new value of the adjacent cell into the cell of the next empty row (1st column) in the second sheet.
The code below is what I have tried so far, but the value does not appear on the second sheet. Does anybody know where the problem is in my attempt below?
Thx
function onEdit() {
var a = [19,21,23]
var ss = SpreadsheetApp.getActive()
var s = ss.getActiveSheet();
if( s.getName() == "ALL" ) {
var valActive = s.getActiveCell();
var col = valActive.getColumn();
var row = valActive.getRow();
var range = s.getRange(row, 1);
var val0 = range.getValue();
if( a.indexOf(col) > -1 && valActive.getValue() != '') {
var nextCell = valActive.offset(0, 1);
var val1 = valActive.getValue();
var time = Utilities.formatDate(new Date, "GMT+1", "HHmm");
nextCell.setValue(val0 + '_' + val1 + '_' + time);
var rowNext = nextCell.getRow();
var colNext = nextCell.getColumn();
var target = SpreadsheetApp.getActive().getSheetByName("Samples");
var lastRow = target.getLastRow();
s.getRange(rowNext, colNext).copyTo(target.getRange(lastRow + 1, 1), {contentsOnly: true});
}
}
}
To get the second part to work you want to append a row to your other sheet. Try something like this:
var sheet = SpreadsheetApp.getActive().getSheetByName("Name");
sheet.appendRow([newValue]);
Related
This is my first Google Script and I am coming from a VBA background so I have likely missed something obvious. I am attempting to copy from one sheet to another, some that is quite simple in VBA, but I am struggling with it and I dont understand what I am missing
The below code I would have though would copy a range in one sheet to another sheet. Not the whole range, just a section of it and only 1 row per an OnEdit()
I checked the ranges I am wanting to copy from and copy to using targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1).activate(); & sheet.getRange(row, 1, 1, numColumns-1).activate(); and it selects the range I would expect
Currently the execution doesn't show any fails either
function onEdit(e) {
//This is sheet we will be copied to
const VALUE = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const COLUMN_NUMBER = 25
//The main sheet that is being copied from
const MAIN_SHEET = 'Form Responses 1'
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var lead_or_landscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if((COLUMN_NUMBER == cell.getColumn() && MAIN_SHEET == sheet.getName && cell.isChecked() == true)
&& (lead_or_landscape == VALUE[0] || lead_or_landscape == VALUE[1])){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(lead_or_landscape);
var target = targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1);
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
}
}
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
You've to use parentheses in sheet.getName() and not use them in copyTo(target())
And you can use sheet.appendRow() method instead of copyTo(), that is easier.
function onEdit(e) {
//This is sheet we will be copied to
const sheets = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const colNumber = 25;
//The main sheet that is being copied from
const mainSheet = 'Form Responses 1';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var leadOrLandscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if(colNumber == cell.getColumn()
&& mainSheet == sheet.getName()
&& cell.isChecked() == true
&& sheets.includes(leadOrLandscape)){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(leadOrLandscape);
targetSheet.appendRow(sheet.getRange(row, 1, 1, numColumns-1).getValues()[0])
}
}
I just took a quick look at your code, are you sure about this line?
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
it shouldn't rather be
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target);
I have the following data:
[Source] Sheet 1 (Quote Generator):
Sheet 1, Cell A4: Dropdown menu to select a job reference
Sheet 1, Cells K4>Q4:= figures pulled from google maps & calculations dependant on A4 menu selection
[Destination] Sheet 2 (Quote Log):
Sheet 2, Column B: Quote References
Sheet 2, Columns V>AB: Travel data and calculations from sheet 1
I'm after a script that will copy the data in Sheet 1, Cells K4:Q4, and paste them in to Sheet 2, Columns V:AB on the same row as the selected job ref '100001' on Sheet 1, Cell A4, which will also be present in Sheet 2, Column B
Any help would be greatly appreciated
TIA
The data range you have specified is large than the range you want to put data in hence I have reduced the source range in the code. Try this.
function copyrow() {
var ss = SpreadsheetApp.getActive();
var source = SpreadsheetApp.openById('SheetID');
var dest = SpreadsheetApp.openById('SheetID');
var sourcerange = source.getRange('B4:H4');
var sourcerangevalue = sourcerange.getValues();
var checkval = source.getRange('A4').getValue();
var lastrow = dest.getLastRow();
var destrange = dest.getRange('B1:B');
var destrangevalue = destrange.getValues();
for (i = 1; i <= lastrow; i++) {
if (checkval == destrangevalue[i]) {
dest.getRange('A15').setValue(destrangevalue[i])
dest.getRange("V" + i + ":AB" + i).setValues(sourcerangevalue)
};
};
};
function myFunction() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get data from Sheet1
var s = ss.getSheetByName("Sheet1");
var cel = s.getRange("A4").getValue();
var data = s.getRange("K4:Q4").getValues();
// get to Sheet2 and get values from column 'B'
var s = ss.getSheetByName("Sheet2");
var col = s.getRange("B1:B").getValues();
// find the row number in columnn B that contain the value
var row = col.flat().findIndex( c => c == cel ) + 1;
// put the 'data' into the cells of this row
if (row) s.getRange("V" + row + ":AB" + row).setValues(data);
}
Updated version:
function onEdit(e) {
if (e.range.getA1Notation() !== "Q6") return;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Sheet1");
var cel = s.getRange("A4").getValue();
var data = s.getRange("K4:Q4").getValues();
var s = ss.getSheetByName("Sheet2");
var col = s.getRange("B1:B").getValues();
var row = col.findIndex(c => c[0] == cel) + 1;
if (!row) return;
s.getRange("V" + row + ":AB" + row).setValues(data);
var s = ss.getSheetByName("Sheet1");
ss.getRange("A1").clear();
ss.getRange("F5").clear();
}
I need to pull/import data from "sheet 1" to "sheet 2" based on column 4 being a specific text string. The script should not pull lines that already exist.
I have no idea if this is possible. I can pull the data but it just recopies everything so I have duplicates.
Any help would be super appreciated.
function onEdit() {
var ss = SpreadsheetApp.openById('1Ognzsi6C0DU_ZyDLuct58f5U16sshhBpBoQ8Snk8bhc');
var sheet = ss.getSheetByName('Sheet 1');
var testrange = sheet.getRange('D:D');
var testvalue = (testrange.getValues());
var sss = SpreadsheetApp.getActive();
var csh = sss.getSheetByName('Sheet 1');
var data = [];
var j =[];
for (i=0; i<testvalue.length;i++) {
if ( testvalue[i] == 'Dan') {
data.push.apply(data,sheet.getRange(i+1,1,1,11).getValues());
j.push(i);
}
}
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
}
Sheet 1
Sheet 2
Solution
You should be able to replace your code with this and it will work. You would put this script in the target sheet (Sheet 2), and replace the ID in the first line of the function with the origin (Sheet 1).
I'll leave it up to you to change to an onEdit or to make it a menu item. Right now it can be run from the script editor. onEdit doesn't make sense to me as an appropriate trigger. Maybe you prefer a Time-Driven Trigger. Though a custom menu would be the best way IMO.
function pullData() {
var sourceSs = SpreadsheetApp.openById('[YOUR_SPREADSHEET_ID]');
var sourceRange = sourceSs.getSheetByName('Sheet1').getDataRange();
var sourceHeight = sourceRange.getHeight();
var sourceWidth = sourceRange.getWidth();
var sourceData = sourceSs.getSheetByName('Sheet1').getRange(2, 1, sourceHeight - 1, sourceWidth).getValues();
var targetSs = SpreadsheetApp.getActive();
var targetRange = targetSs.getSheetByName('Sheet1').getDataRange();
var targetHeight = targetRange.getHeight();
var targetWidth = targetRange.getWidth();
var sourceDataChecker = [];
var targetDataChecker = [];
sourceData.forEach((row) => {
sourceDataChecker.push(row[0] + row[1] + row[2] + row[3]);
})
if (targetHeight != 1) {
var targetData = sourceSs.getSheetByName('Sheet1').getRange(2, 1, targetHeight - 1, targetWidth).getValues();
targetData.forEach((row) => {
targetDataChecker.push(row[0] + row[1] + row[2] + row[3]);
});
};
sourceData.forEach((row, i) => {
if (!(targetDataChecker.includes(sourceDataChecker[i]))) {
targetSs.appendRow(row);
};
});
}
Explanation
This script builds an "index" of each row in both sheets by concatenating all the values in the row. I did this because I noticed that sometimes you have "joe" in two rows, and so, you can't simply use column 4 as your index. You are basically checking for any row that is different from one in the target sheet (Sheet 2).
If the target sheet is blank, then all rows are copied.
References
Append Row to end of sheet
Get Data Range (range of sheet that contains data)
Get Range Height (to deal with headers)
Get Range Width
for Each
My code below works, but I thinking that there's a much more elegant way of doing it. I want to copy a portion of a selected row (D:R) on the Customer sheet (source) to the Test sheet (destination) to the first blank row in that sheet (C:Q).
The code works, but just looks non-performant/non-elegant.
function rowSelected() {
var customer_sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Customer_Info");
var invoice_sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test");
var customer_selection_row = customer_sheet.getActiveRange().getRow();
//Browser.msgBox(customer_selection_row);
var customer_selection_start = 'D' + customer_selection_row;
var customer_selection_end = 'R' + customer_selection_row;
var customer_selection_range = customer_selection_start + ':' + customer_selection_end;
var source_range = customer_sheet.getRange(customer_selection_range);
customer_sheet.setActiveRange(source_range);
//Browser.msgBox(source_range.getA1Notation());
var invoice_selection_row = getFirstEmptyRowWholeRow();
var invoice_selection_start = 'C' + invoice_selection_row;
var invoice_selection_end = 'Q' + invoice_selection_row;
var invoice_selection_range = invoice_selection_start + ':' + invoice_selection_end;
var destination_range = invoice_sheet.getRange(invoice_selection_range);
invoice_sheet.setActiveRange(destination_range);
//Browser.msgBox(destination_range.getA1Notation());
customer_sheet.setActiveRange(source_range).copyTo((destination_range), {contentsOnly:true});
}
I'm thinking there is some way of doing this with less code.
You want to copy the column "D" to "R" at the row of the active range of the sheet Customer_Info to the column "C" to "Q" at the row retrieved by getFirstEmptyRowWholeRow() of the sheet Test.
You want to activate the source range.
If my understanding is correct, how about this modification?
Modification points:
SpreadsheetApp.getActiveSpreadsheet() is declared one time as `ss``.
getRange(row, column, numRows, numColumns) is used instead of getRange(a1Notation).
About destination_range, when the start cell is set, the source range can be copied from it.
When the active sheet is Customer_Info, the script is run.
Modified script:
function rowSelected() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var customer_sheet = ss.getActiveSheet();
if (customer_sheet.getSheetName() == "Customer_Info") {
var invoice_sheet = ss.getSheetByName("Test");
var activeRange = ss.getActiveRange();
var source_range = customer_sheet.getRange(activeRange.getRow(), 4, activeRange.getNumRows(), 15).activate();
var destination_range = invoice_sheet.getRange(getFirstEmptyRowWholeRow(), 3); // or invoice_sheet.getRange("C" + getFirstEmptyRowWholeRow())
source_range.copyTo(destination_range, {contentsOnly: true});
}
}
getFirstEmptyRowWholeRow() of your script is also used for above modified script.
In this modified script, if you want to select the range of "A1:A3" on the sheet Customer_Info and run the script, the values of cells "D1:R3" are copied from the cell of the column "C" and the row of getFirstEmptyRowWholeRow().
References:
getRange(row, column, numRows, numColumns)
activate()
If I misunderstood your question and this was not what you want, I apologize.
I have the following script (some of which I found and modified to my needs:
function onedit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var targetSheetName = "Completed";
var sourceSheetName = "Eligibility & Pre-Auths"
var targetSheet = ss.getSheetByName(targetSheetName);
var sourceSheet = ss.getActiveSheet();
var sourceRow = sourceSheet.getActiveRange().getRow();
var targetRow = targetSheet.getLastRow() + 1;
if (sourceSheet.getName() == SourceSheetName) {;
if (sourceRow[22]=="Yes") {;
if (targetRow > targetSheet.getMaxRows()) targetSheet.insertRowAfter(targetRow - 1);
sourceSheet.getRange(sourceRow, 1, 1, sourceSheet.getLastColumn()).copyTo (targetSheet.getRange(targetRow, 1));
sourceSheet.deleteRow(sourceRow);
};
};
}
Everything seems to working except my condition - if (sourceRow[22]=="Yes")
I am new to this, so I know I am just not referencing it correctly.
I am just trying to check if the text "Yes" is in column 22 of the current row. I am executing this script on edit. So basically, when a "Yes" is entered in this fieild, I am moving this record to the sheet called "Completed"
the statement getRow() returns an integer, the number of the row of that range, what you want is the value of the 22cd cell in that row , so try
var sourceRow = sourceSheet.getActiveRange().getRow();
var sourceRowValue = sourceSheet.getRange(sourceRow,1,1,sourceSheet.getMaxColumn()).getValues();
and then to get the cell value condition :
if (sourceRowValue[0][21]=="Yes") {;
...
The result of getValues() is always a 2 dimension array, that's the reason for the [0] and is 0 indexed >> changed to 21
Note that I guess your code could be simpler if you use sourceSheet.getActiveCell().getValue() which returns directly the value of the cell you are writing to...
try this small example where I get the Value and the column index:
function onEdit(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var cellValue = ss.getActiveCell().getValue()
ss.getRange('A1').setValue(cellValue+' in col '+ss.getActiveCell().getColumn())
}