2

Does anyone know if it's possible to have a textbox in a userform in Excel 2010 work like the formula editor?

In other words when the userform is up and the textbox is the focused control allow me to type say

=AND( 

Then click cell D2 and have the text box then be

=AND($D$2

Then type a =

=AND($D$2= 

Then click cell E2

=AND($D$2=$E$2

Then type )

=AND($D$2=$E$2)

I've played around with the RefEdit control but it just overwrites any custom text as soon as a range is selected on the sheet, I basically need it to append to the text box when I click on a range.

2
  • 1
    You could look into using the worksheet's SelectionChange event to do this. Does it need to work across sheets? Commented Dec 5, 2015 at 6:02
  • Do you try Application.Inputbox method? Application.InputBox("Select cell.", Type:=8).Address It may help you. Commented Dec 5, 2015 at 6:41

3 Answers 3

2

Put this code in the ThisWorkbook module:

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
On Error GoTo EndOfSub

If UserForm1.ActiveControl.Name = "TextBox1" Then
  UserForm1.TextBox1.Value = UserForm1.TextBox1.Value & Target.Address
End If

EndOfSub:

End Sub

This way when your userform is loaded (UserForm1 here) and your textbox is active (TextBox1 here), the address of the selection is appended to it. If you need to add the worksheet's name too, change the 3rd line above:

  UserForm1.TextBox1.Value = UserForm1.TextBox1.Value & sh.Name & "!" & Target.Address

If you need to use it on only one sheet, put the code to that Sheet's code instead of the ThisWorkbook's code.

It is not as sophisticated as the formula editor, as it always appends the selection. (Changing the just inserted reference is doable too if you need it, just takes a bit more checking.)

Do note that putting code into the ThisWorkbook's SheetChange method takes its toll: you will not be able to use Undo in this workbook.

A bit more elegant way to check if a Userform is loaded can be found (here)[http://www.ozgrid.com/forum/showthread.php?t=152892]. You can use this instead of the On Error Goto part.

Sign up to request clarification or add additional context in comments.

Comments

1

Yes, this is possible in a TextBox, but the problem you have is that you'll need to show the UserForm modelessly because you need to select cells in a worksheet while the Userform is on show. If you want to do exactly as you describe, ie the very next keystroke is '=', then you will need to re-activate the UserForm otherwise you'll simply add an '=' into your selected cell.

I believe the Show command won't re-activate a modeless UserForm that is already on show and I'm not aware of an Activate command for a UserForm. Others may well know of one, but I'd use a couple of APIs to do the job. So the code in your Userform could be as follows (you may need to adjust the API declarations if you have Win64 and/or VB7 https://msdn.microsoft.com/en-us/library/office/ee691831(v=office.14).aspx):

Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetFocusAPI Lib "user32" Alias "SetForegroundWindow" _
    (ByVal hwnd As Long) As Long
Private mHwnd As Long
Private mTextBoxHasFocus As Boolean
Public Property Get TextBoxHasFocus()
    TextBoxHasFocus = mTextBoxHasFocus
End Property
Public Sub AppendText(appendedText As String)
    'Add the text to textbox
    TextBox1.Text = TextBox1.Text & appendedText
    'Activate this userform window
    SetFocusAPI mHwnd
    'API doesn't trigger UserForm_Activate event so call it
    Me.ActivateByCode
End Sub
Private Sub TextBox1_Enter()
    mTextBoxHasFocus = True
End Sub
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    mTextBoxHasFocus = False
End Sub
Public Sub ActivateByCode()
    'Set focus on any another control then back to textbox
    btnSave.SetFocus
    'Set cursor at end of text
    TextBox1.SelStart = Len(TextBox1.Text)
    TextBox1.SelLength = 0
    TextBox1.SetFocus
End Sub
Private Sub UserForm_Initialize()
    'Acquire the handle for this window
    mHwnd = FindWindow("ThunderDFrame", Me.Caption)
End Sub

You'd then call the AppendText routine from a WorkSheet_Change event or, as in this case, a Workbook_SheetSelectionChange event (which caters for selections of a cell in any WorkSheet):

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    If UserForm1.TextBoxHasFocus Then
        UserForm1.AppendText Target.Address
        'Uncomment the line below if you want sheet name as well as address
        'UserForm1.AppendText Sh.Name & "!" & Target.Address
    End If
End Sub

And remember to show your UserForm modelessly:

UserForm1.Show False

If you want to cursor to be in the TextBox when the UserForm opens, then add this line too:

UserForm1.ActivateByCode

Comments

0

(Posted on behalf of the question author).

Checking for the selection changed was what I was missing. I was SO focused on trying to make the UserForm behave I completely spaced on ALL the other events Excel has to work with!

In the end I went with a check in the SelectionChanged sub to see if a simpler UserForm (minimal size with textbox and restore button) was visible and the textbox was active.

I added a little more logic to handle inserting into the cursor location of the textbox as well as straight appending. Might add some support for arrow keys in the future but I have the original functionality I set out to have.

Microsoft, if you're listening, would it have been possible to give us a RefEdit control that looks and behaves like the one built into Excel? Just a thought.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.