After input in text box how do cause AfterUpdate event to run? - excel

I have an Excel VBA userform with several text boxes.
The user will input a weight in a text box. They can then do other things on the form or click Apply, Update, Previous Event, Next Event or Cancel.
After the weight is input, it must be validated, and if it is OK, the form is marked as mbFormChanged=True. This validation occurs in the text box's AfterUpdate event.
My problem is that if the user types in a value and immediately clicks Apply, Update, Previous Event or Next Event, the field is not validated and it is as if it was never changed.
I.e enter weight: 200[Update]
However, if the user tabs to another field after typing the weight, then it is validated and the form is marked as changed.
I.e. enter weight: 200[Tab][Update]
How can I make sure AfterUpdate runs when a command button is clicked immediately thereafter?
I can't put the validation at the point of OK/Apply because the moment a user enters a new weight and it is valid, it immediately updates many other fields and lists visible on the form (real time update).

I assume this is an Excel user form in which case I don't think there is a built in AfterUpdate event. Excel forms are not bound to anything (unlike Access) so there is nothing the form updates. You'll need to make your own AfterUpdate event.

I know this is a an old/dead thread and I certainly hope the original problem has been solved, but in case anyone else is searching this, here is what I have done in similar situations: Open your form with the 'Ok' / 'Done' / 'Exit" or whatever button(s) you are using to confirm the form entries then exit the form in a disabled state. That way they do nothing if clicked on. Once your data validation is complete, enable those buttons (or circle back for corrected entries).

As commented, you can try this:
Private Sub TextBox1_Change()
If (MsgBox("Done?", vbYesNo)) = vbYes Then Me.TextBox2.SetFocus 'Or any other ctrl
End Sub
Above code like forces TextBox1_AfterUpdate() event.

Related

VBA Dynamic Userform Population Based on which Module Called It

I have a user form where individuals can add details about tasks that populate a project planning table. If someone is creating a new task, all of the controls initialize with blank values. However, I want to create the ability for them to modify an existing task and along with it to populate the same user form's controls with the inputs that were originally submitted upon its initialization so they can tweak only what they need and not have to fill it out entirely.
I think there are several ways I could approach this, either by somehow passing variables from the EDIT TASK module to the userform or by potentially initializing the userform from the CREATE TASK and EDIT TASK modules themselves and populating the values of the controls from there like so
Sub Show_Insert_Task_Form()
INSERT_TASK_FORM.Show
INSERT_TASK_FORM.TASK_TBOX.value = "VALUE"
End Sub
This code runs, but it does not populate the textbox unfortunately.
What is the best way to approach this?
Your Show_Insert_Task_Form actually does populate the textbox.
From the behavior you are describing, I can deduce the ShowModal property (in the property window) of your form is True. When that is the case, VBA pauses the execution until you close the Window. In other words, what your code does is:
Show the form in modal mode.The textbox is not populated yet and as the form is modal, the execution is paused.
When you close the form, the execution resumes and the textbox gets populated (too late for you to see).
Solution:
You must populate your form before calling Show.
Sub Show_Insert_Task_Form()
INSERT_TASK_FORM.TASK_TBOX.value = "VALUE"
INSERT_TASK_FORM.Show
End Sub
Doing so means the code will pause after the form is populated.
About making the form non-modal:
The 2 changes below stop the execution from pausing:
Change the ShowModal property to False in the property window.
Call INSERT_TASK_FORM.Show False.
Both these alternatives are apparently a valid solution to your problem (without the execution pausing, the form gets populated while displayed on screen). However, they also make the bug prone to reappearing (example: if one day you change your mind and change the form back to being modal).
Good news is: the solution as well as these alternatives are not mutually exclusive. I recommend you implement the solution as well as alternative 1, alternative 2, or neither or both alternatives.

combobox is not showing added items

.cmbcom11.AddItem "cotton"
.cmbcom11.AddItem "elastane"
.cmbcom11.AddItem "polyester elastane"
.cmbcom11.AddItem "nylon elastane"
.cmbcom11.AddItem "seashell"
This is the method I used to add the a list for one of the combo boxes in the following interface
cmbcom11 is composition 1 (first row) and 12 will be the next one and 13 will the one after
I just showed a small part of the code which I will be repeating for all cmbcom
I know I got the name right when typing because there is no compile error or runtime error
Then why isnt my list showing up in the combo box?
You need to understand where your code lives and how it is called.
In the video, a subroutine Reset is defined that fills up the controls of the form: It empties the textboxes and sets the options of the combobox. This sub is stored in a regular module. It could also be in the code of the form itself (except that you would write Me.txtId.Value instead of frmForm.txtId.Value).
However, this routine reset needs to be called (and that is the point you are missing). When do you want to execute this routine? Exactly in the moment the form is shown - or more precise when someone tells the form "please show yourself", but before the user sees the form.
A form (and all controls on the form) has events that are called automatically at a certain event. In VBA, those event routine names contain two parts, the first part is the name of the control, the second part is the name of the event. These names are fix, if you change them, the VBA runtime will not find them and nothing will happen.
Now those event routines need to be in the (object) code. For a form, go to the form editor and press F7: This is the code of the form. Press the left drop down on the top of the editor: It contains all controls of the form, including the form itself. Select "Userform". Now you see all events of the form that you can handle in the right drop down. Select "Initialize". You will notice that an empty routine Userform_Initialize is added to the code. Add the statement Reset (or Call Reset) to this routine. This event routine is called when the form is initialized, do whatever you need before the form gets visible.
In the video, the author has some more event routines that reacts on the click of the buttons: Those routines need to be also in the code of the form. It's of no use to put them in a separate module, the VBA event handler cannot find them.
Last remark: To show the form, the author placed a big shape on the sheet. Clicking this shape calls also an event routine, however, you are free to name the routine whatever you want, and this routine needs to be in a module. In the video, it is named show_form. Just be sure that you don't rename it after you assigned it to the shape.

VBA Listbox not updating to reflect new source list when called from itself

Edit:
Playing around further, it seems that you can't assign a new array to a listbox via the .list=somelist approach when the assignment happens in response to a click on the listbox itself. Or rather, you can assign the list, but it simply won't visually populate the listbox...although Excel seems to think it's there.
The .additem or .removeitem methods do however result in a visual change when called from a listbox click, which means you have to build your new array up that way I guess. How tedious.
You can however feed a listbox an entirely new array using the .list=somelist approach via a CommandButton-initiated action. But the user has to obviously click a button to do this. Which in my case below defeats the purpose.
Edit Over.
I'm designing a UserForm to help filter PivotTables. It's a cross between the existing Pivot Filter functionality and a Slicer. Here's what you see if you double-click on a PivotField header:
Note the Search field at the top, and the three buttons immediately below that search field. If you type something into that field, then instead of displaying everything that's currently filtered, you instead get a list of any matches, and you can then apply those search results to the underlying PivotTable via those three CommandButtons. The first cb simply filters the PivotTable to reflect the search, and the other two let you add or remove any search result from an existing filter.
I want to do away with those three command buttons, and instead (in the event that a search is performed) simply list those three options at the top of the ListBox above any search results returned. Clicking on those three options will then trigger the exact same code as currently triggered by the Command Button.
Here's how that looks currently if I actually type something in that Search box (Note I haven't yet removed the three command buttons this does away with from that Search frame):
I've added a simple bit of code to the lbResults_Change() event handler that checks if a user clicks any of those first three options. All that code does is trigger the exact same routines as would be triggered if they'd simply clicked on the actual command buttons themselves:
For i = 0 To 4
If Me.lbResults.Selected(i) Then Exit For
Next i
Select Case i
Case 0: cmdApplySearch_Click
Case 1: cmdAddToFilter_Click
Case 2: cmdSubtractFromFilter_Click
Case 3: Me.lbResults.Selected(3) = False
End Select
Here' the problem: The listbox gets updated just fine if I click on those command buttons, as you can see from the below. The Pivot has been filtered accordingly, and those contextual search options have been removed from the top of the listbox (and the search field cleared):
But the listbox does NOT get updated if the exact same routine is triggered from a click on one of those top three options in listbox itself:
As you can see from the above screenshot, it still shows those three options at the top, even though they are NOT in the array that I assigned to the listbox, as evidenced by the screenshot below:
But as you could see from the earlier screenshot, it shows 7 items in the ListBox instead of the three there actually are. But there are indeed just three items that should be showing in that list box:
? .ListCount
3
? .List(0)
263213: ICT Systems Test Engineer
? .List(1)
263299: ICT Support and Test Engineers nec
? .List(2)
839313: Product Tester
Basically, as soon as I try to update what's in the listbox via a click on the listbox itself, I can't update it.
It doesn't seem to matter if I set focus to something other than the listbox before the filtering code executes, and I've even tried completely clearing the Listbox with .clear. It just doesn't clear, until I manually click on one of those command buttons again.
Anyone have any pointers?
Ah, what an idiot I am for overlooking the painfully obvious solution. The ListBox list happily redraws in response to any event other than the ListBox_Click event, right? So all I needed to do was to use the ListBox_Click event to determine what got clicked (as I currently do), and then use the ListBox_MouseUp event to trigger the actual updating of the ListBox list. Works a treat.
Hopefully this post will save someone else two days of pain in the future. Probably me.

vba-excel click event triggered during initialize when load data into a text box

I am using VBA Excel. I am formatting data from several sources to display in a text box (as a quick summary), when the user clicks on this text box I have another userform that will display to edit this data. When I move the data into the text box during initialize the click event triggers. Is there a way to turn off the event during initialize then turn it back on? This does not happen if I have the user do the double click, however I would like it to be a single click if possible for consistency with the rest of the maintenance screens.
If the click event triggers then you must be using the wrong event make sure that the event handler does not look like this TextBox1_Change() if so change the event to DblClick

Excel VBA Dialog box with custom buttons

I would like to create a dialog box or message box in excel WITH custom button labels i.e. FIRST and SECOND. I would like for this box to open up when the file is first opened...and doesn't allow user access to the worksheet until they select either FIRST or SECOND.
I can make a form, but I would rather not add a form since this should be simple... I remember doing something very similar back in the VB6 days, but that has been sometime.
The MsgBox function does not support different names (than the given ones) for the buttons, and neither the InputBox method or function will allow you to change the button names.
You'll have to make a simple form.

Resources