Solved Implements and Class specific methodes (1 Viewer)

silentwolf

Member
Local time
Today, 08:43
Joined
Jun 12, 2009
Messages
94
Hi guys,

I am working on implement classes in vba access

I do understand how it works and how to set it up but what makes me wonder is how can I achieve in one class its ohn methods.

So if I got an implement class like


Sub DateiOeffnen(strPfadDatei As String)
End Sub

Function LiesDatensatz() As Variant
End Function

Function Datenliste() As Variant
End Function

Function Datenherkunft() As String
End Function


and one class which uses the implement class


Implements clsQuelle

Private m_strPfadDatei As String
'

Sub clsQuelle_DateiOeffnen(strPfadDatei As String)
m_strPfadDatei = strPfadDatei
End Sub

Function clsQuelle_LiesDatensatz() As Variant
'still missing
End Function

Function clsQuelle_Datenliste() As Variant
'still missing
End Function

Function clsQuelle_Datenherkunft() As String
'still missing
End Function

[B]'This would be a method for the class[/B]
Function GetAString() As String
MsgBox "working"
End Function


Its ofcourse just a samble with no real meaning as yet but how can I use the Function GetAString ?

What needs to be done in Order to be able to have a class specific method working?

Hope this is understandable what I am asking?

There are only examples of where all methods are in the implement Class and the upstract classes the same so I was wondering if someone can help me to understand what needs to be done in order to make that work.


Many Thanks

Albert
 

Ranman256

Well-known member
Local time
Today, 11:43
Joined
Apr 9, 2015
Messages
4,003
these look like normal functions not in a class.
if they are in a module, then just call: x = GetAString ()

if you had them in a class , you must create the class, then call it via:

dim clsMyClass as new cMyClass
x = clsMyclass.GetAString
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:43
Joined
May 21, 2018
Messages
5,908
I discuss interfaces in detail here.

However, IMO since VBA does not support inheritance there is such little utility in building interfaces in vba.

What needs to be done in Order to be able to have a class specific method working?
This is a huge limitation of VBA and reduces the utility of using a VBA interface. In most languages you have to implement all the methods of the interface, but you can have additional class unique methods. If I remember correctly, in VBA you are limited to only those methods of the interface, and this severely limits the utility of doing interfaces in VBA.
 
Last edited:

Pat Hartman

Super Moderator
Staff member
Local time
Today, 11:43
Joined
Feb 19, 2002
Messages
34,439
Forms are already class modules The purpose of making a class is to standardize a method that is used multiple times in multiple places. If the reuse is in the same form/report, just make a procedure in the class module of the form/report and call it.

I've never encountered any situation where I couldn't generalize some procedure by using a call and passing in a reference to the form that is invoking it. I've seen some people create a subform to handle custom navigation buttons or create a class module. For me, I put the cose in a general module and call it by passing in a reference to the form that is calling the function.

I don't want to discourage you from making classes. Just do it for the right reason and make sure you are reducing complexity rather than increasing it. The worst application I have ever had to change was written by someone who didn't understand the purpose of a class. I would read the code and find myself constantly 7 levels down with each level having no more than one line of code to get to the lowest procedure which also had only one line of code. All I can say is WHY? The code was impossible to understand it was nested so deeply for no reason. One of the things he abstracted was the TransferSpreadsheet. So instead of just writing a TransferSpreadsheet with the appropriate arguments, he created a class that took half a dozen arguments and built a TransferSpreadsheet. Did this do anything except obfuscate the code? I don't think so.
 

MarkK

bit cruncher
Local time
Today, 08:43
Joined
Mar 17, 2004
Messages
7,869
Any class in VBA, including an Access.Form, can implement one or more interfaces, can be instantiated directly, and can expose it own methods beyond the scope of any interface it implements.
A simple example: Lets say you make a navigation subform, and you want it to show the title of the form that hosts it. You could write a INavHost interface with a single property...
Code:
Property Get Title as String
End Property
So that is a class, pure interface, zero implementation.

Then, you could implement that interface in various forms that will host your Nav subform.
Code:
Option Compare Database
Option Explicit

Implements INavHost

Property Get INavHost_Title as String
    INavHost_Title = "Purchase Orders"
End Property
So that is an Access.Form that implements a custom interface.

Finally, you can write a property on your Nav subform, and (assuming you load the subform programmatically) you can do....
Code:
Private Property Get ParentForm As INavHost
    Set ParentForm = Me.Parent
End Property

Private Sub Form_Load()
    Me.lblTitle.Caption = Me.ParentForm.Title
End Sub

As long as the parent form implements INavHost, your subform is going to be totally happy interacting with it, without ever needing to know what type of object it actually is. To the subform, the ParentForm's type is INavHost, not Access.Form

That is of course a trivial example, but if you think of all the data a real nav subform and main form might want to formally exchange, you could easily elaborate on the INavHost interface to good effect. The simplicity this affords is that the next time you need to develop a new main form that needs navigation, the contract about how to make the objects work together is already completely defined.
 

silentwolf

Member
Local time
Today, 08:43
Joined
Jun 12, 2009
Messages
94
Hi guys,

many thanks to all of you and for your explainations and thoughts on this subject!
I will look through it all and hope to use it wisely in my application!

Cheers!!
 

sonic8

AWF VIP
Local time
Today, 17:43
Joined
Oct 27, 2015
Messages
483
If I remember correctly, in VBA you are limited to only those methods of the interface, and this severely limits the utility of doing interfaces in VBA.
You don't remember correctly.
 

silentwolf

Member
Local time
Today, 08:43
Joined
Jun 12, 2009
Messages
94
Hi,

You don't remember correctly.

but when I do write a method in a class and access this class then the method is not showing?
But also I do not get any compile error.
But the methode in clsQuelleCSV the method is not showing...

This is the interface Class

Code:
Sub DateiOeffnen(strPfadDatei As String)
End Sub

Function LiesDatensatz() As Variant
End Function

Function Datenliste() As Variant
End Function

Function Datenherkunft() As String
End Function


This the clsQuelleCSV

Code:
Implements IQuelle

Private m_strPfadDatei As String
'

Sub IQuelle_DateiOeffnen(strPfadDatei As String)
    m_strPfadDatei = strPfadDatei
End Sub

Function IQuelle_LiesDatensatz() As Variant
    'still missing
End Function

Function IQuelle_Datenliste() As Variant
    'still missing
End Function

Function IQuelle_Datenherkunft() As String
    'still missing
End Function

Function GetAString() As String
    GetAString = "working"
End Function

Test Module
Code:
Sub TestClassWithInterface()
    Dim clsT As IQuelle
    
    Set clsT = New clsQuelleCSV
    
    clst.GetAString                    'is not showing! '
    
End Sub


This is not really a usable code as such but was just wondering it this kind of programming could work??

As mentioned I do not get any compile Error but if I type "clsT." all methods show accept GetAString
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 16:43
Joined
Jul 9, 2003
Messages
13,796
Please bear in mind I am a complete beginner with class modules, even though I've been messing around with them for years, I still don't really know what I'm doing! My main class module is "CallCalled" which is on my website here:-


This is the "Class Module" I cut my teeth on. The above link shows you videos where I go through how it works. You can also download the class module and use it yourself.

I have recently made a new product, a "Simulated Option Group" which uses images instead of checkboxes. It is based on a class module. If you want a free copy of it, contact me by private message with in Access World Forums (AWF) and I will explain how you can get a free copy...

You may find my YouTube playlist on Class Modules useful:-

Another Play list Here on OOP's and moving to a Class Module Approach..
 
Last edited:

silentwolf

Member
Local time
Today, 08:43
Joined
Jun 12, 2009
Messages
94
Hi,
thanks for the links I will look into it!
All ideas are mostly welcome for me and give me a better understanding of it and the usage of them!

It may take a bit tougth to get through those examples but I will get back to you if I do have any questions or need further assistance !

Cheers to all for great explaination and help!

Very much appreciated :)
 

sonic8

AWF VIP
Local time
Today, 17:43
Joined
Oct 27, 2015
Messages
483
As mentioned I do not get any compile Error but if I type "clsT." all methods show accept GetAString
That's the point. You declared your variable as being of type IQuelle. - But the interface IQuelle does not have a method GetAString.
If you want to use a method that is part of your class but not the implemented interface, you need to cast your variable to the type of the class.

Code:
Sub TestClassWithInterface()

    Dim InterfaceVariable As IQuelle
    Dim ClassVariable As clsQuelleCSV
        
    Set InterfaceVariable = New clsQuelleCSV
    
    ' Both variables point to the same object!
    Set ClassVariable = InterfaceVariable
    
    MsgBox ClassVariable.GetAString     ' Compiles and runs
    MsgBox InterfaceVariable.GetAString ' Does not compile
    
End Sub
 

silentwolf

Member
Local time
Today, 08:43
Joined
Jun 12, 2009
Messages
94
Hi Sonic8,

wow many thanks!!!
Well that is a game changer lol :)

Fantastic so it works after all (y)

Cheers
 

MarkK

bit cruncher
Local time
Today, 08:43
Joined
Mar 17, 2004
Messages
7,869
If you use interfaces, you'll likely be interested in the TypeOf operator, which can tell you which interfaces a class implements, so if cEmployee implements IPerson, you can do...
Code:
Dim tmp as IPerson
Set tmp = New cEmployee
Debug.Print TypeOf tmp Is cEmployee ' True
Debug.Print TypeOf tmp Is IPerson   ' True
Similarly with Access.Controls...
Code:
Dim tmp as Access.CommandButton
Set tmp = Me.cmdTestButton
Debug.Print TypeOf tmp Is Access.CommandButton ' True
Debug.Print TypeOf tmp Is Access.Control       ' True
In this case, CommandButton does not implement Control, it inherits from it.
From the example in post #5, you could test if the parent form implements INavHost, and if not, raise a meaningful error message, like...
Code:
Private Property Get ParentForm As INavHost
    If TypeOf Me.Parent Is INavHost Then
        Set ParentForm = Me.Parent
    Else
        Err.Raise 5, , "Parent form must implement INavHost"
    End If
End Property
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:43
Joined
May 21, 2018
Messages
5,908
You don't remember correctly.
I guess I did not say that correctly. In other languages like VB when I implement an interface I can define a procedure to implement a specific interface procedure. This allows me to give it a useable name.

If I develop my iMove interface I could have a procedure for moving the x and y location of my class that implements the Interface

iMove
Code:
Option Compare Database
Option Explicit

Public Sub Move(X As Long, Y As Long, Direction As String)
  'Interface procedure
End Sub

Then if I have say a Rabbit and Turtle class that implement iMove they must have a procedure called iMove_Move. like
Rabbit class
Code:
Private Sub iMove_Move(X As Long, Y As Long, Direction As String)
  Select Case Direction
  Case "Forward"
    Me.Location_X = X + 5
    Me.Location_Y = Y + 5
  Case "Backward"
    Me.Location_X = X - 5
    Me.Location_Y = Y - 5
  End Select
End Sub

Correct me if I am wrong, but in other languages you can do something like this where you declare which methods implement which method of the interface
Notional code (not real)
Code:
Private Sub Hop(X As Long, Y As Long, Direction As String) implements iMove.move
  Select Case Direction
  Case "Forward"
    Me.Location_X = X + 5
    Me.Location_Y = Y + 5
  Case "Backward"
    Me.Location_X = X - 5
    Me.Location_Y = Y - 5
  End Select
End Sub
The name of a member that implements an interface member can use any legal identifier, and it is not limited to the InterfaceName_MethodName convention used in earlier versions of Visual Basic.

So in my instantiation I would want to do something like

Code:
Public Sub TestImove()
  Dim bunny As New Rabbit
  bunny.HopForward
  MsgBox bunny.ToString
  MsgBox bunny.iMove_ToString
End Sub

This notation does not exist in VBA to name the method implementing the interface method, and it would look strange to then write something like
bunny.Imove_Move
So in vba you end up wrapping your interface methods and properties. Something like

Code:
Public Sub HopForward()
  iMove_Move Me.Location_X, Me.Location_Y, "Forward"
End Sub

So since you do not have real inheritance and some of the limitations of the structure you loose a lot of the utility of an interface.
 

sonic8

AWF VIP
Local time
Today, 17:43
Joined
Oct 27, 2015
Messages
483
So in my instantiation I would want to do something like

Code:
Public Sub TestImove()
  Dim bunny As New Rabbit
  bunny.HopForward
  MsgBox bunny.ToString
  MsgBox bunny.iMove_ToString
End Sub

This notation does not exist in VBA to name the method implementing the interface method, and it would look strange to then write something like
bunny.Imove_Move
I'm not sure what you are saying here.
The above code would work in VBA, but not in VB.Net. In VB.Net you would need to write:
Code:
CType(bunny, IMove).ToString()
The same approach would work in VBA but you need more code to achieve the type conversion.
Code:
Dim mv as IMove
Set mv = bunny
mv.ToString()

So since you do not have real inheritance and some of the limitations of the structure you loose a lot of the utility of an interface.
I also very much dislike the required method naming convention of InterfaceName_MethodName and also would appreciate an Implements keyword on method level. But beyond that I don't see limitations that I would consider very relevant.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:43
Joined
May 21, 2018
Messages
5,908
Sorry that was not very clear either.
I was just trying to say that it would be great to be able to call a method that implements an interface method, but have that be seamless.
so instead of bunny.iMove.move I could call bunny.hop that implements iMove.Move. In vba the limitation is you are am stuck with putting a wrapper around all the methods and properties of the interface to make it more intuitive.
This seems to be the intent. When I add an interface method to the class it will default as private. So my ToString function which returns a string to use for reporting location is private by default. I can make it public and call it directly iMove_ToString() or leave it private and wrap it in another ToString string function in the class. I prefer the latter, because that is intuitive to me. I just think when I build my class I need to know it implements the interface, but as a user of the class it would be nice if it was seamless. I guess I should not be picky since, for years I assumed since there is no inheritance there is no interfaces. I was suprised to even learn the construct existed.
 

silentwolf

Member
Local time
Today, 08:43
Joined
Jun 12, 2009
Messages
94
Hi guys,

Sorry for the late responds to you all!!
I have been very busy with work and not beeing here!
I will look at all your post tomorrow and will get back to you!
Sure there are many good ideas and alot to learn!

Thanks
 

Users who are viewing this thread

Top Bottom