Suggestions |
Example File
VBA check of userinput in a Userform
|
To guide/support/check userinput you can apply Userforms. You will need a bunch of code if you want to prevent every possible 'error'. A classmmodule can reduce the amount of necessary code. The same applies to the checking of userinput by ActiveX-controls in a worksheet. An explanation for ActiveX controls you'll find in this page. We'll illustrate this approach with Textboxes in a userform. Let's assume the userform contains 10 Textboxes: their names being text1, text2 .... text10. The content of a textbox can be adapted by the user. To check this input you can use the 'change' event of the textbox. Every adaptation in the textbox will trigger this event. To check whether each textbox contains any text you can use this code. If all textboxes contain some text the button 'btn_Next' will become visible. Private Sub Text1_Change() For j=1 To 10
End Sub If Trim(Me("Text" & j).Text)="" Then Exit For
NextMe("btn_Next").Visible = j =11 Private Sub Tex2_Change() For j=1 To 10
End SubIf Trim(Me("Text" & j).Text)="" Then Exit For
Next Me("btn_Next").Visible = j =11 Private Sub Text3_Change() For j=1 to 10
End SubIf Trim(Me("Text" & j).Text)="" Then Exit For
NextMe("btn_Next").Visible= j =11 etc. Private Sub Text1_Change() m_next
End Sub Private Sub Text2_Change() m_next
End SubPrivate Sub Text3_Change() m_next
End SubPrivate sub m_next() For j=1 to 10
End SubIf Trim(Me("Text" & j).Text)="" Then Exit For
NextMe("btn_Next").Visible = j =11 - put all textboxes into a collection or an array - link the checking-macro (like m_next) to the change event of every item in the collection/array All those links will be part of the collection/array. Every change in a textbox will trigger a corresponding link in the collection/array. But, you can only link an event using a 'WithEvents' variable. The use of 'Withevents' variables is restricted to a classmodule. Therefore you need a classmodule to put this method into practice. To begin with we name the classmodule (ad libitum) 'inputcheck'. Every control (Textbox, combobox, checkbox, optionbutton, commandbutton, etc) has it's own specific events. So you have to define a separate 'event' variable for every controltype. And you have to specify an 'event' for that variable. This means that the 'event' variable 'replaces' the corresponding userform control; the event in the classmodule 'replaces' all eventprocedures of the corresponding Userform control. NB. You can do a lot more with a classmodule, but here we restrict ourselves to intercepting events of userform controls. 2.3.2 Which code is in the classmodule ? 1. A public object-variable that represents all possible events of a certain controltype, i.c. textboxes.Public WithEvents cl_textbox As MSForms.TextBox 2. An event procedure for the objectvariable 'cl_textbox'. In this case this can only be an event that applies to a TextBox. For example the events 'Change' and 'DblClick' Private Sub cl_textbox_Change() ------- End Sub Private Sub cl_textbox_DblClick() ----- End Sub 2.3.3 Which code is in the Userform ? All userform controls that have to be controlled by the classmodule have to be connected to the classmodule.These connection have to be made in the Userform_Initialize event. You can either use a collection to store those connections or an array. We'll discuss them separately. Declare a 'public' variable as a new collection Public ctl_collection as New Collection The use of an underscore prevents any coinciding with a reserved name in VBA. In the event procedure Userfom_Initialize: Private Sub Userform_Initialize() For Each ct in Controls
End Subctl_colletion.Add New inputcheck, ct.Name
NextIf TypeName(ct)="TextBox" Then Set ctl_collection(ct.Name).cl_textbox = ct Put that link into the collection 'ctl-collection'. Use the control's name as key in the collection, so the control's name can be used to address that item in the collection. ctl_collection.Add New inputcheck, ct.Name The event variable for textboxes in the classmodule is 'cl_textbox'. Since the textbox in the userform is an object we need the instruction 'Set' to connect it as an object to the objectvariable 'cl_textbox'. set ctl_collection(ct.Name).cl_textbox = ct Public sr Private Sub Userform_Initialize() ReDim sr(Controls.Count)
End SubFor j = 0 to Controls.Count - 1 Set sr(j)= New inputcheck
NextIf typename(controls(j))= "TextBox" Then Set sr(j).cl_textbox=Controls(j) ReDim sr(Controls.Count) For j = 0 to Controls.Count - 1 Since the classmodule is an object we need the instruction 'Set' to add a new instance of the classmodule to the array. Set sr(j)= New inputcheck Connect the control via the link in the array to the corresponding 'WithEvents'-variable in the classmodule. The event variable in the classmodule is cl_textbox. Since cl_textbox is an object variable we need the instruction 'Set' to connect the Textbox in the userform to the classmodule objectvariable cl_textbox. Set sr(j).cl_textbox=Controls(j) These events can't: - Activate
- Deactivate - QueryClose - Resize - Terminate - AfterUpdate - BeforeUpdate - Enter - Exit 3 The contents of the example file - the classmodule 'inputcheck'- the userform 'form collection', using the 'collection' method. - the userform 'form array', using the 'array' method. Het bestand illustreert tegelijkertijd dat de code in een klassemodule voor diverse userforms tegelijkertijd dienst kan doen. The classmodule 'inputcheck' The classmodule contains WithEvents variables for: - Label - TextBox - ComboBox - ListBox - CheckBox - OptionButton - CommandButton - SpinButton - MultiPage - Frame - UserForm The classmodule contains all events for every controltype that can be intercepted by a classmodule. There's code for every controltype in the eventprocedure 'Click'. The Textbox_change event calls the macro 'A_vervolg'. That macro checks whether all textboxes in the userform contain any text; and makes the commandbutton 'btn_Next' visible if that is the case. All other events contain code to show a messagebox; this code has been inoculated by a preceding hyphen. You can check the functioning of every event if you remove that preceding hyphen. As an illustration you'll find several kinds of code in the 'click' event of labels in a userform: - to adapt the content of the control itself - to adapt the formatting of the control itself - to adapt another control - to call a macro - to call a function - to adapt a worksheet Userform 'form_collection' and 'form_array' The sheet contains a commandbutton to show this userform. Each userform contains 10 items of every type of controls, the ListBox, Multipage and the Frame excepted. Both userforms are identical; the only difference resides in the VBA code: the use of the method 'collection' vs. the method 'array' Both userforms are functionally identical because they both use the same classmodule. Check userinput in ActiveX controls 5 Example files for each controltype LabelsTextboxes Comboboxes Listboxes Checkboxes Optionbuttons Commandbuttons Spinbuttons Frames Multipage ToggleButton Scrollbar |