Vba 集合对象-ByRef-ByVal

Vba 集合对象-ByRef-ByVal,vba,pass-by-reference,ms-access-2013,Vba,Pass By Reference,Ms Access 2013,我在Access 2013中使用VBA 在常规模块中有两个过程,RunProc()和PopulateCollection() 执行RunProc时,它调用PopulateCollection,其中 传递的参数是名为mycl的集合instace PopulateCollection添加3项,然后RunProc继续迭代集合 我的问题是: 我希望RunProc中的参数mycl不被PopulateCollection填充。实现这一目标的正确方法是什么 为什么PopulateCollection同时填充参

我在Access 2013中使用VBA

在常规模块中有两个过程,
RunProc()
PopulateCollection()

执行
RunProc
时,它调用
PopulateCollection
,其中 传递的参数是名为
mycl
的集合instace

PopulateCollection
添加3项,然后
RunProc
继续迭代集合

我的问题是:

我希望
RunProc
中的参数
mycl
不被
PopulateCollection
填充。实现这一目标的正确方法是什么

为什么
PopulateCollection
同时填充参数和参数

' --------Module1------------------
Option Compare Database
Option Explicit

Dim i As Integer
Dim MyCol As VBA.Collection

Sub RunProc()
    Set MyCol = New VBA.Collection

    PopulateCollection MyCol

    For i = 1 To MyCol.Count
        Debug.Print MyCol.Item(i)
    Next i
End Sub

Function PopulateCollection(ByRef pMyCol As VBA.Collection)
    For i = 1 To 3
       pMyCol.Add "Item" & i
    Next i            
End Function

这是问我问题的另一种方式:

选项比较数据库 选项显式

Sub Proc1()

    Dim myInt As Integer
    myInt = 1

    Proc2 myInt

    Debug.Print myInt

    myInt = 1

    Proc3 myInt

    Debug.Print myInt

End Sub

Sub Proc2(ByVal pmyInt)

    pmyInt = pmyInt + 1
    Debug.Print pmyInt

End Sub

Sub Proc3(ByRef pmyInt)

    pmyInt = pmyInt + 1
    Debug.Print pmyInt

End Sub
'考虑三个过程:Proc1、Proc2、Proc3

'Proc1调用Proc2和Proc3

“Proc2和Proc3之间的唯一区别是 '参数pmyInt的调用方式不同:ByVal vs ByRef

'Proc2不会更改参数myInt 'Proc3会更改参数myInt

我的问题的根源是为什么会有同样的行为 '未与对象一起显示(VBA.Collection) “假设我不想更改原始收藏 '如何处理?

在VBA中,对象(如集合)始终通过引用传递。通过ByRef传递对象时,将传递对象的地址,PopulateCollection可以更改引用

当您通过val传递它时,将传递引用的副本。引用的副本仍然指向原始集合,但如果更改副本,则不会在RunProc中更改引用

Sub RunProc()

    Dim MyCol As Collection
    Dim i As Long

    Set MyCol = New Collection

    PopCollByVal MyCol

    'I changed what pMyCol points to but *after*
    'I populated it when it still pointed to MyCol
    'so this returns 3
    Debug.Print "ByVal: " & MyCol.Count

    PopCollByRef MyCol

    'When I changed the reference pMyCol it changed
    'MyCol so both became a new Collection. This
    'return 0
    Debug.Print "ByRef: " & MyCol.Count

End Sub

Function PopCollByVal(ByVal pMyCol As Collection)

    Dim i As Long

    'The pointer pMyCol is a copy of the reference
    'to MyCol, but that copy still points to MyCol
    For i = 1 To 3
        'I'm changing the object that is pointed to
        'by both MyCol and pMyCol
        pMyCol.Add "Item" & i
    Next i

    'I can change what pMyCol points to, but I've
    'already populated MyCol because that's what
    'pMyCol pointed to when I populated it.
    Set pMyCol = New Collection

End Function
Function PopCollByRef(ByRef pMyCol As Collection)

    Dim i As Long

    'The pointer pMyCol is the actual reference
    'to MyCol
    For i = 1 To 3
        pMyCol.Add "Item" & i
    Next i

    'When I change what pMyCol points to, I also
    'change what MyCol points to because I passed
    'the pointer ByRef. Now MyCol is a new collection
    Set pMyCol = New Collection

End Function

“参数和参数”是什么意思?你的问题有点不清楚,你能试着更清楚地表达你期望发生什么吗?(另外,如果您不想
PopulateCollection()
更改您的集合,那么首先为什么要调用该函数?)。。。如果不希望填充
mycl
,则不要将其传递给函数。当执行RunProc并在过程结束时循环mycl时,它应不返回任何内容,因为不应填充mycl(参数)。在PopulateCollection中只应填充pMyCol,而不是MyColIn。换句话说,实例化一个集合,然后将其传递给一个过程。此过程获取集合并对其进行处理。但是我不希望原始的collection:MyCol仅被更改为传递的collection:pmycol但是该函数被称为
PopulateCollection
,当它按照框中的说明执行时,您不应该感到惊讶
pMyCol
mycl
是一回事,它们不是分开的。问题是:如果不想填充集合,为什么要调用函数
PopulateCollection