How to check particular value in google spreadsheet - google-apps-script

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.

Related

RefreshImport function not working in Google Sheets

I tried to fill it with my sheet data, but that
var dataRange = sheet.getDataRange();
get an error. What should I do?
function RefreshImports() {
var lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) return; // Wait up to 5s for previous refresh to end.
var id = "1r7TgCWXfjmcjufT0yz9qcFDlr482SdHDHlZYblXyAt0"; // [YOUR SPREADSHEET ID]
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName("crypto"); // sheet name
var dataRange = sheet.getDataRange();
var formulas = dataRange.getFormulas();
var content = "";
var now = new Date();
var time = now.getTime();
var re = /.*[^a-z0-9]import(?:xml|data|feed|html|range)\(.*/gi;
var re2 = /((\?|&)(update=[0-9]*))/gi;
var re3 = /(",)/gi;
for (var row=0; row<formulas.length; row++) {
for (var col=0; col<formulas[0].length; col++) {
content = formulas[row][col];
if (content != "") {
var match = content.search(re);
if (match !== -1 ) {
// import function is used in this cell
var updatedContent = content.toString().replace(re2,"$2update=" + time);
if (updatedContent == content) {
// No querystring exists yet in url
updatedContent = content.toString().replace(re3,"?update=" + time + "$1");
}
// Update url in formula with querystring param
sheet.getRange(row+1, col+1).setFormula(updatedContent);
}
}
}
}
// Done refresh; release the lock.
lock.releaseLock();
// Show last updated time on sheet somewhere
sheet.getRange(7,2).setValue("Rates were last updated at " + now.toLocaleTimeString())
}
I set up the trigger.
Not sure what you trying to do and you explanation leaves a lot to be desired.
So this is a simple way to put your formulas into a sheet named "Destination".
function RefreshImports() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("crypto");
const rg = sh.getDataRange();
const formulas = rg.getFormulas();
sh.getRange(1,1,formulas.length,formulas[0].length).setFormulas(formulas);
}

Google App Scripts: How do you copy a row to the next available row in a new tab depending on the value in a cell

I am trying to transfer a row (range A:AE) from sheet NSI to the next available row in Sheet1 if cell AE= 1.
My code doesn't seem to work, please could somebody help me?
Thank you!!
function myFunction() {
function copyRows() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("NSI");
var lastRow = srcSheet.getLastRow();
for (var i = 2; i <= lastRow; i++) {
var srcRange = srcSheet.getRange("A" + i + ":AE" + i);
var cell = srcSheet.getRange("AE" + i);
var val = cell.getValue();
//sets the target sheet depending on the exam in column AE
if (val == "1") {
var tarSheet = sSheet.getSheetByName("Sheet1");
}
//insets the row in the correct target worksheet
var tarRow = tarSheet.getLastRow()+1;
tarSheet.insertRows(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow) + ":AE" + (tarRow));
srcRange.copyTo(tarRange);
}
};
}
function copyRows() {
var sSheet = SpreadsheetApp.getActive();
var srcSheet = sSheet.getSheetByName("NSI");
const vs = srcSheet.getRange(2, 1, srcSheet.getLastRow() - 1, 31).getDisplayValues();
var tarSheet = sSheet.getSheetByName("Sheet1");
vs.forEach(r => {
if (r[30] == "1") {
tarSheet.appendRow(r);
}
});
}

Replace character using google apps script

I have a column which is a date in string format with this format
2020-02-23T12:14:06+0000
And i want to remove the T and replace it with space and also just completely remove the last part (+0000)
I have tried this
var A1 = CONTENT.getRange("B:B").getValue();
var A1String = A1.toString().replace("T*", "");
but it doesn't work.
Any ideas?
This is the original script in which i want to incorporate it into.
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('sheetname');
var range = sheet.getRange("A:C");
var response = UrlFetchApp.fetch("API CALL");
var dataAll = JSON.parse(response.getContentText());
var dataSet = dataAll.data;
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([new Date(),data.created_time,data.message,data.permalink_url,
data.reactions.summary.total_count
,data.comments.summary.total_count,data.insights.data[1].values[0].value,data.insights.data[2].values[0].value,data.insights.data[3].values[0].value,data.insights.data[0].values[0].value['link clicks'],data.insights.data[0].values[0].value['photo view'],data.insights.data[0].values[0].value['other clicks'],data.insights.data[0].values[0].value['video play'],data.insights.data[4].values[0].value,data.insights.data[5].values[0].value,data.insights.data[6].values[0].value,data.insights.data[7].values[0].value["like"],data.insights.data[7].values[0].value["love"],data.insights.data[7].values[0].value["wow"],data.insights.data[7].values[0].value["haha"],data.insights.data[7].values[0].value["sorry"]]); //your JSON entities here
}
Logger.log(rows)
//sheet.getRange(getlastRow() + 1, 1, rows.length, 2).setValues(rows);
sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 22).setValues(rows);
/**
* Removes duplicate rows from the current sheet.
*/
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetname');
var data = sheet.getDataRange().getValues();
data.reverse(); //reverses the row order.
var last=sheet.getLastRow();
var newData = new Array();
for(i in data){
//Logger.log(i);
var row = data[i];
//Logger.log(row[5]);
var duplicate = false;
for(j in newData){
//Logger.log(newData[j][3]);
if(row[3] == newData[j][3]){
duplicate = true;
}
}
if(!duplicate){
newData.push(row);
}
}
newData.reverse(); // reverses your data back to its original order.
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
//
//
If you want to remove always the same thing (i.e. "T" and "+0000"), you could use the following script:
The result obtained: 2020-02-23 12:14:06
CODE:
// ---------- Menu ----------
// Add a Menu named Format Date to run the script
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Format Date')
.addItem('Go!', 'FormatDate')
.addToUi();
}
function FormatDate() {
var ss = SpreadsheetApp.getActiveSheet(),
array = [];
ss.getRange("B2:B") // Choose the range here
.getValues()
.forEach(function (dates) {
// "T" is replaced with a space: " " and "+0000" is replace with empty:""
[["T", " "], ["+0000", ""]]
.map(function (a, i) {
return dates = replace(dates.toString(), a[0], a[1])
})
array.push([dates])
});
// You can set a different column to write the data
// Or keep B2:B to overwrite your data
ss.getRange("B2:B")
.setValues(array)
}
function replace(d, a, r) {
return d.indexOf(a) > -1 ? d.split(a)
.join(r) : d;
}
Credit: got inspired by JPV's code to a different question long time ago

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

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);
}

Adding a timestamp when specific data is entered from another sheet in Google Sheet

I have a Google Sheet containing two sheets, one named Form and the other Data. Information on the Data sheet is usually entered via the Form sheet, where a button click on the Form sheet sends the data over to the bottom row on the Data sheet.
I'm trying to figure out how I can add a timestamp to the appropriate cell in column E on the Data sheet when a cell on the same row in column D receives the word 'CLEANED' either as a submission from the Form sheet or as a direct manual entry on the Data sheet.
This code currently adds the timestamp, but only when I change a value in column D directly on the Data sheet (not when values are added via the Form sheet), and it adds the timestamp for any value that's added.
var ColumnToCheck = 4;
var DateTimeLocation = [0,1];
var sheetName = 'Data'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
if( sheet.getSheetName() == sheetName ) {
var selectedCell = ss.getActiveCell();
if( selectedCell.getColumn() == ColumnToCheck) {
var dateTimeCell = selectedCell.offset(DateTimeLocation[0],DateTimeLocation[1]);
dateTimeCell.setValue(new Date());
}
}
}
I am using this code to transfer data from the Form sheet:
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form");
var dataSheet = ss.getSheetByName("Data");
var values = formSS.getRange("B2:B5").getValues().reduce(function(a, b) {
return a.concat(b)
});
var partNum = values[0];
var row;
dataSheet.getDataRange().getValues().forEach(function(r, i) {
if (r[0] === partNum) {
row = i + 1
}
})
row = row ? row : dataSheet.getLastRow() + 1;
var data = dataSheet.getRange(row, 1, 1, 4).getValues()[0].map(function (el, ind){
return el = values[ind] ? values[ind] : el;
})
dataSheet.getRange(row, 1, 1, 4).setValues([data]);
formSS.getRange("B2:B5").clearContent()
}
What would be the best way to have the date added automatically when only the word 'CLEANED' is entered? The date shouldn't clear if the word 'CLEANED' is removed or changed to a different word.
EDIT - SOLUTION
Thanks to Sourabh Choraria, I was able to change my UPDATE function to this in order to incorporate my needs (my additions to his code are commented):
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form");
var dataSheet = ss.getSheetByName("Data");
var values = formSS.getRange("B3:B6").getValues().reduce(function(a, b) {
return a.concat(b)
});
var partNum = values[0];
var row;
dataSheet.getDataRange().getValues().forEach(function(r, i) {
if (r[0] === partNum) {
row = i + 1
}
})
row = row ? row : dataSheet.getLastRow() + 1;
var data = dataSheet.getRange(row, 1, 1, 4).getValues()[0].map(function (el, ind){
return el = values[ind] ? values[ind] : el;
})
var statusValue = formSS.getRange("B6").getValue(); //added
if (statusValue != 'CLEANED') { //added
dataSheet.getRange(row, 1, 1, 4).setValues([data]); //added
} //added
if (statusValue == 'CLEANED') { //added
var now = [new Date()];
var newData = data.concat(now)
dataSheet.getRange(row, 1, 1, 5).setValues([newData]);
} //added
formSS.getRange("B3:B6").clearContent()
}
Update the submitData() function with the following code -
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form");
var dataSheet = ss.getSheetByName("Data");
var values = formSS.getRange("B2:B5").getValues().reduce(function(a, b) {
return a.concat(b)
});
var partNum = values[0];
var row;
dataSheet.getDataRange().getValues().forEach(function(r, i) {
if (r[0] === partNum) {
row = i + 1
}
})
row = row ? row : dataSheet.getLastRow() + 1;
var data = dataSheet.getRange(row, 1, 1, 4).getValues()[0].map(function (el, ind){
return el = values[ind] ? values[ind] : el;
})
// modification begins here
var now = [new Date()];
var newData = data.concat(now)
dataSheet.getRange(row, 1, 1, 5).setValues([newData]);
// modification ends here
formSS.getRange("B2:B5").clearContent()
}
Basically, I'm declaring a new array variable (now) and concatenating it to the existing data array, thus forming a "newData" variable and then updating the setValues function to accommodate this change.
Hope this helps and thanks for sharing the view access to the sheet - I made a copy of that and tested the solution directly :)
Edit note1
As for updating the sheet only when the dropdown selected is 'CLEANED', kindly modify your onEdit() function to accommodate the following IF condition -
var statusValue = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form').getRange("B6").getValue();
if (statusValue == 'CLEANED') {
// update timestamp as required
}