2012-02-29 67 views
1

VBA函數(UDF)中可能創建具有全局範圍的對象嗎? I.e是否超越了函數的運行時間?我想用一個可以傳遞給其他函數的獨特密鑰將其保存在散列表中。我知道你可以在c#/ C++ dll中做到這一點。VBA:在Excel中創建會話持久對象(散列)

這個動機是一個重要的處理過程,我不想重複數百次函數調用:我想緩存結果,所以我只需要做一次。 E.g讓我們想象我有一個UDF它建立的結果在單元格A1對象:

=CreateResultsObject(arg1, arg2, arg3...) 

功能做繁重的工作,並返回一個唯一的ID字符串(存儲在持久哈希對象的關鍵)。單元格A1現在包含這個字符串值,然後我可以將其傳遞給其他函數:然後它們可以使用密鑰訪問散列中的緩存對象。

這可能嗎?如果是這樣如何?

回答

7

您在模塊中聲明的變量是持久的。

此代碼模塊中可能會進入你想要的方向:

Option Explicit 

Dim col As New Collection 


Public Function GetValue(ByVal strName As String) As String 

    GetValue = col.Item(strName) 

End Function 

Public Sub SetValue(ByVal strName As String, ByVal strValue As String) 

    col.Add strValue, strName 

End Sub 

注:

對於重複或缺失的名稱代碼將失敗。 而不是字符串值可以通過修改相應的函數簽名來傳遞任何類型的對象。

附錄:

相同的代碼有位更智能 - 集合中現有的密鑰值將被替換,而不是用一個錯誤而失敗。

Option Explicit 

Dim col As New Collection 


Public Function GetValue(ByVal strName As String) As String 

    GetValue = col.Item(strName) 

End Function 

Public Sub SetValue(ByVal strName As String, ByVal strValue As String) 

    If HasValue(strName) Then 
     col.Remove (strName) 
    End If 

    col.Add strValue, strName 

End Sub 

Private Function HasValue(ByVal strName As String) As Boolean 

    Dim val As Variant 
    Dim bRes As Boolean 

    bRes = True 

On Error Resume Next 

    val = col.Item(strName) 

    If Err.Number <> 0 Then 
     bRes = False 
     Err.Clear 
    End If 
On Error GoTo 0 

    HasValue = bRes 

End Function 
+0

相同原理的礦井,但使用集合(或字典)是更優雅:)(+1) – JMax 2012-02-29 10:19:23

+0

啊!我不知道你可以聲明模塊範圍的變量!感謝vm – 2012-02-29 10:21:46

+1

有關記錄,[關於Ozgrid變量範圍的此鏈接](http://www.ozgrid.com/VBA/variable-scope-lifetime.htm)可能會有所幫助 – JMax 2012-02-29 10:25:16

2

在模塊中使用全局變量怎麼樣?

事情是這樣的:

Option Explicit 
Dim sHash As String 

Function CreateResultsObject() 
    'very long code 
    sHash = "MyTest" 
    CreateResultsObject = "ok" 
End Function 

Function displayresultsobject() 
    displayresultsobject = sHash 
End Function 

請注意,只有當你調用工作表中的CreateResultsObject()您的哈希將會被重新計算,並在每次請求重新計算時間。

+0

真棒感謝VM – 2012-02-29 10:22:33