简体   繁体   中英

Excel Match Multiple Criteria Lookup Array: Find columns that contains all values from a list and return the columns position in the array

I cannot seem to solve this possibly simple excel function problem (Not VBA). In Microsoft Excel Array: I want to find a column that contains all values from a list(numbers) and return that column position in the array (numerical values).

Col1 Col2 Col3 Col4 Col5
4 8 4 7 4
1 4 2 9 10
9 3 2 8 8
10 3 2 6 10
10 5 8 4 9
5 9 1 9 5
5 5 5 6 4
4 1 5 1 2

ValuesList:

val1 val2 val3 val4
1 4 6 9

ValidColumn(s)#: 4

Array(Table): arrayTable1

Formula(function) Tested using (CTR+SHIFT+ENTER):

{=SMALL(IF(($A$2:$E$9)*($A$12:$A$15),COLUMN($A$2:$E$9)-COLUMN($A$2)+1),ROWS($1:$5))}

The formula generated: #N/A

Thanks in advance for your help.

Edit to clarify formula requirements/additional info:

1: Using Microsoft Excel 2010 version. Some newer functions not available. Using Microsoft Excel 2010 version. Some newer functions not available.

2: Can use functions like: v/h/lookup,small/large,index,match,countif/countifs,sumproduct,mode,mmult,transpose,aggregate,indirect,etc.

3: Actual data set for array (table) is hundreds of columns and growing. This means I need a formula that can check the whole array AND return columns# (4,etc.) that matches (contains) all the values in the list (criteria). Actual data set for array (table) is hundreds of columns and growing. This means I need a formula that can check the whole array AND return columns# (4,etc.) that matches (contains) all the values in the list (criteria).

4: Brainstorming

I saw some other answers that had basic lookup concept, but they did not include searching a whole table array at the same time.

Formula concept1: {=SMALL(IF(INDEX(IFERROR(--($A$2:$E$9=$A$12:$A$15),0),,),COLUMN($A$2:$E$9)-COLUMN($A$2)+1),ROW($1:$5))}

The formula generated: incorrect results (possibly first value column location only)

Formula concept2: {=IFERROR(MODE.MULT(IF((INDEX((((($A$2:$E$9=$A$12)*COLUMN($A$2:$E$9))+(($A$2:$E$9=$A$13)*COLUMN($A$2:$E$9))+(($A$2:$E$9=$A$14)*COLUMN($A$2:$E$9))+(($A$2:$E$9=$A$15)*COLUMN($A$2:$E$9)))),,)<>0),COLUMN($A$2:$E$9))),"")}

The formula generated: 4 *This formula is not a solution to original problem and will only work under specific instances to solve a specific problem. I will explain more in an answer below. *This formula is not a solution to original problem and will only work under specific instances to solve a specific problem. I will explain more in an answer below.

Possible relevant links to other answers?:

Ref: can-match-function-in-an-array-formula-to-return-multiple-matches

Ref: excel-match-multiple-criteria

Ref: match-function-to-match-multiple-values

Ref: excel-modal-value-in-list-with-if-function

Ref: how-do-you-extract-a-subarray-from-an-array-in-a-worksheet-function

Ref: can-excels-index-function-return-array

Edit: For our purposes @EEM solution is currently the easiest to implement, validate, and maintain. Thanks for all responses. For our purposes @EEM solution is currently the easiest to implement, validate, and maintain. Thanks for all responses.

In Office 365 we can acheive this with some array formulae, combined with the IFS statement (here the data are in A1:C9, and the array is in H1:K1):

=IFS(MIN(--COUNTIFS(A1:A9,H1:K1)),"Col1",
MIN(--COUNTIFS(B1:B9,H1:K1)),"Col2",
MIN(--COUNTIFS(C1:C9,H1:K1)),"Col3",
MIN(--COUNTIFS(D1:D9,H1:K1)),"Col4",
MIN(--COUNTIFS(E1:E9,H1:K1)),"Col5",
TRUE, "None")

The way this works is by computing the COUNTIFS for the first column, then turning that to a boolean (0 or 1), and finding the minimum value to check they are all present. If not then it checks the second column and so on.

Kind Regards

MTwem

I'm close, but am not sure how to filter out non-matches.

Use tables to make the formulas easier and to name the data table range.

  1. Highlight all of your data table including the header row, and Insert - Table .
  2. If your cursor is in the table then you should see a new "Table" tab on your ribbon. Use that to name the table "DataTable".
  3. Do the same to your row of values in "ValuesList".
  4. Now you'll have to create a new table with the same column titles as ValuesList, plus an additional column called "MatchCols". Just do one row for now Name it "ResultsTable".
  5. Assuming that the first column title of your new "ResultsTable" table is "val1", the data cell for that column should be: =MATCH(OFFSET(ValuesList,0,COLUMN()-Column(ResultsTable),1,1),OFFSET(DataTable,0,ROW()-ROW([val1]),ROWS(DataTable),1),0)
  6. Drag-copy that formula to the data cells for val2 through val6. (You should see values of 2, 1, #N/A, and 3.
  7. Add a new column by simply typing this formula in the cell on the ResultsTable data row that is immediately to the right of the last column: =IF(ISNA(SUM(ResultsTable[@[val1]:[val4]])),"",ROW()-ROW(ResultsTable)+1)
  8. Replace the auto-created column header value with "MatchCols" to name your column.
  9. Drag-copy that table down, to make it larger, for at least as many rows as you have columns in your table. If you add columns to your table, no problem, just add rows in ResultsTable.

Okay, so now ResultsTable[MatchCols] is an array, one value per column, where each value is either "" if that column isn't a perfect match, or the column number if it does contain all values in ValuesList, In your example, ResultsTable[MatchCols] should be {"","","",4,"","","",""}

For others, @suntech1 tried this and contributed an image of it. 对于其他人,@suntech1 尝试了这个并提供了它的图像。*

If you have a variable number of values to match against, that's fine but you'll need to create enough columns in your table. The column names don't have to match between ValuesList and ResultsTable. (In fact, ValuesList could just be an array rather than a table.) Also, you could change the MatchCols column formula to be sensitive to COUNT(ValuesList) so that it threw an error if ResultsTable didn't have enough columns, and ignored extra columns if ResultsTable had too many columns.

You mentioned a list of values to match against. If you need to match against an arbitrary number of value lists then... well... you should have mentioned that in your question. :-P

What this doesn't give you is what you asked for because DataTable[MatchCols] is what you asked for interspersed with "" values in the array.

Does this get you close enough?

Does anyone have ideas on how in Excel 2010 to take the array DataTable[MatchCols] , which is numbers and "" , and filter out the empty strings so that it returns only numbers?

This solution uses helping cells and the TEXTJOIN function .

Assuming that the Data and the list of values are located at [D2:H10] and [B13:B17] respectively.

This formula validates the presence of the values in each column, enter in D14 and copy to [D14:H17] :

= IFERROR( MATCH( $B14, D$3:D$10, 0 )^0, "" )

在此处输入图像描述

This formula validates the columns with presence of all values, enter in D18 and copy to [D18:H18] :

= IF( SUM(D14:D17)=COUNT($B$14:$B$17), COLUMNS($D$18:D$18), "" )

在此处输入图像描述

This formula consolidates the results of the columns, enter in [D20]

= TEXTJOIN( ",",TRUE, $D$18:$H$18 )

在此处输入图像描述

This method only returns the columns that contain at least one time each of the values in the List.

在此处输入图像描述

EDIT - FormulaArray that combines 1st and 2nd formula

This FormulaArray validates the presence of the values in each column and returns the column with presence of all values, enter in D18 and copy to [D18:H18] :

= IF( SUM( IFERROR( MATCH( $B$14:$B$17, D$3:D$10, 0 )^0, 0 ) )
 = COUNT($B$14:$B$17), COLUMNS($D$18:N$18), "" )

FormulaArray are entered holding down ctrl + shift + enter simultaneously, the formula would be wrapped within { and } if entered correctly.

在此处输入图像描述

EDIT - Excel 2010 formula to show only the columns that comply with criteria (each column in a separated cell)

Enter this formula in [D22] then copy to [E22:N22] :

= IFERROR( INDEX( $D$18:$N$18,
 AGGREGATE( 15, 6, COLUMN($18:$18) / ( $D$18:$N$18 <> "" ),
 COLUMNS($D$18:D$18) ) ), TEXT(,) )

在此处输入图像描述

This is not the solution I was looking for, but this solution might help someone else or might lead others to provide a solution for the original question. I discovered through trial and error while researching.

Formula: {=IFERROR(MODE.MULT(IF((INDEX((((($A$2:$E$9=$A$12)*COLUMN($A$2:$E$9))+(($A$2:$E$9=$A$13)*COLUMN($A$2:$E$9))+(($A$2:$E$9=$A$14)*COLUMN($A$2:$E$9))+(($A$2:$E$9=$A$15)*COLUMN($A$2:$E$9)))),,)<>0),COLUMN($A$2:$E$9))),"")}

The formula generated: 4 *Formula works under certain instances.

Caveats:

1: Need unique values in columns for this solution (no duplicates in columns).

2: This formula provides column positions that has the max modal matches (partial list matches & complete list matches can result per column).

Under testing this meant that partial matches per column resulted if those column(s) matched the max match per column.

3: If duplicates in columns this can result in the duplicate values being counted towards the max match per column.

So if have [4,2,2,2] in a column and have [2,4] as your list, then that column will result in 4 matches. So if your use case desires that results then this might work for you.

If others can explain why this works or come up with solutions that fits original question please do so.

Thanks, Suntech1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM