【问题标题】:Copy data Using Vba, Match function使用 Vba 复制数据,Match 功能
【发布时间】:2017-04-10 01:40:01
【问题描述】:

我是一名新程序员。 只是 vba 的初学者,希望得到一些帮助来解决这个问题。 我知道我可以使用普通的 excel 公式,但这是为了学习。 到目前为止,这是我的代码:

Sub matchpart()
Dim ocell As Range
Dim swb As Workbook
Dim sws As Worksheet, dws As Worksheet
Dim stext As String
Dim iRow As Long
Dim nxtRow As Long


Set swb = ActiveWorkbook
Set sws = swb.Sheets("sheet1")
Set dws = swb.Sheets("sheet2")

For Each ocell In dws.Range("FILE_NAMES")
    stext = Left(ocell.Value, 12)
On Error Resume Next
iRow = Application.WorksheetFunction.Match(stext, sws.Range("ID_NUMBER"), 0)
On Error GoTo 0
    If iRow > 0 Then
       Application.Index (Range("ID_PARENT").Copy)
    Else
        ocell.Offset(0, 1) = ""
        End If
        Next

MsgBox ("Done")
End Sub

我的任务是将工作表 2 (ID_NUMBER) 中的 1 列与工作表 1 (FILE_NAMES) 的 1 列相匹配。在此之后复制工作表 1 下一列中的相应值(已匹配)并将其粘贴到工作表 2 的下一列中。

这是我的数据,例如 表 1:

ID_PARENT     ID_NUMBER 
pan               3
same              2
kappa             1
lame              5
dame              5

sheet 2:

FILE_NAMES      BPM_LIST
1                   
5
3
2
4
5

因此想使用我的代码匹配并复制到 BPM_LIST。

【问题讨论】:

  • 我强烈建议你 read this 在它咬你之前。另外..到底是什么问题? “请帮我完成我的代码”?

标签: vba excel match


【解决方案1】:

不要使用Application.WorksheetFunction.Match(...);使用Application.Match(...) 并将返回值传递回一个变体。这将允许您与IsError(...) 联系。

此外,(就像在工作表上使用 MATCH 一样),您无法使用 text-that-looks-like-a-number 找到数字;例如1 <> "1"。我不知道您的数据实际上是什么样的(真实数字或看起来像数字的文本),但您可能必须在匹配中使用 Int(stext) 而不是 stext

dim iRow  as variant
For Each ocell In dws.Range("FILE_NAMES")
    stext = Left(ocell.Value, 12)
    iRow = Application.Match(stext, sws.Range("ID_NUMBER"), 0)
    If IsError(iRow) Then
        ocell.Offset(0, 1) = vbnullstring
    Else
       ocell.Offset(0, 1) = Range("ID_PARENT").Cells(iRow, 1).Value
    End If
Next ocell 

【讨论】:

  • 嗨,感谢您的重播,是的,您的代码对我帮助很大 :) 是另一种方法,看起来也更简单!
【解决方案2】:

您希望学习和学习代码。这里是。我没有太在意它是否也能做你想要的,因为我认为你可以按照你希望它弯曲的方向调整我的代码。玩得开心!

Sub matchpart()
    ' 10 Apr 2017

    Dim Wb As Workbook
    Dim WsSrc As Worksheet                  ' Identify the sheet as Source
    Dim WsTgt As Worksheet                  ' Identify the sheet as Target
    Dim sText As String
    Dim R As Long, lastRow As Long          ' last row in WsTgt
    Dim iRow As Long                        ' why do you call "Found row" iRow?

    Set Wb = ActiveWorkbook                 ' actually, this is the default
    With Wb                                 ' declaring it just reminds you of the fact
        Set WsSrc = .Sheets("IDs")
        Set WsTgt = .Sheets("File Names")   ' I used my own names for testing
    End With

    With WsTgt
        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        ' most programmers prefer to call the columns by their numbers
        ' instead of their names (like "A") as I have done here.
        ' VBA must convert the names to numbers.
        ' Therefore using numbers to begin with is faster.
        ' You can change all names to numbers in this code
        ' Just replace "A" with 1, "B" with 2 etc.

        For R = 2 To lastRow                ' omit row 1 (captions)
            sText = .Cells(R, "A").Value    ' can't use partial with MATCH function
            On Error Resume Next
            iRow = WorksheetFunction.Match(sText, WsSrc.Columns("B"), 0)
            If Err.Number = 0 Then
                .Cells(R, "B").Value = WsSrc.Cells(iRow, "A").Value
            End If
            Err.Clear
        Next R
    End With

    MsgBox ("Done")
End Sub

我的代码偏离您的意图的地方是您想要“部分匹配”。使用 MATCH 工作表功能无法实现这一点。您需要为此使用 VBA 的 Find 。但这最好改天再上一课,哈哈:

【讨论】:

  • 哦,是的,部分匹配正是我想要的。感谢您的代码似乎是我的一种更合理的方式:)
  • 这里解释了 find 方法的语法。 msdn.microsoft.com/en-us/library/office/ff839746.aspx 它返回一个范围对象或 Nothing。所以你测试 Nothing 而不是 Err.Number (不需要错误捕获)。如果找到匹配范围,则可以使用其 Value 属性来获取部分的整体。
  • 所以你说使用所谓的“部分匹配”,要走的路是使用查找功能?
  • 是的。只需将 MATCH 函数周围的结构替换为 Find 方法所需的结构即可。将找到的范围的 Row 属性作为您的 iRow 并从那里继续您之前的代码。
  • 哦,好的,谢谢你 :) 试过了,更容易了。感谢您的帮助和您的时间:)
【解决方案3】:

您好,很抱歉占用您的时间。 我找到了解决问题的方法。 这只是使用索引函数,因为我已经得到了匹配的行号,即 iRow。

Sub matchpart()
Dim ocell As Range
Dim ocells As Range
Dim swb As Workbook
Dim sws As Worksheet, dws As Worksheet
Dim stext As String
Dim iRow As Long
Dim nxtRow As Long


Set swb = ActiveWorkbook
Set sws = swb.Sheets("sheet1")
Set dws = swb.Sheets("sheet2")

For Each ocell In dws.Range("FILE_NAMES")
    stext = Left(ocell.Value, 12)
On Error Resume Next
iRow = Application.WorksheetFunction.Match(stext, sws.Range("ID_NUMBER"), 0)
On Error GoTo 0
    If iRow > 0 Then
       ocell.Offset(0, 1) = WorksheetFunction.Index(sws.Range("ID_PARENT"), iRow, 0)

    Else
        ocell.Offset(0, 1) = ""
        End If
        Next

MsgBox ("Done")
End Sub

无论如何感谢您的帮助:)

【讨论】:

  • 很高兴您找到了解决方案。仍然花点时间阅读 Jeeded 的答案,其中包含合理且有价值的建议。你需要阅读和理解this
  • 是的,我做到了,我明白了。我给出的解决方案是另一个程序的子程序,因此我现在更有可能使用它。但我确实同意 Jeeded 的回答要好得多,也更有意义,因此感谢他的建议。我还阅读了您显示的链接并理解我的错误。感谢所有的帮助。
  • 您可以通过单击他答案旁边投票按钮下的小空心复选标记来感谢他。如果您不确定整个 Stack Exchange 的工作原理,请使用 tour ;-)
猜你喜欢
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2016-09-21
相关资源
最近更新 更多