如何在不激活工作表的情况下使用VBA过滤另一个工作表中的范围

时间:2018-04-09 01:15:33

标签: excel vba excel-vba named-ranges

美好的一天,

我遇到了Set Ranges的问题,而且在使用非活动工作表中的设置范围时非常令人沮丧。

问题是:

我有一张名为“仪表板”的表格。在此工作表中,我有一个列表框,选中后将在另一个名为“预算”的工作表中的表上过滤值(基于listbox.column值)。但是,我得到错误1004(Range类的自动过滤方法失败),关闭错误后它会过滤范围。所以它似乎以某种方式工作,但它给了我错误。

下面的代码是我用来过滤范围的代码。它被插入“Dashboard”Sheet对象中。

Private Sub DashboardBudgetlst_Change()

Dim rng As Range
Dim i As Integer

  i = Me.DashboardBudgetlst.ListIndex

    If i >= 0 Then
     If Me.DashboardBudgetlst.Selected(i) And Me.DashboardBudgetlst.Column(0, i) <> "" Then
          Set rng = Budget.Range("B1:E" & lrow(Budget, "A"))
          rng.AutoFilter 1, Me.DashboardBudgetlst.Column(1, i)
          Set rng = Nothing
     End If
   End If

End Sub

宏将过滤用于图表的范围,因此将过滤我的图表的值。此外,我不想使用数据透视表,因为它非常慢。

进一步探讨这个问题。如何使用另一个工作表中设置的工作表中的范围而不必激活该范围的工作表? (大多数时候我必须在使用Sheet的Set范围之前进行Sheet.Activate。)

您是否知道解决方法以及Set Ranges存在此问题的原因?

我知道范围有类似的问题,但没有相同的规格。

附加信息(编辑):

1 - 错误在线:

 rng.AutoFilter 1, Me.DashboardBudgetlst.Column(1, i)

2 - 列表框索引&gt; = 0以确保列表框不为空并且选择了一个项目。当列表框为空时,listindex = -1。

3 - lrow(预算,“A”)调用以下函数来获取指定工作表中的最后一行:

   Function lrow(SH As Worksheet, col As String)
        lrow = SH.Cells(Rows.Count, col).End(xlUp).Row
   End Function

4 - 在错误行之前使用msgbox rng.address,我收到$ B $ 1:$ E $ 5作为地址。

5 - 我使用

进行了临时解决方法
On Error Resume Next

6 - Me.DashboardBudgetlst.Column(1,i)的值是要过滤的关键字,具体取决于选择。列表框的输入范围与我过滤的范围相同。所以我从列表“Item”下面的列表中选择列“1”。当我从列表框中选择某些内容时,我希望它按预算项目进行过滤,有时可以是“住宿”或我在那里的任何其他内容。

7 - Debug.Print on:

Debug.Print rng.AutoFilter; 1, Me.DashboardBudgetlst.Column(1, i)

在列表框中的旅行费用中选择在立即窗口上返回:

True 1        Travel Expenses

8 - 一些截图:

仪表板中的列表框(Excel视图) Listbox in Dashboard Sheet (Excel View)

预算表中的范围(Excel视图) Range in Budget Sheet (Excel View

正在使用的对象(VBA视图) Objects being used (VBA view)

它在我关闭过滤器将应用的错误之后起作用。但是,我想知道是否有另一种解决方法,我不确定使用“On Error Resume Next”(对你的代码有害吗?)

1 个答案:

答案 0 :(得分:1)

我能够复制错误

根据ListBox中选择的项目数量,问题似乎是有多个_Change事件被触发

我能够通过使用事件标志

来停止错误
Option Explicit

Private Sub DashboardBudgetlst_Change()
    Dim rng As Range, i As Long, lstItm As String, crit As String, startIndex As Long

    If Application.EnableEvents = False Then Exit Sub    'If flag is Off exit Sub

    Application.EnableEvents = False    'Turn flag Off
    With Me.DashboardBudgetlst
        i = .ListIndex
        If i >= 0 Then
            If .Selected(i) And .Column(0, i) <> "" Then

                Set rng = Budget.Range("B1:E5") ' & lrow(Budget, "A"))
                rng.AutoFilter 1, .Value

            End If
        End If
    End With
    Application.EnableEvents = True    'Turn flag back On
End Sub