I've created a spreadsheets consist of multiple complex dates & strings.
When I use concatenate, the date become numbers
=CONCATENATE('2021'!A2:'2021'!F61)
The results is like
44519in44471out44472Guest1in44475out44476SGuest2
How can I produce the result like this in one cell
November 2021
in 6/11 out 10/11 Guest 1
in 26/11 out 28/11 Guest 2
December 2021
in 29/12 out 31/12 Guest 3
I just need the copy & paste cell features, but I can't find any.
An option would be to use an Apps Script Custom Function.
First, open a bound script by selecting Tools > Script editor, and copy the following function to the script:
function CONCAT_WITH_DATES(rangeNotation) {
const values = SpreadsheetApp.getActiveSheet()
.getRange(rangeNotation)
.getDisplayValues()
.map(row => row.filter(cell => String(cell)))
.map(row => row.join(" "))
.join("\n");
return values;
}
Once the script is saved, you can use this function the same you would use any sheets built-in function:
Note:
The input range has to be provided in quotes in order to retrieve the values with the displayed format via Range.getDisplayValues(). If the range is provided directly, the date values won't keep the format.
Reference:
Custom Functions in Google Sheets
Please note that an extra column F, which should be blank, is selected in order to identity row break
=REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(TEXTJOIN("♦",FALSE,'2021'!A1:F5),"♦{2,}",CHAR(10)),"♦$",),"♦",CHAR(9))
Related
I have a Google Sheet problem that looks like this:
Google Sheet Image Example
In Column "A" I have a group of IDs organized in a specific way.
In Column "B" I have a list with all the IDs present in column "A" and their specific audience name. The names and IDs are separated by ";" and the ID is the number between "( )".
I need a formula or solution that replaces the ID on column "A" with the audience name referenced on column "B".
Here's a link to the example sheet: https://docs.google.com/spreadsheets/d/1BS6_frcliNV882kWcDb2ZjpjERdPtI_ZiivWzHvRVuk/edit?usp=sharing
In your situation, for example, how about using Google Apps Script? I thought that when Goolgle Apps Script is used, your goal might be able to be achieved using a simple script. The sample script is as follows.
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet. And, please put a custom function of =SAMPLE(A2:B). By this, the script is run.
function SAMPLE(values) {
const obj = values.flatMap(([, b]) => [...b.matchAll(/(.+?) \((.+?)\);?/g)].map(e => [e[2].trim(), e[1].trim()]));
return values.map(([a]) => obj.reduce((s, e) => s.replace(...e), a));
}
Testing:
When this script is run to your provided Spreadsheet, the following result is obtained.
Note:
This sample script can be used for your provided Spreadsheet. When you change the structure of each value, this script might not be able to be used. Please be careful about this.
References:
Custom Functions in Google Sheets
map()
reduce()
I've got a text field containing different dates and cells containing -infinity (meaning today's date).
How can I change -infinity to today's date in Google Data Studio or Google Sheets and how do I change the cell from text to date?
The image below contains the column with the dates and -infinity.
Apart from the formula already presented in the previous answer, you can also make use of Apps Script in order to achieve your task.
Apps Script version
You will have to go to Tools > Script editor and use the code below which loops through the A column and whenever it encounters an -infinity value, it replaces it with the current date.
function replaceInfinity() {
let ss = SpreadsheetApp.getActiveSheet();
let validUntil = ss.getRange("A2:A").getValues();
for (let i=0; i<validUntil.length; i++)
if (validUntil[i][0] == "-infinity")
ss.getRange(i+2,1).setValue(new Date());
}
Before
After
Reference
Google Apps Script.
Now that you have added a spreadsheet, I duplicated your raw data sheet and added a processing formula in B1:
=ArrayFormula({"valid_until V2";IF(A2:A="";;IFERROR(VALUE(REGEXEXTRACT(A2:A;"\S+"))+VALUE(REGEXEXTRACT(A2:A;"\s([^/./+]+)"));DATEVALUE("1/1/2050")))})
This one array formula produces all results for Column B, including the header (which you can change to whatever you like).
I processed your "infinity" dates to show as the real date January 1, 2050 — a date far enough in the future to essentially serve the same purpose as "no expiration."
I'm working with google forms and google sheets. I'm trying to create a summary sheet that will automatically update as the form is being filled.
I've been able to pull the data from the other sheets using a FILTER function. Now I want to add a column that shows the name of a country to the filtered column. I tried using concatenate but it didn't work as well as I'd hoped. Can someone help me figure out how to solve this problem.
Please see here for an example of the problem.
Well this is a very inelegant brute force way, but I think it works. See Solution-GK in your sheet.
=QUERY({
{TRANSPOSE(SPLIT(REPT("Nigeria~",ROWS(UNIQUE(FILTER(NIGERIA!A:E,NIGERIA!C:C<TODAY(),NIGERIA!B:B="Charity Fundraiser")))),"~")),
UNIQUE(FILTER(NIGERIA!A:E,NIGERIA!C:C<TODAY(),NIGERIA!B:B="Charity Fundraiser"))};
{TRANSPOSE(SPLIT(REPT("Sierra Leone~",ROWS(UNIQUE(FILTER('SIERRA LEONE'!A:E,'SIERRA LEONE'!C:C<TODAY(),'SIERRA LEONE'!B:B="Charity Fundraiser")))),"~")),
UNIQUE(FILTER('SIERRA LEONE'!A:E,'SIERRA LEONE'!C:C<TODAY(),'SIERRA LEONE'!B:B="Charity Fundraiser"))}},
"select Col1,Col2,Col3,Col4, Col5 where Col2 is not null")
I've added a hard coded literal of the country name, repeated it the number of times needed for the matching data rows, and made it into the first column in your existing data array. I repeat this for the second array you have for the second country.
I'm sure there are far more elegant ways to do this, so we'll see what else is proposed. If you had a list somewhere in your sheet of your country names - ie. Nigeria and Sierra Leone, possibly many more - I'm sure an elegant solution would cycle through those names, pulling the name to build the concatenated data ranges, and also adding the name as the text for each row.
Without needing a list in the sheet, a little bit of code could find all of your tab names, and exclude the non data ones, eg. Solution Here and Summary, and process all of the rest as data.
Note: I'm not clear that you need your UNIQUE statements, unless you are expecting duplicates for some reason. Also, the outer QUERY doesn't seem to be necessary - the inner FILTERs seem to do everything you need.
You could do this with an Apps Script Custom Function.
First, open a bound script by selecting Tools > Script editor, and copy the following functions to the script (check inline comments for more details about the code):
// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0
function SUMMARIZE_FUNDRAISING_EVENTS(sheetNames, ...ranges) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
sheetNames = sheetNames.split(","); // Comma-separated string to array of sheet names
const filteredData = sheetNames.map(sheetName => { // Iterate through each sheet name
const sheet = ss.getSheetByName(sheetName);
if (sheet) { // Check if sheet exists with this name
const sheetData = sheet.getRange(2,1,sheet.getLastRow()-1,4).getValues(); // Source sheet data
const filteredData = sheetData.filter(rowData => {
return rowData[1] === "Charity Fundraiser" && rowData[2] < new Date()
}); // Filter data according to date and type of event
filteredData.forEach(filteredRow => filteredRow.unshift(sheetName)); // Add sheet name to filtered data
return filteredData;
}
}).flat();
return filteredData;
}
Once it is defined, you can use the function SUMMARIZE_FUNDRAISING_EVENTS the same you would any sheets built-in function. This function would accept a series of parameters:
A comma-separated string with the names of the sheets whose data should be summarized (don't add blank spaces after the comma or similar).
The different source ranges (in your case, NIGERIA!A:E and 'SIERRA LEONE'!A:E).
Both of these are necessary, because, on the one side, specifying the source ranges as parameters makes sure that the function executes and updates the summarized data every time the source ranges are edited, and on the other side, when passed as parameters, these source ranges don't contain information about the sheet names, which the script will need when returning the summarized data.
Example of calling the function:
Reference:
Custom Functions in Google Sheets
I am trying to create data validation dropdown from a single cell which has all , separated values and I am splitting them using SPLIT(K4,","). But when I apply the formula drop-down just goes away. Here is how it looks:
And here is where I have applied validation:
It just happens and I can't see any drop-down here. Even validation doesn't work as I type a value from given values, it still identifies it as invalid:
Here it says that it is actually not possible, but otherwise, my data column will grow very big, that's why I wanted to keep it in a single cell.
Method to reproduce: Just make a copy of this sheet and experiment on your own whatever you want it to be like:
It is not possible to do this from the sheets editor, but you could use Google Apps Script to accomplish this:
Open the script editor by selecting Tools > Script editor.
Copy and run this function:
function createDataValidation() {
const sheet = SpreadsheetApp.getActiveSheet();
const values = sheet.getRange("A1").getValue().split(","); // Get array with values from A1
const rule = SpreadsheetApp.newDataValidation().requireValueInList(values); // Create DV
sheet.getRange("F8").setDataValidation(rule); // Set DV to F8
}
Reference:
Class DataValidationBuilder
I have a cell that contains a number range, say 50-60 that I would like to apply custom number formatting to. Ideally, I'd like to be able to format that to output 50Hz-60Hz.
The syntax that works for a regular integer is #"Hz", but I can't find an in-built way to do this for dashed ranges, and I suspect it isn't possible.
Answer:
As you suspected, this isn't possible to do.
More Information:
As Tanaike has said in his above comment, the cell input 50-60 is a string - purely read as text as it contains the - character. Resultantly, Sheets does not have the functionality to use Number formatting to change the way this is displayed.
(Kind of) Workarounds:
Disclaimer: These suggestions are not perfect workarounds and depending on how the data in the cells is processed elsewhere in the sheet, these may not work. They do however provide solutions if you are looking to affect the UI only.
Workaround 1: Using a custom Number Format
You can use the format ##"Hz-"##"Hz" which will display 50Hz-60Hz for the example you give, if the input of the cell is 5060 rather than 50-60. You will however need to change the format to contain three # characters if the frequency range of the cell goes above 100:
##"Hz-"##"Hz" will make the number 5060 display as 50Hz-60Hz
###"Hz-"###"Hz" will make the number 120130 display as 120Hz-130Hz
####"Hz-"####"Hz" will make the number 14201430 display as 1420Hz-1430Hz
Workaround 2: Using an onEdit(e) Trigger
If inputting the - yourself is important, then you can use an onEdit() Apps Script trigger to change the format of the cell to include the Hz unit after-the-fact.
For this workaround, I will assume that the column your frequency ranges are in is column C.
From the Tools > Script editor menu item, you can create a function with the following code:
function onEdit(e) {
if (e.range.getColumn() != 3) {
return;
}
else {
var f = e.value.split("-");
e.range.setValue(f = f[0] + "Hz-" + f[1] + "Hz");
}
}
Make sure to change the value on the line if (e.range.getColumn() != 3) to be whichever column your frequency ranges are: this example uses the value 3 because the column is assumed to be column C, but column D would be 4, E would be 5, etc.
Save the script with the save icon, press the run button (►), and confirm the authentication of running the script.
This will automatically run whenever a value like 50-60 is inputted into column C, and will change to display 50Hz-60Hz instead.
Workaround 3: Using a Custom Function
Google Sheets allow you to write custom formulae that work in a similar way to the built in formulae like =SUM() or =COUNT().
Following the same steps as in workaround 2 to open the Script editor, create the following function:
function hertzify(f) {
f = f.split("-");
return f[0] + "Hz-" + f[1] + "Hz";
}
This does a similar thing as workaround 2, but instead of automatically changing the values of whatever is in a specific column, you call the function by entering the following formula in a cell:
=HERTZIFY("50-60")
This will change the cell's display value to 50Hz-60Hz like before.
You can also use this on other cells; for example if cell C3 has the text 120-130 and in cell D3 you input =HERTZIFY(C3), then D3 will display 120Hz-130Hz.
Feature Request:
As the above workarounds either process the cell data as if they are text or require the number to be formatted in a specific way, they might not be perfect workarounds for all situations.
In this case I suggest filing a feature request with Google for the ability to define a number format for a range of values in a specific cell.
You can do this by either following the Help > Report a problem menu item from the Google Sheets user interface, or make a feature request on Google's Issue Tracker asking to implement this as a feature. The link to the Issue Tracker is here
References:
Format numbers in a spreadsheet - Computer - Doc Editors Help
Simple Triggers | Apps Script | Google Developers
Custom Functions in Google Sheets | Apps Script | Google Developers
Google's Issue Tracker