Assign macro to a button created in run time VBA - excel

My question is basically answered in this post
But instead of the class code below:
Sub CmdEvents_Click()
MsgBox "Hello World"
End Sub
I need to run this code (it's just a sample, I want to use the name of the button clicked later in the program)
Sub CmdEvents_Click()
Dim mvCtrl As Control
Set mvCtrl = Me.ActiveControl
MsgBox mvCtrl.Name
End Sub
But this code above will NOT, by any means return correctly the Name of the button I just created in run time in the message box.
It returns "Button 6".... I did a search in my workbook and I don't even have this name.
I actually I modified the original code from the link above to get the names of the buttons all from a list. This way I can modify the list, thus modifying the name of the buttons, or caption if I want to. And this Button 6 doesn't even exists in my list.
I made some traps in my code, showing message boxes for the variable I use to get the button name from, and it's correct, it's carrying the string I want to name my button before it creates it.

Assuming you followed the post you linked to, your class instance already contains a variable CmdEvents which references the clicked button, so you can use
Msgbox CmdEvents.Name
If your code is different, it would be useful to post the relevant parts so we can see what's going on.

Related

Updating userform textboxes in userform frames

I'm trying to create a system within a VBA textbox that modifies the input.
Textboxes along with other options are in frames that can be opened and closed. Done to keep the form readable for other people.
I know it can be done by editing the string solely in code (and have done that to keep working on the project) but I want people to see the edits the code makes.
These updates are inconsistent. I have two textboxes that edit themselves with identical lines of code and they are both set to update themselves once the textbox has been exited. One only updates if something within the frame that it is in gets clicked on again and the other doesn't update at all whether clicking within its frame or outside.
Ideally the moment a textbox gets edited and something else gets clicked on the textbox updates.
Update
Only updates itself if something else like another checkbox in the frame is clicked or selected and it will also then work when clicking outside of the frame. Does anyone know why?
Code for both
Private Sub Pathbox_Change()
End Sub
Private Sub Pathbox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim sDir As String
sDir = S5Int.Pathbox.Text
If Right(sDir, 1) <> "\" Then
S5Int.Pathbox.Text = sDir & "\"
End If
End Sub
The same code for both except the name of the procedure. Frames are also same except for their names. In the form they look something like this:
Form with textboxes
Settings of the elements are also identical
Found a solution last week;
I have just put the trigger of updating on the form itself whenever the form itself is clicked it runs through checks to see what needs to be updated and updates; Its a bit crude but it works quite well. This solution wont work if something else other than the form is clicked but that didnt work either for Textbox1_Exit(etc). Since it only updates the form when the form is in the forefront.
It is Also a bit wasteful of cycles as it runs every single time anything on the form is clicked too but as long as the checks are efficient it should be good enough.
I will keep working on a better solution however when I have time, maybe see if I can get exiting from the frame working like FaneDuru said but something else on the form seems to be blocking that solution for now.

Stop message box on a given situation Excel VBA

I am creating a userform using Excel VBA that is meant to be used to register some sales. The form looks like this:
As you may have noticed, I am using an image as a button. This is because the CommandButton included in VBA looks very outdated. However, using an image as a button also creates me a new error (or not, depending on how you see it) that is driving me crazy. The usual process for filling this is entering a product, a quantity, a price, a customer and clicking the button to save all the information to a worksheet. The payment textbox is only filled sometimes.
I created a data validation mechanism for all these fields, including the customer combobox. If the user types an invalid entry or leaves the field empty after clicking it, a message box appears. The code for that is the following:
Private Sub cmbCustomer_AfterUpdate()
If cmbCustomer.ListIndex > -1 Then
Else
MsgBox "Please choose a valid customer", vbExclamation
cmbCustomer.Value = ""
End If
End Sub
This works great for avoiding invalid entries. The tricky part is that, once the button is clicked, all the fields are automatically erased. The data is correctly saved, but if the last field used before clicking was cmbCustomer (or any other, actually, because all of them have a similar mechanism to avoid empty or invalid data) and the user decides to begin filling the form again starting by the product, the message box appears, because it is empty and the code detects the invalid entry. I know this is the expected behavior for my code, but this doesn't happen if I use a traditional CommandButton because when clicking it the focus goes to said button. If I use my image-based button the focus remains on the last text field used before clicking it.
One solution would be to override the message box in this specific situation (when saving the data). The second one would be to reset the focus of the form, or set focus to the image like what happens with a regular CommandButton. Any suggestions would be greatly appreciated.
You can do yourself what the traditional CommandButton does automatically: Set the focus where you want it:
Private Sub cmbCustomer_AfterUpdate()
If cmbCustomer.ListIndex > -1 Then
Else
MsgBox "Please choose a valid customer", vbExclamation
cmbCustomer.Value = ""
myButton.SetFocus
End If
End Sub
If SetFocus doesn't work, be mindful of where you are in the UI event chain: Why is my .setfocus ignored?
As mentioned in the comments, an image button can't acquire the focus. A transparent CommandButton behind it can be used as a proxy.

Get command button by using cell address

I want to call/ activate a button at the end of a Sub. I know the cell address of the command button, but I don't know the name/ID of the button.
How do I select/activate the button without looping through each button on active sheet?
https://stackoverflow.com/a/30600479/13049793
I have created my buttons on multiple rows with each assigned to the same macro, from my understanding, I cannot call the macro the button is assigned to because the macro uses the button's relative position, below is a simple example to illustrate the use of the buttons relative position:
Sub ExampleButtonClick()
Dim Cellvalue As String
Cellvalue = ActiveSheet.Buttons(Application.Caller).TopLeftCell.Offset(0, -1).Value
Msgbox (Cellvalue)
End Sub
i assume you want to run one macro that at the end initiates a different macro, i also assume the reason the button is rather not as a sub that is just called is because it has its independent function that can be used without the other sub
assuming that you used a command button as an activeX control, why not just use a private sub that the button performs and place that in an individual module and at the end of your current sub;
call module1 'assuming the private sub exists in module 1
or rather include the code even if duplicated in the first sub, searching for a button seems the circular route unless there is another intention you wish to pursue.
maybe elaborate on the task at hand or post the current code you are working on?

Rowsource not working via VBA

I can't get the RowSource property of a list box to update via VBA. From another thread, I found the syntax, so I think this is correct. But, despite not failing, it doesn't do anything to the RowSource property (it remains blank). Below:
frmAddIngredient is the user form.
lbxIngredient is a listbox control in that form.
UniqueIngredients is one of the sheets in the workbook.
NumberOfItems is 1 (in this case).
It doesn't give an error, but it doesn't change anything, either. The form itself is not active at this time. This code is supposed to set up the form for later showing.
frmAddIngredient.lbxIngredient.RowSource = Sheets("UniqueIngredients").Range("A1:A" & CStr(NumberOfItems)).Address
The most recent code is
frmAddIngredient.lbxIngredient.RowSource = "=UniqueIngredients!A1:A1"
but, it still doesn't change anything in the actual form.
Also, can I add a new post, or do I have to continue editing this one and adding stuff?
What you want (as discussed in the comments on your question) is not possible. Setting something by code does not change it's property in the properties window and is only so until your project resets.
Consider a Userform with 2 buttons, with their original name and caption and then in a module paste these 2 subs.
Sub demo1()
UserForm1.CommandButton1.Caption = "Demo 1"
UserForm1.Show
End Sub
Sub demo2()
UserForm1.CommandButton2.Caption = "Demo 2"
UserForm1.Show
End Sub
When you run the first Sub demo1 Button 1's caption has changed but Button 2's caption has not.
Close the Userfom and now run demo2, you'll see that Button 1's caption is back to it's original hard set (properties window) name and that now Button 2 has a different name.

How do you ignore earlier content control using VBA in Microsoft Word?

I have a Word template where I have a checkbox content control in the middle of the document. Once this checkbox is clicked, it triggers some commands using VBA. However, I also have plain text content control and date picker content control earlier on in the document that helps in filling out the template for the user. When these boxes are selected, I keep getting an error message saying "Run-time error 6290 - This property is only available for check box content controls".
My question - is there any way to ignore the earlier content control boxes and only run the code when the checkbox is pressed?
My code at the moment looks something like this:
Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
If (ContentControl.Title = "Checkbox1" And ContentControl.Checked = True) Then
*code in here*
End If
End Sub
So you would think that the code would only get triggered once Checkbox1 is checked... but the earlier text and date fields give me an error code. Anyone know what's going on?
I'm not familiar with "content control" or Word VBA, but in Excel, when coding for the .OnChange event, it's important to make sure the cell passed in to the Sub is (one of) the one(s) you want to work with. I'd assume the same is true here.
My guess is your error is on the
ContentControl.Checked = True
portion of your If statement, so give this a try:
Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
If (ContentControl.Title = "Checkbox1") Then
If ContentControl.Checked = True Then
*code in here*
End IF
End If
End Sub
i.e., make sure you're looking at a checkbox control before testing to see if the box is checked.
VBA does not do conditional short-cutting, so it's going to evaluate all statements in a AND conditional even if the first one is False.

Resources