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 27.06.2001

Diese Seite wurde zuletzt aktualisiert am 27.06.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...

Grenzkontrolle

Zurück...


Anzeige

(-hg) mailto:hg_between@aboutvb.de

Interessanterweise gibt es in Visual Basic keine Funktion, die prüft, ob ein Wert innerhalb bestimmter Grenzen liegt. Eine solche Prüfung ist eigentlich recht simpel: In einer Select...Case-Verzweigung prüfen Sie, ob der Wert einer der beiden Grenzen entspricht, ob er dazwischen liegt, oder ob er außerhalb des Bereichs liegt.

Select Case Wert
  Case LinkeGrenze
  -> gleich linksseitige Grenze
  Case RechteGrenze
  -> gleich rechtsseitige Grenze
  Case Is > LinkeGrenze And Is < RechteGrenze
  -> innerhalb der Grenzen
  Case Else
  -> außerhalb der Grenzen
End Select

Sieht tatsächlich ganz einfach aus, nicht wahr? Aber, Hand auf's Herz - haben Sie auf Anhieb gemerkt, dass die dritte Bedingung gar nicht den Syntax-Regeln für Case-Bedingungen entspricht? Sie kommt einem zwar irgendwie bekannt vor, aber Visual Basic würde sie so nicht akzeptieren. Für ganzzahlige Datentypen wie Byte, Integer und Long lässt sich die Bedingung jedoch leicht modifizieren:

  Case LinkeGrenze + 1 To RechteGrenze +1

Aber bei Fließkommawerten wie Single und Double (und auch Date wird ja bekanntlich im Speicher als Fließkommazahl des Datentyps Double verwaltet) entfällt diese Möglichkeit. Denn wie viel genau müssten Sie zur eigentlichen linken Grenze addieren, damit die linke Grenze für diese Bedingung gerade eben um das "minimalste" Quäntchen größer wird? Oder wie viel genau müssten Sie vom eigentlichen rechten Grenzwert subtrahieren, damit der rechte Grenzwert gerade eben kleiner wird? Ihre mathemtischen Kenntnisse werden Ihnen sicher sagen, dass das eine unmögliche Aufgabenstellung ist.

Die Lösung liegt im ganz normalen Verhalten der Select...Case-Verzweigung. Traf bereits eine der vorhergehenden Bedingungen zu, werden die übrigen Bedingungen erst gar nicht mehr geprüft. War der zu prüfende Wert also bereits gleich einem der Grenzwerte, wird die Bedingung mit der Bereichsprüfung gar nicht mehr berücksichtigt. Sie können also getrost schlicht und ergreifend die Grenzwerte auch hier verwenden:

   Case LinkeGrenze To RechteGrenze

Sie können die Prüfung so nun direkt in Ihrem Code verwenden. Benötigen Sie sie häufiger, packen Sie sie am besten in eine Funktion. "Eine" Funktion? Nein, leider brauchen Sie für jeden nummerischen Datentyp eine eigene Funktion - falls Sie nicht nur eine universelle Funktion mit Performance fressenden Variant-Datentypen deklarieren wollen (oder müssen, wie in VBScript). Schauen wir uns zunächst eine passende Funktion für Integer-Werte an. Der Rückgabewert kann übrigens für alle datentyp-spezifischen Funktion gleichermaßen verwendbar als Enumeration von Konstanten angelegt werden.

Public Enum BetweenMarginsConstants
  bmNone
  bmLMargin
  bmRMargin
  bmBetween
End Enum

Public Function BetweenInteger(ByVal Value As Integer, _
 ByVal LMargin As Integer, ByVal RMargin As Integer) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenInteger = bmLMargin
    Case RMargin
      BetweenInteger = bmRMargin
    Case LMargin To RMargin
      BetweenInteger = bmBetween
  End Select
End Function

Eine Kleinigkeit fehlt dieser Funktion dieser Funktion aber noch. Sie und ich könnten uns nämlich jetzt noch auf eine haarspalterische Diskussion darüber einlassen, ob unter "innerhalb" von Grenzen diese Grenzen einzuschließen wären, oder ob darunter ein tatsächliches "Dazwischen" zu verstehen sei. Sparen wir uns lieber die Magengeschwüre und grauen Haare, die solche fruchtlosen Semantik-Debatten immer einbringen, und erweitern wir die Funktion um den optionalen Parameter "IncludeMargins" mit der Voreinstellung True. Innerhalb der Funktion brauchen jedoch keine weitere Verzweigung, um diesen Parameter auszuwerten. Es genügt, die Ergebnisse der beiden ersten Grenzprüfungen jeweils mit "And" mit dem Parameter-Wert zu verknüpfen. Sollen die Grenzen eingeschlossen werden, ist der Wert des Parameters ja True, und die Verknüpfung ergibt unverändert den Prüfwert. Ist der Parameter-Wert False, ergibt die Verknüpfung 0 - der zu prüfende Wert liegt eben nicht tatsächlich zwischen den Grenzen, sondern genau auf einer Grenze.

Public Function BetweenInteger(ByVal Value As Integer, _
 ByVal LMargin As Integer, ByVal RMargin As Integer, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenInteger = bmLMargin And IncludeMargins
    Case RMargin
      BetweenInteger = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenInteger = bmBetween
  End Select
End Function

Nach diesem Muster sind nun auch die folgenden Funktionen für die übrigen Datentypen gebildet - mit Ausnahme für den Datentyp Variant. Für diesen folgt noch eine eigene Version ganz zum Schluss.

Public Function BetweenByte(ByVal Value As Byte, _
 ByVal LMargin As Byte, ByVal RMargin As Byte, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenByte = bmLMargin And IncludeMargins
    Case RMargin
      BetweenByte = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenByte = bmBetween
  End Select
End Function

Public Function BetweenLong(ByVal Value As Long, _
 ByVal LMargin As Long, ByVal RMargin As Long, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenLong = bmLMargin And IncludeMargins
    Case RMargin
      BetweenLong = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenLong = bmBetween
  End Select
End Function

Public Function BetweenSingle(ByVal Value As Single, _
 ByVal LMargin As Single, ByVal RMargin As Single, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenSingle = bmLMargin And IncludeMargins
    Case RMargin
      BetweenSingle = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenSingle = bmBetween
  End Select
End Function

Public Function BetweenDouble(ByVal Value As Double, _
 ByVal LMargin As Double, ByVal RMargin As Double, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenDouble = bmLMargin And IncludeMargins
    Case RMargin
      BetweenDouble = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenDouble = bmBetween
  End Select
End Function

Public Function BetweenCurrency(ByVal Value As Currency, _
 ByVal LMargin As Currency, ByVal RMargin As Currency, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenCurrency = bmLMargin And IncludeMargins
    Case RMargin
      BetweenCurrency = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenCurrency = bmBetween
  End Select
End Function

Public Function BetweenDate(ByVal Value As Date, _
 ByVal LMargin As Date, ByVal RMargin As Date, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  Select Case Value
    Case LMargin
      BetweenDate = bmLMargin And IncludeMargins
    Case RMargin
      BetweenDate = bmRMargin And IncludeMargins
    Case LMargin To RMargin
      BetweenDate = bmBetween
  End Select
End Function

Eine kleine Ausnahme bildet die Funktion für Variant-Werte. Die Grenzprüfung ist schließlich nur für nummerische Werte sinnvoll. Sinnlos wäre sie jedoch etwa für Strings oder gar Objekte, die ja auch ein Variant-Variablen stecken können. Da es allerdings auch keinen Sinn hätte, ein Datum mit irgend einem anderen nummerischen Wert zu vergleichen, müssen Werte des Datentyps Date gesondert behandelt werden. Da diese von der VB-Funktion IsNumeric nicht als nummerische Werte erkannt werden, wird zunächst geprüft, ob alle drei Werte nummerisch sind. Dies erfolgt in einer Staffelung von If-Bedingungen - ist die erste schon falsch, brauchen die übrigen erst gar nicht ausgeführt werden. Sind alle drei Werte nummerisch, wird der Select...Case-Vergleich ausgeführt und die Funktion wird verlassen. Falls nicht, können es ja immer noch Datumswerte sein - die Prüfungsstaffel mit IsDate sieht ähnlich aus. Ist einer der Werte weder nummerisch noch ein Datum, wird schließlich der Fehler 5 ("Ungültiger Prozeduraufruf oder ungültiges Argument") ausgelöst.

Public Function BetweenVariant(ByVal Value As Variant, _
 ByVal LMargin As Variant, ByVal RMargin As Variant, _
 Optional ByVal IncludeMargins As Boolean = True) _
 As BetweenMarginsConstants

  If IsNumeric(Value) Then
    If IsNumeric(LMargin) Then
      If IsNumeric(RMargin) Then
        Select Case Value
          Case LMargin
            BetweenVariant = bmLMargin And IncludeMargins
          Case RMargin
            BetweenVariant = bmRMargin And IncludeMargins
          Case LMargin To RMargin
            BetweenVariant = bmBetween
        End Select
        Exit Function
      End If
    End If
  End If
  If IsDate(Value) Then
    If IsDate(LMargin) Then
      If IsDate(RMargin) Then
        Select Case Value
          Case LMargin
            BetweenVariant = bmLMargin And IncludeMargins
          Case RMargin
            BetweenVariant = bmRMargin And IncludeMargins
          Case LMargin To RMargin
            BetweenVariant = bmBetween
        End Select
        Exit Function
      End If
    End If
  End If
  Err.Raise 5
End Function

Modul modBetween (modBetween.bas - ca. 4,9 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