我熟悉通過引用將參數傳遞給過程。或者,ParamArray
也允許我通過引用將0個或更多參數傳遞給過程的靈活性。但是,這種方法讓我懷疑是否有辦法保留對一個或多個超出程序範圍的變量的引用。我希望第一一線希望是VBA Array
功能,當我看到它聲明如下:VBA - 安全地存儲可變引用
Array(ParamArray ArgList() As Variant)
所以,我總結了以下的測試代碼:
Private Sub Test()
Dim a As Object
Dim b() As Variant
ParamArrayTest a
Debug.Print TypeName(a) ' Output is 'Dictionary'
b = Array(a) ' b should be like ParamArray ArgList()
Set b(0) = Nothing ' This should clear a
Debug.Print TypeName(a) ' Output is still 'Dictionary'
End Sub
Private Sub ParamArrayTest(ParamArray ArgList() As Variant)
Set ArgList(0) = CreateObject("Scripting.Dictionary")
End Sub
不幸的是,這並沒有按我的預期工作。儘管通過ParamArray
將參數傳遞到Array
函數中,但看起來返回的數組是通過值而不是通過引用。
進一步的研究使我無證VBA /StrPtr
/ObjPtr
功能。我發現了很多與API RtlMoveMemory
函數配合使用的例子。然而,我所閱讀的所有文章強烈建議不要使用這種方法,因爲它很容易使應用程序崩潰。我的一些測試確實使Access崩潰。
另一個想法我是要看看我能一個變量的引用直接分配到另一個:
Private Sub Test()
Dim a As Object
Dim b As Variant
b = ByRef a ' Throws a compiler error
End Sub
我只想說,編譯器根本不會允許。我的問題是,變量引用是否可以安全地存儲/保存在一個過程的範圍之外(最好在另一個變量中)?
編輯
我決定這將是更有益的,如果我揭示什麼,我試圖建立一些輕。
我目前正在創建一個包裝類,它將所有的表單/控制事件傳遞給我的模塊之一的過程。它將與2種具有相同控制結構但連接到不同源表的表單一起使用。請記住,代碼是不完整的,但應該足以說明我試圖克服的問題。另外,Database
是我的VBA項目名稱。
有四個部分的代碼:
Form_TEST_FORM
- 表格模塊Private Sub Form_Open(Cancel As Integer) FormHub.InitForm Me, Cancel End Sub
FormHub
- 模塊Public Sub InitForm(_ ByRef Form As Access.Form, _ ByRef Cancel As Integer _ ) Dim Evt As Database.EventHandler Set Evt = New Database.EventHandler Evt.InitFormObject Form, Cancel FormList.Add Evt, Form.Name End Sub Private Function FormList() As VBA.Collection Static Init As Boolean Static Coll As VBA.Collection If Not Init Then Set Coll = New VBA.Collection Init = True End If Set FormList = Coll End Function
FormControl
- 類模塊Public Ptr As Variant ' Pointer to form control variable Public acType As Access.AcControlType
EventHandler
- 類模塊Private WithEvents Form As Access.Form Private WithEvents SForm As Access.SubForm Private CtrlList As VBA.Collection Private Sub Class_Initialize() InitCtrlList End Sub Public Sub InitFormObject(FormObj As Access.Form, ByRef Cancel As Integer) Dim ErrFlag As Boolean Dim Ctrl As Access.Control Dim FCtrl As Database.FormControl On Error GoTo Proc_Err Set Form = FormObj If Form.Controls.Count <> CtrlList.Count Then Err.Raise 1, , _ "Form has incorrect number of controls" End If ' This is where I want to validate the form controls ' and also initialize my event variables. For Each Ctrl In Form.Controls If Not CtrlExists(FCtrl, Ctrl.Name) Then Err.Raise 2, , _ "Invalid control name" ElseIf FCtrl.acType <> Ctrl.ControlType Then Err.Raise 3, , _ "Invalid control type" Else ' Initialize the correct variable with it's ' pointer. This is the part I haven't been ' able to figure out yet. Set FCtrl.Ptr = Ctrl End If Next Proc_End: On Error Resume Next If ErrFlag Then ClearEventVariables End If Set Ctrl = Nothing Set FCtrl = Nothing Exit Sub Proc_Err: ErrFlag = True Debug.Print "InitFormObject " & _ "Error " & Err & ": " & Err.Description Resume Proc_End End Sub Private Function CtrlExists(_ ByRef FCtrl As Database.FormControl, _ ByRef CtrlName As String _ ) As Boolean On Error Resume Next Set FCtrl = CtrlList(CtrlName) CtrlExists = Err = 0 End Function Private Sub InitCtrlList() Set CtrlList = New VBA.Collection CtrlList.Add SetCtrlData(SForm, acSubform), "SForm" End Sub Private Function SetCtrlData(_ ByRef Ctrl As Access.Control, _ ByRef acType As Access.AcControlType _ ) As Database.FormControl Set SetCtrlData = New Database.FormControl With SetCtrlData ' This assignment is where I need to keep a reference ' to the variable in the class. However, it doesn't ' work. Set .Ptr = Ctrl .acType = acType End With End Function Private Sub ClearEventVariables() Dim FormCtrl As Database.FormControl Set Form = Nothing For Each FormCtrl In CtrlList ' Assuming I was able to retain a reference to the ' class variable, this would clear it. Set FormCtrl.Ptr = Nothing Next End Sub Private Sub Class_Terminate() ClearEventVariables Set CtrlList = Nothing End Sub
我只用1個控制在爲了簡單起見,代碼示例。但是,這個想法是爲了在表單設計更改時簡化爲了添加/刪除控件而需要修改多少代碼。或者,如果我必須添加更多表單到項目中。
究竟你是什麼意思與「*保持一個參考超出了程序的範圍一個或多個變量*」?你的問題還不清楚。 –
@ Mat'sMug舉例來說,如果我傳遞一個變量到一個程序'ByRef'我能夠通過修改過程參數修改源變量的值。但是,只要程序退出,我就會失去指向源變量的指針。我想安全地存儲指向source變量的指針,以便在單個過程的範圍之外更新它的值。請讓我知道這個解釋是否更有意義。 –
這是「我失去了指向源變量」的一部分,它沒有任何意義了我。當程序退出時,你回到調用者,其中*您已經有*變量你路過'ByRef'。我只是沒有看到你想要解決什麼問題。 –