Data validation Script loop - google-apps-script

I have a code to create a data validation on a cell from a range next to it.
example:
var cellC4 = cell.getRange('F11');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG11:AG11');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC4.setDataValidation(rule);
var cellC5 = cell.getRange('F12');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG12:AG12');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC5.setDataValidation(rule);
var cellC6 = cell.getRange('F13');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG13:AG13');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC6.setDataValidation(rule);
var cellC7 = cell.getRange('F14');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG14:AG14');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC7.setDataValidation(rule);
can someone help me do it correctly
Im stuck here:
function onOpen(){
var ss0 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MAIN');
var EndRow = ss0.getLastRow();
for ( var c = 16;c <= 25; c) {
for ( var i = 11;i <= EndRow; i++ ) {
//►PO# VALIDATION►
var range1 = ss0.getRange(i, c);
var rule1 = SpreadsheetApp.newDataValidation().requireValueInRange(range1).build();
ss0.getRange(i, 5).setDataValidation(rule1);
}}}

Findings:
Your looping for this part for ( var c = 16;c <= 25; c) { has a
wrong iteration with c instead of using c++. Thus, this looping
will never finish running.
SUGGESTION:
==UPDATE===
You can try this sample script below:
function onOpen(){
var ss0 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MAIN');
var EndRow = ss0.getLastRow();
for(row=11; row<=EndRow; row++){
var data = ss0.getRange("P"+row+":Y"+row).getDisplayValues();
var rule = SpreadsheetApp.newDataValidation().requireValueInList(data[0]).build();
ss0.getRange(row,5).setDataValidation(rule);
}
}
Sample:
Result on column 5 or column E after the onOpen() function finishes running

Related

How I create pdf with select area and how to fix last row got empty value

I don't need empty how I should do, I think problem in lastrow funtion (see in picture)
I want to create pdf with can select area and select sheet without hide other sheet is posible ?
this is code(copy from some youtube)
function test() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shtprint = ss.getSheetByName("Test print");
var shtkishu = ss.getSheetByName('proplan');
var shmaster = ss.getSheetByName('Master')
var shsetting = ss.getSheetByName('SETTING')
var shdata = ss.getSheetByName('DATA')
var shzttpp = ss.getSheetByName('ZTTPP038')
var LastRow = shtkishu.getRange(5,8).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
var kishu = shtkishu.getRange(5,8,+LastRow).getValues().flat().map(v=>[v.slice(-7)]);
Logger.log(kishu)
for (var i = 0;i < kishu.length;i++){
shtprint.getRange('E2').setValue(kishu[i][0]);
var name = shtprint.getRange('E2').getValue();
shtkishu.hideSheet();
shmaster.hideSheet();
shsetting.hideSheet();
shdata.hideSheet();
shzttpp.hideSheet();
var folder = DriveApp.getFoldersByName("test").next();
var Blob = shtkishu.getParent().getBlob().getAs('application/pdf');
folder.createFile(Blob).setName(name);
}
shtkishu.showSheet();
}
don't know how to fix that

Iterate through named range and update values

I need to iterate through a named range in Google Sheet and update the value based on other named ranges.
I have this now and I'm getting an error on line 13
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var FreeCopiesTarget = ss.getRangeByName('FreeCopiesTarget');
var CostPerCopy = ss.getRangeByName('CostPerCopy');
var FreeCopies = ss.getRangeByName('FreeCopies');
var values = FreeCopiesTarget.getValues();
for (var counter = 0; counter <= 4; counter++) {
var cost = CostPerCopy.getValues()[counter][0] * FreeCopies.getValues()[counter][0];
var r = FreeCopiesTarget.getValues()[counter][0];
r.setValue(cost);
}
}
Any help is appreciated.
Issue:
r is a value from a cell, which can be a Number, Boolean, String, or a Date. None of these includes the method setValue. r should be a Range instead.
Code sample:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var FreeCopiesTarget = ss.getRangeByName('FreeCopiesTarget');
freeCopiesValues = FreeCopiesTarget.getValues();
var CostPerCopy = ss.getRangeByName('CostPerCopy').getValues();
var FreeCopies = ss.getRangeByName('FreeCopies').getValues();
for (var counter = 0; counter <= 4; counter++) {
var cost = CostPerCopy[0][counter] * FreeCopies[0][counter];
freeCopiesValues[0][counter] = cost;
}
FreeCopiesTarget.setValues(freeCopiesValues);
}
Note:
It's not best practice to use getValues iteratively. It's preferrable to get all values at once and work with the resulting 2D array, as shown in the sample above.
Following Iamblichus answer, I tweaked as follows and it works as expected.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var FreeCopiesTarget = ss.getRangeByName('FreeCopiesTarget');
freeCopiesValues = FreeCopiesTarget.getValues();
var CostPerCopy = ss.getRangeByName('CostPerCopy').getValues();
var FreeCopies = ss.getRangeByName('FreeCopies').getValues();
for (var counter = 0; counter <= 4; counter++) {
var cost = CostPerCopy[0][counter] * FreeCopies[0][counter];
freeCopiesValues[0][counter] = cost;
}
FreeCopiesTarget.setValues(freeCopiesValues);
}

Conditional MOVE data from one sheet to another in google spreasheet

I got the code online and added in the if statement myself and it did not work.
What i would like to achieve:
One column to indicate 'ok' . If 'ok' is present, that row of data will be moved to the other spreadsheet.
function moveData(){
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
var originalSheet = app.getActiveSpreadsheet().getSheetByName("Form Responses 4");
var copySheet = app.getActiveSpreadsheet().getSheetByName("RECORDS");
var lc = originalSheet.getLastColumn();
var lr = originalSheet.getLastRow();
var originalData = originalSheet.getDataRange().getValues();
for (var i=originalData.length-1; i>=1 ; --i){
var crange = originalSheet.getRange(i, 37).getValue();
if ( crange == 'ok' ){
copySheet.getRange(copySheet.getLastRow()+1, 1, 1,
originalData[i].length).setValues([ originalData[i] ]);
}
}
}

Google Apps Script: RegExp g Modifier

I can't seem to get the "g modifier" in a RegExp to work in a Google script.
When I try to apply it, sometimes I get the error that "ReferenceError: "g" is not defined.". When I remove the /g both regExp.exec and input.match(regExp) work, but only for the first match. Other times, I'll get the /g to work, but it returns null, not even producing the first match. I had attempted a while loop, but I didn't want to slow down this process even more (I'll save optimizing this script for another post once I get it to work as intended).
The short version is, I'm trying to get ALL matches (email addresses) not just the first one. Where do I apply the /g? Should I use another method?
You can see (below) what I've been attempting below.
Any tips? I appreciate any help me understand this and anyone that can show me a better way to approach this. Thanks!
if (colA != "" && colE != processed) {
var html = UrlFetchApp.fetch(colA).getContentText();
//Logger.log(html);
var regExp = new RegExp("[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}");
var regExp2 = new RegExp("[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}");
var regExp3 = '[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]/g {2,4}';
var regExp4 = '[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}/g';
var extractTest = html.match(regExp3);
//var extract = regExp.exec(html);
Logger.log(extractTest);
}
You can see the "bigger picture" of it all below.
//TEST
var processed = "YES";
function test() {
var ss = SpreadsheetApp.openById('1E4yUVIpwi00DzjfnXrZSgNFmVjOQbNWewxAiTBHRdD4');
var sheet = ss.getSheetByName('Sheet5');
var currentRow = 2;
var currentColumn = 1;
var numRows = sheet.getLastRow()-1;
var numColumns = 5;
var range = sheet.getRange(currentRow, currentColumn, numRows, numColumns);
var values = range.getValues();
//Logger.log(values);
for (var i = 0; i < numRows; ++i) {
var column = values[i];
var colA = column[0];
var colB = column[1];
var colC = column[2];
var colD = column[3];
var colE = column[4];
if (colA != "" && colE != processed) {
var html = UrlFetchApp.fetch(colA).getContentText();
//Logger.log(html);
var regExp = new RegExp("[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}");
var regExp2 = new RegExp("[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}");
var regExp3 = '[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]/g {2,4}';
var regExp4 = '[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}/g';
var extractTest = html.match(regExp3);
//var extract = regExp.exec(html);
Logger.log(extractTest);
}
}
//var destRange = sheet.getRange(currentRow+i,2);
//destRange.setValue(extract);
//var destRange2 = sheet.getRange(currentRow+i,5);
//destRange2.setValue(processed);
SpreadsheetApp.flush();
}
Using the solution provided by #I'-'I (see comments above): var re = /[A-z0-9._%+-]+#[A-z0-9.-]+\.[A-z]{2,4}/g;

Method is heavily used by the script

I am very new on using Google Apps Script and has a shallow knowledge on programming. What I am trying to do is copy the values of specific columns to a different Spreadsheet. Here's my code:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var responses = ss.getSheetByName("Responses ID");//Where ID's of the spreadsheets are listed.
var consolidatedSheet = ss.getSheetByName("Consolidated");//Where the data should be pasted.
var responseColValues = responses.getRange(2,2, responses.getMaxRows() -1).getValues();
var responsesIds = [i for each (i in responseColValues)if (isNaN(i))];
var ssSelected = SpreadsheetApp.openById(responsesIds[0]);
var selectedSheets = ssSelected.getSheets();
for (i=0; i<3; i++){
var maxRows = selectedSheets[i].getLastRow()-1;
var x=2, y=2;
var lastRow = consolidatedSheet.getLastRow()+1;
for (j=0; j<maxRows; j++){
var eventID = selectedSheets[i].getRange(y,2).getValue();
var employeeName = selectedSheets[i].getRange(y,3).getValue();
var productionDate = selectedSheets[i].getRange(y,4).getValue();
var consolidatedSheetCell = consolidatedSheet.getRange(lastRow,1).setValue(eventID);
var consolidatedSheetCell = consolidatedSheet.getRange(lastRow,2).setValue(employeeName);
var consolidatedSheetCell = consolidatedSheet.getRange(lastRow,3).setValue(productionDate);
y++;
lastRow++;
}
}
}
However, I am experiencing this notification on the Execution hints (light bulb icon):
screenshot of the message. I am thinking that my code can be simplified. I am just not sure how to do it. Thank you in advance.
Every line with .getRange().getValue() and getRange.setValue() is a call to the file. Since you have these inside a for(){} loop, they are being called many times. Your goal is to limit these to as few as possible. Since you can read and write a range, you could do something similar to this:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var responses = ss.getSheetByName("Responses ID");//Where ID's of the spreadsheets are listed.
var consolidatedSheet = ss.getSheetByName("Consolidated");//Where the data should be pasted.
var responseColValues = responses.getRange(2,2, responses.getMaxRows() -1).getValues();
var responsesIds = [i for each (i in responseColValues)if (isNaN(i))];
var ssSelected = SpreadsheetApp.openById(responsesIds[0]);
var selectedSheets = ssSelected.getSheets();
for (i=0; i<3; i++){
var maxRows = selectedSheets[i].getLastRow()-1;
var y=2;
var lastRow = consolidatedSheet.getLastRow()+1;
var copyValues = selectedSheets[i].getRange(y,2, maxRows, 4).getValues();
consolidatedSheet.getRange(lastRow,1, maxRows, 4).setValues(copyValues);
}
}