Solved

Two Variables Referencing The Same Array

Posted on 2002-07-16
11
168 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
Comment Utility
Oh, and I want to avoid copies... I want to REFERENCE B1 and B2 via BA. Thanks.
0
 
LVL 1

Expert Comment

by:Evlich
Comment Utility
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
Comment Utility
I dont think you reference an Array as an object like that in VB as you can (I think) in C++.
0
 
LVL 4

Expert Comment

by:AlonHirsch
Comment Utility
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
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 17

Expert Comment

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
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…
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…

728 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now