Get Selected Row's Specific Col Value via script (Google Sheets) - google-apps-script

I've been trying to get this one to work without success so far.
I need to get the TaskNumber on the first column of the row I'm on and bring it to the destination sheet, so that I can update it there.
I have the following, which I'm tweaking to achieve my goal, but I guess I've bumped into my limitation walls:
function jump() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var TaskNumberSheet = ss.getSheetByName('To-Do List');
var TaskNoRow = TaskNumberSheet.getActiveCell();
var TaskNoCol = TaskNoRow.getColumn() == 1
var TaskNo = TaskNoCol.getValue;
var sheet = ss.getSheetByName('Updates');
//var Tasks = ss.getSheetByName("To Do List").getActiveRange(Tasks.getColum(1)).getValue();
var values = sheet.getRange("B:B").getValues();
var maxIndex = values.reduce(function(maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
sheet.setActiveRange(sheet.getRange(maxIndex + 2,2)).setValue(TaskNo);
}
Any help is appreciate.
Cheers,
A

If I understood you correctly, you want to:
Get the value in column A from the currently active row (in sheet To-Do List).
Find the first empty cell in column B (in sheet Updates) (start looking at row #8).
Copy the value that was retrieved in step 1 to the cell retrieved in step 2.
Set the cell retrieved in step 2 as the active cell.
If that's the case, you can do the following:
function jump() {
var ss = SpreadsheetApp.getActive();
// Step 1:
var TaskNumberSheet = ss.getSheetByName('To-Do List');
var TaskNoRow = TaskNumberSheet.getActiveCell().getRow();
var TaskNoCol = 1;
var TaskNo = TaskNumberSheet.getRange(TaskNoRow, TaskNoCol).getValue();
// Step 2:
var sheet = ss.getSheetByName('Updates');
var firstRow = 8;
var column = 2;
var numRows = sheet.getLastRow() - firstRow + 1;
var values = sheet.getRange(firstRow, column, numRows).getValues().map(function(value) {
return value[0]
});
var i = 0;
for (i; i < values.length; i++) {
if (values[i] === "") break;
}
var targetRange = sheet.getRange(i + firstRow, column);
targetRange.setValue(TaskNo); // Step 3
sheet.setActiveRange(targetRange); // Step 4
}

function jump() {
var TargetRow=?;//Fillin target row
var TargetCol=?;//Fillin target column
var ss=SpreadsheetApp.getActive();
var TaskNumberSheet=ss.getSheetByName('To-Do List');
var TaskNoRow=TaskNumberSheet.getActiveCell().getRow();//Getting row from active cell
var TaskNoCol=1
var TaskNo=TaskNumberSheet.getRange(TaskNoRow,TaskNoCol).getValue();
ss.getSheetByName('Updates').getRange(targetRow,targetCol).setValue(TaskNo);
}

Related

Activate cell in column A on next empty row in a Google sheet

I am trying to activate the cell in column A of the next empty row in my Google sheet.
I have created the below script based on a video of youtube - this does return the value of the next empty row but I am struggling on how to activate the selection.
Can anyone help on this please?
function jumpToLastRowChilled() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Chilled Sheet");
var rng = ss.getRange("A1:H").getValues();
var lrIndex;
for(var i = rng.length-1;i>=0;i--){
lrIndex = i;
if(!rng[i].every(function(c){ return c == ""})){
break;
}
}
var lr = lrIndex + 2;
}
I found to do this you can do the below:
function jumpToLastRowChilled() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Chilled Sheet");
var rng = ss.getDataRange();
var lr = rng.getLastRow();
var alr = ss.getRange(lr+1,1).activate();
}

How to getRange() of a group of cells while doing iteration in a Google Apps Script?

I want to check if there is any blank cells in a given range and trying to use below code for that. Problem is Range is not certain and subject to change with every iteration.
I tried something like getRange('A'+ row : 'H'+ row) but its in wrong syntax. Can someone help me with this issue ? Thanks!
var sheet1 = spreadsheet.getSheetByName('Red'); // Get worksheet
var endRow = sheet1.getLastRow();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); // Get current active spreadsheet.
var sheet2 = spreadsheet.getSheetByName('Template');
var runloop = true;
var startRow = 3;
for (var row = startRow; row <= endRow; row++) {
var sheet_name = sheet1.getRange("A" + row).getValue(); // Get the JD number for the file name.
var range = sheet1.getRange('A' + row: 'H' + row);
if (range.isBlank()) {
# Dome Something here
}
}
You can concatenate the A1Notation before passing it to getRange()
Example:
function myFunction() {
for (var row = 1; row <= 5; row++) {
var rangeA = "A" + row;
var rangeB = "H" + row;
var range = rangeA + ":" + rangeB;
Logger.log(range);
// Get the JD number for the file name.
var sheet_name = SpreadsheetApp.getActiveSheet().getRange(rangeA).getValue();
var range = SpreadsheetApp.getActiveSheet().getRange(range);
if (range.isBlank()) {
Logger.log(range.getA1Notation() + " is blank!.");
}
}
}
Output log from the example:
You can try Utilities.formatString
var range = sheet1.getRange(Utilities.formatString('A%s:H%s', row, row));
For V8 runtime
const range = sheet1.getRange(`A${row}:H${row}`);

Adding a row to a filtered range

I have a to-do list app in google sheets. I have functions for filtering by "note type" and "done status" that can be in use at any given moment by the user.
I also have functions to easily add a new note of any given type. However, when running the function to add a new note, and the sheet is already filtered, I'm getting the following error:
"This operation is not supported on a range with a filtered out row."
Any advice on how I can add a row to a filtered range?
Here is the code that I am using to add a new note of a particular type:
function addNewCueNote() {
if( sheet.getSheetName() == sheetName ) {
var noteType = "CUE"
//ADDS ROW AND COPIES FORMULA DOWN
//SETS VARIABLES FOR LAST ROW AND LAST COLUMN
var lRow = sheet.getLastRow();
var lCol = sheet.getLastColumn();
//INSERT LAST ROW
sheet.insertRowsAfter(lRow, 1);
//COPY FORMULAS DOWN FOR SPECIFIED COLUMNS
sheet.getRange(lRow,firstCopyCol,1,numColCopy).copyTo(sheet.getRange(lRow+1,firstCopyCol,1,numColCopy));
//SETS NOTE TYPE
sheet.getRange(sheet.getLastRow(),noteTypeCol).setValue(noteType);
}
Grab the existing filter, remove it from the sheet, add the new row, then recreate the filter using the criteria from the initial filter.
function addNewCueNote() {
var sheet = SpreadsheetApp.getActiveSheet(); // added to get code to run; not sure if you handle elsewhere
if (sheet.getSheetName() === sheetName) {
// Save state of existing filter before removing it
var oldCriteria = [];
var filter = sheet.getFilter();
if (filter != null) {
var oldNumColumns = filter.getRange().getNumColumns();
for (var c = 1; c <= oldNumColumns; c++) {
var criteria = filter.getColumnFilterCriteria(c);
if (criteria != null) {
oldCriteria.push([c, criteria.copy()]);
}
}
filter.remove();
}
//*** PUT YOUR ROW INSERT LOGIC HERE ***
// Recreate filter on new data range
var dataRange = sheet.getDataRange();
var newFilter = dataRange.createFilter();
if (filter != null) {
var newNumColumns = dataRange.getNumColumns();
for (var i = 0; i < oldCriteria.length && oldCriteria[i][0] <= newNumColumns; i++) {
newFilter.setColumnFilterCriteria(oldCriteria[i][0], oldCriteria[i][1]);
}
}
}
#Nick there is something wrong with your code logic. In any ways this is a working code
// *** I have to add this for tests ***
var firstCopyCol = 3;
var numColCopy = 2;
var noteTypeCol = 2;
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = 'MatchImport';
// ************************************
function addNewCueNote() {
if (sheet.getSheetName() === sheetName) {
var filter = sheet.getFilter();
if (filter) {
var dataRange = sheet.getDataRange();
var oldNumColumns = filter.getRange().getNumColumns();
var newNumColumns = dataRange.getNumColumns();
var criterias = {};
for (var c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
var criteria = filter.getColumnFilterCriteria(c);
if (criteria) criterias['_' + c] = criteria;
}
filter.remove();
}
// START OF YOUR INSERT LOGIC
var noteType = 'CUE';
// ADDS ROW AND COPIES FORMULA DOWN
// SETS VARIABLES FOR LAST ROW AND LAST COLUMN
var lRow = sheet.getLastRow();
var lCol = sheet.getLastColumn(); // This is never used
// INSERT LAST ROW
sheet.insertRowsAfter(lRow, 1);
// COPY FORMULAS DOWN FOR SPECIFIED COLUMNS
sheet
.getRange(lRow, firstCopyCol, 1, numColCopy)
.copyTo(sheet.getRange(lRow + 1, firstCopyCol, 1, numColCopy));
// SETS NOTE TYPE
sheet.getRange(sheet.getLastRow(), noteTypeCol).setValue(noteType);
//* * END OF YOUR INSERT LOGIC
if (!filter) return;
dataRange = sheet.getDataRange();
var newFilter = dataRange.createFilter();
newNumColumns = dataRange.getNumColumns();
for (c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
if (criterias['_' + c])
newFilter.setColumnFilterCriteria(c, criterias['_' + c]);
}
}
}

How to check particular value in google spreadsheet

I picked this code online and I am trying to check if the value in the column B is 'Done' then the value will be be copied otherwise not. Here is the code I am using:
copy sheet function below will copy the datat from source sheet to destination sheet but what I want that it will only pick the row if the col B value contains Done
function copySheet() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Source");
var destSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Destination");
var columns_to_be_copied =['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U'];
var columns_to_be_pasted =['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U'];
for (column in columns_to_be_copied) {
var copy_range_string = columns_to_be_copied[column] + ':' + columns_to_be_copied[column];
var paste_range_string = columns_to_be_pasted[column] + ':' + columns_to_be_pasted[column];
var source = sourceSheet.getRange(copy_range_string);
var destination = destSheet.getRange(paste_range_string);
if(findInColumn('A','Done') !== -1) {
copyTo(source,destination );
}
}
}
function copyTo(source,destination) {
var sourceSheet = source.getSheet();
var destSheet = destination.getSheet();
var sourceData = source.getValues();
var dest = destSheet.getRange(
destination.getRow(), // Top row of destination
destination.getColumn(), // left col of destination
sourceData.length, // # rows in source
sourceData[0].length); // # cols in source (elements in first row)
dest.setValues(sourceData);
SpreadsheetApp.flush();
}
function findInColumn(column, data) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sprint");
var column = sheet.getRange(column + ":" + column); // like A:A
var values = column.getValues();
var row = 0;
while (values[row] && values[row][0] !== data) {
row++;
}
if (values[row][0] === data)
return row+1;
else
return -1;
}
As I am a fan of simple and easy to read (even after long time) solutions I would suggest the following script:
function main() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Source');
var destinationSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Destination');
copyFromTo(sourceSheet, destinationSheet);
}
function copyFromTo(sourceSheet, destinationSheet) {
const ColumnB = 1; //Array indexing starts from 0
const FilterValue = 'Done';
var sourceValues = sourceSheet.getSheetValues(1, 1, 100, 28); //startRow, startColumn, numRows, numColumns
var filteredValues = sourceValues.filter(function(row) {
return row[ColumnB] === FilterValue;
});
destinationSheet.getRange(1, 1, filteredValues.length, filteredValues[0].length).setValues(filteredValues);
}
It's about the same function. I just modified it to facilitate my debugging process. It copies the columns from source to destination if Sprint has "Done" in that column.
function copySheet() {
var srcsh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Source");
var dessh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Destination");
var from = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U'];
var to = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U'];
for(var i=0;i<from.length;i++) {
var fromrg = from[i] + ':' + from[i];
var torg = to[i] + ':' + to[i];
var src = srcsh.getRange(fromrg);
var des = dessh.getRange(torg);
if(findInColumn(from[i],'Done')!== -1){
src.copyTo(des);
}
}
}
function findInColumn(col, data) {
var col=col || 'A';//This is here for initial testing so I could run the function without parameters.
var data=data || 'Done';
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sprint");
var rg = sh.getRange(col + "1:" + col + sh.getMaxRows());//MaxRows is kind of big but I was not sure what else you'd like to do and I dont know what your Sprint sheet looks like.
var vA = rg.getValues();
var rv=-1;
for(var i=0;i<vA.length;i++){
if(vA[i][0]==data){
rv=i+1;
break;
}
}
return rv;
}
I see that you changed the question a bit. This function looks in your sprint sheet as you show in your answer and copies from source to destination only those columns that have the word "Done" on any row of that column. But it checks every column in your "columns_to_be_copied" which I called "from". Originally, that's what your function was trying to do. So I just wanted to be clear what this function is doing. If it's not what you want then leave a comment and I'll delete it.

Merging google sheets: match with specific col values and merge data in 2 different sheets

I would like to ask if there is any possible way to set up a simple version of app script that is similar to the below add-ons.
https://chrome.google.com/webstore/detail/merge-sheets/gdmgbiccnalapanbededmeiadjfbfhkl?utm_source=ablebits
Basically, I've got sheet 1 and sheet 3, both sheets will have a common key column with specific values in each cell, and I would like to map both sheets with the data in that column then update the whole row data in the other sheets (For example, if i updated the sheet 3 then it map that col value in sheet 1, then paste the data in the corresponding row)
I have came up with a code that runs but no changes have been made, could anyone please advise how can I modify it to a simple version similar to the above add-ons? Thanks in advance.
I would like to populate the date from sheet 3 to sheet 1 after the code run, while the data from col C is matched in both sheets, please see example below, thanks!
For example, the data in sheet 1 highlighted row is having its key col with col C for common lookup value with sheet 3 while the row sequence is diff with sheet 3 (Please see the next photo, thanks!)
As you can see in sheet 3, the data of the whole row is inserted to the correct row according to the col C key col value which matched with sheet 1.
function myFunction2(){
// Get your spreadsheet and the sheets "TB" and "2"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet 1");
var sheet3 = ss.getSheetByName("Sheet 3");
// Get the range on sheet "TB"
var tabsheet1 = sheet1.getRange(2, 2, sheet1.getLastRow(),
sheet1.getLastColumn());
// Get the values to compare
var datasheet1 = tabsheet1.getValues();
var datasheet3 = sheet3.getRange(2, 2, sheet3.getLastRow(), sheet3.getLastColumn());
for(var i = 0; i < datasheet1.length; i++){
for(var j = 0; j < datasheet3.length; j++){
// Compare data: if they're the same, put the value
if(datasheet1[i][0]=(datasheet3[j][0]) == 0){
//if(datasheet1[i][0].localeCompare(datasheet3[j][0]) == 0){
datasheet1[i][1] = datasheet3[j][1];
}
}
}
// Take the modified tab and put it on the spreadsheet
tabsheet1.setValues(datasheet1);
}
You want to copy the data of sheet 3 to sheet 1. For this situation, when the values of column C of sheet 3 and sheet 1 is the same, you want to copy the row of sheet 3 to sheet 1, because the order of rows for sheet 3 and sheet 1 are different. If my understanding is correct, how about this modification?
Modification points :
In order to retrieve the values from column C to last column, it uses getRange(2, 3, sheet1.getLastRow(), sheet1.getLastColumn()).
In your script, datasheet3 is the range.
About if(datasheet1[i][0]=(datasheet3[j][0]) == 0){, in order to comare the date, I used getDisplayValues().
By this, the values retrieved as a string are compared.
Modified script :
function myFunction2(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet 1");
var sheet3 = ss.getSheetByName("Sheet 3");
var tabsheet1 = sheet1.getRange(2, 3, sheet1.getLastRow(), sheet1.getLastColumn());
var datasheet1 = tabsheet1.getValues();
var datasheet1d = tabsheet1.getDisplayValues(); // Added
var tabsheet3 = sheet3.getRange(2, 3, sheet3.getLastRow(), sheet3.getLastColumn()); // Added
var datasheet3 = tabsheet3.getValues(); // Modified
var datasheet3d = tabsheet3.getDisplayValues(); // Added
for (var i = 0; i < datasheet1.length; i++) {
for (var j = 0; j < datasheet3.length; j++) {
if (datasheet1d[i][0] == datasheet3d[j][0]) { // Modified
datasheet1[i] = datasheet3[j]; // Modified
}
}
}
tabsheet1.setValues(datasheet1);
}
Reference :
getDisplayValues()
If I misunderstand your question, please tell me. I would like to modify it. At that time, in order to modify, can you share the sample sheet? Of course, please remove your private information from it.
Edit 1 :
function myFunction2(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet 1");
var sheet3 = ss.getSheetByName("Sheet 3");
var tabsheet1 = sheet1.getRange(2, 3, sheet1.getLastRow() - 1, sheet1.getLastColumn() - 2); // Modified
var datasheet1 = tabsheet1.getValues();
var datasheet1d = tabsheet1.getDisplayValues(); // Added
var tabsheet3 = sheet3.getRange(2, 3, sheet3.getLastRow() - 1, sheet3.getLastColumn() - 2); // Added
var datasheet3 = tabsheet3.getValues(); // Modified
var datasheet3d = tabsheet3.getDisplayValues(); // Added
for (var i = 0; i < datasheet1.length; i++) {
for (var j = 0; j < datasheet3.length; j++) {
if (datasheet1d[i][0] == datasheet3d[j][0]) { // Modified
datasheet3[j].push(""); // Modified
datasheet1[i] = datasheet3[j]; // Modified
}
}
}
tabsheet1.setValues(datasheet1);
}
Edit 2 :
function myFunction2(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("comment_log");
var sheet3 = ss.getSheetByName("CM");
var tabsheet1 = sheet1.getRange(2, 3, sheet1.getLastRow() - 1, sheet1.getLastColumn() - 2); // Modified
var datasheet1 = tabsheet1.getValues();
var datasheet1d = tabsheet1.getDisplayValues(); // Added
var tabsheet3 = sheet3.getRange(2, 3, sheet3.getLastRow() - 1, sheet3.getLastColumn() - 2); // Added
var datasheet3 = tabsheet3.getValues(); // Modified
var datasheet3d = tabsheet3.getDisplayValues(); // Added
for (var i = 0; i < datasheet1.length; i++) {
for (var j = 0; j < datasheet3.length; j++) {
if (datasheet1d[i][0] == datasheet3d[j][0]) { // Modified
if (datasheet1[i].length != datasheet3[j].length) {
for (var k = 0; k < datasheet1[i].length - datasheet3[j].length; k++) {
datasheet3[j].push(datasheet1[i][datasheet1[i].length - 1]);
}
}
datasheet1[i] = datasheet3[j]
}
}
}
tabsheet1.setValues(datasheet1);
}