Коллекции VBA, определенные как статический тип, возможны? - PullRequest
0 голосов
/ 30 октября 2018

Можно ли определить статические коллекции в макросах VBA для Outlook?

Sub mySub()

    Static myCollection As VBA.Collection

    Set myCollection = New VBA.Collection

        myCollection.Add "entry1"

        myCollection.Add "entry2"

        myCollection.Add "entry3"

End Sub

Так что myCollection не нужно переопределять при каждом запуске макроса mySub ().

1 Ответ

0 голосов
/ 30 октября 2018
Переменная

A Static в VBA сохранит свое значение между вызовами. Обычно переменная, которая выходит из области видимости и на которую больше не ссылаются, уничтожается; Static изменяет объявление переменной.

Это не меняет того, что делает эта инструкция безусловно :

Set myCollection = New VBA.Collection

Независимо от того, какую ссылку держал предыдущий прогон, мы перезаписываем его каждый раз , отменяя то, что Static должно нас купить.

У вас была бы одна и та же проблема независимо от типа используемой переменной: проблема не в типе, а в безусловности инструкции Set.

Сделать условным:

Static myCollection As VBA.Collection
If myCollection Is Nothing Then
    Set myCollection = New VBA.Collection
End If

А теперь myCollection будет только Nothing при первом вызове; при последующих запусках ссылка myCollection сохраняется между вызовами.

В значительной степени то, что вы получаете с переменной уровня модуля:

Option Explicit
Private myCollection As VBA.Collection

Public Sub TestModuleVariable()
    If myCollection Is Nothing Then
        Set myCollection = New VBA.Collection
    End If
    With myCollection
        .Add "entry" & .Count + 1
        Debug.Print .Count
    End With
End Sub

Public Sub TestStaticVariable()
    Static items As VBA.Collection
    If items Is Nothing Then
        Set items = New VBA.Collection
    End If
    With items
        .Add "entry" & .Count + 1
        Debug.Print .Count
    End With
End Sub

Какой из них использовать, зависит от того, что остальная часть модуля должна делать с этим Collection. Если никто больше не должен знать об этом, тогда, конечно, оставьте его локальным.

Рассмотрите вопрос , возложившего на собеседника ответственность за предоставление коллекции в качестве аргумента - за то, чтобы вызывающий вызывал интерес, чтобы знать, сколько раз он вызывает эту процедуру.

Public Sub TestParameter(ByRef items As VBA.Collection)
    If items Is Nothing Then
        Set items = New VBA.Collection
    End If
    With items
        .Add "entry" & .Count + 1
        Debug.Print .Count
    End With
End Sub
...