I am very new to appscript and any help on the below query will really be helpful.
I am having data in Sheet1 in column A and Column B, now I want to design an appscript which get the below job done.
(1) Sheet1 Column A has Roll number along with student name i.e. Roll No.*Name, column B has actual value (these both columns are user input).
(2) Sheet2 has two columns Roll No. and Dummy value.
(3) In Sheet1 column C, I want the dummy value from Sheet2 column B by matching the Roll number of both sheets, however, I want value only in those rows in which actual value (column B) in Sheet1 is blank.
For reference I am sharing the link of the sheets.
https://docs.google.com/spreadsheets/d/1vI22QCmixKe3aoWMLODTFzt7pNXIKO3pjXS4mT6GHT0/edit#gid=524973836
I had checked different question on this community but not found a solution to my query.
Any help on above will really be appreciated.
Regards
Assume you want to put down 'dummy values' in Sheet1 column C if column B is empty, and that so call 'dummy value' need to has its 'Roll No.' value matched with the number of the front part of 'Roll No.#Name' column in sheet1:
Solution - 1. in-app lookup function:
Put this code into Column C2 in sheet1.
This code lookup for matches of 'Roll No.' from sheet2 column A whenever there Column A is not empty and Column B is empty in sheet1.
=ArrayFormula(
IFS(
$A$2:$A="","",
$B$2:$B<>"","",
TRUE,XLOOKUP(INDEX(SPLIT($A$2:$A,"*"),,1),sheet2!$A:$A,sheet2!$B:$B)
)
)
Solution - 2. write a custom function in apps-script:
in-app call:
apps-script js code:
this solution create a custom function called 'MYLOOKUP()' with apps-script, and call the function form the spreadsheet.
// apps-script:
function MYLOOKUP(data1,data2) {
return data1
.map(([rollNo_Name,value]) => {
return (rollNo_Name !== '' && value === '') ?
data2.find(([rollNo,]) => rollNo_Name.split('*')[0] == rollNo)[1] :
''
});
}
in-app call:
=MYLOOKUP(A2:B,sheet2!A:B)
There are a lot other solution to your question if you mention apps-script, such as...
instead of calling the custom function in-app, you can instead create a custom menu to run the function when you click on it,
or add simple trigger so that every time the spreadsheet is edited, the function will be run one time.
you can even create a web ui for this thing to run, etc.
Related
On Google form submission, I am trying to get a unique patient id in column A automatically whenever there is a response being submitted. You can also see the formula in the formula bar.
As of now, I am able to do it with the following google script but due to the trigger limit, it is not getting fulfilled as the COVID response is quite higher and requests are keep coming in.
function myFunction1() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lr=sheet.getLastRow()
sheet.getRange(lr,1).setFormula('="PID"&row()-1');
}
If I add the formula to all cells in column A of this sheet, every time a new row is being inserted on form submission and the formula is NOT available for that row by default.
So, Is there a way that I can automate generating the PID automatically.? or any other smart ideas without the trigger option?
Alternative ARRAYFORMULA in cell A1:
=arrayformula({"Patient Unique ID #";if(B2:B<>"","PID"&row(A2:A)-1,iferror(1/0))})
"Patient Unique ID #" puts the title (Patient Unique ID #) in cell A1, then the ; returns the line.
If B is not empty then generate the unique ID as per "PID" and a unique number based on ROW() less 1. If B is empty, then nothing iferror(1/0).
In Google Sheets, this sort of thing is usually done with an array formula. I would recommend that you leave the 'Form Responses 1' sheet as is and insert the timestamps in a new sheet with something like this:
cell A1:
=arrayformula(
ifs(
row('Form Responses 1'!A1:A)) = 1, "Patient ID",
isnumber('Form Responses 1'!A1:A), row('Form Responses 1'!A1:A) - 1,
true, iferror(1/0)
)
)
cell B1:
={ 'Form Responses 1'!A1:Z }
If you absolutely want to insert the Patient ID column directly in the form responses sheet, you may want to place it on the right after the columns that get updated by the form.
An array formula is more reliable than using a function that runs on a trigger, but do note that the patient IDs will be dynamic and only remain valid as long as no rows are inserted or deleted in the data. The same is true with your current approach.
To get static IDs, use an on form submit trigger that writes an ID on a row when that row is first submitted. See the insertUniqueId_ script for one example — it runs on an on edit trigger, but can be modified to run on an on form submit trigger.
I own two columns A contains numbers and B contains checkboxes.
If A = 0 I would like to auto-check the checkbox else I would like to let the user checks it (or not). But when I use a IF statement in the checkbox cell I can't check it myself (I lose its behavior).
I need something like :
=IF(A1=0;TRUE;#keep checkbox classical behavior#)
How could I do that ?
Explanation:
I don’t think you can accomplish this behaviour with a google sheet formula without compromises. This auto-check behaviour you describe can only be achieved with a trigger; activated when you edit a cell in column A.
I believe you need to take advantage of Google Apps Script and in particular use an onEdit trigger.
Solution:
Click on Tools => Script editor on the top menu of the spreadsheet file, copy & paste the below code into a blank script and click on save. After that, when you put 0 in column A, the corresponding row in column B will be checked. This behaviour will be applied to a sheet named Sheet1. Change that part of the code to apply it to a sheet with a different name.
function onEdit(e) {
const sheet= `Sheet1`; // change Sheet1 to the name of your sheet
const as = e.source.getActiveSheet();
const col = e.range.getColumn();
const row = e.range.getRow();
if(as.getName()==sheet && col==1 && e.value==0){
as.getRange(row,2).setValue(true);
}
}
Unfortunately you can't do what you wish in one formula. As you discovered, interacting with a checkbox in a cell with a formula is essentially like typing over that formula and would overwrite it.
My suggestion to accomplish this is to add an extra column and use the formula you suggested as the final check to what the state of that row should be (true or false).
=if(A2=0,True,B2)
Where A is your values and B is your user entered checkbox.
Here's a sample sheet with it loaded as an array formula. https://docs.google.com/spreadsheets/d/1z8A4WqVppcxGlGiM3l-kW6q88iYBE6LGw5PyVfRh9Js/edit#gid=0
You could then format that column as checkboxes, but if you use an array formula it will get tripped up when it thinks the checkbox is blocking the formula for each new row.
I am trying to document in a certain column, for each row, the user info as it is shown when using the "show edit history" option (by right-clicking a cell).
More specifically- for a given row, if the cell in column G was last modified by me- the cell in column B should say "Yaniv A" or "yaniva#emaildomain.com". Of course this should apply the same way for any other editor.
New information should replace any old in column B one anytime the coresponding cell in column G is modified.
On Apps Script you can set up an onEdit trigger that retrieves the username of the editor and cell where the change was made; but you will have to keep in mind that there may be cases where the username is not retrievable (mainly if the user haven't accepted the script scopes), you can read more about those situations on getActiveUser docs.
You can achieve what you are requesting with the following function. It will use the event object to check if the change was made on the G column, and if it was, the email of the user (or Unknown if the scopes weren't accepted) will be written on the B column of the same row.
function onEdit(e) {
var range = e.range;
var editor = e.user.getEmail();
if (editor == '' || editor == null) {
editor = 'Unknown';
}
if (range.getA1Notation().search('G') != -1) {
range.offset(0, -5).setValue(editor);
};
}
After saving this function you will have to create a installable trigger. To do so, go to Edit 🡆 Current project's triggers. After that, click on + Add Trigger and fill this settings:
Choose which function to run: onEdit
Choose which deployment should run: Head
Select event source: From spreadsheet
Select event type: On edit
Failure notification settings: as you wish
After saving the trigger you could test the function by yourself modifying a cell in the G column. Please, do not hesitate to ask for any clarification about my answer or the code itself.
Please help this non-expert -- his job depends upon it.
I have a Google Form that feeds answers into a sheet on a Google Spreadsheet -- let's call it the "main sheet." One of the form's questions asks for a job number. I have been able to figure out how to take each unique job number respondents have entered and create a sheet by that name in the same spreadsheet. I even have copied the headers for the form's answers at the top of each of the new sheets.
What I cannot get to work is rifling through all of the answers in the main sheet, sans the column headers, and copy the rows to the sheet names based on a conditional match with the job number value equaling the sheet name value. So if someone applies for job number 65, that response gets copied from the main sheet to sheet with the name "65."
For starters, I may have the loops set up incorrectly, trying to exclude the header in the main sheet and creating the array of all of the sheet names.
But a second problem I have is that I need to use the variables for both the sheet name value and the job number value. I need to be able to account for an ever increasing job numbers. Staff do not want to have to create a new sheet with every new job number -- they want that done automatically when a user fills in a new job number.
I am happy to share my work, as it is, with anyone who can help point me in the right direction.
+++
Solved, so I yanked down the link to the spreadsheet. In spite of myself, it appears, this community was able to help me out. Thanks.
This function that I wrote will help you find your job number:
function searchColumn(value, rangeValues) {
for (var i = 1; i < rangeValues.length; ++ i) {
if (rangeValues[i] == value) return i;
}
return -1;
}
Give it an array of values (usually by Range.getValues()), and the value you want to search and it will return the row number where that value was found. If it didn't find it, it returns -1.
example:
// Gets all data in the first column of the sheet
var valuestoSearch = mySheet.getRange(1, 1, sheet.getLastRow()).getValues();
// then
var rowNum = searchColumn(job_number, valuesToSearch);
Now that you have the row number, you can use:
var rowData = mySheet.getRange(rowNum, 1, 1, mySheet.getLastColumn()).getValues();
This will give you all the values in that row up to the last column in the sheet.
Once you have that data, you can copy it to another sheet by using:
var jobSheet = mySpreadsheet.getSheetByName(job_number);
jobSheet.getRange(jobSheet.getLastRow() + 1, 1, 1, rowData.length).setValues(rowData);
Or something very similar to this. Then you may want to erase the data in the old spreadsheet so that you don't keep repeating the same operation. But that's up to you how you want to handle that. Take a good look at the documentation for SpreadsheetApp, as it has everything you're looking for and more :)
I would like to create a Google Apps Script to do the following: When I select a cell containing the name of a person in a spreadsheet (a spreadsheet that records sales, for example), and use a menu button to call the function, the script does a search (a query) using the person's name (or number of his document) in another spreadsheet that stores complete consumer data and that contains all the information that I need from that consumer to generate a contract or a payment receipt.
What is the best strategy to implement this search for information from one spreadsheet in another spreadsheet using Google Apps Script?
Do you have some script sample with a implementation similar to this? THANK YOU in advance for any help/guidance!
There is no event triggered by a cell selection, you'll have to use a menu item or a button to call the function or, if it is acceptable for your use case, edit the cell to trigger an onEdit event.
The 'search part' is actually very simple, the data being on the spreadsheet itself or in another one has no importance, it will simply change the way you access data ( getActiveSpreadsheet or openById()). From there just get all the values and do a search in the resulting 2D array.
EDIT following your comment : here is an example of such a code that returns the range of the found cell (and we get the A1 notation but we could getValue() as well of course.).
function test(){ // to test the find function with an argument, 'any' in this case
var result = findItem('any');
if(result){Logger.log(result.getA1Notation())}else{Logger.log('no luck !')};
}
function findItem(item){
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = ss.getDataRange().getValues()
for(var n = 0;n<data.length;++n){
if(data[n].indexOf(item)>-1){ // this is a "strict" find, ie the value must be the entire search item. If you want to do partial match you should compare differently...
return (ss.getRange(n+1,data[n].indexOf(item)+1)); // if found return the range. note the +1 because sheets have 1 index while arrays have 0 index
}
}
return false;// if we come to the end of sheet without result...
}