2016-08-08 12 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

2つのループは必要ありません。チェックのための値を取得するためのループが1つだけあります。もし 'If Application.WorksheetFunction.CountIf(cdRangeToCheck、" Value to check ")> 0 Then' –

+0

もう一つのオプションは 'Scripting.Dictionary' 。 – Comintern

答えて

0

私は障害が次の行にあると思う:私は2番目の1がnewDataをポイントする必要がありながら、これは第一Cells発生の正しいだと思いながら、両方のCells参照がcurrentDataを指す

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

これは、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

関連する問題