简体   繁体   中英

Excel: using vlookup but with wildcards in the array

I have a list of values in a column on one sheet. On another sheet I have two columns. One is a list of wildcards, and the other is another list of values. Next to the column on the first sheet, I want an additional column to contain a formula that will check the value in the first column against the wildcards in the second sheet. If a match is found, it should display the value next to that wildcard.

Is there any way to do this? Been at it for hours and I can't get it to work.

Thanks in advance.

Some sample data:

Sheet One

Column A

randomunnecessarydataUSEFULTHINGS123INFOmoregarbage

morerandomstuffIMPORTANT456junkjunkjunk

IMPORTANT456lotsofmorejunk

morejunkUSEFULTHINGS789INFOgarbage

Column B

<some formula>

<some formula>

"

"

etc.

Sheet Two

Column A

*usefulthings???INFO*

*important456*

Column B

Useful Things - Info

Important 456

I want <some formula> to check the value in sheet 1 column A next to it against the table in Sheet 2. If one of the wildcard in sheet 2 column A match, the cell containing the formula should display what's in Sheet 2 column B.

If I got you right you want something like this (in B1 and then copy down):

=IF(MIN(IFERROR(MATCH(Sheet2!$A$1:$A$100,A1,0)*ROW($1:$100),FALSE)),INDEX(Sheet2!B:B,MIN(IFERROR(MATCH(Sheet2!$A$1:$A$100,A1,0)*ROW($1:$100),FALSE))),"")

This is an array formula and must be confirmed with ctrl + shift + enter .

在此输入图像描述
Left is sheet 1 with the lookup term and right is sheet2 with the wildcard-list and the values.

EDIT
To auto-range it simply use this formula:

=IF(MIN(IFERROR(MATCH(Sheet2!$A$1:INDEX(Sheet2!A:A,MATCH("zzz",Sheet2!A:A)),A1,0)*ROW(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A))),FALSE)),INDEX(Sheet2!B:B,MIN(IFERROR(MATCH(Sheet2!$A$1:INDEX(Sheet2!A:A,MATCH("zzz",Sheet2!A:A)),A1,0)*ROW(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A))),FALSE))),"")

And yes, only the first value will be outputted... if you want to get multiple values, you could use this formula (as always in B1 and then copy down and this time also to the left):

*² =IFERROR(IF(SMALL(IFERROR(MATCH(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A)),$A1,0)*ROW(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A))),FALSE),COLUMN()-1),INDEX(Sheet2!$B:$B,SMALL(IFERROR(MATCH(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A)),$A1,0)*ROW(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A))),FALSE),COLUMN()-1)),""),"")

But keep in mind that all the formulas will slow down your excel the more cells use them (the last one the most). If your list is pretty long, I suggest a UDF.

EDIT 2

To speed it a bit up again you can use this formula for C1 (copy down / right) (just use the last formula only for column B):

=IF(B1="","",IFERROR(IF(SMALL(IFERROR(MATCH(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A)),$A1,0)*ROW(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A))),FALSE),COLUMN()-1),INDEX(Sheet2!$B:$B,SMALL(IFERROR(MATCH(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A)),$A1,0)*ROW(Sheet2!$A$1:INDEX(Sheet2!$A:$A,MATCH("zzz",Sheet2!$A:$A))),FALSE),COLUMN()-1)),""),""))

Also keep in mind that all formulas are array-formulas ;)

*² If using the first EDIT formula for column B and the EDIT 2 formula for column C+ you do not need the second EDIT formula.

EDIT 3

For the UDF-way go to your VBA-editor (hit alt + F11 ) and there "Insert" -> "Module". Then put in the code window for this module:

Option Explicit

Public Function getLikeLookup(str As String, rng As Range, Optional nCou As Long, Optional outCol As Range) As String

  'for not case sensitive
  str = LCase(str)

  'set ranges
  If nCou < 1 Then nCou = 1
  If outCol Is Nothing Then Set outCol = rng.Offset(, rng.Columns.Count - 1).Resize(, 1)
  Set rng = Intersect(rng.Resize(, 1), rng.Parent.UsedRange.EntireRow)
  Set outCol = Intersect(outCol.Resize(, 1), outCol.Parent.UsedRange.EntireRow)

  'get check-array (will be faster than running the sheet directly)
  Dim inArr As Variant
  inArr = rng.Value

  'run checks
  Dim i As Long
  For i = 1 To UBound(inArr)
    'If str Like inArr(i, 1) Then nCou = nCou - 1
    If str Like LCase(inArr(i, 1)) Then nCou = nCou - 1 'for not case sensitive
    If nCou = 0 Then Exit For
  Next

  'check for valid output
  If i > UBound(inArr) Or i > outCol.Rows.Count Then Exit Function

  'set output
  getLikeLookup = outCol.Offset(i - 1).Resize(1, 1).Value

End Function

Now you are able to use your UDF like other worksheet functions. To explain this in detail.

getLikeLookup(lookup_string,lookup_range,[#_occurrence,[output_range]])
  • lookup_string : the string you want to check against (the whole string, does not work with placeholder)

  • lookup_range : the leftmost column in this range will be checked to be like lookup_string . If output_range is omitted then the rightmost column in lookup_range will be used for the output.

  • #_occurrence : [optional] Indicates which match to output. If omitted (like 1) than the first one will be picked.

  • output_range : [optional] the first column in output_range will be used for the output.

Now for the example you can use (starting in B1):

=getLikeLookup($A1,Sheet2!$A:$B,COLUMN()-1)

And to speed it up a bit use(still starting in B1):

=IF(A1="","",getLikeLookup($A1,Sheet2!$A:$B,COLUMN()-1))

This 2 formulas are no arrays and can be confirmed by just hitting enter .

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