Solved

Two Variables Referencing The Same Array

Posted on 2002-07-16
11
170 Views
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

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

Thanks
0
Comment
Question by:enoch100
11 Comments
 

Author Comment

by:enoch100
ID: 7158652
Oh, and I want to avoid copies... I want to REFERENCE B1 and B2 via BA. Thanks.
0
 
LVL 1

Expert Comment

by:Evlich
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
~evlich
0
 
LVL 6

Expert Comment

by:xSinbad
ID: 7158685
I dont think you reference an Array as an object like that in VB as you can (I think) in C++.
0
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 
LVL 4

Expert Comment

by:AlonHirsch
ID: 7158795
Hi,

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

HTH,
Alon
0
 
LVL 14

Expert Comment

by:puranik_p
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.
0
 
LVL 17

Expert Comment

by:inthedark
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


0
 
LVL 17

Expert Comment

by:inthedark
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.
0
 
LVL 17

Expert Comment

by:inthedark
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"
Else
    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.

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
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




0
 
LVL 4

Expert Comment

by:TigerZhao
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

  'Now...
  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
0
 
LVL 6

Accepted Solution

by:
pierrecampe earned 300 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)
    Next
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
0
 

Author Comment

by:enoch100
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.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

Suggested Solutions

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

828 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