Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I? : Hide nested classes

Status
Not open for further replies.

thefarg

Programmer
Jan 25, 2012
94
NZ
Hi. I have a class consisting of several nested classes. How do I make these hidden to the project while still allowing them to be accessed through the parent classes namespace? If It was just the functions, properties etc, I could make them private. Can I make private or friend classes? Any way I can accomplish this?

Cheers
Mike
 
No such thing as a nested class in VBA so I assume it is a vb.net question.
1) Create a Nested Interface with Private accessibility. This will give only the Parent class and nested children access
2) Add the properties/methods you want access to to that interface
3) Make the Nested class implement the interface
4) Make all of the implementations have private
Now the parent class and only the parent class will have access to those properties and methods.
 
Sorry, MajP, I only use VBA. My main/parent class ....
Code:
Public Settings As cBDBSettings
Public Shortcuts As cBDBShortcuts
Public CompanyData As cBDBProps

Private Sub Class_Initialize()
Set Settings = New cBDBSettings
Set Shortcuts = New cBDBShortcuts
Set CompanyData = New cBDBProps
End Sub
where cBDBSettings, cBDBShortcuts & cBDBProps are the classes doing the work. I can use via cBorus.Settings.<whatever> . So what is it I have created and how do I hide the workhorse classes?

Thanks
Mike
 
Just so you know a Nested class is very different then a composite class. In a language like vb.net you can build a nested class. Where the nested class is built inside another class

public class someclass
....
private class NestedClass
....
end class
end class

What you are describing is simply a composite class. A class with properties that are also classes

Although you can choose to make class properties public, I really recommend to make them private and use set/get assessors even in vba.

In vba the terms you list, "nested", "freind", "namespace" do not even have meaning. There is no such thing as inheritance in vba. So what you describing for sure cannot be done as you said. It does not even have meaning.

Is this an academic exercise or is there a purpose? I cannot imagine you are making a commercial library "add -in" that people would use for coding. I assume this is for your own use. So why the concern of hiding the ability to instantiate the child classes?
 
Sorry should say

Although you can choose to make class Variables public, I really recommend to make them private ...
 
Just personal preference. I have written an invoicing/accounts system for our company and am spending time tidying up the code.
I'd prefer for most of the settings and company information to be accessible as part of my class. I'd prefer not to see the sub-composite (or whatever) classes in the Object browser and intellitype. Is it possible?
You recommend making the variables private..... what effect will this have on the scope?
 
You recommend making the variables private..... what effect will this have on the scope?
The normal practice is to make the variable in the class private and the accessors public. This allows you to have a layer of encapsulation. It is poor practice to allow outside access to have access to class variables. This is a tenant of good OOP. Outside access should go through you let/set and get accessors.

Unfortunately in VBA I do not think there is a way to do what you want.

sub-composite (or whatever)
Sorry but there is no "whatever" here. A composite class is not a nested class. In computer programming there is a very specific lexicon for a purpose. These two things are completely different and one does not even exist in vba as I pointed out.

 
So... can I make the accessors of the sub-composite classes friend only with the super-composite or does Friend mean friend to the whole project?
Are you suggesting that I create an Interface class to make the accessors public?
 
I am sorry, but your questions are like an enigma. You reference advanced concepts, but none of these even have meaning in vba. Please do not take this wrong, but I have posted thousands of replies to threads, and have never met anyone who poses questions like this. My guess you are some super genius who never programmed before. Then you picked up a vba book and memorized it, but you started reading it from the back forward and then the first 5 chapters were missing. So you digested the really complex stuff with no understanding of the simple stuff.

You keep throwing out complex terms that have absolutely no meaning in vba. Again there is no nesting in vba. There is no "super class" because there is no inheritance. You can kind of sort of make interfaces in vba, but there is not such thing as an interface class.

However, we have two things going on. One is just the proper encapsulation of a vba class. Normally you do not allow class variables to be directly accessed. You require that the instantiated object properties are accessed through accessors.

so I would always do this

Code:
Private mSettings As cBDBSettings
Private mShortcuts As cBDBShortcuts
Private mCompanyData As cBDBProp

Public Property Get Settings() as cBDSettings
  Settings = mSettings
end property

Public Set Settings(byVal Value as cbdSettings)
  Set Settings = value
end Property

If this looks primitive compared to other languages, it is but that is how you do it. Is it required? No. Is it preferred yes. There is lots of reasons. But bottom line I will not give direct access to my class variables. This has nothing to do with your original question.

Friend modifier in vba is almost useless. A friend modifier allows a procedure in an object module be called only from within the project that contains the class, regardless of the Instancing property of the class. Although you can instance classes in other vba projects, it is extremely clumsy.

Are you planning to put your code in a library external to the datbase current project? As I said this can be done, but using objects in external libraries is extremely clumsy.

So I may be wrong, but doing what you want is really not doable in vba. I can think of a workaround, but it becomes so clumsy it is not worth it.
 
Not quite. Used to program in Basic on my Vic 20, hook into local BBS etc. A whiiile back. I've written levels for Neverwinter Nights, using a language very similar to C, written InstallShield installers, language syntax, again very simular to C, written a few installers using .inf, javascript,WSH, small amount of python, ASP, PHP, dhtml etc. Decided to make a custom invoicing/management/etc app to take over from the minimally featured one we use now. I have a book on VB.Net so had a quick read of that prior to getting started. Bit disappointed at the amount of fairly simple tasks needing to call the API. Didnt realize that VBA was still at the level of VB6, but happy enough with that. Seems that plenty of usefull calls are documented but the wide ranging community, however there are several things I still need to examine in order to utilise in my app. Such as inter-application use of withevents, these class issues and things related to both outlook and word object models.
I have seen an example of an interface, essentially a class with no procedures, Is that actually what it is or is it differently named and only mimicing an interface?
Oh, one more question, any idea on the language to be shipped with the next version of office?
 
I can think of a workaround, but it becomes so clumsy it is not worth it.
Workarounds are usually clumsy. Please post the code, If it doesnt help me progress the project, it may help progress my understanding ;)
 
Hmmm. after using your code I got an 'object variable or with block variable not set' error, pointing to this line.
Code:
ChangeGraph (BorusDB.Settings.HomeGraphNumber)
Using your code, MajP, should I still be able to access the nested members?
 
VB6 and VBA are very primitive when it comes to working with classes. With your background have you considered building this in Visual Studio? Although I consider myself a expert in Access VBA, I have been developing in VB.net for the last year. I am just so impressed. The design environment makes everything so easy and the VB.net is so robust. I am just using VS express with SQL express all for free, and you can do some pretty impressive things. Now coding in vba is becoming painful. It seems in a lot of your questions, you are trying to figure out ways to do things that cannot be done in vba, but are easily done in vb.net.

Below you say:
Bit disappointed at the amount of fairly simple tasks needing to call the API.
Are you referring to VBA or .net.


Read this article. For working with classes in vb6 and vba. This will show you the accessors using get, let, and set procedures.


Here is one reason to make class variables private with public accessors, but there many others:

should I still be able to access the nested members?

Again, I hate to be picky but the term is not nested. In OOP the term is "Containment" or "Aggregation". Containment means that an object contains another object. This is a "Has a" relationship. This is different from inheritence where you have "is a" relationship. A "dog" class should inherit from an animal class because a dog "is an" animal. A customer class should contain an adress class because a customer "has an " address. Nested classes are a "has a" relationship with the stipulation that it really only exists in the context of the parent class. Unfortunately VBA does not support inheritence or nesting.

should I still be able to access the class properties?
Yes of course. That is the whole purpose. See the link above. You do this almost every time you write vba code.
Forms.item("frmName").controls.item("controlName").value = 2
The control object has value property with a getter and setter
The controls collection has an item property with a getter and setter. (Note. Most times you omit the item property because it is the default property)

I have seen an example of an interface, essentially a class with no procedures, Is that actually what it is or is it differently named and only mimicing an interface

Unfortunately yes.
Versions of Visual Basic prior to Visual Basic .NET could consume interfaces but not create them directly. Visual Basic .NET introduces the Interface statement, which allows you to define true interfaces as distinct entities from classes, and to implement them with an improved version of the Implements keyword.
I never found a real use for interfaces in VBA. In vba it is nothing more than a contracts that says if you implement this class then you have to provide the same methods. In VB.NET and other languages interfaces introduce another level of abstraction that you can apply to your program logic. By declaratively implementing an Interface in many Classes, you can then refer to instances of those Classes through the Interface type. Then, you can call the Interface functions, which will invoke the specialized functions from the Classes. This makes it possible to streamline the logic in your program through data-directed design. That cannot be done in vba.
 
You should pick up a vba book, and go to the chapter on custom classes. After reading the 3 pages, you will then understand that is all there is. Nothing more. The stuff that is basic in other Object Oriented languages just does not exist. So either lower you expectations and stick with vba or switch to a vb.net or other front end. Obviously the complex things that are very very easy to do in access (example: bound continous forms) will require a lot more work. Also I expect to see vba to always be the language inside office. However, you will see more use of macros not less, because of sharepoint compatability. But I also think it is getting easier and easier to build .net applications that use/manipulate office products.
 
Do you think that some .net functionality will migrate to Office? Surely with the large installed user base VB6/VBA wont go away but integration of native sound, registry, shell tasks etc wouldnt be hard for MS to implement. I have seen plenty of classes, typelibs and controls that tidy up the interface with the WinAPI. The "My" namespace would be very handy too.
Any idea with the error posted above? I did change your code as the set statement omitted the word property and it threw an error. It appears to error out on the first access of the property get,
Code:
ChangeGraph (BorusDB.Settings.HomeGraphNumber)
code is asking the class for the value of .HomeGraphNumber. Any ideas?
 
In my code, I use
Code:
Private Sub Class_Initialize()
Set Settings = New cBDBSettings
Set Shortcuts = New cBDBShortcuts
Set CompanyData = New cBDBProps
End Sub
to initialise the variables. How should I initialise whilst using your code MajP?
 
This is a subroutine and not a vba function
ChangeGraph ?

If so then the proper way in vba
ChangeGraph BorusDB.Settings.HomeGraphNumber
No parenthese when calling methods that do not return values or if not keeping the value
However if you use the call keyword
call ChangeGraph (BorusDB.Settings.HomeGraphNumber)

That is why it is

Msgbox "Some message"

Or
if msgbox("Some Message,,vbOKCancel) = vbOk then

If not returning a value no () unless using the call keyword.
 
OK. Syntax compiles and runs either way for me. Still, I am getting 'object variable or with block variable not set' error. I tried running your code with the mSettings Set in the class initialise routine, still with no luck. Have you had similar code operational?
 
Also does your
cBDBSettings
have a getter for HomegraphNumber

public Property Get HomeGraphNumber as someDatatype
HomeGraphNumber = mSomePrivateClassVariable
end property


Just to be clear, using accessors is not required but it is a very good practice for encapsulation, reuse, and flexibility. When working in .net I use accessors even for class variables used only within the class. Just makes the code cleaner and more modular.
 
I would prefer to do it your way, not sure where the error lies. I Have gets and sets for all properties in these 'sub' classes. They are complete classes, lacking methods but all properties are sound. Just to be clear... it works as I had it, just trying to encapulate it as in your code throws the error.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top