Frage

Wann ist es sinnvoll, eine Klasse in Visual Basic für Applikationen (VBA) zu verwenden?

Ich gehe davon aus dem Entwicklung und Verringerung der Einführung von Fehlern beschleunigt ist ein gemeinsamer Nutzen für die meisten Sprachen, die OOP unterstützen. Aber mit VBA gibt es ein bestimmtes Kriterium?

War es hilfreich?

Lösung

Es hängt davon ab, wer wird den Code zu entwickeln und zu pflegen. Typische „Power User“ Makro Schriftsteller kleinen Ad-hoc-Apps Hacker können auch durch die Verwendung Klassen verwechselt werden. Aber für ernsthafte Entwicklung, um die Gründe Klassen zu verwenden, sind die gleichen wie in anderen Sprachen. Sie haben die gleichen Einschränkungen wie VB6 - kein Erbe - aber man kann Polymorphismus durch Schnittstellen mit

.

Eine gute Verwendung von Klassen ist es, Unternehmen zu repräsentieren, und Sammlungen von Objekten. Zum Beispiel sehe ich oft VBA-Code, kopiert ein Excel-Bereich in ein zweidimensionales Feld, dann mit dem Code die zweidimensionale Anordnung manipuliert wie:

Total = 0
For i = 0 To NumRows-1
    Total = Total + (OrderArray(i,1) * OrderArray(i,3))
Next i

Es ist besser lesbar den Bereich in eine Sammlung von Objekten mit entsprechend genannten Eigenschaften zu kopieren, so etwas wie:

Total = 0
For Each objOrder in colOrders
    Total = Total + objOrder.Quantity * objOrder.Price
Next i

Ein weiteres Beispiel ist Klassen zu verwenden, um das RAH-Entwurfsmuster (google für sie) zu implementieren. Zum Beispiel ist eine Sache, die ich brauchen kann zu tun ein Arbeitsblatt aufzuheben, einige Manipulationen zu tun, dann schützen Sie es erneut. eine Klasse ist sichergestellt, dass das Arbeitsblatt immer wieder selbst dann geschützt werden, wenn ein Fehler im Code auftritt:

--- WorksheetProtector class module ---

Private m_objWorksheet As Worksheet
Private m_sPassword As String

Public Sub Unprotect(Worksheet As Worksheet, Password As String)
    ' Nothing to do if we didn't define a password for the worksheet
    If Len(Password) = 0 Then Exit Sub

    ' If the worksheet is already unprotected, nothing to do
    If Not Worksheet.ProtectContents Then Exit Sub

    ' Unprotect the worksheet
    Worksheet.Unprotect Password

    ' Remember the worksheet and password so we can protect again
    Set m_objWorksheet = Worksheet
    m_sPassword = Password
End Sub

Public Sub Protect()
    ' Protects the worksheet with the same password used to unprotect it
    If m_objWorksheet Is Nothing Then Exit Sub
    If Len(m_sPassword) = 0 Then Exit Sub

    ' If the worksheet is already protected, nothing to do
    If m_objWorksheet.ProtectContents Then Exit Sub

    m_objWorksheet.Protect m_sPassword
    Set m_objWorksheet = Nothing
    m_sPassword = ""
End Sub

Private Sub Class_Terminate()
    ' Reprotect the worksheet when this object goes out of scope
    On Error Resume Next
    Protect
End Sub

Sie können dann diese verwenden Sie den Code zu vereinfachen:

Public Sub DoSomething()
   Dim objWorksheetProtector as WorksheetProtector
   Set objWorksheetProtector = New WorksheetProtector
   objWorksheetProtector.Unprotect myWorksheet, myPassword

   ... manipulate myWorksheet - may raise an error

End Sub 

Wenn diese Sub Ausgänge, objWorksheetProtector den Gültigkeitsbereich verlässt, und das Arbeitsblatt erneut geschützt.

Andere Tipps

Ich denke, die Kriterien das gleiche ist wie andere Sprachen

Wenn Sie zusammen mehrere Stücke von Daten zu binden und einige Methoden und auch speziell behandeln, was passiert, wenn das Objekt erstellt wird / beendet, Klassen sind ideal

sagen, wenn Sie ein paar Prozeduren haben, die Feuer, wenn Sie ein Formular öffnen, und einer von ihnen ist eine lange Zeit, können entscheiden, ob Sie Sich Zeit wollen jede Stufe ......

Sie können eine Stoppuhr-Klasse mit Methoden für die offensichtlichen Funktionen schaffen zum Starten und Stoppen, könnten Sie dann eine Funktion hinzufügen, die Zeit so weit zu holen und es in einer Textdatei zu berichten, ein Argument mit dem Namen des Prozesses Wesen darstellt, timed. Sie könnten Logik schreiben nur die langsamste Leistungen für die Untersuchung zu protokollieren.

Sie könnten dann einen Fortschrittsbalken Objekt mit Methoden hinzufügen und es zu schließen zu öffnen und die Namen der aktuellen Aktion angezeigt werden, zusammen mit den Zeiten in ms und wahrscheinlich Zeit auf früheren gespeicherten Berichten basierend verbleibenden etc

Ein weiteres Beispiel könnte sein, wenn Sie wie Access Benutzergruppe Müll nicht, können Sie Ihre eigene User-Klasse mit Methoden für loging in und out und Funktionen für die Gruppe-Level Benutzer-Zugriffskontrolle / Auditierung / Protokollierung bestimmter Aktionen / Tracking-Fehler usw. erstellen

Natürlich können Sie dies tun, eine Reihe von nicht verwandten Methoden und viele Variable Gang verwendet wird, aber es ist alles gekapselt in einer Klasse zu haben scheint nur besser zu mir.

Sie tun früher oder später kommen nahe an die Grenzen der VBA, aber es ist eine ziemlich mächtige Sprache, und wenn Ihr Unternehmen Bindungen Sie es können Sie tatsächlich ein paar gute, komplexe Lösungen aus ihm heraus.

Die Klassen sind sehr nützlich, wenn sie mit den komplexeren API-Funktionen zu tun, und vor allem, wenn sie erfordern eine Datenstruktur.

Zum Beispiel kann das GetOpenFileName () und GetSaveFileName () Funktionen übernehmen eine OPENFILE stucture mit vielen Mitgliedern. Sie könnten nicht alle Vorteile von ihnen zu nehmen brauchen, aber sie sind da und initialisiert werden sollen.

Ich mag die Struktur (UDT) und die API-Funktionsdeklarationen in eine Klasse CFileDialog wickeln. Das Class_Initialize Ereignis setzt die Standardwerte der Struktur der Mitglieder, so dass, wenn ich die Klasse zu verwenden, ich nur die Mitglieder gesetzt muss ich (über Property-Prozeduren) ändern möchten. Flag Konstanten sind als Enum umgesetzt. So zum Beispiel eine Tabelle zu wählen, zu öffnen, mein Code könnte wie folgt aussehen:

Dim strFileName As String
Dim dlgXLS As New CFileDialog

With dlgXLS
  .Title = "Choose a Spreadsheet"
  .Filter = "Excel (*.xls)|*.xls|All Files (*.*)|*.*"
  .Flags = ofnFileMustExist OR ofnExplorer

  If OpenFileDialog() Then
    strFileName = .FileName
  End If
End With
Set dlgXLS = Nothing

Die Klasse setzt das Standardverzeichnis auf Eigene Dateien, aber wenn ich will ich es mit der InitDir Eigenschaft ändern könnte.

Dies ist nur ein Beispiel dafür, wie eine Klasse in einer VBA-Anwendung sehr vorteilhaft sein.

ich würde nicht sagen, dass es ein bestimmtes Kriterium, aber ich habe nie wirklich einen perfekten Platz verwenden Klassen in VBA-Code. In meinem Kopf gebunden es so zu den bestehenden Modellen um die Office-Anwendungen, die das Hinzufügen von zusätzlichen Abstraktion außerhalb dieses Objektmodell nur Dinge verwechselt.

Das ist nicht ein sagen kann nicht einen perfekten Platz für eine Klasse in VBA finden, oder perfekt nützliche Dinge tun, um eine Klasse verwenden, nur, dass ich sie nie in dieser Umgebung nützlich gefunden habe.

Sie können auch VBA-Code wiederverwenden, ohne tatsächliche Klassen zu verwenden. Zum Beispiel, wenn Sie ein genannt, VBACode. Sie können eine beliebige Funktion zugreifen oder Unter in jedem Modul mit folgenden Syntax:

VBCode.mysub(param1, param2)

Wenn Sie eine Referenz auf eine Vorlage / doc erstellen (wie Sie wäre eine dll), von Code aus anderen Projekten in der gleichen Art und Weise verweisen kann.

Entwicklung von Software, auch mit Microsoft Access, Objektorientierte Programmierung mit in der Regel eine gute Praxis. Es wird für die Skalierbarkeit in Zukunft ermöglichen, indem sie Objekte zusammen mit einer Reihe von Vorteilen lose gekoppelt, werden. Das bedeutet im Wesentlichen, dass die Objekte in Ihrem System weniger voneinander abhängig sein, so Refactoring wird viel einfacher. Sie können diese ist Access Class Module erreichen. Der Nachteil ist, dass man nicht die Klassenvererbung oder Polymorphismus in VBA ausführen. Am Ende gibt es keine feste Regel Klassen zu verwenden, nur Best Practices. Aber bedenken Sie, dass Ihre Anwendung wächst, desto einfacher ist es mit Klassen zu halten.

Für die Daten Rekursion (auch bekannt als BOM handling), eine benutzerdefinierte Klasse ist kritisch hilfreich und ich denke, manchmal unverzichtbar. Sie können eine rekursive Funktion ohne Klassenmodul machen, aber eine Menge von Daten Probleme können nicht gelöst werden.

(Ich weiß nicht, warum die Leute nicht aus BOM-Bibliothek-Sets für VBA hausieren. Vielleicht ist die XML-Tools einen Unterschied gemacht haben.)

Mehrere Formularinstanzen ist die gemeinsame Anwendung einer Klasse (viele Automatisierungsaufgaben sind ansonsten unlösbare), nehme ich an die Frage nach ist benutzerdefinierte Klassen.

I-Klassen verwenden, wenn ich etwas tun müssen, und eine Klasse wird es am besten :) Zum Beispiel tun, wenn Sie (oder Intercept) Ereignisse reagieren müssen, dann Sie eine Klasse benötigen. Manche Leute hassen UDTs (benutzerdefinierte Typen), aber Ich mag sie, so dass ich sie, wenn ich will plain-Englisch selbstdokumentiere Code. Pharmacy.NCPDP ist viel einfacher strPhrmNum lesen dann :) Aber ein UDT ist begrenzt, so sagen, ich will Pharmacy.NCPDP setzen und die anderen Eigenschaften alle bevölkern haben können. Und ich möchte auch kann es machen, so dass Sie nicht versehentlich die Daten ändern. Dann brauche ich eine Klasse, weil Sie nicht nur lesbar Eigenschaften in einem UDT usw. können als

Eine weitere Überlegung ist nur einfache Lesbarkeit. Wenn Sie komplexe Datenstrukturen zu tun, dann ist es oft von Vorteil, zu wissen, man muss nur Company.Owner.Phone.AreaCode rufen dann zu versuchen, um zu verfolgen, wo alles strukturiert ist. Vor allem für Leute, die diese Codebasis 2 Jahre zu halten, nachdem Sie links:)

Mein zwei Cent ist „Code mit Zweck“. Verwenden Sie keine Klasse ohne Grund verwenden. Aber wenn Sie einen Grund haben, dann tun Sie es:)

Ich benutze Klassen, wenn ich ein selbst gekapselte Paket von Code erstellen möchten, die ich über viele VBA-Projekte verwenden, die für verschiedene Kunden kommen über.

Sie können eine SQL-Wrapper-Klasse in Zugang definieren, die bequemer als die Cord-Sets und Querydefs ist. Wenn Sie zum Beispiel eine Tabelle auf einem Kriterium in einer anderen verwandten Tabelle basierte aktualisieren möchten, können Sie nicht beitritt verwenden. Sie könnten bauten einen vba recorset und Querydef zu tun, dass aber ich finde es einfacher, mit einer Klasse. Auch kann Ihre Anwendung eine Vorstellung haben, die mehr als 2 Tabellen benötigen, könnte es besser sein imo Klassen verwenden dafür. Z.B. Sie Anwendung Spur Vorfälle. Vorfall haben mehrere Attribute, die in mehreren Tabellen {Benutzer und ihre Kontakte oder Profile, Incident Beschreibung halten wird; Status-Verfolgung; Prüflisten die Unterstützung Offizier helfen tonthe Vorfall zu antworten; Antworten ...} . Für eine Übersicht über alle Abfragen und Beziehungen beteiligt sind, können oop hilfreich sein. Es ist eine Erleichterung der Lage sein, Incident.Update (xxx) anstatt aller Codierung zu tun ...

Ich sehe nicht, warum die Kriterien für die VBA anders aus einer anderen Sprache sein würden, vor allem, wenn Sie auf VB.NET beziehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top