2015-08-14 132 views
1

我有一張工作簿,大約有50張。我想編寫一個按字母順序排序的模塊,然後在名爲「Closed =>」的選項卡之後將具有黑色選項卡的表單移動到最後。按字母順序排序後按顏色排序

Sub sortsheets() 
    Dim WB As Workbook 
    Dim WS_Count As Integer 
    Dim i As Integer 
    Dim j As Integer 

    Set WB = ActiveWorkbook 
    WS_Count = WB.Sheets.count 


'Below will sort alphabetically  
    For i = 1 To WS_Count 
     For j = 1 To WS_Count - 1 

      If UCase(Sheets(j).name) > UCase(Sheets(j + 1).name) Then 
       Sheets(j).Move after:=Sheets(j + 1) 
      End if 

     Next j 
    Next i 


' Move closed tab to the end 
    For i = 1 To WS_Count 
     If UCase(Sheets(i).name) = "Closed =>" Then 
     Sheets(i).Move after:=Sheets(WS_Count) 
     End If 
    Next i 

' Below needs to iterate through the sheets and move all black sheets to the end 

    For i = 1 To WS_Count 

     For j = 1 To WS_Count 

      If Sheets(j).Tab.ColorIndex = 1 Then 
       Sheets(j).Move after:=Sheets(WS_Count) 

      End If 
     Next j 
    Next i 


    End Sub 

問題是,最後一步將黑色頁面移動到結尾處將廢棄字母順序。我認爲那是因爲在它繼續循環的時候,它正在穿過已經移動到最後的黑色牀單,並再次移動它們。我怎樣才能防止呢?

回答

0

這將保持全黑張數保持在第一循環中完成排序:

Option Explicit 

Sub sortSheets() 
    Dim wb As Workbook, wsCount As Integer, i As Long, j As Long, bCount As Long 

    Set wb = ActiveWorkbook 
    wsCount = wb.Sheets.Count 

    Application.ScreenUpdating = False 

    For i = 1 To wsCount 'sort alpha 
     For j = 1 To wsCount - 1 
      If UCase(Sheets(j).Name) > UCase(Sheets(j + 1).Name) Then 
       Sheets(j).Move After:=Sheets(j + 1) 
      End If 
     Next 
    Next 

    For i = 1 To wsCount 'move closed tab to the end 
     If UCase(Sheets(i).Name) = UCase("Closed =>") Then 
      Sheets(i).Move After:=Sheets(wsCount) 
     End If 
     If Sheets(i).Tab.ColorIndex = 1 Then bCount = bCount + 1 
    Next I 

    For i = 1 To wsCount - bCount 'move black sheets to the end 
     If Sheets(i).Tab.ColorIndex = 1 Then 
      Sheets(i).Move After:=Sheets(wsCount) 
      i = i - 1 
     End If 
    Next 

    Application.ScreenUpdating = True 

End Sub 
+0

其實試過循環您在使用'最後一步做的方式I = I-1'但我沒有考慮到'bcount'。星期一讓我試試吧。我有一個關於前兩個循環中的循環算法的問題:對於我來說,對於j..'。我想出了j循環的必要性,因爲如果我們只執行i循環,我們會在將工作表移動到最後之後跳過工作表。但是,我無法向我自己證明這些循環會照顧所有牀單。我能夠成功地對其進行測試,但在概念上並沒有證明它對我自己。這是一個我能讀懂的證明的已知算法嗎? – newdimension

+0

從概念上講,第一個嵌套循環與[冒泡排序](https://en.wikipedia.org/wiki/Bubble_sort)類似(不是最高效但易於實現的),但是對於此循環來說太多;我們可以優化它通過消除中間的一個,如果表「關閉=>」將始終存在於您的文件 –

+0

感謝您的文章!是的,工作簿將始終有一個名爲「已關閉=>」的表單 – newdimension

0

我想如果你扭轉你的操作順序,做顏色排序第一更容易。我會通過標籤顏色將圖紙分成多個集合。最後,您可以按字母順序對這些集合中的每一個進行排序。

注:此輸入我的手機上,所以隨時留意拼寫錯誤,並這樣;)

Option Explicit 

Sub sortSheets() 
    Dim wb As Workbook, Sheet As Worksheet, CloseSheet As Worksheet, BlackTabs As New Collection, OtherTabs as New Collection 

    Set wb = ActiveWorkbook 
    Application.ScreenUpdating = False 

    For Each Sheet in wb.Worksheets 
     If Ucase(Sheet.Name) = Ucase("Closed =>") Then Set CloseSheet=Sheet 

     Select Case Sheet.Tab.ColorIndex 
     Case 1 
      Sheet.Move After:=Sheets(wb.Sheets.Count) 
      BlackTabs.Add Sheet 
     Case Else 
      OtherTabs.Add Sheet 
     End Select 
    Next 

    If BlackTabs.Count >= 1 Then SortAlpha BlackTabs 
    If OtherTabs.Count >= 1 Then SortAlpha OtherTabs 

CloseSheet.Move After:=Sheets(wb.Sheets.Count) 

    Application.ScreenUpdating = True 

End Sub 

Private Sub SortAlpha (ByRef SortSheets as Collection) 
    Dim i as Long, j as Long 
    For i = 1 To SortSheets.Count 
     For j = 1 To SortSheets.Count - 1 
      If UCase(SortSheets(j).name) > UCase(SortSheets(j + 1).name) Then 
      SortSheets(j).Move after:=SortSheets(j + 1) 
     End if 

    Next j 
End Sub 
+0

想要嘗試使用「集合」。感謝這個例子,我將在星期一通過它。 – newdimension

+0

沒問題 - 如果您遇到問題或遇到任何錯誤,請告訴我,我沒有測試過代碼。我選擇使用select case,因爲我不確定是否有其他顏色可以排序,所以稍後您可以輕鬆添加更多顏色選項。或者,如果需要,您可以將其更改爲if塊。此外,只是糾正了一個錯誤,我複製了一些原始代碼,這些代碼在這種情況下不起作用;) – CBRF23