Two Variables Referencing The Same Array

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.

Who is Participating?
pierrecampeConnect With a Mentor Commented:
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
enoch100Author Commented:
Oh, and I want to avoid copies... I want to REFERENCE B1 and B2 via BA. Thanks.
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
Never miss a deadline with

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

I dont think you reference an Array as an object like that in VB as you can (I think) in C++.
Alon HirschSoftware Development ManagerCommented:

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.

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

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

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
enoch100Author Commented:
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.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.