Steuerelemente zur Laufzeit hinzufügen (VBA)  
Autor/Einsender:
Datum:
  Angie
05/2006
Anregungen/Tipps an:   Angie
In der Entwicklungsumgebung der Office-Programme (Excel, Word, PowerPoint ab Office 97) steht eine Oberfläche zur Verfügung, mit der Dialoge (UserForms) manuell entworfen werden können. Aus der Werkzeugsammlung können die verschiedenen Steuerelemente zur UserForm hinzugefügt werden und anschließend ggf. in der Größe verändert und positioniert werden. Auch die Eigenschaften der jeweiligen Steuerelemente können im Eigenschaftsfenster individuell festgelegt werden.
Es gibt jedoch Konstellationen, in der es sinnvoll ist, die Steuerelemente (Objekte) zur Laufzeit zur UserForm hinzuzufügen, beispielsweise wenn zur Entwurfszeit die Anzahl der benötigten Steuerelemente nicht bekannt ist.
Thema dieses Tutorials ist das Hinzufügen von Steuerelementen zur UserForm zur Laufzeit. Bekanntlich ist es auch möglich, beispielsweise in Excel ActiveX-Steuerelemente einem Tabellenblatt hinzuzufügen, in Word in einem Dokument, dies wird hier jedoch nicht behandelt.
Es wird hier davon ausgegangen, dass zumindest Grundkenntnisse in VBA vorhanden sind.
1.  Methoden
Add-Methode
Remove-Methode
2.  Ereignis-Prozeduren
Schlüsselwort WithEvents
im Codebereich einer UserForm
in einem Klassenmodul
3.  Beispiele aus der Praxis
UserForm ohne ScrollBar
UserForm mit ScrollBar
Frame mit ScrollBar
4.  Links zum Thema
5.  Download der Demos
Bei Fragen zu diesem Tutorial nutzen Sie bitte unser VB-/VBA-Forum.

  Methoden
Um Steuerelemente zur Laufzeit zu einem gültigen Objekt, z. B. UserForm oder Frame, hinzufügen und wieder löschen zu können, stehen die beiden Methoden Add und Remove zur Verfügung.
Anmerkung: Wie viele Steuerelemente zur Laufzeit zu einer UserForm hinzugefügt werden können, entzieht sich leider meiner Kenntnis, dies kann jedoch mit den Beispielen in diesem Tutorial ausgetestet werden. Es sei aber schon hier darauf hingewiesen, dass es zwischen den Office-Versionen und -Programmen durchaus Unterschiede in der möglichen Anzahl der Steuerelemente auf einer UserForm geben kann.
Add-Methode
Mit der Add-Methode wird ein Steuerelement zu einem gültigen Objekt hinzugefügt.
 
Set Control = Object.Add(ProgID [, Name [, Visible]])
 
Mit der ProgID wird der Klassenname des Objekts angegeben, das hinzugefügt werden soll.
ProgID Steuerelement ProgID Steuerelement
Forms.CheckBox.1 Kontrollkästchen Forms.MultiPage.1 Multiseiten
Forms.ComboBox.1 Kombinationsfeld Forms.OptionButton.1 Optionsfeld
Forms.CommandButton.1 Befehlsschaltfläche Forms.ScrollBar.1 Bildlaufleiste
Forms.Frame.1 Rahmen Forms.SpinButton.1 Drehfeld
Forms.Image.1 Abbildung Forms.TabStrip.1 Register
Forms.Label.1 Bezeichnungsfeld Forms.TextBox.1 Textfeld
Forms.ListBox.1 Listenfeld Forms.ToggleButton.1 Umschaltfeld
Das Argument Name ist optional und gibt den Namen des Objekts an, das hinzugefügt wird. Wenn kein Name angegeben ist, generiert das System basierend auf den Regeln der Anwendung, in der das Formular verwendet wird, einen Standardnamen, bei einer TextBox z.B. TextBox1, TextBox2 usw.
Mit dem Argument Visible wird angegeben, ob das Objekt sichtbar oder ausgeblendet ist.
Die Add-Methode gibt entsprechend dem angegebenen Wert für ProgID ein Steuerelement zurück.
Mit folgendem kleinen Beispiel wird eine TextBox zur UserForm hinzugefügt, die Position, Höhe und Breite zugewiesen. Werden die TextBox-Eigenschaften Width und Height (Breite und Höhe) nicht angegeben, werden automatisch Standardwerte verwendet, für die Breite 72 und für die Höhe 18 (in Punkt).
 
Private Sub UserForm_Initialize()
  Dim objTextBox As MSForms.TextBox

  Set objTextBox = Me.Controls.Add( _
        "Forms.TextBox.1", "txtDemo1", True)
  With objTextBox
    .Left = 6
    .Top = 6
    .Width = 72
    .Height = 18
  End With
  Set objTextBox = Nothing
End Sub
 
Im weiteren Code kann, wenn wie in obigem Beispiel kein Objektverweis mehr existiert, auf die Eigenschaften (hier die Text-Eigenschaft) der zur Laufzeit hinzugefügten TextBox über die Controls-Auflistung verwiesen werden mit
 
MsgBox Me.Controls("txtDemo1").Text
 
oder über den Syntax mit Ausrufezeichen
 
MsgBox Me!txtDemo_1.Text
 
Es ist nicht möglich, das zur Laufzeit hinzugefügte Objekt anzusprechen mit
 
MsgBox Me.txtDemo_1.Text
MsgBox txtDemo_1.Text
 
Wenn im weiteren Code auf ein zur Laufzeit hinzugefügtes Objekt verwiesen werden muss, kann auch statt einen Namen zu vergeben (wie oben beschrieben), ein Verweis auf das Objekt (hier die TextBox) in einer Variable gespeichert werden. Variablen vom Typ Private stehen nur in dem Modul zur Verfügung, in dem sie deklariert wurden.
 
Option Explicit

Private m_objTextBox As MSForms.TextBox

Private Sub UserForm_Initialize()
  Set m_objTextBox = Me.Controls.Add("Forms.TextBox.1", , True)
  With m_objTextBox
    .Left = 6
    .Top = 6
    .Width = 72
    .Height = 18
  End With
End Sub
 
Nach Ausführung des UserForm_Initialize-Ereignisses wird im weiteren Code mit der Objektvariable m_objTextBox auf die TextBox verwiesen. Der Wert in der TextBox beispielsweise wird zurückgegeben mit
 
MsgBox m_objTextBox.Text
 
Remove-Methode
Mit der Remove-Methode können die zur Laufzeit hinzugefügten Steuerelemente wieder entfernt werden. Der Versuch mit dieser Methode ein Steuerelement zu löschen, das zur Entwurfszeit hinzugefügt wurde, führt zu einem Fehler!
 
Object.Remove(collectionindex)
 
Das Argument collectionindex ist die Position (der Index) eines Elements innerhalb einer Auflistung. Es werden sowohl numerische als auch Zeichenfolgenwerte akzeptiert. Wenn der Wert eine Zahl ist, ist der Minimalwert 0 und der Maximalwert die Anzahl der Elemente in der Auflistung minus 1. Wenn der Wert eine Zeichenfolge ist, muss diese einem gültigen Elementnamen entsprechen.
Die mit der Add-Methode hinzugefügte TextBox kann gelöscht werden mit
 
Me.Controls.Remove "txtDemo_1"
 
oder auch, wenn auf der UserForm sonst keine Steuerelemente vorhanden sind, mit
 
Me.Controls.Remove 0
 
Wurde auf Modulebene eine Objektvariable definiert, kann die TextBox gelöscht werden mit
 
Me.Controls.Remove m_objTextBox.Name
 

  Ereignis-Prozeduren [ Top ]
Jedes Objekt, sowohl die UserForm als auch ein Steuerelement, hat seine eigenen Ereignisse. Wird ein Steuerelement zur Entwurfszeit zur UserForm hinzugefügt und selektiert, können die benötigten Ereignisse im Prozedur-Dropdown-Listenfeld ausgewählt werden und mit entsprechendem Code ergänzt werden. Anders sieht es bei Steuerelementen aus, die zur Entwurfszeit noch nicht existieren.
Schlüsselwort WithEvents
Um eine Ereignisprozedur für ein Steuerelement, das zur Laufzeit hinzugefügt wird, schreiben zu können, muss die auf Modulebene deklarierte Objektvariable mit dem Schlüsselwort WithEvents deklariert werden. Das Schlüsselwort WithEvents gibt an, dass es sich um eine Objektvariable handelt, die verwendet wird, um auf Ereignisse zu reagieren, die von einem ActiveX-Objekt ausgelöst werden.
Damit beispielsweise die Ereignisse der TextBox zur Verfügung stehen, wird die Objektvariable auf Modulebene wie folgt deklariert.
 
Private WithEvents mevt_TextBox As MSForms.TextBox
 
Nachdem das neue Objekt deklariert worden ist, erscheint es im Objekt-Dropdown-Listenfeld im Klassenmodul (hier die UserForm). Die für das Objekt gültigen Ereignisse werden im Prozedur-Dropdown-Listenfeld aufgeführt.
In diesem Zusammenhang sei darauf hingewiesen, dass für ein zur Laufzeit hinzugefügten Steuerelements nicht unbedingt immer alle Ereignisse zur Verfügung stehen. Bei der TextBox beispielsweise fehlen die folgenden Ereignisse:
  - AfterUpdate
  - BeforeUpdate
  - Enter
  - Exit
Ereignis-Prozeduren im Codebereich einer UserForm
Mit folgendem Code im Codebereich einer UserForm wird zur Laufzeit eine TextBox zur UserForm hinzugefügt und positioniert. Wird eine Eingabe in der TextBox gemacht, wird das Change-Ereignis der TextBox ausgeführt und eine MsgBox angezeigt.
 
Option Explicit

Private WithEvents mevt_TextBox As MSForms.TextBox

Private Sub UserForm_Initialize()
  Set mevt_TextBox = Me.Controls.Add("Forms.TextBox.1", , True)
  mevt_TextBox.Move 6, 6, 72, 18
End Sub

Private Sub mevt_TextBox_Change()
  MsgBox "In der TextBox '" & mevt_TextBox.Name & _
        "' wurde eine Eingabe gemacht!" & vbCr & _
        "Text: " & mevt_TextBox.Text
End Sub
 
In VBA (im Gegensatz zu VB) hat jedes Steuerelement auf einer UserForm seine eigenen Ereignisse. Das heißt, dass beispielsweise mehrere TextBoxen normalerweise nicht ein und die selbe Sub-Prozedur aufrufen können. Bei einer geringen Anzahl von Steuerelementen, die zur Laufzeit (oder aber auch zur Entwurfszeit) hinzugefügt werden und die zu einer "Gruppe" gehören, ist es m.E. durchaus vertretbar, für jedes Steuerelement ein eigenes Ereignis zu schreiben. Damit der auszuführende Code nicht unnötig dupliziert werden muss, kann bei Bedarf im Ereignis selbst eine weitere Prozedur aufgerufen werden.
 
Option Explicit

Private WithEvents mevt_TextBox1 As MSForms.TextBox
Private WithEvents mevt_TextBox2 As MSForms.TextBox

Private Sub UserForm_Initialize()
  Set mevt_TextBox1 = Me.Controls.Add("Forms.TextBox.1", , True)
  mevt_TextBox1.Move 6, 6, 72

  Set mevt_TextBox2 = Me.Controls.Add("Forms.TextBox.1", , True)
  mevt_TextBox2.Move mevt_TextBox1.Left, mevt_TextBox1.Top + _
      mevt_TextBox1.Height + 3, mevt_TextBox1.Width
End Sub

Private Sub mevt_TextBox1_Change()
  TextBox_Change_Event mevt_TextBox1
End Sub

Private Sub mevt_TextBox2_Change()
  TextBox_Change_Event mevt_TextBox2
End Sub

Private Sub TextBox_Change_Event(ByRef objTB As MSForms.TextBox)
  MsgBox "In der TextBox '" & objTB.Name & _
        "' wurde eine Eingabe gemacht!" & vbCr & _
        "Text: " & objTB.Text
End Sub
 
Ereignis-Prozeduren in einem Klassenmodul
Wie bereits geschrieben, können mehrere TextBoxen normalerweise nicht ein und die selbe Sub-Prozedur (Ereignis) aufrufen. Im Tipp Steuerelementgruppe erstellen (Userform) wird eine der Möglichkeiten gezeigt, dies doch zu realisieren.
Um das Projekt etwas flexibler gestalten und das Klassenmodul auch für mehrere UserForms verwenden zu können, kann in den Ereignissen die Steuerung auch an eine Sub- oder Function-Prozedur im Codebereich der UserForm zurückgegeben werden, hier Office 97-kompatibel. Noch etwas mehr Flexibilität kann bei gleicher Vorgehensweise ab Office 2000 mit der CallByName-Funktion erzielt werden.
Für die Ausführung des folgenden Beispiels, das in der Excel-Arbeitsmappe im Download enthalten ist, werden zwei Klassenmodule benötigt, eins für das eigentliche Objekt (hier die TextBox) und ein zweites für die Auflistung (Collection) der Objekte.
Code im Codebereich des Klassenmoduls CTextBox
Zunächst wird ein Klassenmodul erstellt, hier mit Namen CTextBox, und ein Objekt des Typs MSForms.TextBox deklariert.
 
Private WithEvents mevt_TextBox As MSForms.TextBox
 
Nachdem das neue Objekt deklariert worden ist, erscheint es im Objekt-Dropdown-Listenfeld im Klassenmodul. Die für das Objekt gültigen Ereignisse (z. B. das Change-Ereignis) werden im Prozedur-Dropdown-Listenfeld aufgeführt.
 
Private Sub mevt_TextBox_Change()

End Sub
 
Im Klassenmodul CTextBox werden alle Objekt-spezifischen Eigenschaften, Methoden und Ereignisse untergebracht, hier die der TextBox zugehörigen UserForm, ein Objektverweis auf die TextBox und das Change-Ereignis der TextBox, in der die Prozedur im Codebereich der UserForm aufgerufen wird.
Diese Klasse dient als Vorlage, aus der eine Objektinstanz zur Laufzeit erzeugt wird. Es wird für jede TextBox, die zur Laufzeit erstellt wird, eine Objektinstanz erstellt.
Infos zu den hier verwendeten Property-Prozeduren für das Zuweisen und die Rückgabe der Objekte und dem Index der TextBox können unter Schreiben einer Property-Prozedur in der VB(A)-Hilfe nachgelesen werden.
 
Option Explicit

Private WithEvents mevt_TextBox As MSForms.TextBox
Private m_objForm As Object

Private Sub Class_Initialize()
  '
End Sub

Private Sub Class_Terminate()
  Set mevt_TextBox = Nothing
  Set m_objForm = Nothing
End Sub

Private Sub mevt_TextBox_Change()
  If Not m_objForm Is Nothing Then
    Call m_objForm.TextBox_Change_Event(mevt_TextBox)
  End If
End Sub

Public Property Set Form(ByRef objForm As Object)
  Set m_objForm = objForm
End Property

Public Property Set TextBox(ByRef objTextBox As MSForms.TextBox)
  Set mevt_TextBox = objTextBox
End Property
 
Code im Codebereich des Klassenmoduls col_CTextBox
Das zweite Klassenmodul dient zur Speicherung der Daten in einem Collection-Objekt. In der Auflistungsklasse col_CTextBox befinden sich die benötigten Methoden mit der der Auflistung neue Objekte hinzugefügt (Add) und gelöscht (Remove) werden können, ein bestimmtes Objekt (Item) und die Anzahl (Count) der in der Auflistung enthaltenen Objekte zurückgegeben werden kann.
Der Vorteil der Erstellung einer eigenen Auflistungsklasse gegenüber der Verwendung des VBA-Collection-Objekts ist, dass hier die Methoden entsprechend angepasst werden können. Mit der Add-Methode kann in diesem Beispiel nur ein Objekt vom Typ CTextBox hinzugefügt werden.
 
Option Explicit

Private mcol_TextBoxes  As Collection
Private m_objForm       As Object

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

Private Sub Class_Terminate()
  Set mcol_TextBoxes = Nothing
  Set m_objForm = Nothing
End Sub

Public Property Set Form(ByRef objForm As Object)
  Set m_objForm = objForm
End Property

Public Function Add(ByRef objTextBox As MSForms.TextBox) _
      As CTextBox

  Dim objCTextBox As CTextBox

  On Error GoTo err_Add
  Set objCTextBox = New CTextBox
  With objCTextBox
    Set .Form = m_objForm
    Set .TextBox = objTextBox
  End With

  mcol_TextBoxes.Add objCTextBox, objTextBox.Name
  Set Add = objCTextBox

  Set objCTextBox = Nothing

exit_Func:
  On Error GoTo 0
  Exit Function

err_Add:
  MsgBox "Fehler: " & Err.Number & vbCrLf & _
          Err.Description, vbOKOnly + vbCritical

  Resume exit_Func
End Function

Public Property Get Item(ByVal Index As Variant) As CTextBox
  Set Item = mcol_TextBoxes.Item(Index)
End Property

Public Property Get Count() As Long
  Count = mcol_TextBoxes.Count
End Property

Public Sub Remove(ByVal Index As Variant)
  mcol_TextBoxes.Remove Index
End Sub
 
Code im Codebereich der UserForm
Im Codebereich der UserForm ist unter anderem das Initialize-Ereignis der UserForm, in der die Auflistungsklasse col_CTextBox initialisiert wird und die TextBoxen zur UserForm und zur Auflistung hinzugefügt werden, enthalten. Natürlich muss auch das im Klassenmodul festgelegte Change-Ereignis, das aus dem Klassenmodul heraus aufgerufen wird, vorhanden sein.
Im Gegensatz zu den bisherigen Beispielen werden hier auf Modulebene die benötigten Konstanten und Variablen deklariert und auch die Größe (Breite und Höhe) der UserForm an die TextBoxen angepasst.
 
Option Explicit

Private Const mc_sngBorder  As Single = 6
Private Const mc_sngGapV    As Single = 3

Private Const mc_sngTxtLeft As Single = 6
Private Const mc_sngTxtWdth As Single = 132
Private Const mc_sngTxtHght As Single = 18

Private mcol_TextBoxes As col_CTextBox

Private Sub UserForm_Initialize()
  Dim objTextBox  As MSForms.TextBox

  Dim sngPosTop   As Single
  Dim i           As Integer

  Set mcol_TextBoxes = New col_CTextBox
  Set mcol_TextBoxes.Form = Me

  sngPosTop = mc_sngBorder
  For i = 1 To 3
    Set objTextBox = Me.Controls.Add("Forms.TextBox.1", , True)
    With objTextBox
      .Move mc_sngTxtLeft, sngPosTop, mc_sngTxtWdth, mc_sngTxtHght
      sngPosTop = sngPosTop + .Height + mc_sngGapV
    End With

    mcol_TextBoxes.Add objTextBox
    Set objTextBox = Nothing
  Next

  Me.Height = (Me.Height - Me.InsideHeight - 3) + sngPosTop + _
        mc_sngBorder
  Me.Width = (Me.Width - Me.InsideWidth) + mc_sngTxtWdth + _
        (2 * mc_sngTxtLeft)
End Sub

Private Sub UserForm_Terminate()
  Set mcol_TextBoxes = Nothing
End Sub

Public Sub TextBox_Change_Event(ByRef objTextBox As _
      MSForms.TextBox)
  With objTextBox
    If Len(Trim$(.Text)) > 0 Then
      If IsNumeric(.Text) Then
        .ForeColor = vbBlue
      Else
        .ForeColor = vbRed
      End If
    End If
  End With
End Sub
 

  Beispiele aus der Praxis [ Top ]
Es ist durchaus möglich, alle benötigten Steuerelemente zur Laufzeit zu einer UserForm hinzuzufügen oder sogar die komplette UserForm zu erstellen. In vielen Fällen wird jedoch ein Teil der Steuerelemente zur Entwurfszeit in der Entwicklungsumgebung bequem manuell hinzugefügt und lediglich ein bestimmter Bereich dynamisch gehalten.
In der Excel-Arbeitsmappe im Download sind die folgenden Beispiele enthalten, mit denen eine vorgegebene Anzahl von Steuerelemente, Labels mit zugehöriger TextBox, zur Laufzeit zur UserForm hinzugefügt und auch wieder entfernt werden können, hier ohne Ereignis-Prozeduren.
UserForm ohne ScrollBar

In Demo 1 werden die Labels und TextBoxen untereinander zur UserForm hinzugefügt und anschließend die Höhe der UserForm an die Anzahl/Höhe der TextBoxen plus Abstand angepasst.

Werden beispielsweise je 20 Labels und TextBoxen untereinander zur UserForm hinzugefügt, könnte es jedoch sein, dass je nach Bildschirmgröße und Auflösung ein Teil der UserForm für den Anwender nicht mehr sichtbar/erreichbar ist. Zu empfehlen ist diese Vorgehensweise also nicht.

UserForm mit ScrollBar

Abhilfe könnte hier die vertikale ScrollBar der UserForm schaffen, wie in Demo 2 gezeigt.

Allerdings sollte man bedenken, dass andere ggf. vorhandene Steuerelemente, hier beispielsweise der obere Frame mit der TextBox und dem Button 'Demo', auch mitgescrollt werden. Das heißt also, damit der Frame inkl. Steuerelemente in den sichtbaren Bereich verschoben wird, müsste der Anwender ggf. die UserForm scrollen. Die "Ideallösung" ist das also auch nicht.

Frame mit ScrollBar

Sinnvoller wäre es m. E., statt ggf. die vertikale ScrollBar der UserForm einzublenden, für den dynamischen Bereich ein Frame hinzuzufügen. In Demo 3 werden in der Entwicklungsumgebung zur Entwurfszeit drei Frames zur UserForm hinzugefügt.

Der obere Frame bleibt zur Laufzeit immer an der zugewiesenen Position und in der Größe gleich.

Der mittlere, dynamische Frame wird ggf. in der Höhe angepasst, je nachdem wie viele Labels und TextBoxen hinzugefügt werden. Es wurde hier jedoch eine maximale Höhe für den Frame festgelegt. Werden mehr als vier Steuerelementpaare hinzugefügt, wird die vertikale ScrollBar des Frames angezeigt und die TextBoxen in der Breite entsprechend angepasst. Es sind also nie mehr als vier Steuerelementpaare sichtbar. Werden keine Steuerelemente hinzugefügt, wird der Frame ausgeblendet.

Der untere Frame wird ggf. nach oben oder unten verschoben, je nach Höhe des mittleren, dynamischen Frames, bleibt jedoch in der Größe immer gleich. Beim Initialisieren der UserForm wird die Darstellung des Frame insoweit geändert, so dass der Rahmen nicht sichtbar ist.

Code im Codebereich der UserForm
Auf Modulebene werden zunächst die benötigten Konstanten und Variablen deklariert. Die Verwendung von Konstanten erleichtert das Dokumentieren und Modifizieren der Programme. Konstanten können im Gegensatz zu Variablen nicht versehentlich geändert werden, während das Programm ausgeführt wird.
 
Option Explicit

Private Const mc_intMaxCtls As Integer = 20

Private Const mc_sngFrameMaxHght As Single = 96

Private Const mc_sngBorder  As Single = 6
Private Const mc_sngGapV    As Single = 3

Private Const mc_sngLblLeft As Single = 6
Private Const mc_sngLblWdth As Single = 30

Private Const mc_sngTxtLeft As Single = 42
Private Const mc_sngTxtWdth As Single = 124
Private Const mc_sngTxtHght As Single = 18

Private ma_Labels()         As MSForms.Label
Private ma_TextBoxes()      As MSForms.TextBox

Private m_intCurNumCtls     As Integer
 
In der Prozedur AddControls() wird die übergebene Anzahl Steuerelementpaare (Label mit zugehöriger TextBox) zum Frame-Objekt hinzugefügt oder gelöscht. Beim Hinzufügen der TextBoxen wird die Breite zunächst nicht zugewiesen, dies geschieht später in der Prozedur ResizeControls(), in der auch die Höhe des Frames und der UserForm angepasst wird und im Frame die vertikale ScrollBar ein- oder ausgeblendet wird. Der Code im Download-Beispiel ist sehr ausführlich kommentiert.
 
Private Sub AddControls(ByVal intNumCtls As Integer)
  Dim sngPosTop  As Single
  Dim i          As Integer

  Select Case intNumCtls
    Case Is < 0

    Case Is = m_intCurNumCtls

    Case Is > mc_intMaxCtls
      MsgBox "Maximal " & CStr(mc_intMaxCtls) & _
             " Steuerelemente möglich!"

    Case Is < m_intCurNumCtls
      For i = m_intCurNumCtls To intNumCtls + 1 Step -1
        Me.Controls.Remove ma_Labels(i).Name
        Me.Controls.Remove ma_TextBoxes(i).Name
      Next

      ReDim Preserve ma_Labels(0 To intNumCtls)
      ReDim Preserve ma_TextBoxes(0 To intNumCtls)

      m_intCurNumCtls = intNumCtls
      ResizeControls

    Case Is > m_intCurNumCtls
      If m_intCurNumCtls > 0 Then
        With ma_TextBoxes(m_intCurNumCtls)
          sngPosTop = .Top + .Height + mc_sngGapV
        End With
      Else
        sngPosTop = mc_sngBorder
      End If

      ReDim Preserve ma_Labels(0 To intNumCtls)
      ReDim Preserve ma_TextBoxes(0 To intNumCtls)

      For i = m_intCurNumCtls + 1 To intNumCtls
        Set ma_Labels(i) = Me.fraDyn.Controls.Add( _
              "Forms.Label.1", , True)
        With ma_Labels(i)
          .Move mc_sngLblLeft, sngPosTop + 3, mc_sngLblWdth
          .Caption = "Pos. " & CStr(i)
        End With

        Set ma_TextBoxes(i) = Me.fraDyn.Controls.Add( _
              "Forms.TextBox.1", , True)
        With ma_TextBoxes(i)
          .Move mc_sngTxtLeft, sngPosTop, , mc_sngTxtHght
          .TabStop = False
          sngPosTop = sngPosTop + .Height + mc_sngGapV
        End With
      Next

      m_intCurNumCtls = intNumCtls
      ResizeControls

    Case Else
  End Select
End Sub
 
 
Private Sub ResizeControls()
  Dim sngHght     As Single
  Dim sngTxtWidth As Single
  Dim i           As Integer

  Dim objCtl      As MSForms.Control

  If m_intCurNumCtls = 0 Then
    Me.fraDyn.Visible = False
    Set objCtl = Me.fraMain

  Else
    Me.fraDyn.Visible = True
    Set objCtl = Me.fraDyn

    With ma_TextBoxes(m_intCurNumCtls)
      sngHght = .Top + .Height + mc_sngBorder
    End With

    If sngHght <= mc_sngFrameMaxHght + mc_sngBorder Then
      With Me.fraDyn
        .ScrollTop = 0
        .ScrollBars = fmScrollBarsNone
        .Height = (.Height - .InsideHeight) + sngHght
      End With
      sngTxtWidth = mc_sngTxtWdth

    Else
      With Me.fraDyn
        .Height = mc_sngFrameMaxHght - mc_sngGapV
        .ScrollBars = fmScrollBarsVertical
        .ScrollHeight = sngHght

        sngTxtWidth = mc_sngTxtWdth - (.Width - .InsideWidth - 3)
      End With
    End If

    For i = 1 To m_intCurNumCtls
      ma_TextBoxes(i).Width = sngTxtWidth
    Next
  End If

  Me.fraButtons.Top = objCtl.Top + objCtl.Height + mc_sngBorder
  Set objCtl = Nothing

  Me.Height = (Me.Height - Me.InsideHeight - 3) + _
        Me.fraButtons.Top + Me.fraButtons.Height + mc_sngBorder
End Sub
 
Hinweise
Die im Download befindlichen *.frm-, *.bas- und *.cls-Dateien können in den unten angegebenen Anwendungen im VB-Editor importiert werden.
Anmerkung: Ab Access 2000 können die genannten *.frm-Dateien zwar importiert werden, es handelt sich hier jedoch nicht um die Formulare und Steuerelemente, die üblicherweise in Access verwendet werden.

Links zum Thema [ Top ]
OFF97: Invalid Page Fault with More Than 411 Controls in UserForm
WD2000: How to Programmatically Create UserForms in Visual Basic for Applications
XL2000: Error Running Macro That Inserts Control into UserForm
XL2000: Macro Examples Using Option Button Controls on a UserForm
Creating Your Own Collection Classes

Betriebssystem
Win 95
Win 98
Win ME
Win NT
Win 2000
Win XP
Anwendung/VBA-Version
Access 97
Access 2000
Access XP
Access 2003
Excel 97
Excel 2000
Excel XP
Excel 2003
Word 97
Word 2000
Word XP
Word 2003
PPT 97
PPT 2000
PPT XP
PPT 2003
Outlook 97
Outlook 2000
Outlook XP
Outlook 2003


Download  (80,7 kB) Downloads bisher: [ 6181 ]

  Zum Seitenanfang  

Startseite | VB/VBA-Tipps | Projekte | Tutorials | API-Referenz | Komponenten | Bücherecke | VB-/VBA-Forum | VB.Net-Forum | DirectX | DirectX-Forum | Foren-Archiv | VB.Net | Chat | Links | Suchen | Stichwortverzeichnis | Feedback | Impressum

Seite empfehlen Bug-Report
Letzte Aktualisierung: Dienstag, 23. Mai 2006