VBA Excel在多列上sorting

我有一个Excel表格,在那里我希望工作表“CR”中有一个值的所有行(除了标题行)(如果可能的话,不包括公式(列A包含公式))首先按列B name = TEAM),然后C(name = BUILDING),最后D(name = DATE_MAJ)保存文件。

我是VBA的一个绝对的noob,所以我尝试了在论坛上发现的东西,并根据需要进行修改。 从四处search,我在Excel VBA对象的“工作簿”中试过这段代码,但是却出现了一个错误:

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 eg 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 

我很感激任何帮助获得代码的权利。 下面是Excel文件的链接(我拿出上面的代码,因为它不工作)。

Dropbox链接到Excel文件

由于您只有三个sorting列,您可能需要使用Range对象的Sort()方法,而不是Worksheet对象的同名方法

此外假设列标题为每个链接的Excel文件,你可以试试这个:

 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