输入用户表单后重复活动过滤器

时间:2018-07-03 18:43:00

标签: excel vba userform

我有一个宏,可以根据“联系日期”,“存款”和“信用”对客户进行排序。假设我选择按“联系日期”排序,然后将新客户端添加到列表中,从用户表单输入新客户端后,如何重新运行活动排序? ?

  

我用来添加客户端数据的用户表单

UserForm I use to enter Data

  

过滤器选项

Filter Options

这是我的代码:

  

贷方余额排序

Sub creditbalance()

    Dim w As Long, lr As Long, wss As Variant

    wss = Array("contactunder")


    For w = LBound(wss) To UBound(wss)
        With ThisWorkbook.Worksheets(wss(w))
            lr = Application.Max(.Cells(.Rows.Count, "a").End(xlUp).Row, _
                                 .Cells(.Rows.Count, "da").End(xlUp).Row)
            With .Range(.Cells(10, "a"), .Cells(lr, "da"))
                .Cells.Sort Key1:=.Columns(97), Order1:=xlDescending, _
                            Orientation:=xlTopToBottom, Header:=xlYes
            End With
        End With
    Next w

End Sub
  

联系日期排序

Sub contactdate()
    Dim w As Long, lr As Long, wss As Variant

    wss = Array("contactunder")


    For w = LBound(wss) To UBound(wss)
        With ThisWorkbook.Worksheets(wss(w))
            lr = Application.Max(.Cells(.Rows.Count, "a").End(xlUp).Row, _
                                 .Cells(.Rows.Count, "da").End(xlUp).Row)
            With .Range(.Cells(10, "a"), .Cells(lr, "da"))
                .Cells.Sort Key1:=.Columns(2), Order1:=xlDescending, _
                            Orientation:=xlTopToBottom, Header:=xlYes
            End With
        End With
    Next w

End Sub
  

存款余额排序

Sub depositbalance()
    Dim w As Long, lr As Long, wss As Variant

    wss = Array("contactunder")


    For w = LBound(wss) To UBound(wss)
        With ThisWorkbook.Worksheets(wss(w))
            lr = Application.Max(.Cells(.Rows.Count, "a").End(xlUp).Row, _
                                 .Cells(.Rows.Count, "da").End(xlUp).Row)
            With .Range(.Cells(10, "a"), .Cells(lr, "da"))
                .Cells.Sort Key1:=.Columns(68), Order1:=xlDescending, _
                            Orientation:=xlTopToBottom, Header:=xlYes
            End With
        End With
    Next w
End Sub

1 个答案:

答案 0 :(得分:2)

您显示的小代码非常多余-通过将硬编码的Key1排序参数作为参数,可以立即消除对这三个克隆中的两个的需要,并重新利用第三个克隆来完成这项工作对于所有三个。

当您的范围是ListObject又名“表格”时,排序和应用排序非常容易。在您的范围内,从主页功能区中选择“表格格式”。现在,您无需再计算最后一行。

此外,如果在编译时wss(w)中存在ThisWorkbook工作表,则没有理由从Worksheets集合中取消引用它-只需使用其代号标识符(您可以通过在 Project Explorer / Ctrl + R中选择工作表,然后在 Properties 工具窗口/ F4中更改其(Name)属性来更改它)-然后您可以执行TheSheetName.Range("whatever")。或更好-由于该代码只需要在特定工作表上工作,就可以将其放入该工作表的代码中,然后使用Me来引用Worksheet实例:

Public Sub ApplySortOrder(Optional ByVal sortColumn As String = vbNullString)

    With Me.ListObjects(1)

        Dim sortColumnRange As Range
        If sortColumn <> vbNullString Then
            'assumes sortColumn is an existing column header
            Set sortColumnRange = .ListColumns(sortColumn).DataBodyRange
        End If
        With .Sort
            If Not sortColumnRange Is Nothing Then
                .SortFields.Clear
                .SortFields.Add sortColumnRange
            End If
            .Apply
        End With
    End With

End Sub

现在,假设我正确假设了假定的列标题,那么您正在调用的depositbalance代码如下所示:

TheSheetName.ApplySortOrder "DepositBalance"

contactdate排序是这样的:

TheSheetName.ApplySortOrder "ContactDate"

creditbalance排序:

TheSheetName.ApplySortOrder "CreditBalance"

如果要重新应用当前排序:

TheSheetName.ApplySortOrder

在需要按其他方式排序的那一天,您可以这样做:

TheSheetName.ApplySortOrder "ThatFancyNewColumn"

并完成它,而无需复制粘贴另一个过程。

您甚至可以为有效列声明一个Public Enum ...

Public Enum SortingColumn
    Current = 0
    CreditBalance = 97
    DepositBalance = 68
    ContactDate = 2
End Enum

然后将签名更改为接受SortingColumn参数:

Public Sub ApplySortOrder(Optional ByVal sortColumn As SortingColumn = Current)

    With Me.ListObjects(1)

        Dim sortColumnRange As Range
        If sortColumn <> Current Then
            'assumes sortColumn is an existing column header
            Set sortColumnRange = .ListColumns(sortColumn).DataBodyRange
        End If
        With .Sort
            If Not sortColumnRange Is Nothing Then
                .SortFields.Clear
                .SortFields.Add sortColumnRange
            End If
            .Apply
        End With
    End With

End Sub

甚至更好的是,省去显式的枚举值,并将每个值映射到字符串列名-然后编写一个函数,使它获得ListColumn.Index,以便用户无法重命名标题,但是他们仍然可以随意移动这90多个柱子。 ...但这是我想写的另一篇文章。