2016-11-12 2 views
0

Ich habe eine Excel-Tabelle, wo ich möchte, dass alle Zeilen (außer der Kopfzeile) in Sheet "CR" einen Wert enthalten (Formeln ausgenommen wenn möglich (Spalte A enthält Formeln))) werden zuerst nach Spalte B (name = TEAM), dann C (name = BUILDING) und schließlich D (name = DATE_MAJ) sortiert, bevor die Datei gespeichert wird.VBA Excel-Sortierung für mehrere Spalten

Ich bin ein absoluter Noob mit VBA, also probiere ich Sachen aus, die ich links und rechts auf den Foren finde und modifiziere sie nach meinen Bedürfnissen. Von der Suche um, habe ich versucht, diesen Code in dem Excel-VBA-Objekt ‚Arbeitsmappe‘, aber es gibt einen Fehler:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) 
'Setup column names 
Col1name = "SECTION" 
Col2name = "BATIMENT" 
Col3name = "DATE_MAJ" 

'Find cols 
For Each cell In Range("A1:" & Range("A1").End(xlToRight).Address) 
    If cell.Value = Col1name Then 
     Col1 = cell.Column 
    End If 
    If cell.Value = Col2name Then 
     Col2 = cell.Column 
    End If 
    If cell.Value = Col3name Then 
     Col3 = cell.Column 
    End If 

Next 

'Below two line:- if they are blank e.g. column not found it will error so a small bit of error handling 
If Col1 = "" Then Exit Sub 
If Col2 = "" Then Exit Sub 
If Col3 = "" Then Exit Sub 

'Find last row - dynamic part 
lastrow = ActiveSheet.Range("A100000").End(xlUp).Row 

'Convert col numer to name 
Col1 = Split(Cells(1, Col1).Address(True, False), "$") 
Col2 = Split(Cells(1, Col2).Address(True, False), "$") 
Col3 = Split(Cells(1, Col3).Address(True, False), "$") 

'Sort 
With ActiveSheet.Sort 
    .SortFields.Clear 
    .SortFields.Add Key:=Range(Col1(0) & "2:" & Col1(0) & lastrow) _ 
     , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal 
    .SortFields.Add Key:=Range(Col2(0) & "2:" & Col2(0) & lastrow) _ 
     , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal 
    .SortFields.Add Key:=Range(Col3(0) & "2:" & Col3(0) & lastrow) _ 
     , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal 

    .SetRange Range("A1:K" & lastrow) 
    .Header = xlYes 
    .MatchCase = False 
    .Orientation = xlTopToBottom 
    .SortMethod = xlPinYin 
    .Apply 
End With 
End Sub 

ich für jede Hilfe dankbar sein würde, den Code direkt zu bekommen. Unten ist ein Link zur Excel-Datei (ich habe den obigen Code herausgenommen, da er nicht funktioniert hat).

Dropbox link to Excel file

+0

Welchen Fehler haben Sie? Welche Linie wirft es? Außerdem hat Ihr verlinktes Beispiel keinen Spaltenkopf, der weder nach "BATIMENT" noch nach "DATE_MAJ" benannt ist. – user3598756

+0

Die Spaltennamen der Spalten C und D sind "BATIMENT" und "DATE_MAJ"; Ihre Header sind in der Tat "BUILDING" und "DATE ​​UPDATE". Spielt das eine Rolle? – Antoon

+0

Der Fehler, den ich bekomme, ist 'Kompilierfehler: Variable nicht definiert' und 'Col1name' ist im VBA-Code ausgewählt. – Antoon

Antwort

2

Da Sie nur drei Sortier Spalten haben, können Sie Sort() Methode von Range Objekt anstelle der gleichnamigen Methode der Worksheet Objekt

Des Weiteren davon aus Spalten-Header als pro verknüpfte Excel-Dateien verwenden möchten, könnten Sie versuchen Sie folgendes:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) 
    Dim col1 As Range, col2 As Range, col3 As Range 
    Dim lastRow As Long 

    'Setup column names 
    Const col1Name As String = "SECTION" 
    Const col2Name As String = "BUILDING" '"BATIMENT" 
    Const col3Name As String = "DATE UPDATE" '"DATE_MAJ" 

    With Worksheets("CR") '<--| reference your worksheet 
     'Find last row - dynamic part 
     lastRow = .Cells(.Rows.Count, 1).End(xlUp).row ' <--|find its column "A" last not empty row index 
     'Find cols 
     With .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft)) '<--|reference its row 1 cells from column 1 to last not empty one and search for sorting columns whose header matches above set column names 
      If Not TryGetColumnIndex(.Cells, col1Name, col1) Then Exit Sub '<--| if 1st sorting column not found then exit sub 
      If Not TryGetColumnIndex(.Cells, col2Name, col2) Then Exit Sub '<--| if 2nd sorting column not found then exit sub 
      If Not TryGetColumnIndex(.Cells, col3Name, col3) Then Exit Sub '<--| if 3rd sorting column not found then exit sub 
      .Resize(lastRow).Sort _ 
          key1:=col1, order1:=xlAscending, DataOption1:=xlSortNormal, _ 
          key2:=col2, order2:=xlAscending, DataOption2:=xlSortNormal, _ 
          key3:=col3, order3:=xlAscending, DataOption3:=xlSortNormal, _ 
          Header:=xlYes, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod:=xlPinYin 
     End With 
    End With 
End Sub 

Function TryGetColumnIndex(rng As Range, colName As String, col As Range) As Boolean 
    Set col = rng.Find(What:=colName, LookIn:=xlValues, LookAt:=xlWhole) 
    TryGetColumnIndex = Not col Is Nothing 
End Function 
+0

Danke, aber dieser Code gibt Folgendes: Laufzeitfehler '438': Objekt unterstützt diese Eigenschaft oder Methode nicht. Wenn Sie auf 'debug' klicken, wird die folgende Zeile hervorgehoben: lastRow = .Cells (.Rows.Count, 1) .End (xlUp) .rowrow '<- | finden Sie ihre Spalte "A" letzten nicht leeren Zeilenindex – Antoon

+0

welcher Fehler ? und welche Linie wirft es? – user3598756

+0

Ich habe den Code in das Objekt 'ThisWorkbook' eingefügt. Ich nehme an, dass ist richtig? – Antoon

Verwandte Themen