首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集合对象- ByRef - ByVal

集合对象- ByRef - ByVal
EN

Stack Overflow用户
提问于 2014-02-17 23:24:51
回答 1查看 13.9K关注 0票数 3

我在Access 2013中使用VBA。

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

RunProc被执行时,它调用PopulateCollection,其中传递的参数是一个名为MyCol的集合实例。

PopulateCollection添加了3个项目,然后RunProc继续迭代集合。

我的问题是:

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

为什么PopulateCollection要同时填充实参和实参?

代码语言:javascript
复制
' --------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

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

代码语言:javascript
复制
Option Compare Database
Option Explicit

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

'Consider the 3 procedures: Proc1, Proc2, Proc3

'Proc1 calls Proc2 and Proc3

'The only difference between Proc2 and Proc3 is that
'the parameter pmyInt is called differently: ByVal vs ByRef

'Proc2 does not change the argument myInt
'Proc3 does change the argument myInt

'The root of my question is why the same behavior is
'not exhibited with an Object (VBA.Collection)
'Assuming I wanted to not have the original Collection altered
'how would I proceed?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-18 08:07:40

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

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

代码语言:javascript
复制
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
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21832891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档