PDA

View Full Version : why cant i see the message box on screen?



xena2305
03-24-2012, 04:02 AM
Hi,
I have a simple code made of class interface, class and module to test it:

in my ClsInterface:

Public Sub shape()
End Sub


class2:


Implements ClsInterface
Private Sub ClsInterface_shape()
MsgBox ("test run")
End Sub


code to test it:

Public Sub test()
Dim obj As New ClsInterface
obj.shape
End Sub


why cant i see the message box?

Paul_Hossler
03-24-2012, 06:42 AM
Without testing it, I think that obj.shape call the empty Public Sub shape()

Put your Msgbox in THAT sub and see if it works for you

Also, I think that 'Impliments' is a VB keyword, not a VBA keyword.

Paul

xena2305
03-24-2012, 07:04 AM
Without testing it, I think that obj.shape call the empty Public Sub shape()

Put your Msgbox in THAT sub and see if it works for you

Also, I think that 'Impliments' is a VB keyword, not a VBA keyword.

Paul

The class interface is abstract, all the coding is in the class that implements it.

Paul_Hossler
03-24-2012, 11:26 AM
The class interface is abstract, all the coding is in the class that implements it.


Yes. I never used it; I just take the default interface from a class. Learned something

Make ClsInterface_shape Public and see if it works: From online Help



When a Visual Basic class implements an interface, the Visual Basic class provides its own versions of all the Public procedures (http://www.vbaexpress.com/forum/ms-help://MS.EXCEL.DEV.14.1033/EXCEL.DEV/content/HV10383569.htm) specified in the type library of the Interface. In


Paul

mikerickson
03-24-2012, 11:43 AM
Paul, I've been curious about the use of Impliments for a while.

Do you have a link to the file your quote came from?

Paul_Hossler
03-24-2012, 11:57 AM
Do you have a link to the file your quote came from?


That was from the Excel 2010 online help.

I had never used / heard of 'Implements' until now.

I rarely use Classes in VBA, and when I do they're pretty basic

Paul

xena2305
03-24-2012, 11:58 AM
Yes. I never used it; I just take the default interface from a class. Learned something

Make ClsInterface_shape Public and see if it works: From online Help



Paul

still doesnt work.

Paul_Hossler
03-24-2012, 12:11 PM
Module 1


Public Sub test()
Dim obj As New clsInterface
obj.shape
End Sub



clsInterface

Public Sub shape()
MsgBox ("test run")
End Sub


class2

Implements clsInterface
Public Sub ClsInterface_shape()

End Sub


Been a learning experience, but unless I'm misunderstanding something (VERY possilble), it seems to work for me

Paul

mikerickson
03-24-2012, 12:49 PM
Thanks for the file.
:)

Paul_Hossler
03-24-2012, 01:43 PM
Thanks for the file.
:)

Don't say that until you're sure it works

Paul

xena2305
03-24-2012, 01:54 PM
Module 1


Public Sub test()
Dim obj As New clsInterface
obj.shape
End Sub



clsInterface

Public Sub shape()
MsgBox ("test run")
End Sub


class2

Implements clsInterface
Public Sub ClsInterface_shape()

End Sub


Been a learning experience, but unless I'm misunderstanding something (VERY possilble), it seems to work for me

Paul
Class2 is unnecessary now, and the code treats the interface like a normal class.
plus the class interface should be abstract, no code, all the coding is in the classes that implements the interface. instead of only 1 class you can add many more that everyone share the interface propeties/methods but still
each one of the classes can behave differently(polymorphism).

Paul_Hossler
03-24-2012, 02:31 PM
Yes, that part I can follow, but I can't even get the Implements on-line help example to work.


But it's a rainy Saturday here, and there's nothing interesting on TV, so this is more fun

Paul

Paul_Hossler
03-24-2012, 07:58 PM
I think that defining an abstract interface just allow objects that Impliments that interface to be assigned to variables of that

You do sort of get polymorphism, but not perfectly

clsInterface:

Option Explicit
Public Sub shape()
'
End Sub



Class2:

Implements clsInterface
Public Sub ClsInterface_shape()
MsgBox ("test run from Class2")
End Sub


and a Class3 that Implements the same interface as Class3 but has different processing in the shape()


Implements clsInterface
Public Sub ClsInterface_shape()
MsgBox ("test run from Class3")
End Sub


The main sub


Public Sub test()
Dim obj As New clsInterface

Dim obj2 As New Class2
Dim obj3 As New Class3

Set obj = obj2
obj.shape

Set obj = obj3
obj.shape
End Sub


It would seem to me (and you pointed it out) that in this example that you really don't need the complexity. The examples I saw used a library and books and a Collection. That would seem to me where polymorphism would be helpful. So thanks for an interesting Saturday afternoon. Much more fun than painting the bedroom.

If you're interested, I attached the library example that I was playing with.

I'm open to any and all suggestions

Paul

xena2305
03-24-2012, 11:48 PM
I think that defining an abstract interface just allow objects that Impliments that interface to be assigned to variables of that

You do sort of get polymorphism, but not perfectly

clsInterface:

Option Explicit
Public Sub shape()
'
End Sub



Class2:

Implements clsInterface
Public Sub ClsInterface_shape()
MsgBox ("test run from Class2")
End Sub


and a Class3 that Implements the same interface as Class3 but has different processing in the shape()


Implements clsInterface
Public Sub ClsInterface_shape()
MsgBox ("test run from Class3")
End Sub


The main sub


Public Sub test()
Dim obj As New clsInterface

Dim obj2 As New Class2
Dim obj3 As New Class3

Set obj = obj2
obj.shape

Set obj = obj3
obj.shape
End Sub


It would seem to me (and you pointed it out) that in this example that you really don't need the complexity. The examples I saw used a library and books and a Collection. That would seem to me where polymorphism would be helpful. So thanks for an interesting Saturday afternoon. Much more fun than painting the bedroom.

If you're interested, I attached the library example that I was playing with.

I'm open to any and all suggestions

Paul
I'll keep looking for answers and let you know if i find one.

Paul_Hossler
03-25-2012, 06:51 AM
Thanks, I'd be interested

Even if it wasn't helpful,I learned a lot

Paul

Aflatoon
03-26-2012, 05:25 AM
What is the outstanding issue? It seems to me that Paul has already answered your question - your original calling sub should have been:


Public Sub test()
Dim obj As ClsInterface
Set obj = New Class2
obj.shape
End Sub

Your version was calling the interface class, not one of its implementations.

Paul_Hossler
03-26-2012, 09:17 AM
It would seem to me that Implements is VBA's way of trying to do OOP polymorphism (as the OP pointed out)

In my really simple example:

clsLibraryItem class defines the abstract interface, which clsFiction and clsHistory Implements

Since the interface 'looks' the same between clsFiction and clsHistory, I can assign either to an object of clsLibraryItem, and the polymorphic (if that's a word) method for the appropriate type of object gets called


Sub test()
Dim i As Long
Dim MyLibrary(1 To 4) As clsLibraryItem

Dim FictionBook As New clsFiction
Dim HistoryBook As New clsHistory


Set MyLibrary(1) = New clsFiction
Set MyLibrary(2) = New clsFiction
Set MyLibrary(3) = New clsHistory
Set MyLibrary(4) = New clsHistory

MyLibrary(1).BookName = "Harry Potter (Fiction)"
MyLibrary(2).BookName = "War of the Worlds (Fiction)"
MyLibrary(3).BookName = "Civil War (History)"
MyLibrary(4).BookName = "Sparta (History)"

For i = 1 To 4
Call MyLibrary(i).LoanTimeMsg
Next i

End Sub


FWIW, this is pretty heavy stuff for me I'm sure there's lots more better ways that it could be done. But sure has been interesting, I'd like to see if the pros have additional examples

Paul

Paul_Hossler
03-26-2012, 09:17 AM
(Hit the wrong key)

Paul_Hossler
03-26-2012, 09:18 AM
(again)

Aflatoon
03-26-2012, 09:21 AM
Basically yes, but the point is that no function code goes in the Interface class, so whilst you declare the variable as implementing that interface, you actually create a variable using the implementing class.

Paul_Hossler
03-26-2012, 03:01 PM
Basically yes, but the point is that no function code goes in the Interface class, so whilst you declare the variable as implementing that interface, you actually create a variable using the implementing class.

Yes and Yes

You seem to know this stuff :bow:

Paul

Aflatoon
03-26-2012, 03:27 PM
I've read PED a few times. :)

Paul_Hossler
03-26-2012, 06:55 PM
I've read PED a few times.


Shows you how far back I am - I don't even know what a PED is :dunno

Paul

GTO
03-27-2012, 05:36 AM
Shows you how far back I am - I don't even know what a PED is :dunno

Paul

Me neither!:( Nor do I know what "...EF imploding..." means.

Pretty please?


Basically yes, but the point is that no function code goes in the Interface class, so whilst you declare the variable as implementing that interface, you actually create a variable using the implementing class.

Hi xena2305,

I hope you will not mind me glomming on to the conversation?

@Aflatoon:

Howdy:hi:

I have only read the help topic a couple of times and could not make it work. Did find a coupleof short examples tonight, and followed well enough to make something that didn't set the PC afire.

As to "...no function code goes in the Interface...you actually create a variable using the implementing class..."

Is this on the right track?

Class named: impEmployee

Option Explicit

Property Let EmpName(AString As String)
End Property
Property Get EmpName() As String
End Property
Property Let EmpDateOfHire(ADate As Date)
End Property
Property Get EmpDateOfHire() As Date
End Property
Property Let EmpAppraisalDue(ADate As Date)
End Property
Property Get EmpAppraisalDue() As Date
End Property


Class named: impInsurance

Option Explicit
Property Let Rate(ARate As Currency)
End Property
Property Get Rate() As Currency
End Property
Property Let InsCompanyName(AInsCompany As String)
End Property
Property Get InsCompanyName() As String
End Property

Class named: clsEmpData

Option Explicit
Implements impEmployee
Implements impInsurance
Private EmpAppraisalDate As Date
Private EmpDOH As Date
Private EmpName As String

Private CompanyName As String
Private Rate As Currency

Private Property Let impEmployee_EmpAppraisalDue(RHS As Date)
EmpAppraisalDate = RHS
End Property
Private Property Get impEmployee_EmpAppraisalDue() As Date
impEmployee_EmpAppraisalDue = EmpAppraisalDate
End Property
Private Property Let impEmployee_EmpDateOfHire(RHS As Date)
EmpDOH = RHS
End Property
Private Property Get impEmployee_EmpDateOfHire() As Date
impEmployee_EmpDateOfHire = EmpDOH
End Property
Private Property Let impEmployee_EmpName(RHS As String)
EmpName = RHS
End Property
Private Property Get impEmployee_EmpName() As String
impEmployee_EmpName = EmpName
End Property

Private Property Let impInsurance_InsCompanyName(RHS As String)
CompanyName = RHS
End Property
Private Property Get impInsurance_InsCompanyName() As String
impInsurance_InsCompanyName = CompanyName
End Property
Private Property Let impInsurance_Rate(RHS As Currency)
Rate = RHS
End Property
Private Property Get impInsurance_Rate() As Currency
impInsurance_Rate = Rate
End Property


In a Standard Module:

Option Explicit

Sub example()
Dim cEmpDate As clsEmpData
Dim iEmp As impEmployee
Dim iIns As impInsurance


Set cEmpDate = New clsEmpData
Set iEmp = cEmpDate
Set iIns = cEmpDate

With iEmp
.EmpName = "Mark"
.EmpDateOfHire = #6/1/1988#
.EmpAppraisalDue = #5/10/2012#
End With

With iIns
.InsCompanyName = "BC&BS"
.Rate = 167.42
End With

MsgBox "Dang! " & iEmp.EmpName & " has been here for " & Format(Now() - iEmp.EmpDateOfHire, "yy") & " years! I know he carries " & iIns.InsCompanyName & "; their good but the rates are high. " & vbCrLf & _
"Mark pays " & iIns.Rate & " per paycheck, just for himself. I sure hope I remember to write his appraisal," & vbCrLf & _
"it is due on " & iEmp.EmpAppraisalDue, vbOKOnly Or vbInformation, vbNullString
End Sub

Thank you so much,

Mark

PS. Hi Paul!:hi:

shrivallabha
03-27-2012, 06:16 AM
Maybe ---> PED (http://www.vbaexpress.com/forum/showthread.php?t=2189)

Aflatoon
03-27-2012, 09:12 AM
@all - yes PED = Professional Excel Development (Edition 2 now). :)

@GTO,

Where did 'EF implodes' come from? (EF = Excel Forum, by the way)

Your code example is functionally correct, but not really how I would use it. I think of it as being more use when several classes share some basic characteristics. For example, you might have classes that represent different types of Employee: Salesman, Office worker, warehouseman, manager and so on. Each class will have its own specific implementation - properties and methods unique to it, but they are all also employees and therefore share a lot of common properties and methods, so you might create an Employee interface for use here (with properties like Name, address, DOB, hire date, salary and so on). By implementing the interface in all the other classes, you can process them all as employees, regardless of the actual class involved. So if for example your code needed to loop through all employees and apply a flat 3% pay rise, you could do that with one variable, rather than having to have a variable for each class and checking at runtime which type of object you are dealing with.

Incidentally, this is the difference between the TypeName function and the TypeOf operator: the former returns the name of the class, whereas the latter tests whether an object implements a specific interface (That is why, when looping through controls on a form, a test to see if TypeOf matches MSForms.Checkbox will also match option buttons and toggle buttons - they implement the CheckBox interface - but using TypeName(ctl) = "CheckBox" will only match CheckBox objects. But I digress. :))

Does that make sense?

Paul_Hossler
03-27-2012, 09:15 AM
Hi Mark -- the more the merrier :dance:

As an experiment I created an 'EmployeeData' interface class, and also 'Employee' and 'Subcontractor' classes that Implements 'EmployeeData'

My 'Company' is a simple array of 'EmployeeData' and then I can assign either 'Employee' or 'Subcontractor' variables to it.

When I use a 'Company' entry, I get the method or property from the correct class.

Any you're right ... the Help leaves something to be desired

Aflatoon is better

Paul

Paul_Hossler
03-27-2012, 09:27 AM
[quote=Aflatoon so you might create an Employee interface for use here (with properties like Name, address, DOB, hire date, salary and so on).[/quote]

In the interface class I have Public variables that all implementing classes will want to use.

In the implementing class, it seems I have to have Private versions of those also. Somehow that just doesn't feel right, so I have to be refering to the interface variables wrong.

Got a simple example?

Thanks

Paul

Aflatoon
03-27-2012, 09:36 AM
Can I ask why you have public variables in the interface (or in any class really)? Much better, in my opinion, to do it the way Mark has it and use public property routines and keep the variables private.

Paul_Hossler
03-27-2012, 10:07 AM
Of course you can ask

The online help example ...


Example
The following example shows how to use the Implements statement to make a set of declarations available to multiple classes. By sharing the declarations through the Implements statement, neither class has to make any declarations itself.
Assume there are two forms. The Selector form has two buttons, Customer Data and Supplier Data. To enter name and address information for a customer or a supplier, the user clicks the Customer button or the Supplier button on the Selector form, and then enters the name and address using the Data Entry form. The Data Entry form has two text fields, Name and Address.
The following code for the shared declarations is in a class called PersonalData:
Public Name As StringPublic Address As String

.... talks about sharing variable declarations in an interface clase

Now ... if all the implementing classes will need Name and Address, it would sort of make sense to put them in with the other common declarations, etc. in the interface

When I do that, there seems to be no way in the implementing class to use them, unless I'm missing something

Paul

Aflatoon
03-27-2012, 02:44 PM
Oh, I see. I haven't read the online help (Mac online help ain't the same, I suspect) article, but I suspect it is basically just saving you the trouble of putting property procedures in the interface class. You add a public variable in the interface (which gives you a read/write member), but then in the implementing class, you actually use property procedures and private variables as you would (ought) in any normal class. So for example (air code warning), in your EmployeeData interface you have:
Public Salary as Double

but in the implementing class you would use the typical:

Implements EmployeeData
Private mdblSalary as Double

Public Property Let EmployeeData_Salary(Value as Double)
mdblSalary = Value
End Property
Public Property Get EmployeeData_Salary() As Double
EmployeeData_Salary = mdblSalary
End Property

Paul_Hossler
03-27-2012, 05:22 PM
Ahh - that would have to be it. I'd expect there's no reason that the private variable couldn't be the same name, as the interface class one, and then you wouldn't even have to edit it



Implements EmployeeData


Private Salary As Double


Public Property Let EmployeeData_Salary(Value As Double)
Salary = Value
End Property


etc.



Thanks

This has been a very educatiional topic

Paul

Aflatoon
03-28-2012, 12:23 AM
Thank you too - it has been useful to refresh my memory of this stuff! :)

GTO
03-28-2012, 01:19 AM
@Aflatoon:

Hi there, sorry for the slow response...


@all - yes PED = Professional Excel Development (Edition 2 now). :)

@GTO,

Where did 'EF implodes' come from? (EF = Excel Forum, by the way)

I no doubt botched that a bit from memory. I cannot seem to find my way back to the thread/poll, but I think it was a comment you made - maybe closer to '...EF imploding...'

I did stop by there tonight, just jumping around a bit. I think I get the drift...


Your code example is functionally correct, but not really how I would use it. I think of it as being more use when several classes share some basic characteristics. For example, you might have classes that represent different types of Employee: Salesman, Office worker, warehouseman, manager and so on. Each class will have its own specific implementation - properties and methods unique to it, but they are all also employees and therefore share a lot of common properties and methods, so you might create an Employee interface for use here (with properties like Name, address, DOB, hire date, salary and so on). By implementing the interface in all the other classes, you can process them all as employees, regardless of the actual class involved. So if for example your code needed to loop through all employees and apply a flat 3% pay rise, you could do that with one variable, rather than having to have a variable for each class and checking at runtime which type of object you are dealing with.

Thank you for taking the time to answer that. As to my delay in response, I was hoping to have the time to try that, on a tiny scale of course, just to see if I am still following (which scarely, I sort of think I am:*))


Incidentally, this is the difference between the TypeName function and the TypeOf operator: the former returns the name of the class, whereas the latter tests whether an object implements a specific interface (That is why, when looping through controls on a form, a test to see if TypeOf matches MSForms.Checkbox will also match option buttons and toggle buttons - they implement the CheckBox interface - but using TypeName(ctl) = "CheckBox" will only match CheckBox objects. But I digress. :))

Does that make sense?

Incidently? I am chuckling, as whether you happened to have spotted a recent answer I gave, or by happenstance that you gave that example, I am suddenly aware that my answer was less stellar than I believed :doh:

I was also hoping to test that, unfortunately, not such a relaxed day though (and/or just muddled brains day for me).

Thanks again - hopefully I get a respite someplace in the morrow (and a chance to try some more),

Mark

Aflatoon
03-28-2012, 02:29 AM
Hi Mark,



I no doubt botched that a bit from memory. I cannot seem to find my way back to the thread/poll, but I think it was a comment you made - maybe closer to '...EF imploding...'

I did say that, but not here (it was here (http://www.thecodecage.com/forumz/general-news-updates/212211-poll-forum-look-2.html))



Incidently? I am chuckling, as whether you happened to have spotted a recent answer I gave, or by happenstance that you gave that example, I am suddenly aware that my answer was less stellar than I believed :doh:


Pure serendipity, actually. :)