Getting Values from Controls in MS Excel Custom Dialog Boxes - vba

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

Related

VBA Center Across Selection Hotkey

I am trying to create a hotkey shortcut for the "Center Across Selection" functionality. The "Merge Cells" functionality looks nice and all, but is horrid to use in practice because of the problems it creates with Macros and such. So, naturally, center across selection is the go-to tool. I use the keyboard to navigate in Excel, so it would be very nice to have a custom shortcut to make this selection easier and faster, since it is used often.
I have some code for this, which I believe should work, but for some reason, it is not:
In PERSONAL.XLSB - Module 1
Private Sub WorkBook_Open()
Application.OnKey "^q", "center_across_selection"
End Sub
In PERSONAL.XLSB - Module 3
Sub center_across_selection()
With Selection
'converts centered text to regular format
If .HorizontalAlignment = xlCenterAcrossSelection Then
.HorizontalAlignment = xlGeneral
'converts regular text to centered across selection
Else
Selection.HorizontalAlignment = xlCenterAcrossSelection
End If
End With
End Sub
Then, once I save this, exit out of the workbook (and all other workbooks as well), reopen the workbook, and try to use the Ctrl+Q shortcut, nothing happens to my cells! Please help me find where I am going wrong.
Move Private Sub WorkBook_Open() from MODULE 1 to the workbook code area.
You've implemented the macro in a standard module; Workbook_Open means to handle the Workbook object's Open event, but a standard module doesn't do that (the ThisWorkbook class/Excel object module does, as shown in Gary's (well, his student's anyway) answer).
So either you move the macro to ThisWorkbook's code-behind, or you rename the macro to Excel4-compatible Auto_Open:
Private Sub Auto_Open()
Application.OnKey "^q", "center_across_selection"
End Sub
Note that this Auto_Open macro will run regardless of the state of Application.EnableEvants when the workbook is opened.

Code that works for a form control doesn't work for ActiveX control

First time poster in StackOverflow (but not stackexchange) so please let me know if I can clarify or make any formatting changes. Thank you.
Try as I might, I can't find the answer to this question. I suspect it's due to a lack of understanding when it comes to the basics of VBA. I have knowledge of VBA, but little understanding. That being said, here's the problem.
I've set up a form control Combo Box linked to a macro. I've set the input range to a list of hyperlinks in a different sheet and named the range "Hyperlinks". Each hyperlink is to a different sheet in the workbook. I've set the cell link to a blank sell adjacent to the hyperlinks and named it "Linked_Cell." A picture is below.
Form Control View
The macro code is as follows
Sub DropDown10_Change()
HyperLink_Index = Range("Linked_cell")
If Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Name <> "" Then
Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
This automatically moves someone to the sheet they select when they select that sheet from the drop-down menu.
I would like to use an Active X combo box instead of a form control for all the obvious reasons (resize text, etc.) However, I can't get it to work.
I've set "ListFillRange" to "Hyperlinks" and linked cell to "Linked_cell" and entered the same macro code. It looks like this:
View of Active X Combo Box
When I select from the drop down in the Active X Combo box I receive run time error 1004: "Method 'range' of object '_worksheet' failed." I've verified that my named ranges are correct and the code returns no such error when it's in a macro linked to a form control.
Any help is much appreciated! Thank you!
UPDATE: Fixed the Range error by updating the code to the following
Sub ComboBox1_Change()
Dim HyperLink_Index As Range
Set HyperLink_Index = Sheets("SheetList").Range("Linked_Cell")
If Sheets("SheetList").Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Name <> "" Then
Sheets("SheetList").Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
I now receive a Type Mismatch error on the beginning of the IF statement. I don't see the error and still have no idea why this behavior doesn't appear for identical macro code linked to a form control.
P.S. Sorry, I don't mean to turn StackOverflow in to my personal debugging team, so the main question I have is "Why is the behavior different between a macro and active x code?"
UPDATE 2: Found a fix. Was using the wrong index. The fix is below. Leaving it here in case someone else can find it useful.
Sub ComboBox1_Change()
If ComboBox1.Value <> "" Then
Sheets("SheetList").Range("Hyperlinks").Hyperlinks(ComboBox1.ListIndex + 1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
Found a fix. Was using the wrong index. The fix is below. Leaving it here in case someone else can find it useful.
Sub ComboBox1_Change()
If ComboBox1.Value <> "" Then
Sheets("SheetList").Range("Hyperlinks").Hyperlinks(ComboBox1.ListIndex +1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub

Why does this code work with F1 and not CTRL-M (for example)

I found this code online, and it works like a charm:
Sub Auto_Open()
Application.OnKey "{F1}", "WorkbooksHandler"
End Sub
Sub WorkbooksHandler()
On Error Resume Next
If ActiveWorkbook.Sheets.Count <= 16 Then
Application.CommandBars("Workbook Tabs"). _
ShowPopup 500, 225
Else
Application.CommandBars("Workbook Tabs"). _
Controls("More Sheets...").Execute
End If
On Error GoTo 0
End Sub
I press F1 and it opens a dialogue with all the sheets. I can select the sheet I want and it goes there.
If I change the code just slightly, and use:
Sub Auto_Open()
Application.OnKey "^{m}", "WorkbooksHandler"
End Sub
Now control-m opens with dialogue showing me the sheets, but when I click on the sheet I want excel doesn't navigate there. Why should the trigger make any difference, and make the execution not work?
Edit: By the way, the code also works fine when I run it manually with F5 as well, just not with the onkey control-m.
The problem appears to be that the Control key, when used with OnKey persists through the whole command even though you've no doubt released the key. This has no effect on most things that you do, but inexplicably effects the More Sheets popup. Take this code
Sub Auto_Open()
Application.OnKey "^m", "WorkbooksHandler"
End Sub
Sub WorkbooksHandler()
SendKeys "{RIGHT}"
End Sub
All that does is press the right arrow key. But it has the effect of pressing Ctrl+Right which takes you to the edge of you worksheet (for a blank worksheet). So the Control part of ^m is sticking around through the execution of WorkbooksHandler.
This happens manually also. Hold down the control key, right click on the sheet navigation buttons, select More Sheets, select a sheet. It doesn't move to that sheet when you have Control held down.
I tried all manner of SendKeys, OnTime, and DoEvents, but couldn't trick Excel into releasing the Control key. I'll bet you could find a Windows API that would do the trick, but it's probably easier to simply pick a key combination that doesn't use Control.
Make sure
Sub WorkbooksHandler()
On Error Resume Next
If ActiveWorkbook.Sheets.Count <= 16 Then
Application.CommandBars("Workbook Tabs"). _
ShowPopup 500, 225
Else
Application.CommandBars("Workbook Tabs"). _
Controls("More Sheets...").Execute
End If
On Error GoTo 0
End Sub
is pasted in Modules,
Then
Compile and Run the Auto_Open() manually then try the shortcut

Program Option Button in Excel to run two different macros or actions

Simple question that I can't seem to get right: I have set up a macro that hides a few cells and another one that shows those same cells. When I run them independently they work fine. But i'm trying to set an option button or a check box that will run both macros. For example: if the box is checked, it shows the cells, if it is unchecked, it hides them.
I have only been able to assign one macro on click, but this doesn't work because it doesn't take into consideration the state of the button. I've tried with an IF, like this:
Private Sub CheckBox2_Click()
If CheckBox2.Value = True Then
Columns("Q:R").Select
Selection.EntireColumn.Hidden = True
Range("A2").Select
Else
Columns("Q:R").Select
Range("R1").Activate
Selection.EntireColumn.Hidden = False
Range("A2").Select
End If
End Sub
What am I doing wrong? Thanks in advance!
Try this to toggle, starting with an unticked check box and visible columns
Sub CheckBox2_Click()
Columns("Q:R").Select
Selection.EntireColumn.Hidden = not (Selection.EntireColumn.Hidden)
Range("A2").Select
End Sub
I don't think you need to worry about the state of the button. You really just need to reverse the state on click no matter what. You can just negate whatever the current state is.
Range("Q:R").EntireColumn.Hidden = Not Range("Q:R").EntireColumn.Hidden
Range("A2").Select
That being said, the logic you have is solid. What do you mean when you say it's not working? Does it never work, or only the first time you click the checkbox?

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