ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 05.01.2001

Diese Seite wurde zuletzt aktualisiert am 05.01.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Wahrheitsdroge

Zurück...


Anzeige

(-hg) mailto:hg_conditions@aboutvb.de

Aufgabenstellungen wie zum Beispiel die folgende kennen sie sicher: "Nur wenn eine bestimmte CheckBox gesetzt ist, eine andere aber nicht, und in einer bestimmten TextBox ein bestimmter Text steht und ein bestimmter Button nicht gesperrt ist, dann soll dieses geschehen..." - "Und wenn die erste CheckBox nicht gesetzt ist, und die TextBox keinen Text enthält oder jene ScrollBar sichtbar ist, dann soll jenes geschehen..." - und dergleichen mehr an Kreuz- und Querkombinationen von Bedingungen.

Wie leicht verhaspelt man sich dann in If...Then...Else(If)-Gestrüppen wie etwa diesem:

If (Check1.Value = vbChecked) And (Check2.Value = vbUnchecked) _
 And (Text1.Text = "abc") And Not (Command1.Enabled = False) Then
  ' ...
ElseIf ((Check1.Value = vbUnchecked) And (Len(Text1.Text = 0) _
 Or (VScroll1.Visible = True)) Then
  ' ...
ElseIf ...
  ' ...
End If

Wenn dann solche Bedingungs-Verkettungen auch noch zur Laufzeit dynamisch erstellt werden sollen, ist meistens der Ofen endgültig aus.

Kombinationen von Steuerelement- oder Objekt-Eigenschaften oder -Zuständen lassen sich nicht so einfach prüfen

Kombinationen von Steuerelement- oder Objekt-Eigenschaften oder -Zuständen lassen sich nicht so einfach prüfen

Wie wäre es mit einer Klasse, in der Sie mehrere einzelne Bedingungen und Zustände ablegen können, und die auf Anfrage anhand einer vorgegebenen Verknüpfung ("And" oder "Or") ein Gesamtergebnis liefert?

Eigentlich ist das Prinzip recht einfach. Diese Klasse enthält eine Collection, in die Arrays aus jeweils dem betreffenden Steuerelement (oder einem beliebigen Objekt, das über eine Standard-Eigenschaft verfügt) und dem gewünschten Wert der Standard-Eigenschaft aufgenommen werden. Bei der Abfrage wird in einer Schleife für jedes dieser Arrays geprüft, ob der Wert der Standard-Eigenschaft des darin enthaltenen Steuerelements mit dem Vorgabewert übereinstimmt. Ist "And" als Verknüpfung für diesen Bedingungsstapel vorgesehen, wird die Schleife verlassen, sobald die erste Prüfung fehlschlägt - nur wenn alle Prüfungen erfolgreich verlaufen, wird als Gesamtergebnis True zurückgegeben. Ist "Or" als Verknüpfung gesetzt, wird die Schleife bei der ersten erfolgreichen Prüfung verlassen und als Gesamtergebnis True zurückgegeben.

Wenn Sie als drittes Element in diese Bedingungs-Arrays noch eine Kennung für den bei der jeweiligen Prüfung anzuwendenden Vergleichsoperator einfügen, können Sie nicht nur auf Gleichheit, sondern auch genau so gut auf Ungleichheit prüfen oder einen Größenvergleich vornehmen.

Da das Prüfergebnis dieser Klasse selbst auch ihr Standardwert ist, können Sie zudem beliebige Verschachtelungen vornehmen - entsprechend der Klammerung in komplexen Ausdrücken. Für jede Klammerung verwenden Sie eine Instanz dieser Klasse, die Sie wiederum als Bedingung in die übergeordnete Instanz aufnehmen.

Die Dynamik zur Laufzeit ergibt sich, weil Sie ja jederzeit eine Instanz der Klasse anlegen und mit Bedingungen füllen können - wobei Sie ebenso dynamisch für jede Bedingung das zu prüfende Objekt, den Prüfwert und den Vergleichsoperator festlegen können.

Im folgenden sehen Sie den Aufbau der ersten fünf Bedingungen, die in dem Beispiel-Progrämmchen zur oben stehenden Abbildung wirken. Den Code der Klasse clsConditions finden Sie weiter unten.

Dim nCondition As clsConditions

Set mConditions1 = New clsConditions
With mConditions1
  .Operator = opAND
  .Add chkA, vbChecked
  .Add chkB, vbChecked
  .Add chkE, vbUnchecked
End With
Set mConditions2 = New clsConditions
With mConditions2
  .Operator = opOR
  .Add chkB, vbChecked
  .Add chkD, vbChecked
  .Add chkE, vbChecked
End With
Set mConditions3 = New clsConditions
With mConditions3
  .Operator = opAND
  .Add chkC, vbChecked
  .Add chkD, vbChecked
  Set nCondition = New clsConditions
  With nCondition
    .Operator = opOR
    .Add chkE, vbChecked
    .Add chkF, vbChecked
  End With
  .Add nCondition, True
End With
Set mConditions4 = New clsConditions
With mConditions4
  .Operator = opAND
  .Add chkA, vbChecked, compNot
  .Add chkB, vbChecked, compNot
  .Add chkC, vbChecked, compNot
  .Add chkD, vbChecked
  .Add chkE, vbChecked, compNot
  .Add chkF, vbChecked
End With
Set mConditions5 = New clsConditions
With mConditions5
  .Operator = opAND
  .Add chkE, vbChecked
  .Add chkF, vbChecked
  .Add txt, "abc"
End With

Die sechste, noch fehlende Bedingungssammlung enthält die Prüfung, ob das Form maximiert ist. Da die Eigenschaft WindowState jedoch nicht die Standard-Eigenschaft des Forms ist, würden die Prüfschleifen versagen, wenn wir das Form einfach so als Bedingungs-Objekt aufnehmen würden. Ab Visual Basic 6 böte sich immerhin die Möglichkeit an, über die CallByName-Funktion auch noch die zu prüfende Eigenschaft zu dynamisieren. Doch auf einem anderen Weg kommen wir nicht nur zu einer VB 5-kompatiblen Lösung, sondern eröffnen auf diesem Weg noch weitere interessante Möglichkeiten. Wir verpacken das Form in eine Hilfsklasse (etwa clsMaximized):

Private mForm As Form

Public Property Get Value() As Boolean
  Value = CBool(mForm.WindowState = vbMaximized)
End Property

Public Sub Init(Form As Form)
  Set mForm = Form
End Sub

Und dazu nun die Erstellung des sechsten Bedingungs-Stapels:

Dim nMaximized As clsMaximized

Set mConditions6 = New clsConditions
With mConditions6
  .Operator = opAND
  .Add chkA, vbChecked
  .Add chkC, vbChecked
  Set nMaximized = New clsMaximized
  nMaximized.Init Me
  .Add nMaximized, True
End With

Statt des Forms wird nun eine Instanz dieser Klasse in den Bedingungs-Stapel aufgenommen, nachdem sie über die Init-Methode mit dem Form "gefüttert" worden ist.

Diese Hilfsklasse ist allerdings festgelegt - sie liefert True als Wert ihrer Standard-Eigenschaft Value, wenn das Form maximiert ist. Die Prüfung erfolgt dann gegen True oder gegen False, wenn Sie wollen). Sie könnten die Klasse auch neutral auslegen, indem Sie in Value den Wert der WindowState-Eigenschaft zurückgeben und nicht gegen True, sondern gegen den gewünschten Wert des Form-Zustands (hier also etwa vbmaximized) geprüft wird. Sie können die Klasse aber auch weiter dynamisieren, indem Sie den internen Vergleichswert dynamisch als Eigenschaft auslegen:

Private mForm As Form
Private mWindowState As Integer

Public Property Let WindowState(New_WindowState As Integer)
  mWindowState = New_WindowState
End Property

Public Property Get Value() As Boolean
  Value = CBool(mForm.WindowState = mWindowState)
End Property

Public Sub Init(Form As Form)
  Set mForm = Form
End Sub

Auf ähnliche Weise könnten Sie auch Hilfsklassen erstellen, die Vergleiche ermöglichen, die spezielle Operatoren erfordern, etwa TypeOf, IsObject, IsArray, VarType und viele mehr. Oder eine solche Hilfsklasse prüft nicht einen mehr oder weniger statisch vorgegebenen Wert, sondern sie führt im Moment der Prüfung irgendwelche komplexen Operationen durch, deren Ergebnis sie als einfachen Wahrheitswert in ihrer Value-Eigenschaft zurückgibt.

Die nun endlich folgende Bedingungs-Stapel-Klasse clsConditions ist somit nur ein Modell, das Sie weiter ausbauen, variieren und auch spezialisieren können. Es fehlt hier beispielsweise die Möglichkeit, einzelne Bedingungen dynamisch entfernen oder die Prüfwerte ändern zu können.

Public Enum OperatorConstants
  opOR
  opAND
End Enum

Public Enum ComparisonConstants
  compEq
  compNot
End Enum

Private mConditions As Collection

Private pOperator As OperatorConstants

Public Property Get Operator() As OperatorConstants
  Operator = pOperator
End Property

Public Property Let Operator(New_Operator As OperatorConstants)
  pOperator = New_Operator
End Property

Public Sub Add(Element As Variant, Value As Variant, _
 Optional Comparison As Variant)

  Dim nCondition As Variant
  
  If IsMissing(Comparison) Then
    nCondition = Array(Element, Value, compEq)
  Else
    nCondition = Array(Element, Value, Comparison)
  End If
  mConditions.Add nCondition
End Sub

Public Sub Clear()
  Set mConditions = New Collection
End Sub

Public Function Value() As Boolean
  Dim nCondition As Variant
  
  Select Case pOperator
    Case opOR
      For Each nCondition In mConditions
        Select Case nCondition(2)
          Case compEq
            If nCondition(0) = nCondition(1) Then
              Value = True
              Exit Function
            End If
          Case compNot
            If nCondition(0) <> nCondition(1) Then
              Value = True
              Exit Function
            End If
        End Select
      Next
    Case opAND
      For Each nCondition In mConditions
        Select Case nCondition(2)
          Case compEq
            If nCondition(0) <> nCondition(1) Then
              Exit Function
            End If
          Case compNot
            If nCondition(0) = nCondition(1) Then
              Exit Function
            End If
        End Select
      Next
      Value = True
  End Select
End Function

Public Sub Init(ByVal Operator As OperatorConstants, _
 ParamArray Conditions() As Variant)

  Dim l As Long
  
  pOperator = Operator
  If UBound(Conditions) = 0 Then
    If IsObject(Conditions(0)) Then
      If TypeOf Conditions(0) Is Collection Then
        Set mConditions = Conditions(0)
        Exit Sub
      End If
    Else
      Err.Raise 380
    End If
  End If
  Set mConditions = New Collection
  With mConditions
    For l = 0 To UBound(Conditions)
      If IsArray(Conditions(l)) Then
        If (LBound(Conditions(l)) = 0) _
         And ((UBound(Conditions(l)) = 1) _
         Or (UBound(Conditions(l)) = 2)) Then
          .Add Conditions(l)
        Else
          Err.Raise 380
        End If
      Else
        Err.Raise 380
      End If
    Next 'l
  End With
End Sub

Private Sub Class_Initialize()
  Set mConditions = New Collection
End Sub

Und letztendlich können Sie das Gesamtergebnis eines solchen Bedingungs-Stapels dazu verwenden, genau so dynamisch erstellte Steuerelement-Gruppen auf einen Schlag zu manipulieren - siehe "Sieben auf einen Streich" khwstateenabled.htm.


Beispiel-Projekt Conditions (conditions.zip - ca. 4,4 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer