2016-08-08 231 views
0

我正嘗試使用新票證數據更新當前工作票證數據的工作簿。我已經爲底部的每個循環嵌套,以檢查票號中的相等性。如果它找到匹配,它應該用新數據更新一些單元格。如果該票不在我的票單列表中,則應該將新票添加到底部。發生的事情是,即使是電子表格中的票據,它也會不斷將newData中的所有票據添加到currentData的底部。我認爲問題最終取決於這些嵌套for循環的邏輯,但我無法弄清楚我做錯了什麼。Excel VBA - 檢查一個範圍內的每個單元格的值是否在另一個範圍內

Sub getNewData() 

Dim newData As Workbook 
Dim ndLastRow As Long 
Dim currentData As Workbook 
Dim cdLastRow As Long 
Dim ndRangeToCheck As Range 
Dim cdRangeToCheck As Range 
Dim ndRow As Long 
Dim cdRow As Long 

Set newData = Workbooks.Open("C:\Users\<user>\Documents\newData.xlsx") 
Set currentData = ThisWorkbook 

' Assign last row and the range to compare for each workbook 
newData.Worksheets("Incident List").Range("A2").Select 
With ActiveSheet 
    ndLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 
End With 
Set ndRangeToCheck = newData.Worksheets("Incident List").Range("A2", Cells(ndLastRow, "A")) 

currentData.Worksheets("Incident List").Activate 
With ActiveSheet 
    cdLastRow = .Cells(.Rows.Count, "B").End(xlUp).Row 
End With 
Set cdRangeToCheck = currentData.Worksheets("Incident List").Range("B2", Cells(cdLastRow, "B")) 

' Iterate through to compare Incident #s between workbooks 
Dim rout As Range 
Dim rin As Range 
Dim match As Boolean 
For Each rout In ndRangeToCheck.Cells 
    match = False 
    For Each rin In cdRangeToCheck.Cells 
     If Cells(rin.Row, rin.Column).Value = Cells(rout.Row, rout.Column).Value Then 
      match = True 
      ndRow = rout.Row 
      cdRow = rin.Row 
      currentData.Worksheets("Incident List").Cells(cdRow, "L").Value = newData.Worksheets("Incident List").Cells(ndRow, "D").Value 
      currentData.Worksheets("Incident List").Cells(cdRow, "O").Value = newData.Worksheets("Incident List").Cells(ndRow, "F").Value 
      currentData.Worksheets("Incident List").Cells(cdRow, "P").Value = newData.Worksheets("Incident List").Cells(ndRow, "G").Value 
      currentData.Worksheets("Incident List").Cells(cdRow, "Q").Value = newData.Worksheets("Incident List").Cells(ndRow, "H").Value 
      currentData.Worksheets("Incident List").Cells(cdRow, "S").Value = newData.Worksheets("Incident List").Cells(ndRow, "L").Value 
      currentData.Worksheets("Incident List").Cells(cdRow, "T").Value = newData.Worksheets("Incident List").Cells(ndRow, "N").Value 
      currentData.Worksheets("Incident List").Rows(rin.Row).Borders.LineStyle = xlContinuous 

      Exit For 
     End If 
    Next rin 

    If match = False Then 
     ndRow = rout.Row 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "B").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "A").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "B").Offset(1, 0).NumberFormat = "0" 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "L").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "D").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "O").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "F").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "P").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "G").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "Q").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "H").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "S").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "L").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "T").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "N").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "F").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "C").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "M").Offset(1, 0).Value = newData.Worksheets("Incident List").Cells(ndRow, "E").Value 
     currentData.Worksheets("Incident List").Cells(cdLastRow, "M").Offset(1, 0).NumberFormat = "m/d/yyyy" 
     currentData.Worksheets("Incident List").Rows(cdLastRow).Offset(1, 0).Borders.LineStyle = xlContinuous 

     ' Reset cdLastRow 
     currentData.Worksheets("Incident List").Activate 
     With ActiveSheet 
      cdLastRow = .Cells(.Rows.Count, "B").End(xlUp).Row 
     End With 
    End If 
Next rout 

newData.Close 
End Sub 
+1

您不需要兩個循環。只需要一個循環來獲取檢查的值,然後您可以使用'If Application.WorksheetFunction.CountIf(cdRangeToCheck,「Value to check」)> 0 Then' –

+0

另一種選擇是將它們簡單地存儲在'Scripting.Dictionary' 。 – Comintern

回答

0

我認爲故障是在下面一行:

If Cells(rin.Row, rin.Column).Value = Cells(rout.Row, rout.Column).Value 

其中兩個Cells引用指向currentData,而我想這是第一次Cells發生正確的,而第二個應該指向newData

這是由於使用Select/Selection和或Activate/ActiveYYY方法/對象是報價容易失去控制了實際引用的工作簿/工作表

你應該使用完全合格的範圍內引用了其母公司的工作簿

除此之外您可以使用Find()方法來避免環路的優勢, ...一些小技巧將代碼縮短一點,如下所示:

Option Explicit 

Sub getNewData() 
    Dim newData As Worksheet, currentData As Worksheet '<--| use just the worksheets since they are what you actually need to work with 
    Dim ndRangeToCheck As Range, cdRangeToCheck As Range '<-- data ranges 
    Dim rout As Range, f As Range '<--| helper ranges 
    Dim cdRow As Long 
    Dim cdAddressStrng As String, ndAddressStrng As String 

    Workbooks.Open "C:\Users\<user>\Documents\newData.xlsx" 
    Set newData = ActiveWorkbook.Worksheets("Incident List") '<--| set just the sheet since it is what you actually need to work with 
    Set currentData = ThisWorkbook.Worksheets("Incident List") '<--| set just the sheet since it is what you actually need to work with 

    ' Assign last row and the range to compare for each workbook 
    With newData 
     Set ndRangeToCheck = .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)) 
    End With 

    With currentData 
     Set cdRangeToCheck = .Range("B2", .Cells(.Rows.Count, "B").End(xlUp)) 
    End With 

    cdAddressStrng = "L|, O|, P|, Q|, S|, T|" 
    ndAddressStrng = "D|, F|, G|, H|, L|, N|" 

    ' Iterate through to compare Incident #s between workbooks 
    For Each rout In ndRangeToCheck 
     Set f = cdRangeToCheck.Find(What:=rout.value, lookat:=xlWhole, LookIn:=xlValues, MatchCase:=False) '<--| look for the "new" value into current data 
     If f Is Nothing Then '<--| if not found... 
      cdRow = currentData.Cells(currentData.Rows.Count, "B").End(xlUp).row + 1 '<--| ...retrieve current data first empty row 
     Else '<--| otherwise... 
      cdRow = f.row '<--| ......retrieve found cell row index 
     End If 
     currentData.Range(Replace(cdAddressStrng, "|", cdRow)).value = newData.Range(Replace(ndAddressStrng, "|", rout.row)).value 
     currentData.Rows(cdRow).Borders.LineStyle = xlContinuous 
    Next rout 

    newData.Parent.Close '<--| close newdata workbook: since newData is a worksheet we need to "climb up" to its parent workbook 
End Sub 
+0

@mdperez:你通過它了嗎? – user3598756

相關問題