按字母顺序排序和过滤使用工作表名称自动填充的组合框

Posted

技术标签:

【中文标题】按字母顺序排序和过滤使用工作表名称自动填充的组合框【英文标题】:Alphabetically sorting and filtering a combo box that's being auto filled using sheet names 【发布时间】:2014-09-04 18:42:05 【问题描述】:

这里的目标是在 50 多张 Excel 工作簿的首页上有一个下拉框,自动填充每个工作表名称,列表按字母顺序(升序)排序并过滤掉某些条目。

到目前为止,我已经有了这个(可以从这里How to make a drop-down list for worksheets)进行自动填充:

    Private Sub workbook_open()
    Dim LSheets As Excel.Worksheet
    Dim OCmbBox As MSForms.ComboBox
    Set OCmbBox = ActiveWorkbook.Sheets(1).CmbSheet
    OCmbBox.Clear
    For Each LSheets In ActiveWorkbook.Sheets
    OCmbBox.AddItem LSheets.Name
    Next LSheets
    End Sub

如上所述,现在的挑战是按字母顺序对该列表进行排序,并过滤掉一些条目。特别是首页工作表本身,以及任何以“BETA”开头的工作表

在这里的其他地方,我发现了 2 个潜在的排序选项,但我在如何将其与我已有的内容结合起来遇到了障碍。

Sort Combobox VBA

至于过滤,我正在查看 SELECT CASE 类型的排列,但看不到如何标记否定。

有点像这样:

    Private Sub workbook_open()
    Dim LSheets As Excel.Worksheet
    Dim OCmbBox As MSForms.ComboBox
    Set OCmbBox = ActiveWorkbook.Sheets(1).CmbSheet
    OCmbBox.Clear
    For Each LSheets In ActiveWorkbook.Sheets
        If UCase(Left(LSheets.Name, 4)) IS NOT "BETA": OCmbBox.AddItem LSheets.Name
        Else Next Lsheets
    End Sub

但你甚至不想知道给我带来的可怕错误!首先,没有 IS NOT,而且 != 也没有让我到任何地方(是的,自从 Cyrix 仍在构建 CPU 之后,我还没有真正看过任何与代码相似的东西......)

社区可以提供的任何帮助/指导将不胜感激。

干杯。

罗伯。

【问题讨论】:

【参考方案1】:

我会这样做,使用临时表进行排序,然后删除临时表。这也将忽略名称以“BETA”开头的工作表以及工作簿中的第一个工作表:

Private Sub workbook_open()

    Dim ws As Worksheet
    Dim arrSheets As Variant
    Dim strSheets As String
    Dim lNumSheets As Long
    Dim cboSheets As MSForms.ComboBox

    Set cboSheets = ActiveWorkbook.Sheets(1).CmbSheet
    cboSheets.Clear

    For Each ws In ActiveWorkbook.Sheets
        If ws.Index > 1 And Not ws.Name Like "BETA*" Then
            lNumSheets = lNumSheets + 1
            strSheets = strSheets & ":" & ws.Name
        End If
    Next ws

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    With Sheets.Add.Range("A1").Resize(lNumSheets)
        .Value = Application.Transpose(Split(Mid(strSheets, 2), ":"))
        .Sort .Cells, xlAscending, Header:=xlNo
        arrSheets = .Value
        .Worksheet.Delete
    End With

    Application.DisplayAlerts = True
    Application.ScreenUpdating = True

    cboSheets.List = arrSheets

End Sub

【讨论】:

您先生,是一个纯粹的传奇。非常非常感谢!【参考方案2】:

您可以制作另一个子过程或函数进行排序:

Sub SortWorksheets()

Dim N As Integer
Dim M As Integer
Dim FirstWSToSort As Integer
Dim LastWSToSort As Integer
Dim SortDescending As Boolean

SortDescending = False

If ActiveWindow.SelectedSheets.Count = 1 Then
    FirstWSToSort = 2
    LastWSToSort = Worksheets.Count
Else
    With ActiveWindow.SelectedSheets
        For N = 2 To .Count
            If .Item(N - 1).Index <> .Item(N).Index - 1 Then
                MsgBox "You cannot sort non-adjacent sheets"
                Exit Sub
            End If
        Next N
        FirstWSToSort = .Item(1).Index
        LastWSToSort = .Item(.Count).Index
     End With
End If

For M = FirstWSToSort To LastWSToSort
    For N = M To LastWSToSort
      If left(UCase(Worksheets(N).Name,4) = "BETA"
      Else
        If SortDescending = True Then
            If UCase(Worksheets(N).Name) > UCase(Worksheets(M).Name) Then
                Worksheets(N).Move before:=Worksheets(M)
            End If
        Else
            If UCase(Worksheets(N).Name) < UCase(Worksheets(M).Name) Then
               Worksheets(N).Move before:=Worksheets(M)
            End If
        End If
      End If
     Next N
Next M

End Sub

FirstWSToSort 你可以更改 - 我将它设置为 2 因为你说你不想包含标题屏幕。

您可以通过将SortDescending 更改为true 来进行降序排序。

您可以在 N 和 M 循环内的 If 语句中包含或删除更多条件:

If left(UCase(Worksheets(N).Name,4) = "BETA"

【讨论】:

那么如何/在哪里是调用该程序的最佳位置/方式?从创建列表的初始 workbook_open() 中?请记住,目前它位于 ThisWorkbook 的(代码)部分,而不是特定的工作表上。 另外,您的其中一行代码给了我一个编译错误。 '预期:列表分隔符或)'它发生在 For 部分中的“If left (UCase(Worksheets(N).Name,4) = "BETA" 行。看起来缺少一个括号,但我不能似乎弄清楚它应该去哪里,因为它仍然在我身上打破,。【参考方案3】:

我喜欢忽略工作表的选择案例想法。此外,最简单的方法可能是先将有效的工作表放入一个数组中,然后对数组进行排序,然后循环遍历它以将项目添加到组合框

例如

Private Sub workbook_open()
    Dim lsheets As Worksheet
    Dim validSheets() As Worksheet
    ReDim validSheets(0)

    For Each lsheets In ActiveWorkbook.Sheets
        Select Case UCase(Left(lsheets.name, 4))
            Case "BETA":
                'sheet's name is beta
                MsgBox "beta"
            Case Else
                'sheet's name is not beta
                'put code to add sheet to combobox here
                MsgBox "not beta"
                'if the last item in the array is used then increase array size
                If Not validSheets(UBound(validSheets)) Is Nothing Then
                    ReDim Preserve validSheets(0 To UBound(validSheets) + 1)
                End If
                'add valid sheet to last place in array
                Set validSheets(UBound(validSheets)) = lsheets
        End Select
    Next lsheets

    'now sort the array of valid sheets
    exampleFunctionSort validSheets

    'now add the array of valid sheets in order
    Dim index As Integer
    For index = LBound(validSheets) To UBound(validSheets)
        'add sheet here
    Next index
End Sub

'place array sort code here
Private Function exampleFunctionSort(arr As Variant)

End Function

【讨论】:

【参考方案4】:

呜呼!我是时候发光了。 (我喜欢简洁。)

Private Sub workbook_open()
Dim LSheets As Excel.Worksheet
Dim OCmbBox As MSForms.ComboBox
Set OCmbBox = ActiveWorkbook.Sheets(1).CmbSheet
Dim sht As Worksheet
OCmbBox.Clear

With CreateObject("System.Collections.ArrayList")
    For Each sht In ThisWorkbook.Worksheets
        If sht.Name <> "BETA" Then .Add sht.Name
    Next
    .Sort
    OCmbBox.List = Application.Transpose(.toarray())
End With

结束子

【讨论】:

以上是关于按字母顺序排序和过滤使用工作表名称自动填充的组合框的主要内容,如果未能解决你的问题,请参考以下文章

VBA Access - 按字母顺序排序列表框

如何使用React过滤和排序相同的表数据?

使用带有 postgresql 表的 vba 填充组合框访问 2007

WPS表格双击不能自动填充

使用组合框过滤记录并填充第二个组合框

是否可以通过组合框值列表进行排序?