How to keep lock a cell value even if the condition changed? - google-sheets

please refer to the images below
Sheet1
sheet2
I have 2 sheets: sheet1 and sheet2, here's what I want to do: if sheet2!B37 = sheet1!B1, take the value of sheet1!B2, if not stay blank.
This part is easy, but what I want is that if I change the date in sheet1!B1 to 16 Mar 2021 and sheet1!B2 to 90, I want sheet2!C37 to stay 100 and sheet2!C38 returns 90.

One way is to copy the content of sheet2!C37 and paste it as value.
Reference: Convert formulas to values in Google Sheets
But I doubt that you would want to convert the formula into a value every time you need to change the condition. Hence, you might want to consider using Google Apps Script and run it using a button.
Sample Code:
function updatePrice() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Get Sheet1 object
var sheet1 = ss.getSheetByName("Sheet1");
//Get Sheet1 object
var sheet2 = ss.getSheetByName("Sheet2");
//Get Sheet1!B1 string value
var targetDate = sheet1.getRange("B1").getDisplayValue();
//Get Sheet1!B2 string value
var targetPrice = sheet1.getRange("B2").getDisplayValue();
//Get Sheet2 column B range
var dates = sheet2.getRange("B1:B");
//Create a textfinder and look for the target date (Sheet1!B1 value)
var textFinder = dates.createTextFinder(targetDate);
var firstOccurrence = textFinder.findNext();
if(firstOccurrence!=null){
//Date found
//Update price in column C
firstOccurrence.offset(0,1).setValue(targetPrice);
}
}
What it does?
Get the active spreadsheet using SpreadsheetApp.getActiveSpreadsheet()
Get the sheet object for Sheet1 and Sheet2 using Spreadsheet.getSheetByName(name)
Select the range for Sheet1!B1 and Sheet1!B2 using Sheet.getRange(a1Notation). Get the string value using Range.getDisplayValue()
Select the range for Sheet2!B1:B using [Sheet.getRange(a1Notation)]
Create a textFinder using Range.createTextFinder(findText)
Get the first occurrence of the date string that was being searched using TextFinder.findNext(). If date string has no match, return will be null. If date string has match it will return a Range of the matching cell
Matching cell will give you a range in column B, to set the price value move the range 1 column to the right by adding 1 column offset using Range.offset(rowOffset, columnOffset) and set the range value using Range.setValue(value)
Add A Google Sheets Button To Run Scripts
Add a Google Sheets button. You add a button via the Insert > Drawing menu.
Click Save and Close, this drawing gets added to your Google Sheet. You can right click on it to resize it or drag it around to reposition it.
To assign a script, Right Click the drawing and click the three little dots in the top right of the drawing and select Assign Script. Then type in the name of the function you want to run from your Apps Script code.
Output:
Note:
Please don't forget to click enter when editing your Sheet1 values before clicking the button. Apps Script cannot update Sheet2 when the cell to be read is still in edit.

Related

Data Validation Dropdown pointed to sheet with name determined by indirect in Google Sheets

I am trying to create a sheet that has a list of areas, and then has a dropdown next to each area name that lets you select one item found in that area.
The contents of each area are in Col A of a sheet that is titled with the name of that area.
I am trying to use Indirect to point to the name of the area, in Col A, and then create a Dropdown using the contents of Col A on the sheet referenced.
The formula I am trying to use is =INDIRECT("'"&A1&"'!A:A")
When I put this into B1, for example, it spits out a list of all the items on the tab that shares a name with the contents of A1.
However, when I try to use this formula to define the range for the dropdown list in Data Validation, it says that it is an invalid range.
Example of what I am trying to make:
Location
Item
Area 1
▼
Area 2
▼
Area 3
▼
And then for example there would be a tab named "Area 1", and Col A would just be a list of all the items in that Area.
The use case here is that I am trying to create a sheet to track encounters in a video game where you're only allowed to acquire the first character you encounter in area named are of the game, and I would like to be able to apply it to any number of different datasets (games), so I would prefer to avoid having to hardcode or specifically limit any names or ranges.
Suggestion:
You can use App Script to automatically create a data validation with values referencing from other sheets.
Below is the script that creates a data validation in Area column after adding a value in the Location column.
Note:
Value you add in the Location column must exactly match the name of the reference sheet
Code
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Main');
var range = sheet.getRange(2,1,sheet.getLastRow() -1,1).getValues(); //contains list of areas
for(var i = 0; i < range.length; i++){
var sh = ss.getSheetByName(range[i]);
var values = sh.getRange(1,1,sh.getLastRow(),1);
var itemrange = sheet.getRange(2+i,2);
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(values).build();
itemrange.setDataValidation(rule);
}
}
sample output:
references:
https://developers.google.com/apps-script/reference/spreadsheet/data-validation-builder
https://developers.google.com/apps-script/guides/triggers
such a formula is not supported under data validation (DV supports only such formulae whose output is boolean TRUE/FALSE)
to do what you want you will need to use that formula in some helper column and feed DV from the resulting range

Is there a way to use FILTER with multiple Sheets containing a specific phrase in Google Sheets?

I will try to be as clear as possible. Here is the example piece: link
What I want to happen is that the Filter formula will search for any Sheet containing “Form Responses” and then display the results. You can see on the Current sheet how I’ve been doing, but this is more tedious and leads to issues of the first formula begins to overwrite the next one, etc. On the Wanted tab, I’ve laid out how I imagine it and put a note in A7. Any help offered is greatly appreciated!
You can get started with this script:
function getSheetResponses(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Wanted");
var getCellValue = sheet.getRange("A7").getValue(); //Gets the name of your designated sheet on "Wanted Sheet" cell "A7"
var getName = ss.getSheetByName(getCellValue);
var getNameValue = getName.getRange(2,5,getName.getLastRow(),1).getValues(); //Gets all the values of Column E on any defined sheet names based on getCellValue
var datalength = getNameValue.length;
Logger.log(datalength);
sheet.getRange(8,6,datalength,1).setValues(getNameValue); //Puts the data on Wanted Sheet Column F
}
What this does is it gets the sheet name on cell A7, and populates the data on Column F row 8 on the "Wanted" sheet like so:
Now, the data it populates on the "Wanted" sheet came from Form Responses 1 based on the sample piece you have provided:
If ever you would want to relocate which specific row or column the data would be pasted on "Wanted" Sheet. You can refer to this documentation on how to modify the rows and columns on sheet.getRange()
Reference:
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow,-column,-numrows,-numcolumns

How to get list of row that has value from a range of data based on column header as the criteria?

I have a range of data populated from a google form in sheet "Data".
I need to make a report (in sheet "Report") that shows the students attendance, based on name (from drop down list). The data that is blank is excluded in that report, as seen in column i to column k
desired result
I have shared the sheet here
I have tried to use filter
=filter(Data!B1:I20,Data!E1:E20<>"")
but still I cant find the way to change the "condition" in this formula to refer to the sheet Report A1.
what is the correct formula to achieve this?
Thanks you for your help.
Using Apps Script you will have to use the function getSheetByName(name).
Example:
// The code below logs the index of a sheet named "Expenses"
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Expenses");
if (sheet != null) {
Logger.log(sheet.getIndex());
}
Then to find from column E the rows that have value you would have to use the getRange(a1Notation) method:
// Get a range A1:D4 on sheet titled "Invoices"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("Invoices!A1:D4");
// Get cell A1 on the first sheet
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("A1");
Then you would have to iterate over that rows and get the rows where the E column has something.
Once you have that you can get the Report sheet and set the values there with setValues(values)
For more information on how the function you may need to use you have the reference of SpreadsheetApp and the overview on Extending Google Sheets

How to record the date on column B every day, in a new line

I use a daily (01:00 am) script to record my daily portfolio value, calculated in sheet A, to a new sheet.
Every day the script runs, opens a new line and records the value in column A, but I have to add the date manually on column B.
The document looks like that:
A-----------B
$1000-----1.1.2019
$1004-----1.2.2019
... ------....
$1006-----1.5.2019
I couldn't find a way to automatize column B date recording. What should I add to my code?
function copy() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange ("calc!U12");
var data = source.getValues();
var ts = ss.getSheetByName("record");
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
}
This can be solved without using script. In cell B1 put your starting date. In all of the other cells in B, drag down this formula:
=IF(COUNTBLANK(A2)=0,B1+1)
This checks to see if the cell to the left (in A) has a value, and if it does, it will add one to the previous date. The first date will still have to put in by hand. You may want to make column B formatted so that the numbers appear as dates.

Google Sheets Conditional Formatting changes when new rows added

So I click on the cell between A and 1 to select entire sheet, then I click "Format" then "Conditional Formatting" and set the rules. Basically, I have about 15 different conditions but all are in columns F through O so I use F:O. For example, if text is exactly YES change the background to green.
The issue is when I add a new row, the formatting stops for that row and the F:O rules are replaced with F1:O15, F17:O59, etc. skipping row 16.
Can I use a script that will never change when rows are added?
You can set up an onEdit trigger that applies the formatting every time you edit the sheet. I've provided an example of a function that would copy the format of cell A1 to all cells in the sheet. This link will bring you to Google's documentation for this type of work.
https://developers.google.com/apps-script/reference/spreadsheet/range
Here's the documentation on triggers...
https://developers.google.com/apps-script/guides/triggers/
function formatRange(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var range = sheet.getRange("A1");
range.copyFormatToRange(sheet,1,sheet.getLastColumn(),1,sheet.getLastRow())
}

Resources