簡體   English   中英

在 excel 的單元格范圍內查找字母數字值

[英]Lookup an alphanumeric value in a range of a cell in excel

我正在尋求有關 excel 問題的幫助。

我有一組與不同值相關的字母數字范圍內的數據。 在一列中,有數值。 在下一列中,有字母數字范圍。 例如 WA001-WA010。

數據表示例在這里

我要做的是返回與我正在查找的字母數字相關的數字。 但是,該數據范圍內的某些字母數字是不可見的。 例如,如果我要查找“WA020”,它應該返回值 2。我正在研究 arrays 的行和間接函數,但這似乎並不是我想要的。

現在存在這樣的 function。 顯示的公式:

查找公式

結果:

成功的結果

要在不編輯單元格內容的情況下解決此問題,您實際上被迫做的是使用兩個向量(一個索引和一個值)構建一個數據集,然后查詢它以獲取您想要的內容到達一個索引。 這種情況下的數據集是一個非常參差不齊的 collections 數組 collections collections 的數組,至少,我會這樣做。 為了保持思路清晰,我為模塊制作了一個准對象 model:

准 Object Model

在上述照片中,Collection Item 鍵位於大括號中。

因此,如果您想實現此 function,請將其放入您的數據所在的任何工作簿中的代碼模塊中。

快速免責聲明 - 以下代碼不是特別優雅或高效,但它確實完成了任務。

Option Explicit

' I'm not a fan of 0-based indexing in VBA, so this fixes it for me.
' You could go without, and doing so could be a good academic
' excercise on utilizing VBA for data management.
Private Function ChangeIndex(StrIn() As String) As String()

    Dim i As Integer
    Dim temp() As String

    ReDim temp(1 To UBound(StrIn) + 1)
    For i = 1 To UBound(StrIn) + 1
        temp(i) = StrIn(i - 1)
    Next i

    ChangeIndex = temp

End Function

'Finds index of first numeric character in string
Private Function FindNumeric(ByVal StrIn As String) As Integer

    Dim i As Integer

    For i = 1 To Len(StrIn)
        If IsNumeric(Mid(StrIn, i, 1)) Then
            FindNumeric = i
            Exit Function
        End If
    Next i
End Function

'Finds numeric components of textual range
Private Function FindRange(ByVal StrIn As String) As Integer()

    Dim answer(1 To 2) As Integer
    Dim num_pos As Integer
    Dim dash_pos As Integer
    Dim temp As String
    Dim temp_two As String

    dash_pos = InStr(1, StrIn, "-", vbBinaryCompare)
    If dash_pos <> 0 Then
        num_pos = FindNumeric(StrIn)
        temp = Mid(StrIn, num_pos, Len(StrIn) - dash_pos - num_pos + 1)
        answer(1) = CInt(temp)
        temp = Mid(StrIn, dash_pos + 1, Len(StrIn) - dash_pos + 1)
        num_pos = FindNumeric(temp) + dash_pos
        temp = Mid(StrIn, num_pos, Len(StrIn) - dash_pos - (Len(StrIn) - num_pos))
        answer(2) = CInt(temp)
    Else
        num_pos = FindNumeric(StrIn)
        temp = Mid(StrIn, num_pos, Len(StrIn) - dash_pos - num_pos + 1)
        answer(1) = CInt(temp)
        answer(2) = answer(1)
    End If

    FindRange = answer

End Function

Public Function AlphaNumLU(Query As String, IndexVector As range, ValueVector As range) As Variant

    Dim csvs() As String
    Dim entries() As Collection
    Dim alpha As Collection
    Dim numeric As Collection
    Dim temp As String
    Dim q_alpha As String
    Dim q_num As Integer

    Dim entry As Variant
    Dim raw_val As Variant
    Dim i, j As Integer
    Dim range() As Integer
    Dim alpha_found As Boolean

    'The bare minimum error handling
    If IndexVector.count <> ValueVector.count Then
        MsgBox Prompt:="Input vectors must be of same length"
        AlphaNumLU = "#VALUE"
        Exit Function
    End If

    'Import Indexes to collection of entries
    ReDim entries(1 To IndexVector.count)
    For i = 1 To IndexVector.count
        Set entries(i) = New Collection
        temp = IndexVector(i, 1).Value
        entries(i).Add Item:="Entry", Key:="Label"
        entries(i).Add Item:=temp, Key:="Index"
    Next i

    'Import Values as Comma Delineated arrays of string
    For i = 1 To ValueVector.count
        temp = ValueVector(i, 1).Value
        csvs = Split(temp, ",")
        csvs = ChangeIndex(csvs)
        entries(i).Add csvs, "RawVals"
    Next i

    'Construct Textual Components
    For Each entry In entries
        For Each raw_val In entry(3)
            i = FindNumeric(raw_val) - 1
            temp = Mid(raw_val, 1, i)
            If entry.count < 3 Then
                MsgBox "Entry should be composed of items Label, Index, alpha..."
                Exit Function
            ElseIf entry.count = 3 Then
                Set alpha = New Collection
                alpha.Add Item:="text comp", Key:="Label"
                alpha.Add Item:=temp, Key:="Index"
                entry.Add alpha
            Else
                alpha_found = False
                For i = 4 To entry.count
                    If entry(i)(2) = temp Then
                        alpha_found = True
                        Exit For
                    End If
                Next i
                If Not alpha_found Then
                    Set alpha = New Collection
                    alpha.Add Item:="text comp", Key:="Label"
                    alpha.Add Item:=temp, Key:="Value"
                    entry.Add alpha
                End If
            End If
        Next raw_val
    Next entry

    'Construct Numerical Components
    For Each entry In entries
        For Each raw_val In entry(3)
            Set numeric = New Collection
            numeric.Add Item:="numeric", Key:="Label"
            range = FindRange(raw_val)
            numeric.Add Item:=range(1), Key:="Min"
            numeric.Add Item:=range(2), Key:="Max"
            temp = Left(raw_val, FindNumeric(raw_val) - 1)
            For i = 4 To entry.count
                If entry(i)(2) = temp Then
                    entry(i).Add numeric
                End If
            Next i
        Next raw_val
    Next entry


    'And Finally, Parse the Massive object we just created for the query.
    q_alpha = Left(Query, FindNumeric(Query) - 1)
    q_num = CInt(Right(Query, Len(Query) - Len(q_alpha)))
    For Each entry In entries
        For i = 4 To entry.count
            If q_alpha = entry(i)(2) Then
                For j = 3 To entry(i).count
                    If q_num >= entry(i)(j)(2) And q_num <= entry(i)(j)(3) Then
                        AlphaNumLU = entry(2)
                        Exit Function
                    End If
                Next j
            End If
        Next i
    Next entry

    'Give notice if the value doesn't exist
    AlphaNumLU = "Not Found"
 End Function

所以這個故事的寓意是——修改數據呈現給查找 function 的方式可能更明智,正如@teylyn 所提到的。 VBA 可以完成,但不一定漂亮。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM