Google Spreadsheet: Query String and Numeric (Involving math formula) - google-sheets

Sorry about the imprecise title. Allow me to elaborate. I'm currently in the process of making 'Order' sheets for the small retailer i work for. Some items are easy to count due to low inventory while other items are abundant and difficult to count but easy to gauge whether we ought to order them.
When an employee takes a store count, the on-hand number they put down is contrasted with a minimum. The minimum is our lower threshold. The minimum is subtracted by the input quantity and a formula produces a third column, "Order". If the number in the order column is < 0 then a query function on a separate sheet will copy the entire row. To be clear, there are three columns, "On Hand", "Minimum", "Order", with the "Order" column containing the following mathematical formula:
="Minimum" - "On Hand"
[Cells are specified so that it would look more like "=B2-A2".]
However, I'd also like to include the ability for employees to put a simple 'x' in the count spot, signifying that we need to order the product without having to count every single instance of the item. I'd still like to include the ability for them to enter a number if they so choose. I'd like for them to be able either the number or the 'x' in the same column. I'm currently using the following query function:
=QUERY('String(Fail)'!A:D;"select * where A contains 'x' or C > 0")
[The above is from a sheet I'm experimenting with. I will provide a link below in case you're more hands-on.]
The issue arises when the formula in the "order" column outputs any sort of number. If the formula is functional, no row marked with an 'x' is copied to the new page via the query command. If any row produces a numeric, no 'x' rows are copied over at all. I've experimented a bit but am at a loss as to where to go next.
The sheet I'm currently experimenting with is linked below. If you'd like any additional information I'd be happy to provide it. I'm relatively new to all of this so excuse my stupidity. I do recognize that I could very likely make a script for this but am not well versed in scripting with Google Apps and enjoy the immediate benefits of the query function.
Any help is welcome. Thank you.
Experimental Spreadsheet

All the values in a column need to be of the same type in order to be evaluated by QUERY. The mix of 'x' and numbers is confusing things.
If you use the Format menu to ensure all the values in column A are Plain Text, then your Query will work. (Formatting a numeric value as plain text does not stop it from working in a numeric calculation, so your column C survives.) Here's a screenshot of your query, after doing that formatting:
Based on your specification, your query needs to have the comparison to zero reversed, like this:
=QUERY('String(Fail)'!A:D;"select * where A contains 'x' or C < 0")
^^^

Related

Advanced filter/configurator based on dataset

I would like help with a problem, or rather a challenge in Excel and/or Google Sheets.
What we want to develop is as follows:
We have a table of products and certain attributes. Now we want to create a kind of search function based on this table.
Example:
Let me give a simple example. Suppose you have as a product an apple, a banana and an orange. The characteristics associated with these are size, color country of origin. We then want a search function, where you indicate one or more preferences, i.e. size, color and/or country of origin and that based on those criteria, all products that meet these criteria are displayed.
So if you specify oblong as the size and do not specify any other criteria, it only shows "Banana. If the banana and the orange have Holland as their country of origin and you only give Holland as the criteria country of origin, it will show 'Banana' and 'Orange'. If you say country of origin Netherlands and format oblong, it again shows only 'Banana'
See below an image of our document and how we would like this to look approximately.
Currently, there is no existing formula, because we simply do not know if this can be done and how best to do it.
The document can be accessed at:
A copy of our document with sample data:
Document
ADDITION:
Hi, Unfortunately I still am not able to get it to work. I am not really a hero in coding/functions. I created a bit more of a clear view in my file and also set the language of my sample file to english. You can find it here: Sample
What I actually need is just that it shows the data on 'Datasheet' if conditions on the left (parameters/value) are met, but only if they are filled. Probably easy one for you, hard to me haha Could you help me out once more? –
Your question is very generic, I will try provide here some guidelines on how to achieve it in Excel or Google Sheet based on my own experience. The approach used for Excel can be used for Google Spreadsheet, since it is based on FILTER function that both tools have but with different signature. For Google Spreadsheet you can also use QUERY that is very powerful for situation like this.
In all cases, it is a good practice to have a sheet with the input raw data (let's say Input tab), then in second sheet the working data of filtered data (let's say WorkData). This is specially relevant when the raw data is big dataset, so you don't touch the original data set, and instead you have the filtered data in a separated tab.
Both tools offer filter features in the UI or slice. This is something to consider, but using Excel/Google Spreadsheet functions, you can show the filter parameters in a more friendly manner, because you can see the parameters selected without additional click to find what filter values where selected. The approach here is based on Excel/Google Spreadsheet functions.
Excel
Let's say you have a block of filter conditions that you want to apply to a range of data. You can use data validation list so you can select a subset of possible values for each of the filter conditions and then to concatenate such conditions logically (OR or AND) using multiplication of addition.
=FILTER(dataset, condition1 * condition2...conditionN)
where each condition is based on the filter value you want to restrict and each condition represents an array of {TRUE,FALSE} values all of them of the same size as dataset (number of rows).
I use some wildcard values to represent all values of the column, in my case I use ALL, but you can setup in a different way. In such case the filter doesn't take effect, but we want to make it work when a specific value is selected. The following trick can be used for both scenarios.
IF(B3="ALL", D3:D15<>"*",D3:D15=B3)
indicating that if B3 is equal to ALL, then the condition to select all of the D3:D15 rows is the following: <>"*". Otherwise select only the rows equals to B3.
Sometimes I would like to consider OR conditions for a given filter condition, for example for a given filter condition, consider value1 or value2 and it is represented in the filter value as a list of values delimited by comma, for example: value1, value2.
Here, some Stack Overflow questions I posted with answers about how to deal with that:
Filter an excel range based on multiple dynamic filter conditions
Filter an excel range based on multiple dynamic filter conditions (with column values delimited)
Google Spreadsheet
The FILTER function here, allows to add the filter conditions via input arguments, so now we have:
=FILTER(dataset, condition1, condition2...,conditionN)
Note: Keep in mind in Google Spreadsheet we don't need to add the conditions by multiplying each one of them. It is added via input argument.
here you can check some of question I posted related to this topic:
Using ARRAYFORMULA with SUMIF for multiple conditions combined with a wildcard to select all values for a given condition
Using ARRAYFORMULA with SUMIF for multiple conditions combined with conditions using a wildcard. Result by Months
In some cases it is better to use QUERY function.
Here, a sample file using QUERY statement and how to combine multiple conditions inserting IF in the where statement.
sample query on C1 cell:
=query('Jira Issues'!$A:$T, "where "
& IF(B2="", "G is not Null", "G >= date '"
& TEXT(startPeriod,"yyyy-mm-dd")&"'")
& IF(B3="", "", " and G <= date '"
& TEXT(endPeriod,"yyyy-mm-dd")&"'")
& IF(OR(B4="ALL",B4=""), "", " and A='"&B4&"'")
& IF(OR(B5="ALL",B5=""), "", " and I='"&B5&"'")
& " label A 'Team', S 'Reporter', T 'Assignee',
P 'Env.', I 'Release'",1)
The raw data is in Jira Issues tab, the data populated is based on multiple filter conditions. I am using some name ranges for the filter values for a better understanding of the formula, such as: startPeriod, endPeriod, etc. You can test the actual query will be invoked looking at the result of the consolidated string of the query input argument of QUERY function.
Similarly you can stablish a where statement to consider whether the input parameter is empty or not. In such case, you can build a logic like this inserting an IF block as part of the where statement and concatenate the string result.
=QUERY(Input!A:Y,
"select *" & " where A " & IF(B2="", "<>'*'", "='"&B2&"'")
"and " & " where B " & IF(B3="", "<>'*'", "='"&B3&"'")
,1)
The above query for column A or B, returns the entire column via condition: "<>'*'" if the input parameter B2 or B3 were not specified. In a similar way you can add additional conditions for more parameters, repeating the third line of the query and changing the column and the parameter cell.
Recommendations
Focus on a specific tool: Excel or Google Spreadsheet, even they have some similarities, you need to get familiar with the specifics of each one of them.
Try to start working on your specific problem, once you face impediments, do some research, usually you are not the first person facing this problem, if you don't find a solution, then post your specific problem using a sample as an extract of your real problem (in English, your sample is in other language). Generic questions like this one are difficult to get some attention.

Google Sheets - Randomize and freeze queried columns

I'm trying to create a dynamic 'worksheet' in Google Sheets to help myself study Chinese.
This is something I'm kind of figuring out as I go, but I'm currently trying to create a template for the basic 'worksheet' that will draw vocabulary from other pages in my document.
Here's a copy of my current version: https://docs.google.com/spreadsheets/d/1U1hclOSo-SM2JuxJB6LXPB4J0UzXt6xJ1B_54ehkALs/edit?usp=sharing
Sheet1 is where I'm currently struggling. The idea behind Column A was that I could create 'switches' to keep the page from updating (Freeze) while I'm actually using the worksheet for studying. Once I've finished and checked my work, I could switch back to (Update) so that the Query will re-run and update to include any new words, etc.
Thus, E2 =if(A2="Update",1,0) is the condition I'm trying to check. 1 in this case would be letting the page update. 0 would be the only other value (Freeze), which would ideally stop the sheet from updating.
Another problem I've run into is that I wanted to use the 'Randomize Range' feature from the right-click menu on the output of my Query, but that doesn't seem to work. I wanted to be able to shuffle the terms so that I am not accidentally memorizing the order rather than the actual information I'm trying to learn.
I don't know which is more efficient: Having the Query grab the definition along with the word and add those to a hidden column, or have a column that matches the word to its definition outside of the Query.
If I could add in another layer of complexity, it would be neat if I could have my worksheet randomly choose between column A and column D (maybe E, too) on my Vocabulary Bank pages so that sometimes it would show me the English term and other times it would show me the Chinese one. (Currently, I'm planning to just have one worksheet for English to Chinese and a second for Chinese to English.)
In the end, I'd like for Sheet1 to work like this:
Column A: Switches
Column B: Terms, grabbed from 'Vocabulary Bank - [etc.]'!A3:A [etc.] being all of the different banks. These are randomly reordered and 'frozen' until the Range switch is changed to 'Update'.
Column C: Hidden, containing the translations of the corresponding words. These update according to a switch.
Column D: This is where I enter my guesses at the translations. There is a switch to enable 'grading' where answers that don't match Column C are highlighted.
Any help would be appreciated. Thanks!

Google Sheets Count Unique Dates based upon a criteria in different columns

I am trying to find a formula that will give me the count of unique dates a persons' name appears in one of two different columns and/or both columns.
I have a set of data where a person's name may show up in a "driver" column or a "helper" column, multiple times over the course of one day. Throughout the day some drivers might also be helpers and some days a driver may come in for duty but only as a helper. Basically all drivers can be helpers, but not all helpers can be drivers.
I've attached a link to a sample sheet for more clarity.
https://docs.google.com/spreadsheets/d/1GqNa1hrViX4B6mkL3wWcqEsy87gmdw77DhkhIaswLyI/edit?usp=sharing
I've created a REPORTS tab with a SORT(UNIQUE(FLATTEN)) Formula to give me a list of the names that appear in the DATA Tab.
I'm looking for a way to count the unique dates a name from the name (Column A of the REPORTS Tab) appears in either of the two columns (Column B and/or C of the DATA Tab) to determine the total number of days worked so I can calculate the total number of days off over the range queried.
I've tried several iterations of countif, countunique, and countuniqueifs but cannot seem to find a way to return the correct values.
Any advice on how to make this work would be appreciated.
I think if you put this formula in cell b7 you'll be set. You can drag it down.
=Counta(Unique(filter(DATA!A:A,(DATA!C:C=A7)+(DATA!B:B=A7))))
Here's a working version of your file.
For anyone interested, Google Sheets' Filter function differs slightly from Excel's Filter function because Sheets attempts to make it easier for users to apply multiple conditions by simply separating each parameter with a comma. Example: =filter(A:A,A:A<>"",B:B<>"bad result") will provide different results between the Sheets and Excel.
Excel Filter requires users to specify multiple conditions within parenthesis and denote each criterion be flagged with an OR condition with a + else an AND condition with a multiplication sign *. While this can appear daunting and bizarre to multiply arrays that have text in it, it allows for more flexibility.
To Google's credit, if one follows the required Excel Syntax (as I did in this answer) then the functions will behave the same.
delete what you got and use:
=QUERY(QUERY(UNIQUE({DATA!A:B; DATA!A:A, DATA!C:C}),
"select Col2,count(Col1),"&D2&"-count(Col2)
where Col2 is not null
group by Col2"),
"offset 1", 0)

Is there a way to specify an input is a single cell in Google Sheets?

I want to iterate over an array of cells, in this case B5:B32, and keep the values that are equal to some reference text in a new array.
However, SPLIT nowadays accepts arrays as inputs. That means that if I use the array notation of "B5:B32" within ARRAYFORMULA or FILTER, it treats it as a range, rather than the array over which we iterate one cell at a time.
Is there a way to ensure that a particular range is the range over which we iterate, rather than the range given at once as an input?
What I considered was using alternative formulations of a cell, using INDEX(ROW(B5), COLUMN(B5)) but ROW and COLUMN also accept array values, so I'm out of ideas on how to proceed.
Example code:
ARRAYFORMULA(
INDEX(
SPLIT(B5:B32, " ", 1), 1
) = "Some text here"
)
Example sheet:
https://docs.google.com/spreadsheets/d/1H8vQqD5DFxIS-d_nBxpuwoRH34WfKIYGP9xKKLvCFkA/edit?usp=sharing
Note: In the example sheet, I can get to my desired answer if I create separate columns containing the results of the SPLIT formula. This way, I first do the desired SPLITS, and then take the values I need from that output by specifying the correct range.
Is there a way to do this without first creating an output and then taking a cell range as an input to FILTER or other similar functions?
For example in cell C35 I've already gotten the desired SPLIT and FILTER done in one go, but I'd still need to find a way to sum up the values of the first character of the second column. Doing this requires that I take the LEFT value of the second column, but for that I need to output the results and continue in a new cell. Is there a way to avoid this?
Ralph, I'm not sure if your sample sheet really reflects what you are trying to end up with, since, for example, I assume you are likely to want the total of the hours per area.
In any case, this formula extracts all of the areas, and the hours worked, and is then easy to do further calculations with.
=ArrayFormula({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))})
Try that in cell E13, to see the output.
The first REGEXEXTRACT pulls out all the text in front of the first space and number, and the second pulls out all the digits in a string of " #hr" in each cell. These criteria could be modified, if necessary, depending on your actual requirements. Note that it requires the use of VALUE, to convert the hours from text to numeric values, since REGEXEXTRACT produces text (string) results.
It involved concatenating your multiple data columns into one long column of data, to make it simpler to process all the cells in the same way.
This next formula will give you a sum, for whatever matching room/task you type into B6, as an example.
=ArrayFormula(QUERY({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))},
"select Col1, sum(Col2) where Col1='"&B6&"' group by Col1 label sum(Col2) '' ",0))
I will also answer my own question given what I know from kirkg13's answer and other sources.
Short answer: no, there isn't. If you want to do really convoluted computations with particular cell values, there are a few options and tips:
Script your own functions. You can expand INDEX to accept array inputs and thereby you can select any set of values from an array without outputting it first. Example that doesn't use REGEXMATCH and QUERY to get the SUM of hours in the question's example data set: https://docs.google.com/spreadsheets/d/1NljC-pK_Y4iYwNCWgum8B4NJioyNJKYZ86BsUX6R27Y/edit?usp=sharing.
Use QUERY. This makes your formula more convoluted quite quickly, but is still a readable and universally applicable method of selecting data, for example particular columns. In the question's initial example, QUERY can retrieve only the second column just like an adapted INDEX function would.
Format your input data more effectively. The more easily you can get numbers from your input, the less you have to obfuscate your code with REGEXMATCHES and QUERY's to do computations. Doing a SUM over a RANGE is a lot more compact of a formula than doing a VALUE of a LEFT of a QUERY of an ARRAYFORMULA of a SPLIT of a FILTER. Of course, this will depend on where you get your inputs from and if you have any say in this.
Also, depending on how many queries you will run on a given data set, it may actually be desirable to split up the formula into separate parts and output partial results to keep the code from becoming an amalgamation of 12 different queries and formulas. If the results don't need to be viewed by people, you can always choose to hide specific columns and rows.

Sort Google Sheet by order values are entered in a data validation

Is there a way to sort a Google Sheet by the order in which values are entered into a data validation criteria?
I want to sort the sheet based in ascending order Low,Medium,High or descending order High,Medium,Low. Not by alphabetical order High,Low,Medium and Medium,Low,High respectively.
Aaron. The easiest way would be to use a helper column (which you can hide later if you like) wherein you assign numerical values to your Low, Medium and High (presumably 1, 2 and 3 respectively). Then you sort using the numerical column. It's fairly easy to write a one-cell array formula that would assign the numerical values to your labels. The numerical column need not be beside the label column; it can be any column.
Without seeing an actual sample sheet, I can't show you. But hopefully the concept is clear, and you can take it from there.
Added description after sheet was shared:
In the example sheet, Sheet1 Column A contained the Priority in words (Low, Medium, High) and Column B contained "other data." I placed the following array formula into C1:
=ArrayFormula({"Priority Val";IF(A2:A="","",VLOOKUP(A2:A,Data!A:B,2,FALSE))})
The formula is an array formula, hence the ArrayFormula() wrap.
Inside this are curly brackets {} which allow the building of arrays that are not "of a type." In this case, the header is listed first ("Priority Val"). The semicolon means "place the next part underneath." Then a VLOOKUP references every value in Column A (i.e., the priority words) against a simple chart in a second sheet named "Data." In that "Data" sheet, Column A simply lists 1, 2, 3 and Column B lists your exact words: Low, Medium, High. The IF() function just checks to see if a row in Sheet1!A:A is blank. If so, a null is assigned before trying the VLOOKUP; otherwise, every blank row would show an #NA error.
If you want to make it even more air tight, it's good practice to wrap VLOOKUP in IFERROR(), just in case you misspell something in Sheet1!A:A. That would look like this:
=ArrayFormula({"Priority Val";IF(A2:A="","",IFERROR(VLOOKUP(A2:A,Data!A:B,2,FALSE)))})
And you can avoid misspelling by applying data validation to Sheet1!A2:A, referencing Data!A:A as the only allowable answers. This is not strictly necessary; but I have done it in the sample sheet to show you.

Resources