1

I'm starting to learn OOP so forgive me (or offer suggestions) if my UML is not keeping to standards.

Currently writing in VBA due to business restrictions so I don't have access to inheritance but it does have support for events and interfaces.

I have a Folder class (in blue) which has an object mFileSystemObject of type FileSystemObject

The Folder class holds many File objects in an array called Files.

Each File object has a FileDetails object (green).

I'd like to use the functions from the FileSystemObject class in the FileDetails class.

I'd like to use the same instance of the FileSystemObject in the Folder class as I don't want to instanciate a new one for every FileDetails class and fill up the heap and I'm not doing any work concurrently.

So I'd like to pass the reference to the FileDetails class so they all use the same one.

The only way I can think of doing this is to pass it through the File object even though File will not use it which just seems a bit ugly.

My question is - is there a pattern that solves this "passing through" problem - I've searched online and looked at several design patterns but they don't seen to offer any suggestions for a solution.

Any help would be greatly appreciated.

Many Thanks

Nick

enter image description here

4
  • You could instantiate a singleton object of FSO class and have it consumed by all FileDetails objects and by all Folder objects, too. It should behave like a Static object in C# but I don't know if VBA allows for that. Commented Apr 8, 2020 at 16:36
  • Are you saying you want a single instance of FileDetails for the entire applilcation? All Files inside all Folders use the same one? Commented Apr 8, 2020 at 16:39
  • @ArcherBird, yes. At least that is my proprosal. But the real need is for Nick to state Commented Apr 8, 2020 at 16:40
  • also, good for you for taking an OOP approach in VBA! :-) Commented Apr 8, 2020 at 16:55

1 Answer 1

1

So this would be a singleton pattern; there are a few ways to do this in VBA. I'll give you two.

1) Create a new Module, let's call it FileDetailsBuilder. In this module, give it a private instance of your FileDetails class. Then expose a public function that will return its instance , or create a new one if it doesn't exist.

Option Explicit

Private mFD As FileDetails

Public Function GetObject() As FileDetails
    If mFD Is Nothing Then
        Set mFD = New FileDetails
    End If
    Set GetObject = mFD
End Function

Now when you create new File objects, you can set their FileDetails member using a line of code like this:

Set mFileDeatils = FileDetailsBuilder.GetObject()

The mFD instance member will live on as long as your application is running.

2) You can alter some code in your FileDetails class to make it be treated like a single, pre-declared object. To do this, you need to export the class and alter some code that you can't see from the VBE.

In a text editor, at the top of the .cls file that you exported, you would see some attribute assignments. One of which is VB_PredeclaredId. Well my friend, you can edit this .cls file and set that attribute to true:

Attribute VB_PredeclaredId = True

Save the file, and import it back into your VBE project. Now, you don't have to instantiate this object. Just use it like a static object. When you create new File objects, assign their member like this:

Set mFileDeatils = FileDetails '// note the lack of new keyword

Sign up to request clarification or add additional context in comments.

3 Comments

as to point 2): should "single, per-declared object." be "single, pre-declared object."?
The RubberDuck can set VB_PredeclaredId for you: rubberduckvba.com
@HackSlash mmm, love me some RubberDuck :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.