Better way to hold a permanent instance besides using public variables?

Banana

split with a cherry atop.
Local time
Today, 08:45
Joined
Sep 1, 2005
Messages
6,318
I'm in middle of development and I find myself losing reference to a declared object which is supposed to stay alive for the application's lifetime. It's currently declared as a public variable.

Now, whenever there's an error, it loses reference, but that's because I am still in development and need to do some more tests, but there are also cases where leaving the application idle for a period causes Access to forget the reference.

I'd have put it in a class module so it could at least clean after itself if the reference is lost, but this would be *lot* extra work just to declare an object, then call the procedures as a method of that object, and besides I don't want more than one instance of that object anyway.

Does anyone know of a better way to hold that object in memory a bit more persistently than a public variable?
 
...there are also cases where leaving the application idle for a period causes Access to forget the reference...

Curious... Do you know why?

As far as an option for persisting the data, could you hold it in a local table?

Regards,
Tim
 
I sometimes use a hidden form to keep variables. I just put several textboxes on the form and name them something I know and then I can use them as needed.

Forms!MyHiddenFormNameHere.MyTextBox1 = "Whatever"
 
pono1,

I definitely do know that if there isn't an error handling, and VBE breaks on an error, even one unrelated to the object, and I click "Stop" on the Debug dialog, it throws out all references. This is easily fixed with error handling, but as I said, this is still in development and I'm just not ready to put in general error handling, and VBE's break on all errors is a bit overkill at this point.

However, leaving Access idle shouldn't do that, but it apparently does, for reasons I have yet to figure out.

Bob, thanks for the suggestion, but what about object variables? In this case, I'm referring to a object that is instatiating using a class from an external library.
 
Bob, thanks for the suggestion, but what about object variables? In this case, I'm referring to a object that is instatiating using a class from an external library.
not completely sure as I am not as OOP on things as you are. I have an app right now that I tried using properties with but when I'm debugging I can still lose them too during errors and all. So, the form seemed to be the least prone to losing things but what you suggest may be a better way as you wouldn't need something predefined.
 
I was afraid of that answer.

But thanks for your help, Bob.
 
>>Now, whenever there's an error, it loses reference,<<

That is not correct but simply maybe ambiguous.

Variables, Local, Global or Public do not loose their value on error and it can be proved.

If an unhandled error occurs the values remain the same as they were before the error.

If Access needs to restart, due to the error, then it also needs to reinstate the conditions with which it originally started.
That means that Access needs to re-initialize its declared Public variables.
(Local variables are automatically initialized when the procedure is called. Not Static variables.)
Numbers are initialized to 0.
Strings are initialized to ZLS.
Objects are initialized to Nothing.
Variants are initialized to Null.

Access variables do not simply loose their value on error.
They are deliberately re-initialized if it is required to a restart from start.

It’s that deliberate restart from start that requires the variable initialization and perhaps data loss.
 
Interesting info.

So local variables can be made persistent if made a static variable.

But when I need it to be public variable, Static is not available.

I tried toying with this:

Code:
Static Property Get MyObject()

Dim pObject As Object

If pObject Is Nothing Then
     pOjbect = New Object
End If

MyObject = pObject

End Property

But I get a "Object variable not set" error on the line when I try to instantiate a static variable for first time.... :(
 
Well, I found it quite unintuitive, but so far, it seems to work:

Code:
Static Property Get MyObject() As MyObject

Dim pObject as New MyObject

Set MyObject = pObject

End Property

I thought it'd instantiate a new object every time it was called, but apparently not...


Edit: I spoke too soon. It seems to survive multiple calls but once the calling procedure is done, the variable goes out of scope.
 
Shouldn't you make the (instance of the) object static? Once instantiated as a static within the subroutine, it should not go away (I think). Not sure what would happen if you went into design mode and back into display mode, though.

And I always wonder about what happens in memory when all these global/static objects are orphaned by switching between design/display modes. Chris was helpful in understanding they're "reinitialized". Does that mean the memory is freed up? If so, cool!
 
George,

The object is supposed to stay in scope for the application's lifetime, and ideally shouldn't be dependent on anything else for its scope. As you can see, I'm trying to cram it in a static property Get procedure, but it won't stick (see my previous post).
Normally, we would do this:
Code:
Private mMyObject As MyObject

Property Get MyObject() As MyObject

Set MyObject = mMyObject

End Property

Property Set MyObject(ReNew as Boolean)

If mMyObject Is Nothing And Not ReNew Then
      mMyObject = New MyObject
End If

End Property

But we're back to square one because we're still using a public variable, mMyObject to hold the instantiation. :/ Unless I'm misinformed, this still could get re-initalized, as per ChrisO's description.

Regarding putting it in a form module:

The trouble with putting it in a form module is that I now have to reference it like this:

Code:
Forms("MyForm").MyObject

A bit awkward, no? Now, I could just create a function:

Code:
Public Function GetMyObject() As MyObject

GetMyObject = Forms("MyForm").MyObject

End Function

But it feels like a clunky solution- If I can make it a function, why didn't I make it an actual instantiation within the function?!?

Yes, VBA does have an automatic garbage collection, but it seems to be the SOP to manually clean up after yourself anyway for reasons that has long been forgotten. :/
 
Why dont you simply use registry to hold your values
Its lot more easy than any other option
 
Why dont you simply use registry to hold your values
Its lot more easy than any other option

Using the registry can have its problems too.

1. Depending on who is doing this, they probably shouldn't be messing with the registry.

2. Security protocols in place may prohibit doing this.

3. Writing registry values in Windows Vista requires a program to "Run As Administrator" which may not be good, or allowed.

Another suggestion would be to use an INI file in the CurrentProject Path to read and write values to (if you were going to go down the path of using the Registry). It would be just as easy and not have as many issues.
 
As usual, Bob nails it.

IMO, the registry is an abomination that should have never had left the Castle Frankenstein, and using a .INI file is much more safe and not as likely to bork up everything else.

The trouble, however, is that they'd just work for primitive types and maybe UDTs, but not for an instance of an object, and if they only worked for primitive types, Const actually would be much more better solution, especially as it's usually faster to access as it's compiled into every time it's called, whereas an variable would be just an pointer to another location of the memory, even if called ByVal.
 

Users who are viewing this thread

Back
Top Bottom