Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Two Variables Referencing The Same Array

Posted on 2002-07-16
Medium Priority
Last Modified: 2010-05-02
Dim B1(5) as byte
Dim B2(5) as byte

Private Sub SomeMethod()
   Dim BA() as Byte
   BA = B1
   BA(0) = 20
   Msgbox B1(0)
   'Should get 20 as a result

   BA = B2
   BA(0) = 30
   Msgbox B2(0)
   'should get 30 as a result
   Msgbox B1(0)
   'should get 20 as a result
End Sub

How do I make this do what I want it to?

Please understand it needs to be extremely fast and efficient.

Question by:enoch100
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Author Comment

ID: 7158652
Oh, and I want to avoid copies... I want to REFERENCE B1 and B2 via BA. Thanks.

Expert Comment

ID: 7158662
This is straight out of the MSDN documentation:

Generally, when you use Set to assign an object reference to a variable, no copy of the object is created for that variable. Instead, a reference to the object is created.

So it sounds to me like you could just say:
Set B2 = B1

Expert Comment

ID: 7158685
I dont think you reference an Array as an object like that in VB as you can (I think) in C++.
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

by:Alon Hirsch
ID: 7158795

The problem with the assignment that you are performing is that you are using a NEW variable and copying the contents from B1 or B2 into it.
The easiest way to accomplish what you are trying to do is to pass the variables B1 and B2 as parameters to the sub using the BYREF syntax.
This will pass a reference (pointer) to the array instead of the actuall array.
The within the sub, simply reference B1 and B2 directly.

Private Sub DoSomething(ByRef B1() As Byte, ByRef B2() As Byte)
    B1(0) = 20
    MsgBox B1(0)
    'Should get 20 as a result
    B2(0) = 30
    MsgBox B2(0)
    'should get 30 as a result
End Sub

If B1 and B2 are module level array variables, then you doi not need to pass them as parameters to this sub if it is within the same module.

VB does not support pointers as C/C++ do.

LVL 14

Expert Comment

ID: 7158864
Dear friends,

Arrays are never passed ByRef, they are always passed ByVal, which means another copy is created for the called function.
so you have to find out another logic to do this.

a thought -
keep it global where calling and caller both the functions can access it.
then you can do whatever you want to do with it.
LVL 17

Expert Comment

ID: 7159030
Here is the concept that you can use in a Value object class.  Here is the simple concept using a Variant Array first, next post will include the full blown object class:

Private Sub Command1_Click()

Dim M
Dim Bt As Byte

' Create an array with 2 elements of Byte
M = Array(Bt, Bt)

' Put in a number
M(1) = 3

' create another variable
Dim J

' Now make a copy of  M in J
MsgBox J(1)

' Create some more elements in J
ReDim Preserve J(10)
J(10) = 12

' now move them back
M = J
MsgBox CStr(J(10))

End Sub

LVL 17

Expert Comment

ID: 7159035
The probem with using the above post is that it when saying:

M = J ' the arrays are copied so subsequent changes won;t be in both arrays. To acheive this you need to use the same concept but within an object. I have some code that does this.
LVL 17

Expert Comment

ID: 7159078
So here it is, have fun:

Private Sub Command3_Click()

Dim M As New clsMagic

M.ReDimPres 100 ' redimension the array
Dim J

Set J = M

M(1) = "Fred"
J(1) = "Jim"

If M(1) = "Jim" Then
    J(2) = " ** Yes it worked"
    J(2) = " ** Bad Idea it failed"
End If

MsgBox "Should be Jim and not Fred: " + M(1) + J(2)

End Sub

Now paste the following into a text file, and rename the  text file clsMagic.cls, then add the file to your project.

  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
Attribute VB_Name = "clsMagic"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Public mVar

Sub ReDimPres(Index As Long)
ReDim Preserve mVar(Index)

End Sub

Public Property Get Value(ByRef Index As Long) As Variant
Attribute Value.VB_UserMemId = 0

Value = mVar(Index)

End Property

Public Property Let Value(ByRef Index As Long, ByVal vNewValue As Variant)
mVar(Index) = vNewValue
End Property

Private Sub Class_Initialize()
 mVar = Array("Fred")

End Sub

Private Sub Class_Terminate()
Set mVar = Nothing
End Sub


Expert Comment

ID: 7159087
some DANGEROUS way:
***** CPtrByteArray *****
Option Explicit
Private Declare Sub CopyMemory _
    Lib "kernel32" Alias "RtlMoveMemory" _
    (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)

Private mPtr            As Long
Private mLBound         As Long

Public Sub PointTo(ByteArray() As Byte)
    mLBound = LBound(ByteArray)
    mPtr = VarPtr(ByteArray(mLBound))
End Sub

'Default Property
Public Property Get Item(ByVal Index As Long) As Byte
    CopyMemory VarPtr(Item), mPtr + (Index - mLBound), 1
End Property
Public Property Let Item(ByVal Index As Long, ByVal RHS As Byte)
    CopyMemory mPtr + (Index - mLBound), VarPtr(RHS), 1
End Property

**** Calling Code *****
Dim B1(5) As Byte
Dim B2(5) As Byte

Private Sub SomeMethod()
  Dim clsPtr As CPtrByteArray
  Set clsPtr = New CPtrByteArray
  clsPtr.PointTo B1
  clsPtr(0) = 20
  MsgBox B1(0)
  'Should get 20 as a result

  clsPtr.PointTo B2
  clsPtr(0) = 30
  MsgBox B2(0)
  'should get 30 as a result
  MsgBox B1(0)
  'should get 20 as a result
End Sub

Accepted Solution

pierrecampe earned 1200 total points
ID: 7159519
or the save way:
Private Type ByteType
     a() As Byte
End Type
Dim T1 As ByteType
Dim T2 As ByteType

Private Sub Command1_Click()
    Dim i As Integer
    For i = 1 To 10
        SetValue i, CByte(i * 2)
End Sub

Private Sub Form_Load()
   ReDim T1.a(1 To 10)
End Sub

Private Sub SetValue(Element As Integer, Value As Byte)
    T1.a(Element) = Value
    LSet T2 = T1
    Debug.Print Element, T1.a(Element), T2.a(Element)
End Sub

Author Comment

ID: 7160103
I'm going to accept this as the correct answer. It led me to ultimately solving my problem using a method very similar to it. Thank you everyone for your input.

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question