PDA

View Full Version : [SOLVED] Is Variable Allocated



fredlo2010
06-12-2014, 07:12 AM
Hello everyone,

I was wondering if there is a way to do this? I mean there is a way to do it as in my example bellow. But is this a reliable way? I am planning to implement this in a class that has about 30 properties and I want to check if the variable has been allocated or not because some of the properties depend on each other.



Function IsVarAllocated(ByVal varVariable As Variant) As Boolean
IsVarAllocated = (Not varVariable = Empty)

End Function


Sub TryFunction()


Dim bSample As Variant

If IsVarAllocated(bSample) Then MsgBox "This Variable has been Allocated."

End Sub


Additional Info:

The code above works as intended and will give me what I need. Also I am checking for Boolean variables which are automatically initialized as FALSE.

Thanks a lot for the help :)

ranman256
06-12-2014, 07:30 AM
I dont think varVariable will EVER be empty. This can only happen if the parameter is OPTIONAL ,yours is not.
Cant you just test for <> "" since its never been assigned?

fredlo2010
06-12-2014, 07:40 AM
Thanks ranman256,

Take a look at the additional Info I posted.


Thanks a lot for the help.

Bob Phillips
06-12-2014, 09:03 AM
Why not initialise all of the variables in the Class_Initialize routine?

Another, kludgy way, would be to use all variant types and initialise with some error text, which would get overwritten when a good value is passed.


'Class1

Option Explicit

Private mcAllDone As Variant

Public Property Get AllDone() As Variant
AllDone = mcAllDone
End Property
Public Property Let AllDone(ByVal Value As Variant)
mcAllDone = Value
End Property

Private Sub Class_Initialize()
mcAllDone = "AllDone not initialised"
End Sub


'Module

Sub test()
Dim c1 As Class1

Set c1 = New Class1
MsgBox c1.AllDone
c1.AllDone = True
MsgBox c1.AllDone

End Sub

fredlo2010
06-12-2014, 12:54 PM
Hi xld,

Yes all the variables are been initialized in the Class_Initialize method. The problem is that some of those variable depend on each other so they have to be initialized in order. I am debugging code somebody else wrote and I am trying to slowly adjust it. So today my code was not working as intended because of that one variable was not initialized and it was been checked (of course the boolean passed "FALSE" which is incorrect)

With this happening I just wanted to add another safety net to the project so I can move with a little more of confidence when re-factoring. This is about 30 modules, 15 procedures average per module and about 10 public variables. (the math is 300 most of them just duplicate variables) All of this can be condensed and optimized I would say to 5 solid classes that I will just pass around. (got a little bit off topic here)

So my main concern here is the memory and optimization of it with all those "variant" variable that are actually "boolean"

This is sample more or less of the way it would look.

Class Module:

Option Explicit

Private m_varAllDone As Variant
Private m_varAllDone1 As Variant

Public Property Get AllDone() As Variant
AllDone = m_varAllDone
End Property
Public Property Let AllDone(ByVal varAllDone As Variant)
m_varAllDone = varAllDone
End Property
Public Property Get AllDone1() As Variant
AllDone1 = m_varAllDone1
End Property
Public Property Let AllDone1(ByVal varAllDone1 As Variant)
m_varAllDone1 = varAllDone1
End Property

Private Sub SetValues()

m_varAllDone = True

If IsVarAllocated(m_varAllDone) Then
If Not m_varAllDone Then
m_varAllDone1 = False
Else
m_varAllDone1 = True
End If
Else
Err.Raise 10000, "Set Values for " & m_varAllDone, "Error the variable has ot been initialized"
Exit Sub
End If
End Sub


Private Function IsVarAllocated(ByVal varVariable As Variant) As Boolean
IsVarAllocated = (Not varVariable = Empty)
End Function

Private Sub Class_Initialize()
Call SetValues
End Sub

Code Module:

Option Explicit

Sub TrySub()

Dim cls As Class1

Set cls = New Class1

End Sub



Thanks

Paul_Hossler
06-12-2014, 01:51 PM
Somehow I don't think that the class initialize method is the way to go. I'd try something like the Sub .Init in my class module




Option Explicit

Private m_varOne As Long
Private m_varTwo As Long

Property Get WhatIsOne() As Long
WhatIsOne = m_varOne
End Property
Property Let WhatIsOne(x As Long)
m_varOne = x
End Property

Property Get WhatIsTwo() As Long
WhatIsTwo = m_varTwo
End Property
Property Let WhatIsTwo(x As Long)
m_varTwo = x
End Property
Sub Init(x As Long, Y As Long)
WhatIsOne = x
WhatIsTwo = Y
End Sub




and this is a standard to keep things streight



Option Explicit
Sub TrySub()

Dim cls As Class1

Set cls = New Class1

Call cls.Init(100, 200)

MsgBox cls.WhatIsOne
MsgBox cls.WhatIsTwo

End Sub



All the sequence dependency sounds like a source of very hard to track down errors

fredlo2010
06-12-2014, 02:12 PM
Thanks a lot for the answer Paul always appreciated. Your idea sounds great. The only thing that I would not make to take arguments because I have a lot of variables. I am not sure why I picked the Class_Initialize for this class in particular; I am guessing I just wanted to move as much code as possible to the class and encapsulate it there and forget about it :)

Any reason in particular reason why not class initialize ?

Yeas the dependencies are not that bad the only problem is that I have to keep my eyes open for it now. Trust me it was easier to track this with the class created that it would have been with the original procedure that's for sure.

Thanks a lot for the help.

Paul_Hossler
06-12-2014, 02:55 PM
It seems a little unusual (to my limited experience as least) to have so many variables in a class, and then to have sequence dependencies on top .... sheeeesh

can you explain why SO many variables?

Paul_Hossler
06-12-2014, 03:11 PM
Another option would be to have a data object to just build your data, and then pass that object to the 'real' object


1 . clsData



Option Explicit
Private a(1 To 10) As Variant

Property Let EnterData(ndx As Long, v As Variant)
a(ndx) = v
End Property
Property Get TheData() As Variant
TheData = a
End Property




2. clsUsingClass



Option Explicit
Private V1 As Variant
Private V2 As Variant
Private V3 As Variant

Sub Init(D As clsData)
V1 = D.TheData(1)
V2 = D.TheData(2)
V3 = D.TheData(3)
End Sub


Property Get WhatV1() As Variant
WhatV1 = V1
End Property


Property Get WhatV2() As Variant
WhatV2 = V2
End Property


Property Get WhatV3() As Variant
WhatV3 = V3
End Property





3. standard module



Option Explicit
Sub Try2()
Dim D As clsData
Dim U As clsUsingClass

Set D = New clsData
With D
.EnterData(1) = 123
.EnterData(2) = "asdfasfdasdf"
.EnterData(3) = #5/7/2014#
End With
Set U = New clsUsingClass

Call U.Init(D)
MsgBox U.WhatV1
MsgBox U.WhatV2
MsgBox U.WhatV3
End Sub




But that seems complicated

fredlo2010
06-12-2014, 03:37 PM
It is strange to have so many variables in a object.

I am re-factoring some code at work I am working on the first module that contained about 3 procedures very long procedures. The variables were set public so everyone could share the data.

In order to see the actual logic a little bit more clear, I put all of those variables in the class which I will pass into all the new procedures I split out of the main one. To this point the whole module is readable. Note that I have to understand the code alone I don't have a person next to me telling me what the end result will be; and the code is really messy. My record was re-factoring a section from around 60 lines of code to about 10; still I had to go through all those lines to figure out that it was creating a list of unique values (.advancedfilter could have helped)

So yeah this is me moving things around making things more clear. Also I have noticed that the same variables are used in other parts of the code. Maybe I could just create a Public class object variable and pass it around. I could just take the data on the fly from the main setup like tab but I will be repeating the same code way too much I think.

So this might not be the last permanent solution.( of course I love this re-factoring thing because I make the code fly and my bosses happy :) )

..and even after all that work I missed that order was important. lol Its a lot I am telling you guys.

Thanks for the help

snb
06-13-2014, 03:00 AM
In one array you can easily store 30 'variables'.

fredlo2010
06-13-2014, 06:12 AM
The problem here is that the variables are all of different type and also I want to call them by the property rather than the index.

myclass.ClientNumber
myclass.IsSpecialCase

and not

ClientInfo(1)
ClientInfo(21)

Thanks for the help snb.

snb
06-13-2014, 09:08 AM
You can store any type of different variables in an array .
Why not using the simplest approach ?

If you want to 'call' by name use a dictionary.

fredlo2010
06-13-2014, 12:16 PM
Thank you all for the answers.

I am keeping the solution without any allocation check. So far I have only a few dependencies so I think I will have everything under control.

I did change the procedure to add the values out of the class initialize event as Paul suggested.

Thanks a lot.

Alfredo