集合对象-ByRef-ByVal [英] Collection Object - ByRef - ByVal

查看:90
本文介绍了集合对象-ByRef-ByVal的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Access 2013中使用VBA.

I am using VBA in Access 2013.

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

In a regular module there are 2 procedures, RunProc() and PopulateCollection()

当执行RunProc时,它将调用PopulateCollection,其中 传递的参数是一个名为MyCol的Collection实例.

When RunProc is executed it calls PopulateCollection where the argument passed is an Collection instace named MyCol.

PopulateCollection添加3个项目,然后RunProc通过迭代Collection继续.

PopulateCollection adds 3 items and then RunProc continues by iterating the Collection.

我的问题是:

我希望RunProc中的参数MyCol不由PopulateCollection填充.完成此操作的正确方法是什么?

I want the argument MyCol in RunProc to NOT be populated by PopulateCollection. What is the proper way to accomplish this?

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

Why does PopulateCollection populate both the argument and parameter?

' --------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


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


Here is another way of asking my question:

选项比较数据库 显式选项

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

'考虑3个过程:Proc1,Proc2,Proc3

'Consider the 3 procedures: Proc1, Proc2, Proc3

'Proc1调用Proc2和Proc3

'Proc1 calls Proc2 and Proc3

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

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

'Proc2不会更改参数myInt 'Proc3确实更改了参数myInt

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

'我的问题的根源是为什么同样的行为是 '未与对象一起展示(VBA.Collection) 假设我不想更改原始收藏集 我将如何进行?

'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 procede?

推荐答案

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

In VBA, objects (such as Collections) are always passed by reference. When you pass an object ByRef, the address of the object is passed and PopulateCollection can change the reference.

当您将其传递给ByVal时,将传递引用的副本.引用的副本仍指向原始Collection,但是如果您更改副本,则不会在RunProc中更改引用.

When you pass it ByVal, a copy of the reference is passed. The copy of the reference still points to the original Collection, but if you change the copy, you don't change the reference in 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

这篇关于集合对象-ByRef-ByVal的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆