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

How do i filter a range in another sheet with VBA without activating the sheet

美好的一天,

我在设置范围时遇到问题,使用 non-active sheet 的设置范围时,我感到非常沮丧。

问题是:

我有一个叫 "Dashboard" 的 sheet。在这个 sheet 中,我有一个列表框,当 selected 将过滤值(基于 listbox.column 值)在另一个 sheet 中的 Table 称为 "Budget".但是,我收到错误 1004(范围 class 的自动过滤方法失败),关闭错误后它会过滤范围。所以它似乎以某种方式工作,但它给了我错误。

下面的代码是我用来过滤范围的代码。它被插入在 "Dashboard" Sheet object.

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

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

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

你们知道解决方法吗?为什么设置范围会出现这个问题?

我知道有关于范围的类似问题,但是 none 具有相同的规格。

附加信息(编辑):

1- 在线错误:

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

2- 列表框索引 >= 0 以确保列表框不为空并且有一个项目 selected。当列表框为空时,listindex = -1。

3- lrow(Budget, "A") 调用以下函数获取指定 sheet 中的最后一行:

   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- Value for Me.DashboardBudgetlst.Column(1, i) 是要过滤的关键字,取决于selection。列表框的输入范围与我过滤的范围相同。所以我 select 从 header "Item" 下的列表中选择列“1”。当我 select 列表框中的某些内容时,我希望它按预算项目进行过滤,有时可以是 "Accommodation" 或我在那里的任何其他内容。

7- Debug.Print 在 :

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

立即选择列表框 Returns 中的旅行费用 Window:

True 1        Travel Expenses

8- 部分截图:

仪表板中的列表框 Sheet(Excel 视图)

预算范围 Sheet(Excel 视图)

Objects 正在使用(VBA 视图)

它在我关闭过滤器将应用的错误后工作。但是我想知道是否还有其他解决方法,我不确定是否使用 "On Error Resume Next"(这对您的代码有害吗?)

我能够重现错误

根据列表框中项目的数量 select,问题似乎是触发了多个 _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