Vba 在全局变量中存储范围引用

Vba 在全局变量中存储范围引用,vba,excel,named-ranges,Vba,Excel,Named Ranges,我正在使用位于不同工作表中的几个命名范围。在VBA代码的许多情况下,我需要读取和写入这些范围 所以我的问题是:什么是将这些范围引用存储在全局变量中以便快速访问的正确方法?还是有更好的办法 我尝试声明全局变量: Public WS_BOARD As Worksheet Public RNG_BOARD As Range 并在打开工作簿时初始化它们: 这可以正常工作,但如果我的代码崩溃,这些全局变量将重置为零,并且不能在工作表事件处理程序中进一步使用 当然,我总是可以用 Worksheets("B

我正在使用位于不同工作表中的几个命名范围。在VBA代码的许多情况下,我需要读取和写入这些范围

所以我的问题是:什么是将这些范围引用存储在全局变量中以便快速访问的正确方法?还是有更好的办法

我尝试声明全局变量:

Public WS_BOARD As Worksheet
Public RNG_BOARD As Range
并在打开工作簿时初始化它们:

这可以正常工作,但如果我的代码崩溃,这些全局变量将重置为零,并且不能在工作表事件处理程序中进一步使用

当然,我总是可以用

Worksheets("BOARD").Range("NR_BOARD")

我的代码中到处都有,但我认为这会影响性能,因为它显然需要使用字符串名称查找对象,更不用说它是干的。

一种方法是将它们加载到内存中一次,然后将它们作为参数传递到其他子函数/函数中。

其次,您可以将它们声明为模块范围变量(类似于public),但只能在模块中声明它们。

第三,你的方式。

每个工作表都有一个名称属性选项卡标题和一个代号属性。如果在代码中使用代码名,则不需要变量。与用户表单一样,工作表的代码名在使用时会自动实例化。在项目浏览器中选择项目下的工作表Ctrl+R,转到属性F4并将名称更改为有意义的代码名。然后,项目资源管理器将该工作表显示为

wshDataEntry (Data Entry)
如果您创建了代码名wshDataEntry,并且选项卡上显示了数据条目

对于范围,我使用了电子表格中定义的名称。它就像一个永远不会超出范围的全局变量。若你们有,比方说,和你们需要在各种程序中阅读的利率单元格,把它命名为利率。然后在你需要的每个步骤的顶部

Set rInterest = wshDataEntry.Range(gsNMINTEREST)
其中,gsNMINTEREST是一个全局字符串变量,用于保持利率。如果单元格曾经移动过,您只需要移动命名区域,代码就可以工作。如果将名称更改为LiborPlusFour,则只需更新全局变量。相当干燥

是的,每次让VBA查找指定范围时都会有轻微的性能影响。我不会担心这个问题,除非你已经计算了一个性能问题,并将其确定为阻力

我保留全局变量的一种方法当然,我非常明智地在作用域中使用它们,那就是初始化过程

Public Sub Initialize()

    If gclsApp Is Nothing Then
        Set gclsApp = New CApp
        'do some other setup
    End If

End Sub

然后我调用任何模块顶部的初始化过程。如果它不是空的,那么它不会重置变量。不过,我不确定什么都不检查,只是查找一个命名范围对性能的影响。

全局变量通常不是一个好主意。在某些情况下,它们是必要的,但这不是其中之一

我认为您不应该担心按字符串名称查找几个范围对性能的影响。我有数百个命名范围的工作表,我从未观察到这会对性能产生负面影响

您是否有具体证据表明这会减慢代码的速度?如果没有,那就不要浪费时间担心它

我经常这样做来定义范围:

Type RangesType
    board As Range
    plank As Range
    wood As Range
End Type

Function GetRanges() As RangesType
    With GetRanges
        Set .board = Range("board")
        Set .plank = Range("plank")
        Set .wood = Range("wood")
    End With
End Function
然后我就这样使用它们:

Sub something()
    Dim rngs As RangesType: rngs = GetRanges

    rngs.board = "My favourite board"
    rngs.wood = "Chestnut"
    'etc.

End Sub
是的,如果您有许多sub,那么范围将被重复地按其名称获取,不,这不太可能对性能有任何明显的影响

Sub something()
    Dim rngs As RangesType: rngs = GetRanges

    rngs.board = "My favourite board"
    rngs.wood = "Chestnut"
    'etc.

End Sub