Excel 宏用新数据更新文件中的行

Excel Macro updating rows in a file with new data

下面的代码运行和执行完美,我只是想添加一些功能。该代码将新行从报告文件导入工作簿文件,我希望它通过行中的每个单元格检查具有新数据的潜在行,而不仅仅是 G 列(包含数字或用逗号分隔的数字),但是在 A2:BQ 范围内。还要更新新找到的单元格,即使该行存在于工作簿中,按列 G 中的数字。还要在工作簿文件中用亮色突出显示新行。最后一件事是在新单元格导入完成后换行。

Sub Weekly_Report()

Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 rows needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report

Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
    
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row

sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next

Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
    MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
    Exit Sub
End If
    
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
    
Dim s As String, rng As Range, m As Long
For iRow = iStartRow To iLastRow
    
    s = CStr(wsReport.Cells(iRow, "G").Value)
    Set rng = wsData.Columns("A:BQ").Find(s)
    
    If rng Is Nothing Then
        m = next_blank_row 'no match - use next blank row and increment
        next_blank_row = next_blank_row + 1
        Debug.Print iRow, s, "New row " & m
    Else
        m = rng.Row
        Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
    End If
    wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value 'Put the new line in Workbook
    
Next
    
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
       " to " & iLastRow, vbInformation, sFilename
wbReport.Close False 'Close the Report

End Sub

由于您似乎坚持比较两个范围:

'Do two ranges contain the same value(s)?
'  does not handle error values...
Function RangesMatch(rng1 As Range, rng2 As Range) As Boolean
    Dim rv As Boolean, v1, v2, r As Long, c As Long
    If rng1.Rows.Count = rng2.Rows.Count And _
       rng1.Columns.Count = rng2.Columns.Count Then
    
        v1 = rng1.Value 
        v2 = rng2.Value
        
        If rng1.Count = 1 Then 
            RangesMatch = (v1 = v2) 'single cell ranges...
        Else
            'multi-cell ranges: loop and compare values
            For r = 1 To UBound(v1, 1)
            For c = 1 To UBound(v1, 2)
                If v1(r, c) <> v2(r, c) Then
                    Exit Function 'by default returns false
                End If
            Next c
            Next r
            RangesMatch = True
        End If
    End If
End Function

这是我的进展:

Sub Weekly_Report()

Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 cells in the row needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report

Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
    
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row

sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next

Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
    MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
    Exit Sub
End If
    
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
    
Dim s As String, rng As Range, m As Long, m2 As String, m3 As String, s2 As String, s3 As String, rng2 As Range, rng3 As Range
For iRow = iStartRow To iLastRow
    
    s = CStr(wsReport.Cells(iRow, "G").Value)
    Set rng = wsData.Columns("G").Find(s)
    s2 = CStr(wsReport.Cells(iRow, "P").Value)
    Set rng2 = wsData.Columns("P").Find(s2)
    s3 = CStr(wsReport.Cells(iRow, "S").Value)
    Set rng3 = wsData.Columns("S").Find(s3)
    
    If rng Is Nothing Then
        m = next_blank_row 'no match - use next blank row and increment
        next_blank_row = next_blank_row + 1
        Debug.Print iRow, s, "New row " & m
    Else
        m = rng.Row
        Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
        m2 = rng2.Row
        m3 = rng3.Row
    End If
    wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
    wsData.Cells(m2, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
    wsData.Cells(m3, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
Next
    
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
       " to " & iLastRow, vbInformation, sFilename
wbReport.Close False 'Close the Report

End Sub

这会更新与 G 列匹配的行的 P 列和 S 列,如果不匹配则添加这些行。

Option Explicit

Sub Weekly_Report()

    Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
    Const NUM_COLS As Long = 69 '69 cells in the row needed to be imported from the Report
    Const FILENAME = "Report.xlsx"
    Const PATH = "C:\Users\Documents\" 'path of the report
    
    Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
    Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
    Dim sFilename As String
        
    Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
    next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
    
    sFilename = PATH & FILENAME
    Debug.Print "Opening ", sFilename 'Openning file
    On Error Resume Next
    
    Set wbReport = Workbooks.Open(sFilename)
    On Error GoTo 0
    If wbReport Is Nothing Then
        MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
        Exit Sub
    End If
        
    Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
    iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
    iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
        
    Dim rng As Range, rng2 As Range, rng3 As Range
    Dim m As Long, m2 As String, m3 As String, s As String, s2 As String, s3 As String, c As Variant
    Dim iAdd As Long, iUpdate As Long
    For iRow = iStartRow To iLastRow
        
        s = CStr(wsReport.Cells(iRow, "G").Value)
        Set rng = wsData.Columns("G").Find(s)
        
        If rng Is Nothing Then
            m = next_blank_row 'no match - use next blank row and increment
            next_blank_row = next_blank_row + 1
            With wsData.Cells(m, 1).Resize(1, NUM_COLS)
                .Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
                .Interior.Color = vbYellow
            End With
            iAdd = iAdd + 1
            Debug.Print iRow, s, "New row " & m
           
        Else
            m = rng.Row
            For Each c In Array("P", "S")
              If wsData.Cells(m, c) <> CStr(wsReport.Cells(iRow, c).Value) Then
                 wsData.Cells(m, c) = CStr(wsReport.Cells(iRow, c).Value)
                 wsData.Cells(m, c).Interior.Color = vbGreen
                 iUpdate = iUpdate + 1
              End If
            Next
            Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
           
        End If
   
    Next
        
    MsgBox wsReport.Name & " scanned from row " & iStartRow & _
           " to " & iLastRow & vbCrLf & "added rows = " & iAdd & vbCrLf & _
           "updated cells = " & iUpdate, vbInformation, sFilename
    wbReport.Close False 'Close the Report

End Sub