Detect Button Press Event on an Excel Sheet MultiPage Form (NOT a VBA MultiPage) - vba

I am struggling to figure out how to detect a button press event on a MultiPage form that resides directly on an Excel sheet. In other words, the form is not generated using VBA, it is built directly on the sheet.
I expect the syntax to be something like:
Private Sub MultiPage1_Frame1_CommandButton1_Click()
Do Stuff
End Sub
However, that doesn't work because I think I also need to specify the page in the MultiPage. For example, a text box on the same form can be accessed via:
MultiPage1.Pages(0).Frame1.TextBox1.Text = "Some Text"
Unfortunately,
Private Sub MultiPage1_Pages(0)_Frame1_CommandButton1_Click()
gives a Compile error: Expected: identifier with the zero inside (0) selected.
So, how do I convert
MultiPage1.Pages(0).Frame1.CommandButton1
to a Sub name that will detect the button press event?
Thank you!

I'm not sure but I think you may have stumbled onto a bug.
There is a Microsoft Forms 2.0 Control under More Controls, but I'm pretty sure it's only intended only for use on UserForms.
I tried adding it to a worksheet and got an error. However, once I added one to a UserForm and went back to the worksheet, I was able to add it... but things got "glitchy" for moment, and when I opened the Properties dialog for the bod, the font was poorly rendered.
All the documentation that I looked at (like this, this and this) only have examples of it being used on a UserForm, or in Outlook.
There are many types of ActiveX controls, and not all of them can be used anywhere. As a rule of thumb in Excel, it's best to stick to the controls that are built-in.
Also, from another forum:
Q: It seems that I could not find and add Multipage control into worksheet.
How to add a Multipage control to Excel worksheet?
A: Unless you put it on a UserForm first, you can't display it on a Worksheet. The UserForm provides the user interface to VBA. The MultiPagecontrol is designed to work with this user interface, and not the Excel Worksheet. Is there a problem using the UserForm to display the MutliPage control? Source: Leith Ross
This evidence combined tells me, even if you can get it to work, you shouldn't. There's no predicting how it will behave.
In case you decide to use a MultiPage on a UserForm, note that in your example above, MultiPage1 is the name of the control; that's not referring to "page 1". The control as a whole has a Click event which is not specific to a page:
Private Sub MultiPage1_Click(ByVal Index As Long)
For the sake of completeness, I'll paste in a complete code sample but once again: this is not recommended for a worksheet-based control.
How to: Access a Page in a MultiPage Control
The following example accesses an individual page of a MultiPage in several ways:
Using the Pages collection with a numeric index.
Using the name of the individual page in the MultiPage.
Using the SelectedItem property.
To use this example, copy this sample code to the Script Editor of a form. Make sure that the form contains a MultiPage named MultiPage1 and a CommandButton named CommandButton1.
Sub CommandButton1_Click()
Dim PageName
Set MultiPage1 = Item.GetInspector.ModifiedFormPages("P.2").MultiPage1
For i = 0 To MultiPage1.Count - 1
'Use index (numeric or string)
MsgBox "MultiPage1.Pages(i).Caption = " & MultiPage1.Pages(i).Caption
MsgBox "MultiPage1.Pages.Item(i).Caption = " & _
MultiPage1.Pages.Item(i).Caption
'Use Page object without referring to Pages collection
If i = 0 Then
MsgBox "MultiPage1.Page1.Caption = " & MultiPage1.Page1.Caption
ElseIf i = 1 Then
MsgBox "MultiPage1.Page2.Caption = " & MultiPage1.Page2.Caption
End If
'Use SelectedItem Property
MultiPage1.Value = i
MsgBox "MultiPage1.SelectedItem.Caption = " & _
MultiPage1.SelectedItem.Caption
Next
End Sub
(Source)
Now I'm going to delete that buggy worksheet and reboot; I'd suggest you do the same!

Mikerickson and Jaafar Tribak on MrExcel.com figured it out:
https://www.mrexcel.com/forum/excel-questions/1054446-detect-button-press-event-excel-sheet-multipage-form-not-vba-userform-multipage-2.html
Big thanks to both of them!

Related

Screen Object not found

I have a Project in Excel. I have a module with sub Load to populate the ActiveForm with data in an Excel table that is tagged to go into that respective form. The idea is that whichever Form is active, I can call Load and get the data from the Excel table.
I am trying to use this simple code to get the name of the active form, like I have seen in so many examples
Debug.Print Screen.activeform.Name
However, the Screen object cannot be found. I get "Variable Not Defined" error.
Is this something that can be added via references? I have searched high and low. Or, can I pass a reference to the "Me" to the module?
Here is the code I have in the module to populate whichever form the user opens:
Public Sub Load()
Dim rw As Long
Set wb = ThisWorkbook
Set wsInputs = wb.Worksheets("Inputs")
Set loInputs = wsInputs.ListObjects("tInputs")
With loInputs
For rw = 1 To .DataBodyRange.Rows.Count
If .ListColumns("Form").DataBodyRange.Rows(rw) = screen.activeform Then
screen.activeform.Controls(.ListColumns("Control Name").DataBodyRange.Rows(rw).Value) _
= .ListColumns("Value").DataBodyRange.Rows(rw).Value
End If
Next rw
End With
End Sub
The different forms are just different categories of data for input into text and combo boxes that read back and forth from the form to Excel, of if there is data in Excel and the user opens that form, it is pre-populated.
I can include a screenshot but its just a bunch of labels and input boxes.
Thanks.
I was able to get this to work by having the function accept the form as a parameter:
Public Sub LoadData(frmLoad As Object)
And simply pass Me to the function:
LoadData Me
Perhaps the is poor design but it works. And therefor I don't need to include the LoadData function in each form.
Matt

Keeping ComboBox Lists Populated

I have created a Word 2010 VBA Macro Sub with a UserForm. The Sub searches for ==Codes== in a form document, places the found ==code== as a label into the Userform and then allows the user to replace the ==code== with his or her input in the Combobox (part of the same UserForm).
Each string of inputted data is then saved to the Combobox list in the UserForm for later selection if needed.
This works fine until this Macro/Userform expires because a searched document is completed (or cancelled).
I would then like to open the next form document, and in the new launch of this same Macro/Sub retain the former combobox list of data (as options to fill this next opened document - for instance, the code ==Client Name== will come up frequently, and I'd rather select a combobox list entry rather than having to type the client name over and over)
But I can't seem to keep the combobox list in the new launch of this Macro Sub populated with the previous combobox data - even if I isolate this routine as a separate module and pre-define the variables with "Public" dimensions.
So, before I knock myself out trying to figure this out ... just a simple question:
Once a Macro terminates are all of the Public variables "dropped"? When I used to program in DOS WP.51 Macros you could keep data strings in the RAM endlessly (until you "killed" them, or closed WP)
If the Public variable are not "dropped", could someone give me a sample of code by which Public variables could be retained and populated into a duplicately launched combobox userform.
Any ideas, howsoever brief, would help
Thanks much in advance. . .
Mike
Not entirely sure what you're trying to do, but what I'd recommend is the following (Assuming that the form is named, "UserForm1" and then "UserForm2":
1) Create a Module that you use to open the form using:
Sub test()
UserForm1.Show
'Rest of things that you want to do...you will be able to access the values in your combobox in userform1
UserForm2.Show
End Sub
2) In your UserForm1, include a button that will close the form and include the following code:
Sub btn_Exit_Click()
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
Cancel = True
MsgBox "The X is disabled, please use a button on the form.", vbCritical
End If
End Sub
This will allow you to maintain control of the UserForm and ensure that you can keep the values. It may be possible to disable the Closing button, but I wasn't able to figure it out (my experience with forms is mostly in Access and those have different properties).
Hiding the form keeps the values so that you can look at them whereas when the user closes the form you lose the values that were in it.
*Note: Code to disable the X button taken from VBA Express

Userform.Show on a form button will not recognize userform, getting Error 424

I know very little about VBA, but I'm trying to design a userform for an excel workbook. The idea is click the button, bring up the userform, enter info, hit OK, and your info is formatted correctly and inserted into the worksheet.
I have 3 userforms that all work fine, but any macro I create that references one of them just does not recognize that that particular userform exists.
The code I'm having a problem with is pretty straightforward:
Private Sub LiquidFormButton_Click()
LiquidEntryUserform.Show
End Sub
Edit (Update): So I tried making a new userform, with a different name. I copied and pasted all of the controls from the object over to the new userform, changed the name of the macro to bring up the userform, and voila, it works. However, now the userform itself doesn't do anything because none of the controls actually have any codes behind them telling them what to do. That's fine, I'll just copy over the codes from the broken form and BOOM now it doesn't work. Soooo something in the very very simple coding within the userform itself is preventing it from being shown, even though the new userform AND the broken one both, in fact, do everything else they need to do besides show up. I'll post the full userform code up later on after some dabbling. Thank you!
You should 'instantiate' the form like so
Private Sub LiquidFormButton_Click()
Dim liquid as LiquidEntryUserform ' define a liquid var of the correct type
Set liquid = new LiquidEntryUserform ' create the Form
liquid.Show 'show it
' here you can still access variables
' on the form
If liquid.TextBox1.Text = "700" Then
'do things
End if
End Sub
My project looks like this:
You can use the Object Browser (View|Object Browser or hit F2) to find the Forms and Classes you have in your project:
I had a similar experience after making some changes to a UserForm. I noticed something was actually working immediately prior to the 424 error occurring. Using F8 to step thru my code, it turned out I was asking a control to be configured - that I had deleted!!
I was using this code in the MS XL Objects worksheet (the button is on the associated worksheet)...
Private Sub cmdTransactions_Click()
frmTransactions.Show
End Sub
to bring up the UserForm and this code in the Forms module...
Private Sub UserForm_Initialize()
: : :
Row_Number = [mostrecent].Value
Cells(Row_Number + 1, 2).Select <<< this bit was happening (.Select works for me!!)
: : :
cmdReset.Enabled = False <<< a control in the UserForm
chkDeposit.Enabled = False <<< this control had been deleted!! Remarked out but un-Remarked for clarity
: : :
End Sub
Hope that might help someone.

VBA cannot find my macro when it has parameters

I am trying to write a macro that will be attached to a series of buttons in an Office 2010 backstage tab. Depending on the button clicked the Macro should be called with different parameters.
The issue I am having is that if the Macro is defined as having parameters then VBA will display the "Macros" dialog box, with no Macros listed. Removing the parameters from the declaration will allow the macro to run, but it needs the Macros to make sense.
The VBA being used is below:
Sub NewDocs(docType As String, docTemplate As String)
Dim sMyShellCommand As String
sMyShellCommand = "C:\NewDocs.exe " & docType & docTemplate
WordBasic.Shell (sMyShellCommand)
End Sub
Any ideas
If I've got your question right....
Because there is no place in the Macros dialog box for entering parameters, the macros with parameters are simply not shown.
If you want to make them visible in the dialog box, you can enumerate those functions you need (and I hope it is not a big number).
For example,
Sub NewDocs1
Dim docType As String
Dim docTemplate As String
docType = "the type you want"
docTemplate = "the template you want"
NewDocs docType, docTemplate
End Sub
In addition, as you said in the question, you wanted the macro to run when buttons were pressed. Then there is no need to make the macro visible in the dialog box (which saves your labor). Simply associate it with the button with correct parameters.
You can pass arguments from the Macro dialog. For example, if you have this macro
Sub myMacro(n As Long)
MsgBox n
End Sub
To run it, enter
mymacro 1000
... and press the Run button.
You can't call functions or subs with parameters from UI components, just subs without parameters. The best solution is to create a parameter free sub for each button you need to associate with, and call the parameterized sub or function from inside each sub

Provide a range selection tool/utility to the user in Excel VBA

I am trying to develop a user form in Excel 2007 VBA and want to provide a user with a range selection icon, something like this:
However, I have not been able to find any built-in form design tool or any online tool which provides this or at least gives me an idea. If anyone has any idea about this, I will greatly appreciate their help.
This control is called RefEdit control.
To use it, you have to first add it to the toolbox window by right-clicking in the toolbox window and selecting Additional Controls.... Then you select RefEdit.Ctrl and close the dialog.
Now you can select it in the toolbox and place it on your form.
Another alternative to using the RefEdit.Ctrl is to hook into some undocumented features of the TextBox control and use the Application.InputBox function.
There are two properties of the TextBox control that do not appear in the Properties dialog, that allow you to add a button on the right. They are DropButtonStyle and ShowDropButtonWhen. When the button is clicked it will fire the DropButtonClick event for the control where you can show the input box.
Start by placing a TextBox control on the form. Then add the following to the UserForm_Initialize procedure:
Private Sub UserForm_Initialize()
txtRefersTo.DropButtonStyle = frmDropButtonStyleReduce
txtRefersTo.ShowDropButtonWhen = frmShowDropButtonWhenAlways
End Sub
Then add an event handler to the DropButtonClick event as follows to capture the range using the Application.InputBox dialog:
Private Sub txtRefersTo_DropButtonClick()
Me.Hide
txtRefersTo.Text = Application.InputBox("Select the range", "Range Picker", txtRefersTo.Text, Type:=8)
Me.Show vbModal
End Sub
The main advantage to this approach is that it allows you to place a control within a frame or on a separate tab without experiencing the issues associated with the RefEdit.Ctrl. The disadvantage is that it requires a separate dialog to interact with Excel.
Although this question is already almost a decade old, it still came up as my first Google search result so I'm going to post an answer as another approach to consider. The InputBox with type set to cell reference might be sufficient for many people's needs. The InputBox type does the drudge work of validating the user's response. See this article for how to use the InputBox types: https://www.thespreadsheetguru.com/blog/vba-to-select-range-with-inputbox
I liked #krey answer which was basically a very simplified version of the link shared in #stifin answer --> https://www.thespreadsheetguru.com/blog/vba-to-select-range-with-inputbox
But both used "odd" names for the buttons and I think guides should use default names/values for easy understand and manipulation by end user. Additionally, I added a CommandButton to "run" the userform and a "select" statement for initial testing. I also wanted to provide an initial value as I try to pre-populate my userforms, but allow end user to override if needed.
Here is the final code snipppets utilizing a UserForm w/ one TextBox named TextBox1 (default) and one CommandButton named CommandButton1 (also default).
Option Explicit
Public rng As Range
Public Sub UserForm_Initialize()
Me.TextBox1.DropButtonStyle = fmDropButtonStyleReduce
Me.TextBox1.ShowDropButtonWhen = fmShowDropButtonWhenAlways
Set rng = Range("A1:B4")
TextBox1.Value = rng.Address(False, False)
End Sub
Public Sub CommandButton1_Click()
rng.Select
Unload Me
End Sub
Public Sub TextBox1_DropButtonClick()
Me.Hide
Set rng = Application.InputBox("Select the range", "Range Picker", TextBox1.Text, Type:=8)
TextBox1.Value = rng.Address(False, False)
Me.Show
End Sub