Formularanwendung "Matrixoperationen"

mit Hinzufügen und Löschen von Steuerelementen zur Laufzeit

 

Dieses Beispiel ist im Hinblick auf folgende Punkte interessant:

 

  •  Als Benutzeroberfläche dient ausschließlich ein Formular. Alle Ein- und Ausgaben werden auf diesem Formular gemacht. Die Benutzersteuerung geschieht auf der Basis von geplanten Dialogzuständen mit Hilfe von Zustandsdiagrammen.

  • Von den Steuerelementen des Formulars werden die meisten erst zur Laufzeit des Programms angelegt. Das hat einen einfachen Grund: wie viele Elemente benötigt werden und in welcher Anordnung, hängt von der Benutzereingabe ab.

  • Die Benutzereingabe wird nur auf simple Art überprüft (validiert). Zum Abfangen der restlichen Fehler wird die (alte) VBA-Fehlerbehandlung benutzt.

  • Zwei von den drei zur Verfügung stehenden Matrixoperationen (Inverse und Transponierte) werden mit Hilfe von Worksheet-Funktionen gelöst, nur die dritte (Sortierung) erfordert eigene Programmierung in nennenswertem Umfang. Hierbei wird das Prinzip der Delegation angewandt.

 

 

 

Die Aufgabenstellung

 

Das Programm soll wahlweise eine von drei Matrixoperationen durchführen. Das folgende Bild zeigt den Kopf des Formulars kurz nach dem Start. Der untere, nicht abgebildete Teil des Formulars ist noch leer. Er wird später den Rest der Eingaben und die Ergebnisse aufnehmen.

 

 

Die Art der Benutzung sei kurz verbal beschrieben:

 

Nach Eingabe einer Zeilen- und einer Spaltenanzahl kann der Benutzer die Schaltfläche <Eingabe vorbereiten> drücken. Es wird dann auf dem Formular die Eingabemöglichkeit für eine Matrix in der gewünschten Größe  eröffnet.

 

Mit der Schaltfläche <Operation durchführen> wird die gewünschte Operation ausgeführt; das Ergebnis wird auf dem Formular unterhalb der eingegebenen Matrix angezeigt.

 

Die Schaltfläche <Operation zurücksetzen> kann nach Durchführung einer Operation benutzt werden, um die Ergebnisse aus dem Formular zu entfernen. Die Eingaben bleiben dabei erhalten.  Der Benutzer kann nun mit denselben Daten eine andere der drei Operationen durchführen. Er kann aber auch die Daten verändern und dann eine beliebige der drei Operationen anstoßen.

 

Die Schaltfläche <Alles zurücksetzen> entfernt die Ergebnisse und die Eingaben aus dem Formular. Sie stellt also den Anfangszustand wieder her. 

 

Die Schaltfläche <Beenden> schließt das Formular und beendet die Programmdurchführung. Sie ist stets verfügbar. Das Programm kann also in jeder Phase beendet werden. Eingegebene Daten werden allerdings nicht gespeichert.

 

 

Planung der Dialogzustände

 

Bei dieser Planung (s. Skript) werden zunächst Zustände gefunden, welche der Dialog zwischen Benutzer und Programm annehmen kann. Solche Zustände sind gekennzeichnet durch den Bearbeitungsstand und, davon abhängig, die Möglichkeiten der Aktion, welche der Benutzer in diesem Augenblick hat. Durch Aktionen des Benutzers, insbesondere das Anklicken von Schaltflächen, wechselt das Programm den Zustand. 

 

Die Planung dieser Zustände geschieht im Wesentlichen in einem Diagramm, dem Zustandsdiagramm, und einer ergänzenden Tabelle (s. unten). Die Tabelle definiert den Zustand. Sie gibt an, welche der Steuerelemente im betreffenden Zustand aktiviert sind (A) und welche nicht (N).

 

Wie das Diagramm zeigt, werden drei Zustände unterschieden. Mit Hilfe der Pfeile werden die Übergänge zwischen den Zuständen angezeigt. Klickt der Benutzer z.B. im Zustand „Eingabe vorbereitet“ auf die Schaltfläche <Operation durchführen>, so geht das Programm in den Zustand „Operation durchführen“ über.

 

Was geschieht, wenn Fehler auftreten, wird in diesem Diagramm vernachlässigt. Nichtsdestotrotz muss natürlich eine Fehlerbehandlung stattfinden. In diesem Falle wird das Programm nach Ausgabe einer Fehlermeldung in den Zustand „Eingabe vorbereitet“ zurückkehren. Der Benutzer kann dann seine Eingaben korrigieren und danach einen weiteren Versuch machen, die Operation anzustoßen.

 

 

 

Das UI im Detail

 

Die folgenden Bilder illustrieren die obigen Ausführungen zum UI. Im ersten Bild befindet sich das Formular noch im Zustand „nicht vorbereitet“. Der Benutzer kann nun die Größe der Ursprungsmatrix eingeben und die gewünschte Operation markieren. Dann muss er die Schaltfläche <Eingabe vorbereiten> drücken.

 

 

Das folgende Bild zeigt das Formular im Zustand „Eingabe vorbereitet“. Die Eingabefelder für die Matrix stehen bereit, aber der Benutzer hat noch nichts eingegeben.

 

 

Auch das nächste Bild beruht noch auf dem Zustand „Eingabe vorbereitet“. Der Benutzer hat nunmehr die Matrix ausgefüllt. Er hat aber noch nicht die Schaltfläche <Operation durchführen> gedrückt. Noch könnte er den Inhalt der Matrix oder die gewünschte Operation verändern.

 

 

 

Indem der Benutzer die Schaltfläche <Operation durchführen> drückt, gelangt er in den Zustand „Operation durchgeführt“ (nächstes Bild). Im unteren Teil des Formulars wird jetzt die Ergebnismatrix angezeigt.

 

 

Der Benutzer kann nun die Schaltfläche <Operation zurücksetzen> anklicken, um mit den Daten noch eine andere Operation durchzuführen zu können. Er kommt dann in den Zustand „Eingabe vorbereitet“ zurück.

 

Er könnte jetzt nach Belieben den Inhalt der Matrix belassen oder verändern und die gewünschte Operation wählen. Wir wollen annehmen, dass er die Matrix unverändert lässt, aber als Operation jetzt das Sortieren auswählt (Bild unten).

 

 

Klickt der Benutzer auf die Schaltfläche <Operation durchführen>, so wird im unteren Teil des Formulars die sortierte Matrix angezeigt. Der Dialog befindet sich wieder im Zustand „Operation durchgeführt“ (nächstes Bild).

 

 

 

Der Aufbau des Programms

 

Das Programm hat eine zweischichtige Architektur, welche eine Trennung von Benutzerführung (UI) und Programmlogik realisiert. Die obere Schicht besteht aus dem Formular bzw. dem Formularmodul (MatrixForm). Die untere Schicht ist zweigeteilt und umfasst ein Modul MatrixSortierung, welches eine Sortierfunktion bereitstellt und ein zweites Modul ValHlp mit Hilfsfunktionen zur Validierung von Eingaben.

 

 

Auffällig und etwas untypisch ist, dass der Code für das Formularmodul umfangreicher ist als der für die Programmlogik. Hierfür gibt es zwei Gründe:

 

  •  Nur ein kleiner Teil des Programmkerns wird selbst programmiert. Für die inverse Matrix und die transponierte Matrix werden Worksheet-Funktionen herangezogen. Besonders die Programmierung der Inversen hätte viel Aufwand erfordert.
  • Im Formularmodul ist auch der Code für das Anlegen und Entfernen der Ein- und Ausgabefelder enthalten.

 

 

Der Code des Formularmoduls

 

Die Formularklasse besitzt eine Reihe von Instanzenvariablen, die alle die Felder für die Matrizen betreffen. Die Variablen m, h und v nehmen die Textboxes der einzugebenden Matrix auf, die Variablen r, u und n die der auszugebenden Ergebnismatrix.

 

Beachten Sie, dass den Textfeldern bei ihrem Anlegen in den Prozeduren AnlegenBtn_Click und insertErgTBxs Namen zugewiesen werden (zweiter Parameter der Methode Controls.Add). Dies ist notwendig, weil die Felder beim Löschen mit der Methode Controls.Remove mit ihren Namen angesprochen werden müssen.

 

Die Prozeduren, welche die Dialogzustände herstellen, befinden sich am Ende des Programmtexts. Das Anlegen und das Löschen der Felder für die Matrizen wurde nicht diesen Prozeduren einverleibt, sondern in gesonderten Prozeduren realisiert, weil diese Vorgänge nicht nur vom Dialogzustand, sondern auch von der gewünschten Größe der Eingangsmatrix und der ausgewählten Operation abhängen.

 

Eine explizite Eingabevalidierung findet nur in Bezug auf die Eingabe der Matrixgröße statt (Prozedur AnlegenBtn_Click()). Von dort aus wird die Funktion ValidierungOK aufgerufen, welche ihrerseits auf allgemein verwendbare Prüffunktionen im Modul ValHlp zurückgreift.  Die vom Benutzer eingegebene Matrix wird nicht validiert. Dies wäre natürlich möglich, aber aufwendig. Stattdessen wird in der Prozedur DurchfuehrenBtn_Click() die klassische VBA-Fehlerbehandlung mit On Error GoTo verwendet, welche alle bei der Realisierung der Matrixoperation auftretenden Fehler abfangen kann. Der Preis für diese pauschale Fehlerbehandlung ist allerdings, dass dem Benutzer nur sehr allgemeine Hinweise auf die Fehlerursache gegeben werden können.

 

 

 

Option Explicit

 

Private m() As Control                     'Eingabematrix

Private h() As Control                      'Beschriftung der Spalten der Eingabematrix

Private v() As Control                       'Beschriftung der Zeilen der Eingabematrix

Private r() As Control                       'Ergebnismatrix

Private u() As Control                      'Beschriftung der Spalten der Ergebnismatrix

Private n() As Control                      'Beschriftung der Zeilen der Ergebnismatrix

Private rVorhanden As Boolean        'verhindert Löschversuch, wenn nicht vorhanden

Private mVorhanden As Boolean 

 

'Aktionen nach Klicken von <Eingabe vorbereiten>

Private Sub AnlegenBtn_Click()

    If Not ValidierungOK Then Exit Sub

   

    Dim i As Integer, j As Integer

    Dim z As Integer, s As Integer

    z = CInt(Me.ZeilenzahlTBx.Text)

    s = CInt(Me.SpaltenzahlTBx.Text)

   

    'die Eingabefelder werden angelegt

   

    ReDim m(1 To z, 1 To s)

    ReDim h(1 To s)

    ReDim v(1 To z)

   

    For j = 1 To s     'Beschriftung der Spalten

        Set h(j) = Me.Controls.Add("Forms.TextBox.1", "h" & j)

        h(j).Height = 24

        h(j).Width = 50

        h(j).Left = 45 + (j - 1) * 50

        h(j).Top = 120

        h(j).Text = "" & j

        h(j).Locked = True

    Next j

   

    For i = 1 To z     'Beschriftung der Zeilen

        Set v(i) = Me.Controls.Add("Forms.TextBox.1", "v" & i)

        v(i).Height = 24

        v(i).Width = 50

        v(i).Left = 15

        v(i).Top = 139 + (i - 1) * 25

        v(i).Text = "" & i

        v(i).Locked = True

    Next i

   

    For i = 1 To z

        For j = 1 To s

            Set m(i, j) = Me.Controls.Add("Forms.TextBox.1", "m" & i & j)

            m(i, j).Height = 24

            m(i, j).Width = 50

            m(i, j).Left = 45 + (j - 1) * 50

            m(i, j).Top = 139 + (i - 1) * 25

        Next j

    Next i   

 

    mVorhanden = True   

    ZustandEingabeVorbereitet

End Sub

 

 

'Aktionen nach Klicken des Buttons <Beenden>

Private Sub BeendenBtn_Click()

    Unload Me

End Sub

 

 

 

'Aktionen nach Klicken des Buttons <Alles zurücksetzen>

Private Sub CancelBtn_Click()

    Me.ZeilenzahlTBx.Text = ""

    Me.SpaltenzahlTBx.Text = ""

    Me.TransponierteOBtn.Value = True

    entferneEingabeTBxs

    entferneErgebnisTBxs

    ZustandNichtVorbereitet

End Sub

 

 

 

'Aktionen nach Klicken des Buttons <Operation durchführen>

Private Sub DurchfuehrenBtn_Click()

 

    On Error GoTo errorhandler1

   

    If Me.TransponierteOBtn.Value = True Then

       transponierteMatrix

    ElseIf Me.InverseOBtn.Value = True Then

       invertierteMatrix

    Else

       sortierteMatrix

    End If

    ZustandOperationDurchgefuehrt

    Exit Sub

   

errorhandler1:

    MsgBox "Es ist ein Fehler aufgetreten. Stellen Sie sicher, " & _

           "dass in allen Eingabefeldern zulässige Werte stehen."

    ZustandEingabeVorbereitet

   

End Sub

 

 

 

'Ermittlung und Ausgabe der Transponierten

Private Sub transponierteMatrix()

    Dim e() As Double, t As Variant

    e = inputMatrix     'Daten aus den Eingabefeldern holen

    t = Application.WorksheetFunction.Transpose(e)

    insertErgTBxs CInt(Me.SpaltenzahlTBx.Text), CInt(Me.ZeilenzahlTBx.Text)

    outputErg t         'Ausgabe in die Ergebnisfelder

End Sub

 

 

'Ermittlung und Ausgabe der Inversen

Private Sub invertierteMatrix()

    Dim e() As Double, t As Variant

    e = inputMatrix      'Daten aus den Eingabefeldern holen

    t = Application.WorksheetFunction.MInverse(e)

    insertErgTBxs CInt(Me.ZeilenzahlTBx.Text), CInt(Me.SpaltenzahlTBx.Text)

    outputErg t         'Ausgabe in die Ergebnisfelder

End Sub

 

 

'Ermittlung und Ausgabe der sortierten Matrix

Private Sub sortierteMatrix()

    Dim e() As Double, t() As Double

    e = inputMatrix      'Daten aus den Eingabefeldern holen

    t = Matrixsortierung.sortMatrix(e)

    insertErgTBxs CInt(Me.ZeilenzahlTBx.Text), CInt(Me.SpaltenzahlTBx.Text)

    outputErg t         'Ausgabe in die Ergebnisfelder

End Sub

 

 

'speichert die Daten der Eingabe zur Weiterverarbeitung in einem Array

Public Function inputMatrix() As Double()

    Dim i As Integer, j As Integer, rows As Integer, cols As Integer

    rows = CInt(Me.ZeilenzahlTBx.Text)

    cols = CInt(Me.SpaltenzahlTBx)

    Dim p() As Double

    ReDim p(1 To rows, 1 To cols)

    For i = 1 To rows

        For j = 1 To cols

            p(i, j) = CDbl(m(i, j).Text)

        Next j

    Next i

    inputMatrix = p

End Function

 

 

'schreibt die Ergebnisdaten in die Ausgabe-Textboxes

'braucht Variant-Input für Ergebnise aus WorksheetFunctions

Public Sub outputErg(a As Variant)

    Dim i As Integer, j As Integer

    For i = 1 To UBound(a, 1)

       For j = 1 To UBound(a, 2)

          r(i, j).Text = CStr(a(i, j))

       Next j

    Next i

End Sub

 

 

'Aktionen nach Klicken des Buttons <Operation zurücksetzen>

Private Sub OpZurueckBtn_Click()

    entferneErgebnisTBxs

    ZustandEingabeVorbereitet

End Sub

 

 

'Aktionen beim Laden der Maske

Private Sub UserForm_Initialize()

    Me.TransponierteOBtn.Value = True

    ZustandNichtVorbereitet

End Sub

 

 

'überprüft die Eingaben der Zeilen- und der Spaltenzahl

Public Function ValidierungOK() As Boolean

    If Not (ValHlp.istImGanzzBereich(Me.ZeilenzahlTBx.Text, 1, 10) And _

            ValHlp.istImGanzzBereich(Me.SpaltenzahlTBx.Text, 1, 10)) Then

            ValidierungOK = False

            MsgBox "Es sind nur Zeilen- und Spaltenzahlen von 1 bis 10 zugelassen"

            Exit Function

    End If

    If Me.InverseOBtn.Value = True And Not CInt(Me.ZeilenzahlTBx.Text) = _

                                               CInt(Me.SpaltenzahlTBx.Text) Then

        ValidierungOK = False

        MsgBox "Die Inverse kann nur von einer quadratischen Matrix ermittelt werden"

        Exit Function

    End If

    ValidierungOK = True

End Function

 

 

'legt die Textboxes zur Ergebnisausgabe auf dem Formular an

Private Sub insertErgTBxs(ByVal z As Integer, ByVal s As Integer)

    Dim i As Integer, j As Integer, shift As Integer

    ReDim r(1 To z, 1 To s)

    ReDim u(1 To s)

    ReDim n(1 To z)

    shift = IIf(s > z, s, z)

   

    For j = 1 To s     'Beschriftung der Spalten

        Set u(j) = Me.Controls.Add("Forms.TextBox.1", "u" & j)

        u(j).Height = 24

        u(j).Width = 50

        u(j).Left = 45 + (j - 1) * 50

        u(j).Top = 120 + shift * 25 + 50

        u(j).Text = "" & j

        u(j).Locked = True

    Next j

   

    For i = 1 To z     'Beschriftung der Zeilen

        Set n(i) = Me.Controls.Add("Forms.TextBox.1", "n" & i)

        n(i).Height = 24

        n(i).Width = 50

        n(i).Left = 15

        n(i).Top = 139 + (i - 1) * 25 + shift * 25 + 50

        n(i).Text = "" & i

        n(i).Locked = True

    Next i

 

    For i = 1 To z     'für die Matrix selbst

        For j = 1 To s

            Set r(i, j) = Me.Controls.Add("Forms.TextBox.1", "r" & i & j)

            r(i, j).Height = 24

            r(i, j).Width = 50

            r(i, j).Left = 45 + (j - 1) * 50

            r(i, j).Top = 139 + (i - 1) * 25 + shift * 25 + 50

        Next j

    Next i

   

    rVorhanden = True

End Sub

 

 

 

'löscht die Textboxes für die Eingabe

Private Sub entferneEingabeTBxs()

 

    If Not mVorhanden Then Exit Sub

   

    Dim i As Integer, j As Integer

    For j = 1 To UBound(h)     'Beschriftung der Spalten entfernen

        Me.Controls.Remove "h" & j

    Next j

   

    For i = 1 To UBound(v)     'Beschriftung der Zeilen entfernen

        Me.Controls.Remove "v" & i

    Next i

   

    For i = 1 To UBound(m, 1)  'Matrix entfernen

        For j = 1 To UBound(m, 2)

            Me.Controls.Remove "m" & i & j

        Next j

    Next i

   

    mVorhanden = False

   

End Sub

 

 

'löscht die Textboxes für die Ergebnisausgabe

Private Sub entferneErgebnisTBxs()

    If Not rVorhanden Then Exit Sub

   

    Dim i As Integer, j As Integer

    For j = 1 To UBound(u)     'Beschriftung der Spalten entfernen

        Me.Controls.Remove "u" & j

    Next j

   

    For i = 1 To UBound(n)     'Beschriftung der Zeilen entfernen

        Me.Controls.Remove "n" & i

    Next i

   

    For i = 1 To UBound(r, 1)  'Matrix entfernen

        For j = 1 To UBound(r, 2)

            Me.Controls.Remove "r" & i & j

        Next j

    Next i

   

    rVorhanden = False

End Sub

 

 

 

'=================================================

'Dialogzustände

'=================================================

 

Private Sub ZustandNichtVorbereitet()

    Me.ZeilenzahlTBx.Enabled = True

    Me.SpaltenzahlTBx.Enabled = True

    Me.TransponierteOBtn.Enabled = True

    Me.InverseOBtn.Enabled = True

    Me.SortierenOBtn.Enabled = True

    Me.AnlegenBtn.Enabled = True

    Me.DurchfuehrenBtn.Enabled = False

    Me.CancelBtn.Enabled = True

    Me.OpZurueckBtn.Enabled = False

End Sub

 

 

Private Sub ZustandEingabeVorbereitet()

    Me.ZeilenzahlTBx.Enabled = False

    Me.SpaltenzahlTBx.Enabled = False

    Me.TransponierteOBtn.Enabled = True

    Me.InverseOBtn.Enabled = True

    Me.SortierenOBtn.Enabled = True

    Me.AnlegenBtn.Enabled = False

    Me.DurchfuehrenBtn.Enabled = True

    Me.CancelBtn.Enabled = True

    Me.OpZurueckBtn.Enabled = False

End Sub

 

 

Private Sub ZustandOperationDurchgefuehrt()

    Me.ZeilenzahlTBx.Enabled = False

    Me.SpaltenzahlTBx.Enabled = False

    Me.TransponierteOBtn.Enabled = False

    Me.InverseOBtn.Enabled = False

    Me.SortierenOBtn = False

    Me.AnlegenBtn.Enabled = False

    Me.DurchfuehrenBtn.Enabled = False

    Me.CancelBtn.Enabled = True

    Me.OpZurueckBtn.Enabled = True

End Sub

 

 

 

Der Code des Moduls Matrixsortierung

 

In diesem Modul wird das Prinzip der Delegation angewandt (s. Skript). Die Hauptfunktion ist sortMatrix, eine sehr kurze Funktion, deren Rumpf nur eine Zeile umfasst. Die Funktion lässt zunächst durch Aufruf von MatrixToList die zu sortierende Matrix in ein eindimensionales Array verwandeln, übergibt dieses Array dann der Funktion InsertionSort zum Sortieren und verwandelt anschließend das von InsertionSort gelieferte eindimensionale Array durch einen Aufruf der Funktion ListToMatrix wieder in eine Matrix der ursprünglichen Dimensionierung.

 

'wandelt eine Matrix in ein eindimensionales Array um

Public Function MatrixToList(ByRef a() As Double) As Double()

    Dim t() As Double

    Dim m As Integer, n As Integer, i As Integer, j As Integer

    m = UBound(a, 1)        'Anzahl der Zeilen

    n = UBound(a, 2)        'Anzahl der Spalten

    ReDim t(1 To m * n)

    For i = 1 To m          'übertrage alle Elemente

        For j = 1 To n

            t((i - 1) * n + j) = a(i, j)

        Next j

    Next i

    MatrixToList = t

End Function

 

 

'wandelt ein eindimensionales Array in eine Matrix um. m ist die Zeilenzahl

'der Matrix. Die Anzahl der Elemente in a ist durch m ohne Rest teilbar

Public Function ListToMatrix(ByRef a() As Double, ByVal m As Integer) As Double()

    Dim n As Integer, i As Integer

    n = UBound(a) \ m                'Anzahl der Spalten in der Zielmatrix

    Dim r() As Double                'Zielmatrix

    ReDim r(1 To m, 1 To n)

    For i = 1 To UBound(a)           'übertrage alle Elemente

        r((i - 1) \ n + 1, i - ((i - 1) \ n) * n) = a(i)

    Next i

    ListToMatrix = r

End Function

 

 

 

'sortiert ein eindimensionales Array in aufsteigender Ordnung

'ohne Nebeneffekte, weil keine Sortierung "in place"

Public Function InsertionSort(ByRef a() As Double) As Double()

    Dim s() As Double

    ReDim s(1 To UBound(a))

    Dim i As Integer, j As Integer, found As Boolean

    s(1) = a(1)

    For j = 2 To UBound(a)

        i = j - 1

        found = False

        Do While i > 0 And Not found

            If s(i) > a(j) Then

                s(i + 1) = s(i)

                i = i - 1

            Else

                found = True

            End If

        Loop

        s(i + 1) = a(j)

    Next j

    InsertionSort = s

End Function

 

 

'sortiert die Elemente einer 1-basierten Matrix in aufsteigender Ordnung;

'benutzt MatrixToList, InsertionSort und ListToMatrix

Public Function sortMatrix(ByRef m() As Double) As Double()

    sortMatrix = ListToMatrix(InsertionSort(MatrixToList(m)), UBound(m, 1))

End Function

 

 

 

Der Code des Moduls ValHlp

 

Bei diesem Modul handelt es sich um eine Sammlung allgemein verwendbarer Funktionen, welche Eingabewerte auf ihre Zulässigkeit überprüfen. Hier sollen nur die Funktionen des Moduls aufgelistet werden, welche in unserer aktuellen Anwendung benutzt werden. Es sind:

 

'ermittelt für den Wert z, ob er einer Ganzzahl entspricht;

'z kann auch ein String sein

Public Function istGanzzahl(ByVal z As Variant) As Boolean

    If Not IsNumeric(z) Then

        istGanzzahl = False

    Else

        If CLng(z) - Int(z) = 0 Then

            istGanzzahl = True

        Else

            istGanzzahl = False

        End If

    End If

End Function

 

 

 

'ermittelt für den Wert z, ob er einer Ganzzahl entspricht und

'im Bereich [min, max] liegt; z kann auch ein String sein

Public Function istImGanzzBereich(ByVal z As Variant, _

                                  ByVal min As Long, _

                                  ByVal max As Long) As Boolean

    If Not istGanzzahl(z) Then

        istImGanzzBereich = False

    Else

        If CLng(z) >= min And CLng(z) <= max Then

            istImGanzzBereich = True

        Else

            istImGanzzBereich = False

        End If

    End If

End Function