Looking up values in third column by two criteria - excel

I have a list similar to this one:
NO | Cat1 | Cat2 | | Crit1 | Crit2 |
---|------|------| | A | O |
5 | A | O |
3 | K | Y |
6 | K | Y |
7 | F | K |
8 | A | O |
9 | J | H |
10 | K | Y |
5 | F | T |
50 | A | O |
8 | L | E |
1 | R | D |
Based on two criteria I want a dynamic list which changes everytime the content are changed or the criteria are changed.
If criteria is A O then the list should be as below,
|List|
|----|
| 5 |
| 8 |
| 50 |
If any other criteria is selected the list will be longer or shorter and if nothing is present it is shown as a blank cell.
I have tried some MATCH and INDEX formulas but I cannot make it work correctly.
=IFERROR(INDEX(LookUpList;MATCH(0;COUNTIF(NewList;LookUpList)+IF(Cat1<>Crit1;1;0)+IF(Cat2<>Crit2;1;0);0));"")

Sorted ascending:
=IFERROR(AGGREGATE(15,7,A$2:A$12/((B$2:B$12=G$1)*(C$2:C$12=G$2)),ROW(1:1)), "")
Ordered by row:
=IFERROR(INDEX(A:A, AGGREGATE(15, 7, ROW(A:A)/((B$1:B$12=G$1)*(C$1:C$12=G$2)), ROW(1:1))), "")
Pick one formula then fill down for subsequent matches.

Related

Filter filter criteria and then apply in countif statement in Excel

I have a table of filter criteria like this:
+----------+----------+------+------+------+
| Category | SpecName | Spec | Pass | Fail |
+----------+----------+------+------+------+
| A | S1 | 3 | | |
| A | S2 | 4 | | |
| B | S1 | 5 | | |
| C | S1 | 2 | | |
+----------+----------+------+------+------+
I have a table I want to apply the filter criteria to like this:
+----------+----+----+
| Category | S1 | S2 |
+----------+----+----+
| A | 5 | 3 |
| B | 4 | |
| A | 5 | 5 |
| C | 2 | |
| A | 2 | 6 |
+----------+----+----+
I want to fill the Pass and Fail columns in the filter criteria table with a count of items in second table with values >= the corresponding spec, like so.
+----------+----------+------+------+------+
| Category | SpecName | Spec | Pass | Fail |
+----------+----------+------+------+------+
| A | S1 | 3 | 1 | 2 |
| A | S2 | 4 | 1 | 2 |
| B | S1 | 5 | 0 | 1 |
| C | S1 | 2 | 1 | 0 |
+----------+----------+------+------+------+
Here are steps for how I might do it in a scripting language:
Filter first table to get all spec filter criteria for the Category on that row, as follows for the first row.
+----------+----------+------+
| Category | SpecName | Spec |
+----------+----------+------+
| A | S1 | 3 |
| A | S2 | 4 |
+----------+----------+------+
Copy table 2 to a variable iTable
+----------+----+----+
| Category | S1 | S2 |
+----------+----+----+
| A | 5 | 3 |
| B | 4 | |
| A | 5 | 5 |
| C | 2 | |
| A | 2 | 6 |
+----------+----+----+
For each spec name:
Find column in iTable with spec name
Filter spec name column in iTable by spec
After all filters applied, we would have:
+----------+----+----+
| Category | S1 | S2 |
+----------+----+----+
| A | 5 | 5 |
+----------+----+----+
Then just count the rows in iTable and assign to the cell in Pass column of the criteria table
Is this possible with Excel formulas?
If not, does anyone know how to do it with VBA?
Looking at an alternative layout for you spec criteria. Expand you columns to suit your need.
With each spec criteria being its own column life gets really easy. You just need to adjust your formula to match the number of criteria you have.
Based on the table at the end for layout, place the following formula in D3 and copy down as required.
=SUMPRODUCT(($G$2:$G$6=A3)*($H$2:$H$6>=B3)*($I$2:$I$6>=C3))
That will give you a count of passing all criteria. Its also a function that performs array like calcs. It could be repeated in the next column but in order to reduce dependency on array calculation and potentially speed things up depending on the amount of data to check, place the following in the top of the fail column and copy down as required:
=COUNTIF($G$2:$G$6,A3)-D3
Basically it subtracts the passes from the total count. This assumes you can only have PASS and FAIL as options.

MIN IF for sub ranges

I had asked this question for MAX IF for sub ranges before. how to find the maximum value (col A) for different items into a range (col B in this case) written on the C col
| A | B | C |
| 10 | cat | |
| 15 | cat | |
| 5 | dog | |
| 4 | dog | |
| 11 | dog | |
| 6 | fish | |
| 10 | fish | |
ppl answered me =MAX(INDEX(("$B$1:$B$7=B1)*$A$1:$A$7,0)) which works fine, but when i tried to use it for the minimum values, I mean =MIN(INDEX(("$B$1:$B$7=B1)*$A$1:$A$7,0)) i got zero for the whole C col.
what could i do wrong?
I always use this for finding min and max with an array formula. Be sure to enter the below with a Shift + Ctrl + Enter.
{=MIN(IF($B$1:$B$7=B7,$A$1:$A$7,""))}

Transform values without VBA but with Index and Match

I'm trying to find a solution without macros in excel for following problem:
There is a table containing ratings of a student for different time periods.
So the rating of the student with ID=1 was 1 from January to April and 3 from Mai to June.
Two other students had a constant ranking (6 and 9) from January to June
| A | B | C |D |
---| ----|------------|------------|-------|
1 | ID | START | END |RANKING|
2 | 1 | 01.01.2014 | 30.04.2014 | 1 |
3 | 1 | 01.05.2014 | 30.06.2014 | 3 |
4 | 2 | 01.01.2014 | 30.06.2014 | 6 |
5 | 3 | 01.01.2014 | 30.06.2014 | 9 |
Next table contains IDs (y axis) and Months (x axis)
| F | G | H | I | J | K | L |
---| ----|--------|--------|--------|--------|--------|--------|
1 | ID | 201401 | 201402 | 201403 | 201404 | 201405 | 201406 |
2 | 1 | | | | | | |
3 | 2 | | | | | | |
4 | 3 | | | | | | |
And I wish to feel this second table like this:
| ID | 201401 | 201402 | 201403 | 201404 | 201405 | 201406 |
| ----|--------|--------|--------|--------|--------|--------|
| 1 | 1 | 1 | 1 | 1 | 3 | 3 |
| 2 | 6 | 6 | 6 | 6 | 6 | 6 |
| 3 | 9 | 9 | 9 | 9 | 9 | 9 |
I tried to use Index and Match, but without any good results because I haven't found a posibility to use IF (if (
Could anybody help?
You can get what you're looking for with SUMPRODUCT
Given the layout you provided, this formula should work when put in G2 and filled down and over
=SUMPRODUCT(--($A:$A=$F2),--($B:$B<=G$1),--($C:$C>G$1),$D:$D)
That looks in column A for an ID matching F2, then for every one it finds of those:
It checks the date in column B against the date in G1
It checks the date in column C against the date in G1
If all criteria match, it returns the value in Column D
This assumes you only have one entry for each period, otherwise it will sum them.
Also, you can use SUMIFS, it's a little less easy to read but I think it's slightly more efficient than SUMPRODUCT (I'm not positive, just anecdotal evidence from usage)
=SUMIFS($D:$D,$A:$A,"="&$F3,$B:$B,"<="&G$1,$C:$C,">"&G$1)
It does the exact same thing, just with different syntax.

How to get QTP and Excel to sort correctly?

I need to sort by columns a ascending, then b ascending, then d ascending and by columns e ascending, then f ascending, then h ascending. Using just QTP, I can't seem to get Excel to sort the data correctly.
What I want:
Table 1:
| a | b | c | d | e | f | g | h |
---------------------------------------------------------------------
| 1 | BE | blank | 51 stuff | 1 | BE | blank | 51 stuff |
| 1 | BE | blank | 100 stuff | 1 | BE | blank | 100 stuff |
| 1 | BE OF A | blank | 121 stuff | 1 | BE OF A | blank | 121 stuff |
| 1 | BE OF A | blank | 200 stuff | 1 | BE OF A | blank | 200 stuff |
| 2 | SEA | blank | 5 stuff | 1 | SEA | blank | 5 stuff |
What I got instead:
Table 2:
| a | b | c | d | e | f | g | h |
---------------------------------------------------------------------
| 1 | BE | blank | 100 stuff | 1 | BE OF A | blank | 121 stuff |
| 1 | BE | blank | 51 stuff | 1 | BE OF A | blank | 200 stuff |
| 1 | BE OF A | blank | 121 stuff | 1 | BE | blank | 100 stuff |
| 1 | BE OF A | blank | 200 stuff | 1 | BE | blank | 51 stuff |
| 2 | SEA | blank | 5 stuff | 1 | SEA | blank | 5 stuff |
Columns e through h gets populated and sorted first. Normally, the cells for those columns are populated in the correct sort order seen in Table 1. However, there have been instances where the sort order is incorrect, but that is rare. Maybe 1 out of 100,000 tries would it be populated with unsorted data.
Columns a through d gets populated and sorted last. The cells for those columns are populated in a somewhat haphazard manner. Table 3 illustrates a very simple end result without forcing a sort.
Table 3:
| a | b | c | d | e | f | g | h |
---------------------------------------------------------------------
| 1 | BE | blank | 100 stuff | 1 | BE | blank | 51 stuff |
| 1 | BE | blank | 51 stuff | 1 | BE | blank | 100 stuff |
| 1 | BE OF A | blank | 121 stuff | 1 | BE OF A | blank | 121 stuff |
| 1 | BE OF A | blank | 200 stuff | 1 | BE OF A | blank | 200 stuff |
| 2 | SEA | blank | 5 stuff | 1 | SEA | blank | 5 stuff |
What's the best way to get QTP and Excel to return the results displayed in Table 1? Is there even a way to?
Snippet of the code(s) that I'm using:
'Some Code Stuff here which leads to exporting the worksheet
rangeOne = "E1:H" & totalRowCnt
Set rangeObj = worksheetOne.Range(rangeOne)
Set range1 = excel1Obj.Range("E1")
Set range2 = excel1Obj.Range("F1")
Set range3 = excel1Obj.Range("H1")
rangeObj.Sort range1, ascend1, range2, ,ascend1, range3, ,ascend1,yes1
'Save worksheet then import sorted data back into Datatable
'and add more Code Stuff here which leads to exporting the worksheet again
rangeOne = "A1:D" & totalRowCnt
Set rangeObj = worksheetOne.Range(rangeOne)
Set range1 = excel1Obj.Range("A1")
Set range2 = excel1Obj.Range("B1")
Set range3 = excel1Obj.Range("D1")
rangeObj.Sort range1, ascend1, range2, ,ascend1, range3, ,ascend1,yes1
'Save worksheet then end script
Try loading the data into a Recordset object. You can sort the recordset like this:
rs.Sort = "a ASC, b ASC, d ASC, e ASC, f ASC, h ASC"
then copy the sorted data to Excel or write them to a CSV.
rs.MoveFirst
Do Until rs.EOF
For i = 0 To rs.Fields.Count - 1
'copy/write rs.Fields(i).Value
Next
rs.MoveNext
Loop

Excel Creating a List from Beginning and End number AND tags

I am trying to create a list from an index of grouped values.
This is very similar to this, however my groups also have "tags" on then that complicate the listings.
Here is an example of my INDEX tab:
| A | B | C | D |
-------------------------
1 | 1 | 1 | 1 | CV |
2 | 1 | 2 | 2 | IS |
3 | 1 | 3 | 3 | IS |
4 | 2 | 4 | 5 | GN |
5 | 2 | 6 | 7 | PS |
6 | 4 | 8 | 11 | SQ |
7 | 2 | 12 | 13 | SS |
8 | 1 | 14 | 14 | AT |
9 | 15 | 15 | 29 | AT |
10| 4 | 30 | 33 | TYP |
Where A is the number of pages, B is the first page, C is the last page and D is the tag. I would also like to add columns such that I can keep a running tally of the tags.
| A | B | C | D | E | F |
---------------------------------------
1 | 1 | 1 | 1 | CV | CV1 | CV1 |
2 | 1 | 2 | 2 | IS | IS1 | IS1 |
3 | 1 | 3 | 3 | IS | IS2 | IS2 |
4 | 2 | 4 | 5 | GN | GN1 | GN2 |
5 | 2 | 6 | 7 | PS | PS1 | PS2 |
6 | 4 | 8 | 11 | SQ | SQ1 | SQ4 |
7 | 2 | 12 | 13 | SS | SS1 | SS2 |
8 | 1 | 14 | 14 | AT | AT1 | AT1 |
9 | 15 | 15 | 29 | AT | AT2 | AT16 |
10| 4 | 30 | 33 | TYP | TYP1 | TYP4 |
Note that the tag could occur multiple times and it may not be in sequential rows.
Here is what I want this to look like for my LIST tab:
| A |
---------
1 | CV1 |
2 | IS1 |
3 | IS2 |
4 | GN1 |
5 | GN2 |
6 | PS1 |
7 | PS2 |
8 | SQ1 |
9 | SQ2 |
10| SQ3 |
11| SQ4 |
and so on...
How do I add the additional columns to the INDEX tab via formulas?
How do I create the LIST via formulas? (...is this even possible?)
The formulas should be pretty simple to write. Just consider what you're trying to accomplish.
Your first formula (in column E) is just taking a running count of the tags (in column D). So you want to count all cells from the first tag up to the corresponding tag where the tag names are the same. That count is to be appended to the tag name.
=$D1 & COUNTIF($D$1:$D1, $D1)
The second formula (in column F) is just taking a running sum of the page counts (in column A). So you want to take the sum of all corresponding page counts from the first tag up to the corresponding tag where the tag names are the same. The sum is to be appended to the tag name.
=$D1 & SUMIF($D$1:$D1, $D1, $A$1:$A1)
Note that the column doesn't change nor does the starting rows of the ranges (hence the need to use absolute ranges). The only thing that changes are the rows of the tag and the row of the end range.
I don't think it would be possible to generate that list through simple formulas. As far as I know, formulas need to have a 1-to-1 correspondence with another range. A single range can yield multiple values so a formula just won't cut it. You'll need to write a VBA script to generate that.
Sub GenerateList()
Dim usedRange As Range
Dim count As Dictionary
Set usedRange = Worksheets("Index").usedRange
Set count = CountValues(usedRange)
Dim output As Range
Dim row As Integer
Dim key As Variant
Set output = Worksheets("List").Columns("A").Rows
output.ClearContents
row = 1
For Each key In count.Keys()
Dim i As Integer
For i = 1 To count(key)
output(row) = key & i
row = row + 1
Next i
Next key
End Sub
Function CountValues( _
usedRange As Range, _
Optional tagsColumn As String = "D", _
Optional valuesColumn As String = "A") As Dictionary
Dim tags As Range
Dim values As Range
Set tags = usedRange.Columns(tagsColumn).Rows
Set values = usedRange.Columns(valuesColumn).Rows
Dim map As New Dictionary
Dim tag As Range
For Each tag In tags
map(tag.Value) = map(tag.Value) + values(tag.row)
Next tag
Set CountValues = map
End Function
This uses a Dictionary so you'll have to reference the scripting runtime.
It sounds like you're just trying to get a list of "Unique Values" on a separate sheet that you can use as your list. Try these pages, there are multiple VBA methods to paste unique items in a range.
Also, Advanced Filter has an option to paste unique values to another location. So none of your repeat tags would appear in this list, only unique ones for your "LIST" tab.
Anyway, not sure if that's what you're wanting, but the question was a smidge vague.
Links here:
Create Unique list
Create Unique list 2

Resources