在excel中的单元格范围内查找字母数字值

在excel中的单元格范围内查找字母数字值,excel,vba,excel-formula,alphanumeric,Excel,Vba,Excel Formula,Alphanumeric,我正在寻找有关excel问题的帮助 我有一组与不同值关联的字母数字范围的数据。在一列中,有数值。在下一列中,有字母数字范围。例如WA001-WA010 我要做的是返回与我正在查找的字母数字相关联的数字。但是,在该数据范围中存在某些不可见的字母数字。例如,如果我要查找'WA020',它应该返回值2。我在研究数组的行和间接函数,但这似乎不是我真正想要的 这样的函数现在已经存在。公式如下: 结果是: 要在不编辑单元格内容的情况下解决此问题,您实际上必须使用两个向量(一个是索引,一个是值)构建一个

我正在寻找有关excel问题的帮助

我有一组与不同值关联的字母数字范围的数据。在一列中,有数值。在下一列中,有字母数字范围。例如WA001-WA010


我要做的是返回与我正在查找的字母数字相关联的数字。但是,在该数据范围中存在某些不可见的字母数字。例如,如果我要查找'WA020',它应该返回值2。我在研究数组的行和间接函数,但这似乎不是我真正想要的

这样的函数现在已经存在。公式如下:

结果是:

要在不编辑单元格内容的情况下解决此问题,您实际上必须使用两个向量(一个是索引,一个是值)构建一个数据集,然后查询它以获得索引。这个场景中的数据集是一个非常参差不齐的集合集合数组,至少我是这样做的。为了保持思路清晰,我为模块制作了一个准对象模型:

在这张照片中,收藏物品的钥匙放在大括号里

所以,如果您想实现这个函数,可以将它放入数据所在工作簿中的代码模块中

一个快速的免责声明-下面的代码不是特别优雅或高效,但它确实完成了任务

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
选项显式
我不喜欢VBA中基于0的索引,所以这为我解决了这个问题。
“你可以不去,这样做可能是一个很好的学术成就
“练习使用VBA进行数据管理。
私有函数ChangeIndex(StrIn()作为字符串)作为字符串()
作为整数的Dim i
作为字符串的Dim temp()
重拨温度(1至UBound(StrIn)+1)
对于i=1至UBound(StrIn)+1
温度(i)=StrIn(i-1)
接下来我
ChangeIndex=temp
端函数
'查找字符串中第一个数字字符的索引
私有函数FindNumeric(ByVal StrIn作为字符串)作为整数
作为整数的Dim i
对于i=1到Len(StrIn)
如果是数字(中间(StrIn,i,1)),则
FindNumeric=i
退出功能
如果结束
接下来我
端函数
'查找文本范围的数字组件
私有函数FindRange(ByVal StrIn作为字符串)作为整数()
将答案(1到2)变暗为整数
Dim num_pos为整数
Dim dash_pos作为整数
作为字符串的Dim temp
Dim temp_2作为字符串
破折号位置=仪表(1,StrIn,“-”,vbBinaryCompare)
如果破折号位置为0,则
num_pos=FindNumeric(StrIn)
温度=中间(条纹、数字位置、透镜(条纹)-划线位置-数字位置+1)
答案(1)=辛特(温度)
温度=中间(条纹、条纹位置+1、透镜(条纹)-条纹位置+1)
数值位置=FindNumeric(temp)+破折号位置
温度=中间(条纹、数字位置、透镜(条纹)-虚线位置-(透镜(条纹)-数字位置))
答案(2)=辛特(温度)
其他的
num_pos=FindNumeric(StrIn)
温度=中间(条纹、数字位置、透镜(条纹)-划线位置-数字位置+1)
答案(1)=辛特(温度)
答案(2)=答案(1)
如果结束
FindRange=答案
端函数
公共函数AlphaNumLU(查询作为字符串,IndexVector作为范围,ValueVector作为范围)作为变量
Dim csvs()作为字符串
Dim entries()作为集合
Dim alpha作为集合
将数字作为集合
作为字符串的Dim temp
Dim q_alpha作为字符串
Dim q_num为整数
作为变体的Dim条目
变暗原始值作为变量
作为整数的Dim i,j
Dim range()为整数
Dim alpha_被发现为布尔值
'最小错误处理
如果IndexVector.count ValueVector.count,则
MsgBox提示符:=“输入向量必须具有相同的长度”
AlphaNumLU=“#值”
退出功能
如果结束
'将索引导入项集合
ReDim条目(1到IndexVector.count)
对于i=1到IndexVector.count
集合项目(i)=新集合
温度=指数向量(i,1)。值
条目(i).添加条目:=“条目”,键:=“标签”
条目(i).添加项:=临时,项:=索引
接下来我
'将值作为逗号分隔的字符串数组导入
对于i=1到ValueVector.count
温度=值向量(i,1)。值
csvs=拆分(温度,“”)
csvs=变更索引(csvs)
条目(i).添加CSV,“RawVals”
接下来我
'构造文本组件
对于条目中的每个条目
对于条目(3)中的每个原始值
i=FindNumeric(原始值)-1
温度=中间(原始值,1,i)
如果entry.count小于3,则
MsgBox“条目应包括项目标签、索引、alpha…”
退出功能
ElseIf entry.count=3然后
Set alpha=新集合
alpha.添加项:=“文本合成”,键:=“标签”
alpha.添加项:=临时,键:=“索引”
条目。添加alpha
其他的
alpha_found=False
对于i=4到entry.count
如果条目(i)(2)=温度,则
alpha_found=True
退出
如果结束
接下来我
如果没有找到alpha_,那么
Set alpha=新集合
alpha.添加项:=“文本合成”,键:=“标签”
alpha.添加项:=临时,键:=“值”
条目。添加alpha
如果结束
如果结束
下一个原始值
下一个条目
'构造数字组件
对于条目中的每个条目
对于条目(3)中的每个原始值
Set numeric=新集合
数字。添加项:=“数字”,键:=“标签”
范围=FindRange(原始值)
数字。添加项:=范围(1),键:=最小值
数字。添加项:=范围(2),键:=“最大”
温度=左侧(原始值,FindNumeric(原始值)-1)
对于i=4到entry.count