Determine which command button was clicked to open userform - vba

I have two command buttons (cmd1 and cmd2) on userform1, when clicked each show the same userform (userform2). Within the initialize or load sub is it possible to determine which command button was clicked on userform1 and therefore show the form differently? I imagine the code in either the initialize or load sub on userform2 to have the following skeleton:
if (cmd1 was clicked)
' do stuff relating to 1
elseif (cmd2 was clicked)
' do stuff relating to 2
else
' error handling
End if
The respective "stuff" could be moved into the event handler for cmd1 and cmd2 however, if the method described above can be used it will be a lot simpler and cleaner.

Use a Public Variable in UserForm1 and then test it in UserForm2_Initialize Event.
Something like this in UserForm1:
Public whatsclicked As String
Private Sub CommandButton1_Click()
whatsclicked = "CommandButton1"
UserForm2.Show
End Sub
Private Sub CommandButton2_Click()
whatsclicked = "CommandButton2"
UserForm2.Show
End Sub
And then in UserForm2:
Private Sub UserForm_Initialize()
Select Case UserForm1.whatsclicked
Case "CommandButton1": MsgBox "CommandButton1 loaded form."
Case "CommandButton2": MsgBox "CommandButton2 loaded form."
Case Else 'Do something else
End Select
End Sub

you can do it also without public variable.
i won't show an example where you can simply write something in a cell or hidden sheet, instead i just pass the wanted info directly .
this time whatsclicked is the name of a label in userform2,
in userform1, before calling userform2:
Private Sub CommandButton1_Click()
load UserForm2
with UserForm2
.whatsclicked.caption= "CommandButton1"
.Show
end with
End Sub
Private Sub CommandButton2_Click()
load UserForm2
with UserForm2
.whatsclicked.caption= "CommandButton2"
.Show
end with
End Sub
Of course, you will have to hide the text of whatsclicked to the user (same color as font or background...)

You can use ActiveControl for this as when you click a control it becomes active/focussed:
Private Sub CommandButton1_Click()
Debug.Print Me.ActiveControl.Name
End Sub
Private Sub CommandButton2_Click()
Debug.Print Me.ActiveControl.Name
End Sub
So more in line with your example:
Private Sub CommandButton1_Click()
Call DoStuff
End Sub
Private Sub CommandButton2_Click()
Call DoStuff
End Sub
Private Sub DoStuff()
select case Me.ActiveControl.Name
case "CommandButton1"
' do stuff relating to 1
case "CommandButton2"
' do stuff relating to 2
case else
'error etc.
end select
End Sub

Related

Is it possible to display a userform and executes a code bellow the .show method?

I want to display Userform2 from Userform1 then continue executing some code in Userform1 WITHOUT unloading Userform1
Private Sub CommandButton1_Click()
UserForm2.Show
x = 1
MsgBox x
End Sub
Not sure that's what you want, but this would do what you describe:
UserForm2.Show vbModeless
Note that UserForm2 isn't modal anymore, which means the user can click outside the form, and even end up hiding it behind UserForm1.
Modal forms return execution to the caller when they're hidden/closed or destroyed, modeless forms return execution to the caller immediately (Initialize and Activate handlers will run first though).
Assuming you mean without unloading Userform2...
Userform1 will wait for Userform2 to finish... however you can do something like this:
Userform1:
Private Sub CommandButton1_Click()
UserForm2.Show
End Sub
Sub uf1msgbox()
X = 1
MsgBox X
End Sub
Userform2:
Private Sub CommandButton1_Click()
UserForm1.uf1msgbox
End Sub

VBA Input Value From Another UserFormB into TextBox From UserFormA

I have a userForm (mappingGuide) that allows user to pick a smartyTag from a list of more user-friendly names.
I have a second user-form (conditionalBuilder) that I would like to call this userForm upon double-clicking a text field so that a user can lookup which smartyTag to apply (in case they don't know).
So logic, is:
open conditionalBuilder
double-click Field text box
mappingGuide opens
pick a smartytag from listbox
fill smartytag value into field text-box in conditionalBuilder
unload mappingGuide
The issue I think I having with completing the requirement is that when I load the forms themselves I cannot find a way to set the text of the fieldName textbox of the loaded instance of conditionalBuilder (see last code block below). I've been searching around, but cannot figure it out.
Here is relevant code:
conditionalBuilder loads from Custom UI ribbon
Sub RunCode(ByVal Control As IRibbonControl)
Select Case Control.ID
Case Is = "mapper": LoadMappingGuide
Case Is = "conditional": LoadConditionalBuilder
End Select
End Sub
Sub LoadConditionalBuilder()
Dim conditionalForm As New conditionalBuilder
conditionalForm.Show False
End Sub
double-click event of fieldName then loads mappingGuide
Private Sub fieldName_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Me.hide
Dim pickField As New mappingGuide
pickField.Show False
End Sub
smartTag listbox click event then attempts to place selection into fieldName (or selection if form not loaded)
Private Sub smartTagList_Click()
If smartTagList.ListIndex > -1 And smartTagList.Selected(smartTagList.ListIndex) Then
Dim smartyTag As String
smartyTag = smartTagList.List(smartTagList.ListIndex, 2)
If isUserFormLoaded(conditionalBuilder.Name) Then
'*** ---> below is my issue how to reference instance of form
conditionalBuilder.fieldName.Text = smartyTag
conditionalBuilder.Show
Else
Selection.Range.Text = smartyTag
End If
End If
Unload Me
End Sub
If there is a better set-up that would be great to know too. I have the forms separate because there's a couple of levels a user can create tags with.
This is how I would do it, a bit of overkill but in case of multiple forms it will be beneficial.
Module 1:
Option Explicit
Sub test()
frmMaster.Show False
End Sub
Form 1 : frmMaster:
Option Explicit
'/ Declare with events
Dim WithEvents frmCh As frmChild
Private Sub TextBox1_DblClick(ByVal cancel As MSForms.ReturnBoolean)
handleDoubleClick
End Sub
Sub handleDoubleClick()
If frmCh Is Nothing Then
Set frmCh = New frmChild
End If
frmCh.Show False
End Sub
'/ Handle the event
Private Sub frmCh_cClicked(cancel As Boolean)
Me.TextBox1.Text = frmCh.bChecked
End Sub
Form 2: frmChild:
Option Explicit
Event cClicked(cancel As Boolean)
Private m_bbChecked As Boolean
Public Property Get bChecked() As Boolean
bChecked = m_bbChecked
End Property
Public Property Let bChecked(ByVal bNewValue As Boolean)
m_bbChecked = bNewValue
End Property
Private Sub CheckBox1_Click()
Me.bChecked = Me.CheckBox1.Value
'/ Raise an event when something happens.
'/ Caller will handle it.
RaiseEvent cClicked(False)
End Sub
You can do this with a presenter class which controls userform instances and pass values between them. I mocked up something similar to give you an idea.
Presenter. This is a class module which creates the userforms, controls their scope, and catches the event thrown by the
ConditionalBuilder. It makes it super easy to pass values between
userforms.
Private WithEvents CB As ConditionalBuilder
Private MG As MappingGuide
Public Sub ShowCB()
Set CB = New ConditionalBuilder
CB.Show vbModal
End Sub
Private Sub CB_ShowMappingGuide()
Set MG = New MappingGuide
MG.Show vbModal
CB.UpdateTB1 Value:=MG.SmartTag
End Sub
ConditionalBuilder.
This has a simple function to update your textbox and also an event which raises actions in the presenter.
Public Event ShowMappingGuide()
Public Function UpdateTB1(Value As String)
TextBox1.Value = Value
End Function
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
RaiseEvent ShowMappingGuide
End Sub
MappingGuide.
The Type and Property could be overkill since we just want one value from the mapping guide but it's still good practice.
Private Type TView
Tag As String
End Type
Private this As TView
Public Property Get SmartTag() As String
SmartTag = this.Tag
End Property
Private Sub UserForm_Initialize()
Tags.List = Array("a", "b", "c")
End Sub
Private Sub Tags_Click()
this.Tag = Tags.List(Tags.ListIndex, 0)
Me.Hide
End Sub
I have one final Standard Module which creates the Presenter. This is what you'd hook up to your ribbon.
Public Sub ShowProject()
With New Presenter
.ShowCB
End With
End Sub
Step 1 (double click text field)
Step 2 (selecting "b")
Step 3 (result)
I actually solved it by placing the below block inside the IF where I check for the form being loaded and I will leave open for better answers, if there are any.
Dim uForm As Object
For Each uForm In VBA.UserForms
If uForm.Name = conditionalBuilder.Name Then
uForm.fieldName.Text = smartyTag
uForm.Show
End If
Next

Is it possible to enter text into an excel userform from a commandbutton on the same userform?

I am attempting to make an excel userform appear to behave more like an independent app than a userform. I would rather program an app but because of company IT rules that is not an option.
See image. Is it possible to enter data into an active textbox on the form by using a commandbutton on the included key pad?
Image of userform:
The form is not coded yet.
Thanks
Depending on what you want to do. Actually, once you click on the button to enter data on the button, the textbox would not be active any more. Anyhow, if you do not need the activetextbox, but another one, you may use the following code:
Let's say that you have a button btnOpenFile and a Label lblInformation.
You want, once you click on the button, to get "ALE ALE" in the lblInformation.
The most simple code to achieve this is probably this one:
Private Sub btnOpenFile_Click()
me.lblInformation = "ALE ALE"
End Sub
Put it inside the UserForm.
Something like this in support of my comment
Private tb As MSForms.TextBox
Private Sub CommandButton1_Click()
tb.Value = tb.Value & CommandButton1.Caption
End Sub
Private Sub CommandButton2_Click()
tb.Value = tb.Value & CommandButton2.Caption
End Sub
Private Sub CommandButton3_Click()
tb.Value = tb.Value & CommandButton3.Caption
End Sub
Private Sub CommandButton4_Click()
tb.Value = tb.Value & CommandButton4.Caption
End Sub
Private Sub TextBox1_Enter()
Set tb = Me.TextBox1
End Sub
Private Sub TextBox2_Enter()
Set tb = Me.TextBox2
End Sub

Global Variable in Userform

I search about this in the forum and found some answers but did not work for me.
I have two UserForms.
In the first one, I give a value to a variable called Word.
In the second one, I have a Label that I need the caption to become the variable Word.
Example:
Public Word as String
Private Sub Userform1_Activate
Word = "Today Is Saturday"
End Sub
Private Sub Userform2_Activate
Label1.Caption = Word
End Sub
But this does not work. The Label caption gets Zero for value.
Could anybody help me on this?
Thanks.
First Form
Private Sub CommandButton5_Click()
Db = "C:\Users\Desktop\db.txt"
Set File1 = CreateObject("Scripting.FileSystemObject")
Set File2 = File1.OpenTextFile(Db, 1)
Do Until File2.AtEndOfStream
If (File2.Readline = TextBox1) Then Exit Do
If File2.AtEndOfStream Then WordNotFound.Show
If File2.AtEndOfStream Then TextBox1.Value = ""
If File2.AtEndOfStream Then Exit Sub
Loop
Word = File2.Readline
MsgBox Word
TextBox1.Value = ""
End Sub
Second Form
Private Sub UserForm_Click()
Label1.Caption = Word
End Sub
As I said in my comment, that your method should work. Here is the test code that I tried
1- In Module1
Public Word As String
2- Create 2 user forms - UserForm1 and UserForm2
2a- In UserForm1
Private Sub UserForm_Activate()
Word = "This is Saturday"
End Sub
2b- In UserForm2
Private Sub UserForm_Activate()
Label1.Caption = Word
End Sub
3- Then in ThisWorkbook
Private Sub Workbook_Open()
UserForm1.Show
UserForm2.Show
End Sub
So when you close UserForm1, the UserForm2 would be displayed as below

How to go back or re-display Userform after hiding it?

I have this code in one command button in UserForm2:
Private Sub CButton1_Click()
UserForm1.Show
Me.Hide
End Sub
Now, Userform1 is shown.
Then I have another code in one command button in Userform1:
Private Sub CButton2_Click()
UserForm2.Show
Unload Me
End Sub
This throws up a:
Runtime Error: Form already displayed; can't show modally
How do I do this properly?
How do I go back to the previous Userform after hiding or unloading it?
I think the problem is the order of the statements. I found out by using the debugger that when I had the Show statements before the Hide or Unload, these last are not executed.
Try this
' on UserForm2
Private Sub CommandButton1_Click()
Me.Hide
UserForm1.Show
End Sub
' on UserForm1
Private Sub CommandButton1_Click()
Me.Hide
UserForm2.Show
End Sub
Change to this:
Private Sub CButton1_Click()
Me.Hide
UserForm1.Show
Unload Me
End Sub
Private Sub CButton2_Click()
Me.Hide
UserForm2.Show
Unload Me
End Sub