Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Klassen Programmieren

Begonnen von datekk, Juli 09, 2017, 22:12:28

⏪ vorheriges - nächstes ⏩

datekk

Hallo,

derzeit arbeite ich mich in C# ein. Hier in meinem Buch läuft viel über Klassen. Um das Thema besser zu verstehen möchte ich gern die Klassen erstmal in VBA erstellen und würde mich freuen, wenn jemand mir einen Einstieg geben.

So sieht die Klasse in C# aus:


public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }


Mit Daten füllen geht wie folgt:


private Product[] products =
        {
            new Product {Name="Kayak", Category="Watersports", Price=275M},
            new Product {Name="Lifejacket", Category="Watersports", Price=48.95M},
            new Product {Name="Soccer Ball", Category="Soccer", Price=19.50M},
            new Product {Name="Corner Flag", Category="Soccer", Price=34.95M}
        };


Wie müsst dazu der VBA Code aussehen?
Access 2016 mit SQL Server Backend. Bereits umgesetzt: Access mit MS SQL Backend,  ADODB Formularbindung, Streamen von Dateien zum SQL Server und zurück (Filestream), Drag&Drop Dateiupload zum Server, CTI / TAPI Integrierung in Access Anwendung - Nutzung auch über Remote Desktop, selbst aktualisierendes Access Frontend auf entfernten Rechnern (Upgrade). Berichte / Kreuztabellen mit SQL Server Backend, Mail Tagging, Outlook Steuerung über Access und umgekehrt // Grundwissen in .Net Core & Blazor Apps

markusxy

Für Programmierer die in der Lage sind sich selbst was zu erarbeiten, gibt es da jede Menge Tutorials.
Hier zum Beispiel.
Falls deine Suchmaschiene nicht kaputt ist, findest du auch sicher weitere Anleitung dazu.


Lachtaube

#2
C#- und VBA-Klassen unterscheiden sich wesentlich und können deshalb auch nicht immer adaptiert werden. VBA-Klassen besitzen nur einen privaten Konstruktor, währen in C# beliebig viele Konstruktoren für eine Klasse bestehen können. In VBA ist man deshalb auf Factory-Methoden angewiesen, die aber vorraussetzen, dass die darin zu setzenden Let-Eigenschaften als Public oder Friend deklariert sein müssen. Dein Beispiel könnte man so ungefähr in VBA umsetzen:
'VBA-Klasse: Product

Option Explicit

Private m_ProductID As Long
Private m_Name As String
Private m_Description As String
Private m_Price As Currency
' erlaubt auch einfachen Property Get-/Let-Zugriff
Public Category As String

Public Property Get ProductID() As Long
   ProductID = m_ProductID
End Property
Public Property Let ProductID(rhs As Long)
   m_ProductID = rhs
End Property

Public Property Get Name() As String
   Name = m_Name
End Property
Public Property Let Name(rhs As String)
   m_Name = rhs
End Property

Public Property Get Description() As String
   Description = m_Description
End Property
Public Property Let Description(rhs As String)
   m_Description = rhs
End Property

Public Property Get Price() As Currency
   Price = m_Price
End Property
Public Property Let Price(rhs As Currency)
   m_Price = rhs
End Property


Factory- und Test-Methode in einem allgemeinen Modul
Option Explicit

'Factory-Methoden (können auch in einer Klasse angesiedelt sein)
Public Function NewProduct(Optional newProductID As Long, _
                           Optional newName As String, _
                           Optional newDescription As String, _
                           Optional newPrice As Currency, _
                           Optional newCategory As String) As Product
   Set NewProduct = New Product
   'entweder so
   CallByName NewProduct, "ProductID", VbLet, newProductID
   CallByName NewProduct, "Name", VbLet, newName
   'oder so auf Eigenschaften/Methoden zugreifen
   NewProduct.Description = newDescription
   'oder kürzer
   With NewProduct
      .Price = newPrice
      .Category = newCategory
   End With
End Function

Sub test()
   'besser eine Products-Collection anlegen, die typensicher ist
   'und um beim Beispiel zu bleiben, müsste die Deklaration in einen Modulkopf
   'letzteres habe ich hier außer acht gelassen.
   Dim products As Collection
   Dim p As Product

   Set products = New VBA.Collection

   products.Add NewProduct(newName:="Kayak", newCategory:="Watersports", newPrice:=275)
   products.Add NewProduct(newName:="Lifejacket", newCategory:="Watersports", newPrice:=48.95)
   products.Add NewProduct(newName:="Soccer Ball", newCategory:="Soccer", newPrice:=19.5)
   products.Add NewProduct(newName:="Corner Flag", newCategory:="Soccer", newPrice:=34.95)

   For Each p In products
      Debug.Print "Name = ", p.Name; vbCrLf; _
                  "Category = ", p.Category; vbCrLf; _
                  "Price = ", format$(p.Price, "Currency"); vbCrLf
   Next
End Sub
Grüße von der (⌒▽⌒)

Wurliwurm

Zitat von: datekk am Juli 09, 2017, 22:12:28
derzeit arbeite ich mich in C# ein. Hier in meinem Buch läuft viel über Klassen. Um das Thema besser zu verstehen möchte ich gern die Klassen erstmal in VBA erstellen

Eine reinrassige OO-Sprache lernst Du nicht, indem Du dich an VBA festhältst. In VBA gibt es das, was OO ausmacht, nicht: Vererbung, Polymorphie, Schnittstellen, Typenstrenge etc.

PhilS

#4
Zitat von: Wurliwurm am Juli 10, 2017, 08:41:14Eine reinrassige OO-Sprache lernst Du nicht, indem Du dich an VBA festhältst.
Dem kann ich durchaus zustimmen. Viele OO-Konzepte sind in VBA nicht oder nur halbgar umgesetzt. Man darf nicht vergessen, dass die Sprache VBA von ca. 17 Jahren das letzte funktionale Update bekommen hat. (Danach nur noch geringfügige Erweiterungen für die 64-Bit Unterstützung.)

Zitat von: Wurliwurm am Juli 10, 2017, 08:41:14In VBA gibt es das, was OO ausmacht, nicht: Vererbung, Polymorphie, Schnittstellen, Typenstrenge etc.

Vererbung als ein ganz wesentliches Kernkonzept der OO wird allerdings nicht unterstützt. Dies ist IMO der wesentliche Grund warum VBA nicht ideal ist um OO-Programmierung zu lernen.

Die weiteren Punkte, die du nennst sind IMO weniger relevant bzw. nicht ganz zutreffend.

Polymorphie - Welche OO-Sprachen außer C++ unterstützen diese? IMO ist die Hauptfunktion von Polymorphie entweder einen Knoten im Gehirn zu bekommen oder sich selbst in den Fuß zu schießen. Also nicht wirklich von zentraler Bedeutung.

Schnittstellen - VBA unterstützt Schnittstellen so halbwegs. Es gibt zwar keine konkrete Interface-Deklaration, aber du kannst eine leere Klasse (mit Methodensignaturen ohne Implementierung) erstellen und in einer anderen das Implements-Statement verwende um das Interface deiner leeren Klasse zu Implementieren.

Typenstrenge - Hat nichts mit OO zu tun. Es gibt viele, vollwertige OO-Sprachen, die keine Typstrenge haben.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Wurliwurm

Zitat von: PhilS am Juli 10, 2017, 10:36:25
Polymorphie - Welche OO-Sprachen außer C++ unterstützen diese?
Du meinst Mehrfachvererbung? Das ist etwas anderes.

Zitat
Typenstrenge - Hat nichts mit OO zu tun. Es gibt viele, vollwertige OO-Sprachen, die keine Typstrenge haben.

Ist richtig, daß das nicht mit OO zu tun hat. Hat aber ebenfalls kein Pendant in VBA.

PhilS

Zitat von: Wurliwurm am Juli 10, 2017, 10:48:27
Zitat von: PhilS am Juli 10, 2017, 10:36:25
Polymorphie - Welche OO-Sprachen außer C++ unterstützen diese?
Du meinst Mehrfachvererbung? Das ist etwas anderes.
Ist es das?
Der Begriff Polymorphie in der OO-Programmierung meint fast immer explizit die Mehrfachvererbung.
Natürlich lässt sich über Interfaces teilweise ein ähnliches Verhalten erreichen, aber dies wird meist nicht mit dem Begriff Polymorphie beschrieben.

Wenn du etwas anderes meinst, dann erläutere das bitte ausführlicher.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Wurliwurm

Zitat von: PhilS am Juli 10, 2017, 11:08:59
Zitat von: Wurliwurm am Juli 10, 2017, 10:48:27
Zitat von: PhilS am Juli 10, 2017, 10:36:25
Polymorphie - Welche OO-Sprachen außer C++ unterstützen diese?
Du meinst Mehrfachvererbung? Das ist etwas anderes.
Der Begriff Polymorphie in der OO-Programmierung meint fast immer explizit die Mehrfachvererbung.

Falsch. Allerdings ist das hier kein OO-Programmierforum für Studis, deshalb will ich auch nicht weiter argumentieren. Eine kurze Google-Suche hilft, das ist tausendfach beschrieben. http://oszhdl.be.schule.de/gymnasium/faecher/informatik/oop/polymorphie.htm

Wir sind uns ja einig, daß C# nicht mit VBA vergleichbar ist und deshalb beim Erlernen von OO man das VBA besser vergisst.

markusxy

@Wurliwurm
Ich verstehe nicht ganz warum du meinst dass Polymorphie in Access nicht möglich ist.
Dieses Konzept ist in Access durch die Verwendung eines Interface umsetzbar.

Man kann man unterschiedliche Objekte, aus unterschiedlichen Klassen als Interface übergeben.
Dadurch sind alle Methoden und Eigenschaften typsicher bekannt und werden von jedem Objekt auf seine Weise umgesetzt ohne zu wissen mit welcher spezielle Klasse ich gerade arbeite.
Also ich sehe bis dahin keinen Unterschied. Vielleicht kannst du aber einen Unterschied nennen.





Wurliwurm

Zitat von: markus888 am Juli 13, 2017, 16:53:56
@Wurliwurm
Ich verstehe nicht ganz warum du meinst dass Polymorphie in Access nicht möglich ist.
Dieses Konzept ist in Access durch die Verwendung eines Interface umsetzbar.

Du hast recht. Strenggenommen ist das natürlich Polymorphie.

Ich kenne mit klassenbasierter Programmierung in VBA nicht richtig aus. Eine Frage wäre, ob eine Klasse mehrere Interfaces implementieren kann. Wenn das möglich wäre, könnte man ein paar Sachen mehr machen anderenfalls wäre das sehr rudimentär.

Richtig viel könnte man in Access machen, wenn es Vererbung gäbe, man also z.B. das Form-Object ableiten und erweitern könnte und ähnliches.

markusxy

Zitat von: markus888 am Juli 13, 2017, 16:53:56
Eine Frage wäre, ob eine Klasse mehrere Interfaces implementieren kann.

Ja das geht.
Das Vererbung nicht funktioniert ist allerdings schon ärgerlich.
In anderen prozeduralen Sprachen haben sie das ja auch nachgereicht.
In der Praxis hängt es aber stark davon ab, was man programmiert ob man die Vererbung vermisst. Oder es fällt nicht auf, weil es nicht geht. :).

Also ich setze die Möglichkeit mit der Polymorphie öfter ein.
Aber auch ohne Polymorphie wäre das mittels LateBinding lösbar.
Das Interface bringt aber mehr Sicherheit.

Vor kurzem habe ich in Access ein Interface verwendet um Projektübergreifend zu arbeiten.
Das Child Projekt hat ein Interface.
Das Parent Projekt implentiert das Interface in eine Klasse und übergibt ein aus der Klasse erstelltes  Objekt an das Child Projekt.
Jetzt kann das Child Projekt mit dem Parent Projekt über die Interface Schnittstelle kommunizieren, ohne die Klasse aus dem Parent Projekt zu kennen.
LG M

Lachtaube

#11
Im Prinzip handelt es sich bei VBA um ein abgespecktes VB6 (mit anwendungsspezifischen Klassen - abhängig von der Anwendung), was keine Executables erstellen kann.

Das Implementieren mehrerer Interfaces ist möglich - auch über Type Libraries (*.tlb). Leider müssen diese dann der Anwendung beigelegt sein.

Vererbung von Klassen ist nur über Composition möglich, was dann in viel Schreibarbeit und langweiligem Wiederholen von Methoden/Eigenschaften durch Deligation ausartet.

Mehr Polymorphie gibt es nicht.

PS: im gewissen Sinn lassen sich auch Methoden überladen, wenn sie in unterschiedlichen Modulen deklariert sind. Sie müssen dann aber über den Modulnamen referenziert werden.
Grüße von der (⌒▽⌒)