Is there a way to check over a column range for a certain data? - if-statement

I have 2 workbooks,
Spreadsheet A has multiple sheets of the same form.
Spreadsheet B records contain cells from Spreadsheet A sheets into a single row per sheet (log).
The first column in Spreadsheet B contains hyperlinks of all sheets in Spreadsheet A. I need to check the hyperlinks column in Spread B as follows:
if hyperlink exist in column A,
check for the next sheet in Spreadsheet A index++
else
record the new data in a row after the last row,,,,
my code used to have clear() function to start submission from scratch to Spreadsheet B, but it's not efficient, execution time wise.
I am trying to manipulate my current code to check manually on existing records and i++/submit new row based on this logic.
you can ignore all missing lines of code because i have it working, i just need the logic of the idea of doing this, since I am not advanced in Apps Script. Thanks in advance for your help.
Spreadsheet A - Sheet1
Spreadsheet A - Sheet2
Spreadsheet B
I want the if statement to run on the Sheet link column in Workbook B.... in case of adding Sheet #3 to Workbook A (picture 1&2), upon submission, I want to check on Sheet links in Workbook B log (because it's unique) if it exists, i++.... if doesn't exist, add 3rd record in log.
for(var index = 2; index < WBA.length; index++)
{
var Sheet = "https://docs.google.com/spreadsheets/d/WBA ID/edit#gid=";
var SID = WBA[index].getSheetId();
var SheetID = Sheet + SID;
var Data = WBB.getDataRange().getValues();
for(var i = 0; i < Data.length; i++)
{
if(Data[i][1] == SheetID)
i++
else
{
var lastRow = WBB.getLastRow() + 1;
var Sheets_ID = new Array()
Sheets_ID.push( [WBA[index].getSheetId()] )
WBB.getRange(lastRow,1).setFormula('=hyperlink("https://docs.google.com/spreadsheets/d/WBA ID/edit#gid=' + Sheets_ID +'")');
var PN_Source = WBA[index].getRange(6,3,1,1).getValues(); //getRange(row number, column number, number of rows, number of columns)
var SC_Source = WBA[index].getRange(8,3,1,1).getValues();

Try this:
function checkForLink() {
var ssB=SpreadsheetApp.getActive();
var sh1=ssB.getActiveSheet();
var rg1=sh1.getRange(1,1,1,4);
var vA1=rg1.getValues()[0];
var hObj={};
vA1.forEach(function(el,i){if(el){hObj[el]=i;}});
var linkA=sh1.getRange(2,hObj['Sheet Link']+1,sh1.getLastRow(),1).getValues().map(function(r){return r[0];});
var ssA=SpreadsheetApp.openById('SSA ID');
var shts=ssA.getSheets();
shts.forEach(function(sh,i){
var vA=sh.getRange(1,1,2,sh.getLastColumn()).getValues();
var sObj={};
vA[0].forEach(function(e,i){sObj[e]=i;});
var shlink=Utilities.formatString('https://docs.google.com/spreadsheets/d/%s//edit#gid=%s',ssA.getId(),sh.getSheetId());
if(linkA.indexOf(shlink)==-1) {
sh1.appendRow([vA[1][sObj.date],vA[1][sObj.age],vA[1][sObj.name],shlink]);
}
});
}

Related

Google Sheets Apps Script - How to add an Arrayformula and multiple associated IF functions within a script (Without showing the formula within UI)

I was wondering if someone is able to assist?
I'm trying to add an Arrayformula consisting of two IF functions, so I'm wanting to merge the following two formulas into one cell:
=ARRAYFORMULA(IF(D13:D104="","",(IF(K13:K104,K13:K104*20,"$0"))))
=ARRAYFORMULA(IF(D105:D="","",(IF(K105:K,K105:K*C4,"$0"))))
So the first section of the sheet needs to be multiplied by 20, and then the figure has changed and needs to be multiplied by 25 (which is cell C4)
Is it possible to merge these into one cell containing an Arrayformula+the two IF functions (or is there another/easier way for this)
Is it possible to add this into Google Apps Script so that it works in the backend (so not just a script that applies the formula into a cell - but doesn't show in the frontend or sheet)
More of a general question - When using Arrayformula with IF; and for example the output is specific text e.g. "Test Complete" associated to the range F2:F (checking if E2:E contains a particular phrase e.g. "Done") - for the empty cells in between (due to setting the False outcome as "") is it possible to somehow randomly add data into these blank cells without interrupting the formula? (so I have to option for automated text if the cell to the left states a particular term/word, but still have the option to manually add random data into blank cells)
Any assistance would be greatly appreciated
As for 1st and 2nd questions: it looks like a task for a custom function. Something like this:
function MULTI() {
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var value = sheet.getRange('K'+row).getValue();
return (row < 105) ? value * 20 : value * 25;
}
It gets a value from column K and multiplies it by 20 if the row less than 105 and by 25 for the rest of rows.
Here is the variant of the same formula that uses the cell 'C4':
function MULTIC4() {
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var value = sheet.getRange('K'+row).getValue();
var c4 = sheet.getRange('C4').getValue();
return (row < 105) ? value * 20 : value * c4;
}
And it can be done with the trigger onEdit():
function onEdit(e) {
var col = e.range.columnStart;
if (col != 11) return; // 11 = K
var sheet = e.source.getActiveSheet();
if (sheet.getName() != 'Sheet1') return;
var c4 = sheet.getRange('C4').getValue();
var row = e.range.rowStart;
var dest_cell = sheet.getRange('D'+row);
var value = sheet.getRange(row,col).getValue();
var result = (row < 105) ? value * 20 : value * c4;
dest_cell.setValue(result);
}
It recalculates automatically the value in the cell of column 'D' (current row) every time when you're changing value in the cell of column 'K'. On the sheet 'Sheet1'.

Extract the digits and append it in a different cell?

I am trying to automatically RegExp(extract) the digits(AREA number) in Column 3 combined with the Text 'A' to append in Column 1 Date INDEX.
The problem is I'm not yet familiar in using google sheets app-scripts.
Tried looking for solutions with similar situation as me, but to no avail.
I don't know to put VBA to app-scripts.
Tried using some codes.
I still can't seem to make it work.
Can anyone point me in the right direction?
Thank you if you can help me out. Thanks.
EDIT:
The scenarios is in the office i cant make column for the formula.
It must be "behind the scene".
My googlesheets
//NOT WORKING code
function onEdit(e) {
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var regExp = new RegExp("\d*"); // Extract the digits
var dataIndex = regExp.exec(area)[1];
if(rg.columnStart==3) { // Observe column 3
var vA=rg.getValues();
for(var i=0;i<vA.length;i++){
if(vA[i][0]) {
sh.getRange(rg.rowStart + i,1).appendText((dataIndex) +'A'); // append to column 1 with 'A' and extracted digits
}
}
}
}
This answer extends your approach of using a script with an OnEdit trigger. But there are a number of differences between the two sets of code.
The most significant difference is that I have used the Javascript split method (var fields = value.split(' ');) to get distinct values from the data entry.
Most of the other differences are error checking:
if(rg.columnStart === 3 && area === "work") {: test for sheet="work" as well as an edit on Column C
var value = e.value.toUpperCase();: anticipate that the test might be in lower case.
if (fields.length !=2){: test that there are two elements in the data entry.
if (fields[0] != "AREA"){: test that the first elment of the entry is the word 'area'
if (num !=0 && numtype ==="number"){; test that the second element is a number, and that it is NOT zero.
if (colA.length !=0){: test that Column A is not empty
var newColA = colA+"A"+num;: construct the new value for Column A by using unary operator '+'.
function onEdit(e){
// so5911459101
// test for edit in column C and sheet = work
var ss = SpreadsheetApp.getActiveSpreadsheet;
// get Event Objects
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var row = rg.getRow();
// test if the edit is in Column C of sheet = work
if(rg.columnStart === 3 && area === "work") { // Observe column 3 and sheet = work
//Logger.log("DEBUG: the edit is in Column C of 'Work'")
// get the edited value
var value = e.value.toUpperCase();
//Logger.log("DEBUG: the value = "+value+", length = "+value.length+", uppercase = "+value.toUpperCase());
// use Javascript split on the value
var fields = value.split(' ');
//Logger.log(fields);//DEBUG
// Logger.log("DEBUG: number of fields = "+fields.length)
// test if there are two fields in the value
if (fields.length !=2){
// Logger.log("DEBUG: the value doesn't have two fields")
}
else{
// Logger.log("DEBUG: the value has two fields")
// test if the first field = 'AREA'
if (fields[0] != "AREA"){
// Logger.log("DEBUG: do nothing because the value doesn't include area")
}
else{
// Logger.log("DEBUG: do something because the value does include area")
// get the second field - it should be a value
var num = fields[1];
num =+num
var numtype = typeof num;
// Logger.log("DEBUG: num= "+num+" type = "+numtype); //number
// test type of second field
if (num !=0 && numtype ==="number"){
// Logger.log("DEBUG: the second field IS a number")
// get the range for the cell in Column A
var colARange = sh.getRange(row,1);
// Logger.log("DEBUG: the ColA range = "+colARange.getA1Notation());
// get the value of Column A
var colA = colARange.getValue();
// Logger.log("DEBUG: Col A = "+colA+", length = "+colA.length);
// test if Column A is empty
if (colA.length !=0){
var newColA = colA+"A"+num;
// Logger.log("DEBUG: the new cola = "+newColA);
// update the value in Column A
colARange.setValue(newColA);
}
else{
// Logger.log("DEBUG: do nothing because column A is empty")
}
}
else{
// Logger.log("DEBUG: the second field isn't a number")
}
}
}
}
else{
//Logger.log("DEBUG: the edit is NOT in Column C of 'Work'")
}
}
REVISION
If the value in Column C is sourced from data validation, then no need for and testing except that the edit was in Column C and the sheet = "work".
Included two additional lines of code:
var colAfields = colA.split('-');
var colAdate = colAfields[0];
This has the effect of excluding any existing characters after the hyphen, and re-establishing the hyphen, row number plus "A" and the AREA numeral.
function onEdit(e){
// so5911459101 revised
// only one test - check for ColumnC and sheet="work"
// test for edit in column C and sheet = work
var ss = SpreadsheetApp.getActiveSpreadsheet;
// get Event Objects
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var row = rg.getRow();
// test if the edit is in Column C of sheet = work
if(rg.columnStart === 3 && area === "work") { // Observe column 3 and sheet = work
Logger.log("DEBUG: the edit is in Column C of 'Work'")
// get the edited value
var value = e.value
//Logger.log("DEBUG: the value = "+value+", length = "+value.length);
// use Javascript split on the value
var fields = value.split(' ');
//Logger.log(fields);//DEBUG
// get the second field - it should be a value
var num = fields[1];
// get the range for the cell in Column A
var colARange = sh.getRange(row,1);
// Logger.log("DEBUG: the ColA range = "+colARange.getA1Notation());
// get the value of Column A
var colA = colARange.getValue();
// Logger.log("DEBUG: Col A = "+colA+", length = "+colA.length);
// use Javascript split on Column A in case of existing value
var colAfields = colA.split('-');
var colAdate = colAfields[0];
// build new value
var newColA = colAdate+"-"+row+"A"+num;
// Logger.log("DEBUG: the new cola = "+newColA);
// update the value in Column A
colARange.setValue(newColA);
}
else{
Logger.log("DEBUG: the edit is NOT in Column C of 'Work'")
}
}

How to auto fill blank cells in column

I need some help with Google Sheets.
I have two columns, let's say A1-A100 and C1-C100. In A1-A100 I have a list of names (students), but there may be less than 100, so it could be blank from A85 to A100 for example. In C1-C100 I have grades, from 0 to 10. I need a script that auto-fills blank cells in grades (C) column with "AUS" (short for 'not present' in Spanish). But only cells corresponding to some student... so from C85 to C100, it should be left blank.
Any help would be appreciated.
Using the functions and classes from the Spreadsheet service [1], i made and tested the code for what you want to do:
function fill() {
var tss = SpreadsheetApp.getActiveSpreadsheet();
var values = tss.getRange("Sheet1!B1:B100").getValues();
for(i=0; i<values.length; i++) {
var value = values[i][0];
if (value == "") {
var rangeB = tss.getSheetByName("Sheet1").getRange(i+1,2);
var rangeA = tss.getSheetByName("Sheet1").getRange(i+1,1);
if(!rangeA.isBlank()) {
rangeB.setValue("AUS");
}
}
}
}
That function needs to be inside a script bound to the Spreadsheet, then you can add a macro [2] so you can run the function from the Sheets UI.
[1] https://developers.google.com/apps-script/reference/spreadsheet/
[2] https://developers.google.com/apps-script/guides/sheets/macros
=ARRAYFORMULA(IF((A2:A<>"")*(B2:B=""), "AUS", B2:B))

Apply Tooltip to diffrent datasets or pass an array to tooltip in Chart.js?

I am trying to show multi line graph for showing profit/loss . I am able to plot graph.
var niftyProfit = [];
var niftyProfitChartData = [];
var sum = 0;
data.forEach(function(obj) {
niftyProfit.push(obj.profit);
});
for (var i in niftyProfit) {
sum = sum + niftyProfit[i];
niftyProfitChartData.push(sum);
}
obj.profit is the p/l column data. I want to populate the value, which I did in for loop for eg. consider profit = [4,2,-3,-5], then my final array to populate in chart would become [4,6,3,-2]. I ploted data on chart which is array niftyProfitChartData , now In tooltip on hover its showing data from niftyProfitChartData .But I want to show data from niftyProfit array in tooltip . Here is Fiddle Link of what i tried till now .
http://jsfiddle.net/zkrh7/159/

Copy cell if certain condition met

I know there are already many topics like mine, but I am completely new to programming scripts and therefore I ask you to help me with following problem:
In cell B2 is the user name and in cell C2 the submitter type - if the submitter type is "Requester" then the user name of cell B2 should be copied to cell AE2 - the problem is, that I also want to keep the previous user names if the submitter type change and gets updated...
That means, first the submitter type is "Requester" then the system should copy the user name to cell AE2 - if the submitter type of my line change, then the already copied user name should not change - understood what I want? This should work for all lines of the spreadsheet...
I tried the code but got following error:
Maybe you can improve the code for me?
I changed those 2:
Before:
for (var i = 1; i <= numRows; i++) {
var userNameCell = rows.getCell(i, userNameColumn);
var subTypeCell = rows.getCell(i, subTypeColumn);
var sUserNameCell = rows.getCell(i, sUserNameColumn);
After:
for (var i = 1; i <= numRows; i++) {
var userNameCell = rows.getCell(i, userNameColumn);
var sUserNameCell = rows.getCell(i, sUserNameColumn);
var subTypeCell = rows.getCell(i, subTypeColumn);
The error now is:
new error
Or was the change wrong? Maybe you mean that:
var userNameColumn = 2; //Column where the user name is written
var subTypeColumn = 5; //Column where the submitter type is written ex. "Requester"
var sUserNameColumn = 3; //Column where the user name is saved
But then only one object (username) is known instead of 2 before - subTypeCell and sUserNameCell again undefined - that says the debugger - the code looks now like that (again with my changes, because then 2 objects instead only 1 is known):
You can do something like this:
var userNameColumn = 2; //Column where the user name is written
var subTypeColumn = 3; //Column where the submitter type is written ex. "Requester"
var sUserNameColumn = 5; //Column where the user name is saved
function saveUserName() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
for (var i = 1; i <= numRows; i++) {
var userNameCell = rows.getCell(i, userNameColumn);
var subTypeCell = rows.getCell(i, subTypeColumn);
var sUserNameCell = rows.getCell(i, sUserNameColumn);
if(sUserNameCell.isBlank() && subTypeCell.getValue() === 'Requester') {
sUserNameCell.setValue(userNameCell)
};
}
}
Firstly this defines the columns that you are working with, which are the "Username"(in the scriptuserNameColumn), the column with the "Submitter type"(in the scriptsubTypeColumn) and the column where the username is saved (in the scriptsUserNameColumn). Each have been assigned a number corresponding to a columns in spreadsheet, wher 2 is B, 3 is C, and so on. You can change them to your needs.
Then we create a function called saveUserName() inside this function we get the current spreadsheet, we define what range in the spreadsheet we will work with, here it is everything, then we get the number of rows that has data in them.
After that we go through the data we defined, and setup some variables we can use for each cell. Then we create our if statement, which states, if the "Saved-User-Name-Cell" is empty and the "Submitter-Type-Cell" = the word 'Requester' then we grab the "Saved-User-Name-Cell" and set it's value equal to what is within the "User-Name-Cell".
That's it!