创建VBA宏以提取匹配项的数据

时间:2016-12-23 20:02:33

标签: excel data-extraction

我正在寻找有关如何在Excel中构建VBA宏的指导(之前从未创建过),它将在两个单独的Excel文件中查找唯一标识符匹配,然后提取匹配的伴随行数据。

更明白地说:

  1. 我有两个单独的excel文件,每个文件都有一个列,用于显示唯一标识符。

  2. 我希望VBA宏在其中一个文件中找到匹配项,其中唯一标识符与另一个文件中的唯一标识符相同。

  3. 在Excel文件中找到匹配项后,我想提取找到匹配项的特定行的数据。

  4. 理想情况下,我希望将提取的数据放入新的Excel工作表中。

1 个答案:

答案 0 :(得分:1)

这是一个可以引导您做您想做的事情的例子。以下是您必须采取或考虑的步骤:

  • 启用开发人员工具
  • 在VBA中创建模块
  • 将一些常量添加到模块顶部
  • 创建将检查工作簿是否已打开的代码;
  • - 如果不是,请将其打开
  • - 如果工作簿不存在,请创建并打开它
  • 创建将使用上述代码打开一本或多本图书的代码
  • 创建将循环遍历文件1中的行的代码,签入文件2以及找到匹配项的位置写入文件3

在Excel中启用开发者工具

使用这篇文章:https://msdn.microsoft.com/en-us/library/bb608625.aspx

打开第一个文件。然后创建一个模块,如下一个主题所示

创建模块

使用本文并按照它直到第3步 - 创建模块:https://www.ablebits.com/office-addins-blog/2013/12/06/add-run-vba-macro-excel/

创建常量

编写下面的代码来声明文件名和工作表名称的常量。

Const FIRST_FILE_NAME As String = "Book1.xlsx" ' This current file
Const SECOND_FILE_NAME As String = "Book2.xlsx"
Const RESULTANT_FILE_NAME As String = "Result.xlsx"

Const wstFirst As String = "Sheet1" ' Sheet name of first file
Const wstSecond As String = "Sheet1"
Const wstResultant As String = "Sheet1"

创建将检查工作簿是否已打开的代码

将此代码写在常量声明代码

下面
' Check if a workbook is open; if inexistant, create one
Function Isworkbookopen(FileName As String)

    Dim ff As Long, ErrNo As Long
    Dim wkb As Workbook
    Dim nam As String

    wbname = FileName

    On Error Resume Next
    ff = FreeFile()
    Open FileName For Input Lock Read As #ff
    Close ff

    ErrNo = Err

    On Error GoTo 0
    Select Case ErrNo
        Case 0: Isworkbookopen = False
        Case 70: Isworkbookopen = True
        Case 53:
            Workbooks.Add
            ActiveWorkbook.SaveAs FileName:=RESULTANT_FILE_NAME
            Isworkbookopen = False
        Case Else: Error ErrNo
    End Select

End Function

如果文件不存在,请创建一个新文件并报告该文件未打开。我刚刚在VBA macro to copy data from one excel file to another回答中使用了Dan Wagner的代码。其余代码也是对Dan代码的修改。

创建将打开图书的代码

将此代码写在您的其余代码下面。此代码将采用文件名和引用变量。如果工作簿未打开,请将其打开并将其分配给引用变量。你必须自己在ByRef阅读。

' Open a workbook and pass the reference back
Private Sub OpenBook(FileName As String, ByRef wkb As Workbook)
    ret = Isworkbookopen(FileName)
    If ret = False Then
        Set wkb = Workbooks.Open(FileName)
    Else
        Set wkb = Workbooks(FileName)
    End If
End Sub

创建将循环并在结果文件中插入数据的代码

将此代码写在当前代码的底部。此代码将打开所有3本书(第一本书,第二本书以及将粘贴数据的结果书)。逐行读取第一个文件(假设第一个文件是第一个和第二个文件之间的公共字段,则只读取第一个文件)。然后,文件1

Sub copydata()

    Dim wkbFirst As Workbook
    Dim wkbSecond As Workbook
    Dim wkbResultant As Workbook

    ' open all 3 files
    OpenBook FIRST_FILE_NAME, wkbFirst
    OpenBook SECOND_FILE_NAME, wkbSecond
    OpenBook RESULTANT_FILE_NAME, wkbResultant

    Dim First_File_Counter As Integer, Second_File_Counter As Integer, Resultant_File_Counter As Integer
    Dim First_Value As String, Second_Value As String
    Resultant_File_Counter = 1

    ' loop from row 1 to a large number for file #1
    For First_File_Counter = 1 To 10000

        ' get value of A1, then A2 and so on during each loop
        ' if that cell does not have a value, assume that there're no more rows of data
        First_Value = wkbFirst.Worksheets(wstFirst).Range("A" & First_File_Counter).Value
        If IsNull(First_Value) Or Len(Trim(First_Value)) = 0 Then Exit For

        ' loop from row 1 to a large number for file #2
        ' and look up information obtained from file #1 in file #2
        For Second_File_Counter = 1 To 10000
            Second_Value = wkbSecond.Worksheets(wstSecond).Range("A" & Second_File_Counter).Value
            If IsNull(Second_Value) Or Len(Trim(Second_Value)) = 0 Then Exit For

            ' if first file's A1 matches any of the rows in this second file
            ' copy the row from first file into the resultant file
            If First_Value = Second_Value Then
                wkbFirst.Worksheets(wstFirst).Rows(First_File_Counter).EntireRow.Copy
                wkbResultant.Worksheets(wstResultant).Rows(Resultant_File_Counter).Select
                wkbResultant.Worksheets(wstResultant).Paste
                Resultant_File_Counter = Resultant_File_Counter + 1
                Exit For
            End If
        Next
    Next

End Sub

示例

我创建了Book1.xlsx。我有:

    A    B
  ----- --------
1  UID  Name
2   1   John
3   2   Matt
4   3   Katie

Book2.xlsx有

    A    B
  ----- --------
1  UID  Address
2   1   100 2nd St, Chicago
3   3   Lukas Tower, Houston

当我点击任意一行复制码并按F5时,将运行copycode子程序。它将遍历代码,然后生成的文件将如下所示:

    A    B
  ----- --------
1  UID  Name
2   1   John
3   3   Katie

请注意,文件1中的数据转到文件3,但只有文件2中具有匹配UID的那些行。来自文件1的Matt的行没有转到结果文件,因为文件2没有UID 2。

希望这会让你说明。