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
Related
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!
As per the question: selecting a new value in an ActiveX combobox linked to a cell by it's .LinkedCell property does not fire the worksheet change event.
I know there are various events for combo boxes like it's own change event but none of them are really suitable for what I need to do (custom data validation on the changed cell).
As a workaround I pass the .LinkedCell to my validation code on the combobox mouse up and key up events (I can't use lost focus... long story, and on change fires on every character change which is too much).
Does anyone know of a cleaner way to pass the value around at the event level once the user has finished using the control?
If you want to trigger the ChangeEvent in a worksheet, without doing anything, here is a way to do it:
In a module:
Option Explicit
Public Sub CheckMe()
Application.Run "tblDB.Worksheet_Change", tblDB.Cells(1, 1)
End Sub
In a workbook, named tblDB:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print "triggered"
End Sub
Now, whenever you run the CheckMe, the Worksheet_Change event would be triggered.
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
first question here. I've been racking my brains all morning for the simplest thing to do in Excel's VBA: get the value of what a user types into a text box (list box, etc.) in a custom dialog box and copy that, via a macro, into a cell. Not sure why it has to be so ridiculously tough. I've tried the .Value property, the .Text property, everything, but it all comes up blank.
I'd post an image of my dialog box, but I don't have the reputation yet to do so. At any rate, just assume it's a banking dialog box with an Amount text box and two buttons: Ok and Cancel.
And here's my code, cut down to the necessary bit:
Sub AddTransaction()
frmAddTransaction.Show
ActiveCell.Offset(0, 1).Range("A1").Select
ActiveCell.FormulaR1C1 = frmAddTransaction.txtAmount.Value
End Sub
Private Sub cmdCancel_Click()
Unload frmAddTransaction
End Sub
Private Sub cmdOk_Click()
Unload frmAddTransaction
End Sub
As I've said, I've tried the .Value and .Text properties and everything else that came to mind. I've tried throwing it up into a MsgBox or just sticking it into a cell and, at this point, I'm racking my brains not only to find the answer but to figure out why Microsoft made is so tough just to take a value from one thing and put it into a cell.
Same thing with the buttons: I'd like to know how to tell a macro what button was pushed. I've tried using any property that even remotely looks promising, as well as adjusting the .Top property so I can compare that number. Everything. Nothing is working.
Any help would be great. I've been stuck on this literally all morning.
You want to add the buttons to the form, not to the sheet.
So you have 1 button on the sheet that says "Enter Amount" which runs the following:
Private Sub CommandButton1_Click()
frmAddTransaction.Show
End Sub
and the user form has 3 elements: an input box (txtAmount) and two buttons.
Private Sub Cancel_Click()
Me.Unload
End Sub
Private Sub OK_Click()
'modify this to add it to the correct cell
ActiveCell.Offset(0, 0).Value = txtAmount.Value
Me.Unload
End Sub
I am trying to develop a macro for a publisher document. This macro will, when run, show a pop-up allowing the user to select one of three types of clients, and add different bullet points to a text box depending on which option was selected. I'm having two different problems which I suspect are coming from the same source. Problem number one is that I can't get the button on my User Form to run a different macro when the button is clicked. Problem two is that I've added my macros to one of the toolbars, and nothing happens when I click on them. In both cases, it's simply not running the macro. What am I doing wrong?
UserForm1
Private Sub CommandButton1_Click()
Application.Run ("ShapeTest")
End Sub
Private Sub UserForm_Initialize()
With ListBox1
.AddItem ("Federal")
.AddItem ("State")
.AddItem ("Local")
End With
End Sub
ThisDocument
Private Sub GenerateStatement()
UserForm1.Show
End Sub
Private Sub ShapeTest()
MsgBox ("Hello!")
Application.ActiveDocument.Pages(1).Shapes(1).TextFrame.TextRange.InsertAfter`enter code here`(Chr(13) & "My Text")
End Sub
Why are you using Application.Run("ShapeTest") rather than simply ShapeTest?
I don't have enough information to be 100% sure, but the following should work: To make ShapeTest callable from the userform you do two things:
1) Move it from ThisDocument to a general code module (first Insert/Module in the editor).
2) Eliminate the word Private in front of Sub ShapeTest()-- you don't want this to be a private sub since you want code outside of the module to be able to use it.
On edit: Alternatively -- you could keep ShapeTest() where it is in ThisDocument, get rid of the Private qualifier and in the userform code refer to ShapeTest as ThisDocument.ShapeTest. I prefer using the first method since I tend to like to keep as much code as possible in general code modules (reserving things like ThisDocument for event handlers) but OTOH my VBA experience is mostly Excel with a smattering of Word and there might be reasons to keep the code in ThisDocument in Publisher. I don't know Publisher, but a problem that I have run into in Word at times is I have sometimes accidentally put code in the Normal template that I wanted to go in the document's project. If something similar is possible in Publisher you should double check where your code is living.