2017-04-11 4 views
1

Ich habe ein Hauptblatt mit dem Namen Mainsheet und 12 andere Blätter, eines für jeden Monat.VBA Kopieren und Einfügen von Daten aus Großschot in ein anderes Blatt je nach Datenwert

Meine Mainsheet für die Monate haben Daten von Januar oder Februar oder März kann usw. Ich reflektiert die Daten kopieren müssen in meinem mainsheet und es zu einem der Jan oder Feb Paste je nach welchem ​​Monat sie ist.

Hier ist, was ich bisher ..

Sub Macro1() 

    Dim i, LastRow 
    LastRow = Sheets("Mainsheet").Range("A" & Rows.Count).End(xlUp).Row 

    For i = 5 To LastRow 

     If Sheets("Mainsheet").Cells(i, "E").Value = "1/20/2017" Then 
      Sheets("Mainsheet").Cells(i, "A").EntireRow.Copy 
      Destination:=Sheets("Jan").Range("A" & Rows.Count).End(xlUp).Offset(1) 
     End If 

    Next i 

End Sub 

Meine Frage ist, wie ich weiterhin das Makro, wenn die Daten für den Monat Feb und nicht Jan? Und wie gebe ich nur den Monat Jan an, aber kein bestimmtes Datum wie 20/20/2017 das in meinem Code?

Wie kann ich nur den Bereich von A5:M5 plus die Zeilen bis zur letzten gefüllten Zelle kopieren, anstatt den gesamten Bereich von A:5 bis zur letzten verwendeten Spalte zu kopieren?

Antwort

1

Gut gemacht! Sie haben den Code geschrieben, um ein Monatsblatt zu behandeln!

nun, dass Brocken nehmen, kopieren Sie es - aber anstatt sie unter Einfügen und "Jan" mit "Feb" und so weiter ersetzen ... 12 mal .... dies zu tun:

Private Sub UpdateMonthlyData(ByVal target As Worksheet) 

End Sub 

es dann dort einfügen, und ersetzen Sheets("Jan") durch target. Sie sind mit diesem links:

Private Sub UpdateMonthlyData(ByVal target As Worksheet) 
    Dim i, LastRow 
    LastRow = Sheets("Mainsheet").Range("A" & Rows.Count).End(xlUp).Row 
    For i = 5 To LastRow 
     If Sheets("Mainsheet").Cells(i, "E").Value = "1/20/2017" Then 
      Sheets("Mainsheet").Cells(i, "A").EntireRow.Copy 
      Destination:=target.Range("A" & target.Rows.Count).End(xlUp).Offset(1) 
     End If  
    Next i 
End Sub 

ist dies ein wenig Lassen aufzuräumen - doppelklicken Sie auf das Mainsheet (Sheet1) Objekt im Projekt-Explorer (Strg + R - bringt den Code-Explorer mit Rubberduck) und dann drücke F4, um seine Eigenschaften anzuzeigen. Ändern Sie die (Name) Eigenschaft von Sheet1 zu MainSheet. Jetzt können Sie dies tun:

Private Sub UpdateMonthlyData(ByVal target As Worksheet) 
    With MainSheet 

     Dim lastRow As Long 
     lastRow = .Range("A" & .Rows.Count).End(xlUp).Row 

     Dim i As Long 
     For i = 5 To lastRow 
      If .Cells(i, "E").Value = #1/20/2017# Then 
       .Cells(i, "A").EntireRow.Copy target.Range("A" & target.Rows.Count).End(xlUp).Offset(1) 
      End If 
     Next 

    End With 
End Sub 

MainSheet ist eine „freie“ global-scope Objektvariable Sie bekam durch seine (Name) Eigenschaft MainSheet Einstellung - VBA erstellt ein global-Bereichsobjekt nach ihm benannt, und Sie können es verwenden, überall im Code, um auf das Blatt zu beziehen.

Also was haben wir hier? Wir erhalten einen monthSheet Parameter, der das Blatt ist, auf das wir kopieren: das herauszufinden, ist ein weiteres Problem, und wir müssen uns nicht darum kümmern. Ich habe die Deklarationen näher an den Verwendungsort verschoben und den Deklarationen einen expliziten Typ gegeben, und der With MainSheet Befehl qualifiziert alles, was einen Punkt . mit dieses Arbeitsblatt Objekt verwendet.

Qualifikation Zeug ist wichtig: Wenn es durch einen expliziten Arbeitsblatt Verweis nicht voraus ist, Range, Cells, Rows, Columns, ... sie alle implizit auf die ActiveSheet verweisen - und wenn Sie mit jedem Blatt arbeiten, die nicht das aktive Blatt, dann implizit aufrufen auf das aktive Blatt bedeutet Ärger.

ich eingeschlossen, um die #date literal# mit # statt " - dass Literale für Zeichenfolge ist. Durch eine #date literal# Verwenden Sie eine implizite Konvertierung von String zu Date, vermeiden, weil .Cells(i, "E").Value ein Variant/Date sein sollte.

Next parametrieren wir den Monat und schließen Sie das Arbeitsblatt:

Private Sub UpdateMonthlyData(ByVal monthIndex As Long) 
    With MainSheet 

     On Error GoTo ErrHandler 

     Dim name As String 
     name = MonthName(monthIndex, True) 

     Dim target As Worksheet 
     target = ThisWorkbook.Worksheets(name) 

     On Error GoTo 0 'from this point onward any error bubbles up to the caller 

     Dim lastRow As Long 
     lastRow = .Range("A" & .Rows.Count).End(xlUp).Row 

     Dim i As Long 
     For i = 5 To lastRow 
      Dim monthCell As Range 
      monthCell = .Cells(i, "E") 
      If Not IsError(monthCell.Value) Then 
       If CStr(monthCell.Value) = name Then 
        .Cells(i, "A").EntireRow.Copy target.Range("A" & target.Rows.Count).End(xlUp).Offset(1) 
       End If 
      Else 
       Debug.Print "Cell " & monthCell.Address & " contains an error value and cannot be processed." 
      End If 
     Next 

    End With 
    Exit Sub 

ErrHandler: 
    Debug.Print "Could not find a worksheet for month " & monthIndex & "." 
End Sub 

nun der Anrufer braucht nur eine Schleife von 1 bis 12 laufen alle Blätter zu verarbeiten:

For i = 1 To 12 
    UpdateMonthlyData i 
Next 

Es ist nicht viel sauberer als das, denke ich :)

Nun, dass .Copy Betrieb immer noch nicht tun, was Sie wollen, um es zu tun - aber ach, diese Antwort ist lang genug schon! Viel Glück!

+0

Mat Becher, vielen Dank für Ihre Zeit und Erklärung alles perfekt funktioniert! Tolle! – Tom

+1

@ Tom Vergnügen! Fühlen Sie sich frei, dass grüne Häkchen ticken neben der Antwort, nur unter den oben/unten Abstimmung Tasten :) –

+0

@ Tom siehe https://meta.stackexchange.com/a/5235/289619 – 0m3r

Verwandte Themen