One of my pet peeves is intrusive VBA code that interrupts workflow. The problem usually goes something like this:
I have an application/workbook that relies on certain user input data. I have a textbox/cell and I only want certain characters to be allowed. (list of characters follows) How can I accomplish this?
The answer usually involves some version of Worksheet_Change or KeyPress events that detect the input characters and act accordingly.
Here's are some examples:
Allowing only certain characters in string in vb6
Restricting Entry In Text Box
Personally I find this approach intrusive. Imagine you are typing and the application just swallows certain letters, with absolutely no explanation of what is going on! Or even worse, when there's a message box every time you hit a restricted letter.
I like Worksheet_Change because at least it waits until after you are done typing.
The way I do it is
- do nothing while characters are being entered
- write a function that checks if the textbox contains valid input and returns a Boolean value
- run said function when user clicks 'Submit' (or does whatever is necessary to trigger the app)
- if return value is false, do any/all of the following:
- display a message box indicating which textbox caused the error (and how to fix, of course)
- change the backcolor of the textbox
- unhide a previously hidden label control and change the caption to indicate which textbox caused the error
Of course, if there were multiple validations, a generic messagebox like "One or more values are incorrect. Please go back and correct them before clicking Submit." would be used, possibly combined with a list of errors inside the messagebox.
This method is the least intrusive and, if I may say so, more intuitive than other methods. It also makes my application faster because we are shifting all the logic checks to the end of the code instead of running functions dozens or even hundreds of times during the life of our application (i.e. every time the Change or KeyPress event fires).
In short:
- Your custom function to check for invalid characters runs once, instead of every time the KeyPress or Change Event fires
- You aren't simply dropping keys without any explanation to the end user. That would drive me nuts.
Another huge consideration is that the KeyPress Event will not fire if a string is copied and pasted into the textbox. So if we are relying only on the KeyPress Event to check input characters, our custom function wouldn't run.
Note that there are some procedures which should run in the Change Event (i.e. dozens or hundreds of times at runtime). One example would be a function that checks if your form is ready to submit and enables the Submit button:
CommandButton1.Enabled = FormReadyToSubmit(Me)
Since we don't know what order the userform is being filled in, we need to check after changing every single control if our form is ready to be submitted (this is really the subject of another post). Again, without actually validating any of the fields, which we do only when we actually click 'Submit'.
How do you accomplish these kinds of logic checks?
Follow Me