Vba 基于其他表格填充单元格
我试图在Excel文件中自动执行某些功能 这是我的问题: 表1包含一个字符串,即“Info”列,后跟两个空单元格。对于表1中的每一行,我想检查表1的“Info”列中是否存在表2的“Fruit”列的值。如果是这样,我想在表1的空白单元格中填写表2的“颜色”和“价格” 例如,第二行包含“香蕉”一词,这意味着“颜色”“黄色”和“价格”“15”应填写在表1第2行的相同列中 不知何故,这个问题对我来说似乎很简单,但当我开始思考如何实现它时,我陷入了困境。所以很不幸,我没有任何代码可以修复。我只是希望这个问题不要太模糊Vba 基于其他表格填充单元格,vba,excel,Vba,Excel,我试图在Excel文件中自动执行某些功能 这是我的问题: 表1包含一个字符串,即“Info”列,后跟两个空单元格。对于表1中的每一行,我想检查表1的“Info”列中是否存在表2的“Fruit”列的值。如果是这样,我想在表1的空白单元格中填写表2的“颜色”和“价格” 例如,第二行包含“香蕉”一词,这意味着“颜色”“黄色”和“价格”“15”应填写在表1第2行的相同列中 不知何故,这个问题对我来说似乎很简单,但当我开始思考如何实现它时,我陷入了困境。所以很不幸,我没有任何代码可以修复。我只是希望这个
我也尝试过使用公式、匹配和索引来解决这个问题,但我也无法实现这一点。这里有一个函数,它将返回ListObject(表)中找到第一个匹配单词的行
Public Function MatchFruit(ByVal sInfo As String, ByRef rFruit As Range) As Long
Dim vaSplit As Variant
Dim i As Long, j As Long
Dim rFound As Range
Dim sWhat As String
vaSplit = Split(sInfo, Space(1))
For i = LBound(vaSplit) To UBound(vaSplit)
'strip out non-alpha characters
sWhat = vbNullString
For j = 1 To Len(vaSplit(i))
If Asc(Mid(LCase(vaSplit(i)), j, 1)) >= 97 And Asc(Mid(LCase(vaSplit(i)), j, 1)) <= 122 Then
sWhat = sWhat & Mid(vaSplit(i), j, 1)
End If
Next j
'find the word in the range
Set rFound = Nothing
Set rFound = rFruit.Find(sWhat, , xlValues, xlWhole, , , False)
If Not rFound Is Nothing Then 'if it's found
'return the row in the ListObject
MatchFruit = rFound.Row - rFruit.ListObject.HeaderRowRange.Row
'stop looking
Exit For
End If
Next i
End Function
价格也差不多
=INDEX(tblFruit[Price],MatchFruit([@Info],tblFruit[Fruit]))
详细解释
vaSplit
赋值行使用Split
函数将字符串转换为基于分隔符的数组。因为示例数据是句子,所以正常的分隔符是一个空格,用于将其拆分为单词。弦状
This is some line about apples.
转换为数组
vaSplit(1) This
vaSplit(2) is
vaSplit(3) some
vaSplit(4) line
vaSplit(5) about
vaSplit(6) apples.
接下来,For循环遍历数组中的每个元素,看看它是否能在其他列表中找到它。使用函数LBound
和Ubound
(下限和上限),因为我们无法确定数组将包含多少个元素
循环中的第一个操作是除去任何无关字符。为此,我们创建变量sWhat
,并将其设置为nothing。然后我们循环遍历元素中的所有字符,查看是否有字符超出范围a…z
。基本上,任何字母都会被附加到上,而非字母(数字、空格、句点)则不会。最后,sWhat
与当前元素相同,去掉了所有非字母字符。在这个例子中,我们永远不会匹配苹果。
因为周期,所以它被剥离了
一旦我们有了一个好的sWhat
,我们现在使用Find
方法来查看该单词是否存在于rFruit
范围内。如果是这样的话,rFound
就不会是Nothing
,我们继续前进
请注意,如果未找到范围内的单词,则rFound
将为Nothing
,函数将返回零
如果找到该单词,函数将返回它在ListObject
开始的行中找到的行。通过这种方式,函数返回它所在的行,其中列表对象的数据不在工作表上。这在合并到索引
公式中时非常有用。要使公式返回某些内容,请将该内容指定给公式的名称
最后,一旦找到匹配项,
行的出口就会停止查看数组。如果数据中有多个匹配项,它将只返回第一个匹配项
故障排除
您将发现的最可能的错误是,当您希望函数返回行号时,它将返回零。这很可能意味着它在列表中没有找到任何单词
如果您确定两个列表都包含匹配的单词,那么下面是如何对其进行故障排除的:在Set rFound=
行之后,放入Debug.Print
语句
Set rFound = rFruit.Find(sWhat, , xlValues, xlWhole, , , False)
Debug.Print "." & sWhat & "."
If Not rFound Is Nothing Then 'if it's found
这将把sWhat
打印到即时窗口(在VBE中按Ctrl+G键可查看即时窗口)。单词周围的句点是可以看到任何不可打印的字符(如空格)。如果您尝试将.pears.
与pears
匹配,它将不匹配,因为第一个在末尾有一个空格-您可以看到这一点,因为我们在前后都有句点
如果空格有问题,可以先使用sWhat
上的Trim$()
函数来消除空格
使用该Debug.Print
语句,您可能会看到如下结果
.paers.
在这种情况下,您会发现您有一个输入错误。这里有一个函数,它将返回ListObject(表)中找到第一个匹配单词的行
Public Function MatchFruit(ByVal sInfo As String, ByRef rFruit As Range) As Long
Dim vaSplit As Variant
Dim i As Long, j As Long
Dim rFound As Range
Dim sWhat As String
vaSplit = Split(sInfo, Space(1))
For i = LBound(vaSplit) To UBound(vaSplit)
'strip out non-alpha characters
sWhat = vbNullString
For j = 1 To Len(vaSplit(i))
If Asc(Mid(LCase(vaSplit(i)), j, 1)) >= 97 And Asc(Mid(LCase(vaSplit(i)), j, 1)) <= 122 Then
sWhat = sWhat & Mid(vaSplit(i), j, 1)
End If
Next j
'find the word in the range
Set rFound = Nothing
Set rFound = rFruit.Find(sWhat, , xlValues, xlWhole, , , False)
If Not rFound Is Nothing Then 'if it's found
'return the row in the ListObject
MatchFruit = rFound.Row - rFruit.ListObject.HeaderRowRange.Row
'stop looking
Exit For
End If
Next i
End Function
价格也差不多
=INDEX(tblFruit[Price],MatchFruit([@Info],tblFruit[Fruit]))
详细解释
vaSplit
赋值行使用Split
函数将字符串转换为基于分隔符的数组。因为示例数据是句子,所以正常的分隔符是一个空格,用于将其拆分为单词。弦状
This is some line about apples.
转换为数组
vaSplit(1) This
vaSplit(2) is
vaSplit(3) some
vaSplit(4) line
vaSplit(5) about
vaSplit(6) apples.
接下来,For
循环遍历数组中的每个元素,看看它是否能在其他列表中找到它。使用函数LBound
和Ubound
(下限和上限),因为我们无法确定数组将包含多少个元素
循环中的第一个操作是除去任何无关字符。为此,我们创建变量sWhat
,并将其设置为nothing。然后我们循环遍历元素中的所有字符,查看是否有字符超出范围a…z
。基本上,任何字母都会被附加到上,而非字母(数字、空格、句点)则不会。最后,sWhat
与当前元素相同,去掉了所有非字母字符。在这个例子中,我们永远不会匹配苹果。
因为周期,所以它被剥离了
一旦我们有了一个好的sWhat
,我们现在使用Find
方法来查看该单词是否存在于rFruit
范围内。如果是这样的话,rFound
就不会是Nothing
,我们继续前进
请注意,如果没有