Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 基于其他表格填充单元格_Vba_Excel - Fatal编程技术网

Vba 基于其他表格填充单元格

Vba 基于其他表格填充单元格,vba,excel,Vba,Excel,我试图在Excel文件中自动执行某些功能 这是我的问题: 表1包含一个字符串,即“Info”列,后跟两个空单元格。对于表1中的每一行,我想检查表1的“Info”列中是否存在表2的“Fruit”列的值。如果是这样,我想在表1的空白单元格中填写表2的“颜色”和“价格” 例如,第二行包含“香蕉”一词,这意味着“颜色”“黄色”和“价格”“15”应填写在表1第2行的相同列中 不知何故,这个问题对我来说似乎很简单,但当我开始思考如何实现它时,我陷入了困境。所以很不幸,我没有任何代码可以修复。我只是希望这个

我试图在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
,我们继续前进

请注意,如果没有