帮助我根据工作表名称按字母顺序重新排列 Excel 工作表, 但我有一个特定的规则,如果工作表名称包含“YTD”,那么它始终是第一个 如果我们有数字 0 那么它将始终位于其组的末尾
谢谢你
输入:
我想这样安排:
您可以将您的工作分为 2 个任务:a) 如何排序 b) 如何说出确切的顺序。
任何库排序例程都会实现或多或少复杂的排序算法(冒泡排序、快速排序、堆排序等)。在排序过程中,对两个对象进行比较,以回答这两个对象中哪一个“先出现”的问题。对于字符串,您通常使用字母顺序(这已经引起了几个问题,例如区分大小写、非 7 位 Ascii 字符等),对于数字,您比较值。当您想要对文件进行排序时,您可以有不同的标准:名称、大小、日期...
现在的重点是,无论您如何比较对象,排序算法本身都保持不变。因此,最常见的实现是排序例程调用一个函数来回答两个对象中哪一个较小(= 首先)的问题。通常,如果第一个对象较小,则该函数返回负数;如果第二个对象较小,则该函数返回正数;如果两者相同,则返回 0。
由于工作簿中只有几张工作表(是的,对于排序而言,即使 100 张工作表也是一个很小的数字),因此简单的冒泡排序就可以了。在评论中链接的问题中(Excel VBA:按字母数字顺序对工作表进行排序),使用了以下代码(我稍作修改)
Sub SortWorksheets()
Dim i As Long, j As Long
For i = 1 To Worksheets.Count - 1
For j = i + 1 To Worksheets.Count
If Worksheets(j).Name < Worksheets(i).Name Then
Worksheets(j).Move before:=Worksheets(i)
End If
Next j
Next i
End Sub
现在例程本身就回答了哪个工作表“较小”的问题:它直接比较工作表名称。现在让我们将此比较转移到一个函数中:
If compare(Worksheets(j).Name, Worksheets(i).Name) < 0 Then
Worksheets(j).Move before:=Worksheets(i)
End If
并且有一个功能
Function compare(name1 As String, name2 As String) as Long
compare = Iif(name1 < name2, -1, 1)
End Function
功能完全相同,但比较是“外包”的。如果您现在想要有不同的顺序逻辑,您所要做的就是更改该比较函数。在你的情况下,可能是这样的:
Function compare(name1 As String, name2 As String) As Long
' (1) Handle the YTD-Case:
If Left(name1, 3) = "YTD" And Left(name2, 3) <> "YTD" Then
compare = -1
ElseIf Left(name1, 3) <> "YTD" And Left(name2, 3) = "YTD" Then
compare = 1
Else
' Compare the names without the leading number
Dim pieces1() As String, pieces2() As String
pieces1 = Split(name1, "_")
pieces2 = Split(name2, "_")
If UBound(pieces1) > 0 And UBound(pieces2) > 0 Then
If pieces1(1) <> pieces2(1) Then
' different groups
compare = IIf(pieces1(1) < pieces2(1), -1, 1)
Else
' Same group, compare numbers
If pieces1(0) = "0" Then
compare = 1
Exit Function
ElseIf pieces2(0) = "0" Then
compare = -1
Exit Function
Else
compare = Val(pieces1(0)) - Val(pieces2(0))
End If
End If
Else
' Whatever that is: Compare names directly
compare = IIf(name1 < name2, -1, 1)
End If
End If
End Function