Validation list with multiple criterias - validation

I sort out my problem but I am wondering if an easier way doing it doesn't exist.
With the function onEdit(), I am creating from a first validation list, a second validation list in the next cell.
So, the code below is just for information.
var validationRange = data.getRange(3, myIndex, data.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
In this validation list, I need to select a name, taking into account two additionnal criterias :
Name
Times
LastWeek
Patrick
2
W22
Rachel
5
W15
Claire
3
W14
Olivier
4
W16
Hélene
2
W20
It means that "Patrick" attended "2" times and last time was in week "W22".
I need to take into account these two criterias to select one of the attendee
I.E. : I try to let each person participate the same number of times but not every week (the oldest first)
So, I created a validation list with a "sorted key" that allows me to first see the person who has attended less and for longer.
Key Sorted
#02W20#Hélene
#02W22#Patrick
#03W14#Claire
#04W16#Olivier
#05W15#Rachel
This validation list is used 3, 5, 7 times in the same sheet because person can do different activities. Then, when all person are selected another script removes the values between # to keep only the name in the final sheet.
So, the question is :
could we create a validation list with multiple columns, the selected value being only the value of the first column.
I guess many users would enjoy it when we glance at questions about multiple criteras selection lists.
Thanks

Related

List non-unique entries and their counts sorted in descending order

If I have a list of names in a sheet for example:
First Name|Last Name|Something else|
Maria|Miller|...|
John|Doe|...|
Maria|Smith|...|
Marc|Meier|...|
Marc|Park|...|
Maria|Muster|...|
Selene|Mills|...|
Adam|Broker|...|
And then I want a second sheet which then shows the list of non-unique first names and their count, and the list being in descending order. So in this example that would be:
First Name|Count
Maria|3
Marc|2
What I found was this example https://infoinspired.com/google-docs/spreadsheet/sort-by-number-of-occurrences-in-google-sheets/
which sorts of partitions the sheet entries by occurrence.
So as of now I have
=UNIQUE(sort(
Names!C3:Names!C12000;
if(len(Names!C3:Names!C12000);countif(Names!C3:Names!C12000;Names!C3:Names!C12000););
0;
2;
1
))
In the first column and
=IF(ISBLANK(A2);;COUNTIF(Names!C3:Names!C12000; A2))
In the second. This does the job somewhat (it still shows the names with count 1), but the second column needs a copying of each cell downwards for each new entry leftwards. Is there a way to tie this up directly in one line? While filtering out the unique occurrences at that.
(Also the formulas are quite slow. The names sheet has about 11k entries so far. These formulas make the sheet crash at times atm. So I kind of want to sorts of comment out the formulas most of the time and only display them by commenting out the formulas. So the second column also just being one formula would be very helpful.)
use:
=QUERY(SORT(QUERY(A2:A, "select A,count(A) group by A"), 2, ), "where Col2>1", )
I think this should work if your headers are in row 1.
=QUERY(QUERY(Sheet1!A:A,"select Col1,COUNT(Col1) where Col1<>'' group by Col1",1),"where Col2>1 label Col2'Count'",1)

List.Distinct and List.Count Challenge

Within PQ, I have a table of data (below) to which I am trying to determine whether all the columns titled Plan Status-# are the same, excluding blanks, and if all the same, display that value and if not display "Varies across plans"
The PQ code is below where I use List.Distinct to create a list of all "unique values".
I then use List.Count to count this number in the list and if 1, set the column equal to the Distinct value.
If List.Count({List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]})})=1 then List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]}) else "Varies across plans"
As per the table above, the List.Count does not seem to working correctly as some of the records show a merged value of items in the list which means the List.Count for a list with multiple values is calcing as 1.
You have extra brackets in your code. Try this:
if List.Count(List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]}))=1
then List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]})
else "Varies across plans"

Google Sheets - How to Combine Filter Function with Filter View

I've been working on a spreadsheet with over 100 rows, and found a hacky way to incorporate a "hide" checkbox that will hide any row where column C matches a specific value (building type), specified beside the box. To do this, I first created a function like this: =FILTER(Data!A1, OR(Data!$C1<>$O$2, $P$2)) and dragged that across every row and column in a seperate sheet. This reads as, "Display current cell if the corresponding column C in that row in Data does not match the building type, or if the the checkbox is checked. This way, the whole row is hidden when the building type matches, and the box is unchecked. A1 adjusted to each row individually, $C1 referenced the building's type, $O$2 referenced the targeted type to potentially hide, and $P$2 was the checkbox.
Problem #1: This created a lot of formulas in hundreds of cells, and when the building type was not found, it displayed #N/A across the entire row. A Filter View was able to hide these values, but it was inconvenient to have to reset the values every time I wanted to hide or unhide another building type.
My Attempt to Fix: I used a filter function once again to recreate the entire sheet from one cell, hiding the appropriate rows, using this: =FILTER(Data!A2:J191, ARRAYFORMULA((Data!$C2:C191<>$O$2)+(Data!D2:D191*$P$2)) This is the hacky part. I multiplied the checkbox's "true" by an array arbitrary positive numerical values in the D column to "OR" it with each building type value to achieve the same goal as before, but for EVERY cell.
Problem #2 arose: When I get my beautiful sheet, I can not sort it via a filter view, or it will throw an error and display nothing. I'm resorting to sorting the original tab, but intend to have it be ignored entirely. So how do I combine these two, Filter View, and Filter Function, to create a nice spreadsheet where I can SORT AND HIDE rows?
Bonus Problem #3: To add more buttons, my formula is this: =FILTER(Data!A1:J191, ARRAYFORMULA((Data!$C1:C191<>$O$2)+(Data!D2:D192*$P$2)), ARRAYFORMULA((Data!$C1:C191<>$O$3)+(Data!D2:D192*$P$3)), ARRAYFORMULA((Data!$C1:C191<>$O$4)+(Data!D2:D192*$P$4)), ARRAYFORMULA((Data!$C1:C191<>$O$5)+(Data!D2:D192*$P$5)), ARRAYFORMULA((Data!$C1:C191<>$O$6)+(Data!D2:D192*$P$6)), ARRAYFORMULA((Data!$C1:C191<>$O$7)+(Data!D2:D192*$P$7)), ARRAYFORMULA((Data!$C1:C191<>$O$8)+(Data!D2:D192*$P$8)), ARRAYFORMULA((Data!$C1:C191<>$O$9)+(Data!D2:D192*$P$9))) This is ugly, and very slow to load. Is there a way to create a function range to handle the same checks on multiple rows, and crunch it into a single formula?
Here is another monstrosity (this one has less repetition) for you:
=QUERY(
{IGNORE!A2:J, IGNORE!P2:P},
"SELECT * "
& "WHERE Col3 is not null "
& IF(COUNTIF(P2:P9, False) = 0, "", "AND NOT Col3 MATCHES '^" & JOIN("$|^", IFNA(FILTER(O2:O9, P2:P9 = False))) & "$' ")
& IF(COUNTIF(A2:K2, ">0") = 0, "", "ORDER BY Col" & JOIN(", Col", IFNA(FILTER(COLUMN(A2:K2) & IF(COLUMN(A2:K2) = 1, "", " DESC"), A2:K2)))),
0
)
Your checkboxes should remain. The second row can have just True/False values, no need for column number (a simple change will be needed COUNTIF(A2:K2, ">0") -> COUNTIF(A2:K2, True)). Also consequent sort works now (but only in the actual order of columns: if checked 1, 3, 4 then it will be sorted first by 1, then by 2, then by 4). You could place another config table on the right about sorting, where you would select all the columns you wish to sort by, their mutual order, and desc/asc for them.
Edit: added IFNA so FILTER won't return an error, changed multiple ANDS to MATCHES and simple regexes.

how can I group sum and count with sequel ORM and postgresl?

This is too tough for me guys. It's for Jeremy!
I have two tables (although I can also envision needing to join a third table) and I want to sum one field and count rows, in the same, table while joining with another table and return the result in json format.
First of all, the data type field that needs to be summed, is numeric(10,2) and the data is inserted as params['amount'].to_f.
The tables are expense_projects which has the name of the project and the company id and expense_items which has the company_id, item and amount (to mention just the critical columns) - the "company_id" columns are disambiguated.
So, the following code:
expense_items = DB[:expense_projects].left_join(:expense_items, :expense_project_id => :project_id).where(:project_company_id => company_id).to_a.to_json
works fine but when I add
expense_total = expense_items.sum(:amount).to_f.to_json
I get an error message which says
TypeError - no implicit conversion of Symbol into Integer:
so, the first question is why and how can this be fixed?
Then I want to join the two tables and get all the project names form the left (first table) and sum amount and count items in the second table. I have tried
DB[:expense_projects].left_join(:expense_items, :expense_items_company_id => expense_projects_company_id).count(:item).sum(:amount).to_json
and variations of this, all of which fails.
I would like a result which gets all the project names (even if there are no expense entries and returns something like:
project item_count item_amount
pr 1 7 34.87
pr 2 0 0
and so on. How can this be achieved with one query returning the result in json format?
Many thanks, guys.
Figured it out, I hope this helps somebody else:
DB[:expense_projects___p].where(:project_company_id=>user_company_id).
left_join(:expense_items___i, :expense_project_id=>:project_id).
select_group(:p__project_name).
select_more{count(:i__item_id)}.
select_more{sum(:i__amount)}.to_a.to_json

SOQL - single row per each group

I have the following SOQL query to display List of ABCs in my Page block table.
Public List<ABC__c> getABC(){
List<ABC__c> ListABC = [Select WB1__c, WB2__c, WB3__c, Number, tentative__c, Actual__c, PrepTime__c, Forecast__c from ABC__c ORDER BY WB3__c];
return ListABC;
}
As you can see in the above image, WB3 has number of records for A, B and C. But I want to display only 1 record for each WB3 group based on Actual__c. Only latest Actual__c must be displayed for each WB3 Group.
i.e., Ideally I want to display only 3 rows(one each for A,B,C) in this example.
For this, I have used GROUPBY and displayed the result using AggregateResults. Here is the result.
I got the Latest Actual Date for each WB3 as shown above. But the Tentative date is not corresponding to it. The Tentative Date is also the MAX in the list.
Here is the code I used
public List<SiteMonitoringOverview> getSPM(){
AggregateResult[] AgR = [Select WB_3__c, MAX(Tentaive_Date__c) dtTentativeDate , MAX(Actual_Date__c) LatestCDate FROM Site_progress_Monitoring__c GROUP BY WBS_3__c];
if(AgR.size()>0){
for(AggregateResult SalesList : AgR){
CustSumList.add(new SiteMonitoringOverview(String.ValueOf(SalesList.ge​t('WB_3__c')), String.valueOf(SalesList.get('dtTentativeDate')), String.valueOF(SalesList.get('LatestCDate')) ));
}
}
return CustSumList;
}
I am forced to use MAX() for tentative date. I want the corresponding Tentative date of the MAX Actual Date. Not the Max Tentative Date.
For group A, the Tentative Date of Max Actual Date is 12/09/2012. But it is displaying the MAX tentative date: 27/02/2013. It should display 12/09/2012. This is because I am using MAX(Tentative_Date__c) in my code. Every column in the SOQL query must be either GROUPED or AGGREGATED. That's weird.
How do I get the required 3 rows in this example?
Any suggestions? Any different approach (looping within in groups)? how?
Just ran into this issue myself. The solution I came up with only works if you want the oldest or newest record from each grouping. Unfortunately it probably won't work in your case. I'll still leave this here incase it does happen to help someone searching for a solution to this issue.
AggregateResult[] groupedResults = [Select Max(Id), WBS_3__c FROM Site_progress_Monitoring__c GROUP BY WBS_3__c];
Calling MAX or MIN on the Id will let you get 1 record per group condition. You can then query other information. I my case I just need 1 record from each group and didn't really care which one it was.

Resources