如何在工作簿中的工作表的命名数组中循环宏

时间:2019-04-28 09:55:17

标签: excel vba loops

摘要:通过ws的特定数组循环宏。在名称管理器中定义数组的名称。宏以某种方式循环通过数组中没有的其他ws。

目标是为我需要运行代码的每一个ws替换一个长宏调用子,并学习如何使用命名范围数组,因为它们是动态的。

代码是:(在stackoverflow上找到它,然后将其调整到我的目的)

    Public Sub Tester02()
    Dim SH As Worksheet
    Dim rng As Range
    Dim rCell As Range

    Set rng = 
    ActiveWorkbook.Sheets("ListOfSheets").Range("ListOfWorksheetsHRIB")

    For Each SH In ActiveWorkbook.Worksheets
    If Not IsError(Application.Match(SH.Name, rng, 0)) Then
    Call SingleCtrRefreshHRIB
    End If
    Next SH
    Worksheets("Dashboard").Activate
    End Sub

由于某种原因,宏会循环浏览另一张工作表(Sheet1 = Dashboard)。

在未经培训的情况下,宏运行到指定范围后即转到“仪表板”。因此,不应包含此工作表。

我可以在不激活仪表板的情况下运行宏,并通过指令重新定位光标。但我想知道为什么它不起作用,并学习如何将宏限制为专门用于命名的范围

不确定是否相关,但是Sub SingleCtrRefreshHRIB取消保护,刷新过滤器并保护指定范围内的ws。

从侧面说,我很惊讶地发现循环并没有比逐个ws更有效(在时间上)。更优雅,更动态,但不快。

如果需要调用宏的代码(我将清除激活代码并尽快选择此代码)。

    Sub SingleCtrRefreshHRIB()
    '
    ' In active IB worksheet macro unprotects, refreshes the "ACTIVE" 12 
    field and reprotects for HR
    '
    Application.ScreenUpdating = False
    ActiveSheet.Select
    ActiveSheet.Unprotect
    ActiveSheet.Range("$A$1:$AB$1051").AutoFilter Field:=12
    ActiveSheet.Range("$A$1:$AB$1051").AutoFilter Field:=12, Criteria1:= 
    _"ACTIVE"
    ActiveSheet.Select
    ActiveSheet.Protect DrawingObjects:=False, Contents:=True, 
    Scenarios:= _False, AllowFormattingColumns:=True, 
    AllowFiltering:=True
    End Sub

谢谢!

1 个答案:

答案 0 :(得分:0)

使用ActiveSheet可能会导致混乱,错误以及不必要的和不可预测的行为。请避免使用它。这是一个坏习惯。

备份文件,然后在副本上尝试:

Public Sub Tester02()
Dim SH As Worksheet 'declare a worksheet variable which can hold a worksheet object
Dim WB As Workbook 'declare a workbook variable which can hold a workbook object
Dim rng As Range 'declare a range variable which can hold a range object
Set WB = Application.Workbooks("The Name of your Workbook") 'assign a specific workbook to your workbook variable
Set rng = WB.Worksheets("ListOfSheets").Range("ListOfWorksheetsHRIB") 'assign a specific range to your range variable. Get the named range ListOfWorksheetsHRIB which belongs to the worksheet named ListOfSheets which belongs to WB and assign it to rng.

For Each SH In WB.Worksheets 'loop through all the worksheets that belong to WB
    If Not IsError(Application.Match(SH.Name, rng, 0)) Then 'check if the current worksheet's name is in the list of worksheets contained in rng
        Call SingleCtrRefreshHRIB(SH) 'if it is, pass this particular worksheet as parameter to SingleCtrRefreshHRIB
    End If
Next SH ' move on to the next worksheet and repeat
Worksheets("Dashboard").Activate 'not sure why you need this. Try avoiding .Activate. Use explicit references to worksheets.
End Sub

Sub SingleCtrRefreshHRIB(sht As Worksheet) 'This procedure gets a worksheet as a parameter and uses it to perform some actions
Application.ScreenUpdating = False
sht.Unprotect
sht.Range("$A$1:$AB$1051").AutoFilter Field:=12
sht.Range("$A$1:$AB$1051").AutoFilter Field:=12, Criteria1:="ACTIVE"
sht.Protect DrawingObjects:=False, Contents:=True, Scenarios:=False, AllowFormattingColumns:=True, AllowFiltering:=True
Application.ScreenUpdating = True
End Sub