userform.show problems - vba

I am making a word document to fill out a form upon clicking a button. I have made a basic form so far named 'NewSite' I have then made a button to click to open the form with the code:
Private Sub NewSite_Click()
NewSiteUserForm.Show
End Sub
This then pops up the error 'Object Required'
Any help will be appreciated!
edit**
I have figured it out...
I set the name of the form back to its original name of 'UserForm1' for ease of use. The code:
Private Sub NewSite_Click()
Dim Form As Object
Set Form = UserForm1
Form.Show
End Sub
semed to work.

If you named it NewSite, you will have to declare your variable as an object of that type and the initialize it. Do it like this:
Private Sub NewSite_Click()
Dim NewSiteUserForm As NewSite
Set NewSiteUserForm = New NewSite
NewSiteUserForm.Show
End Sub

Related

Use VBA to create a dynamic form with a button using "vbModeless"

I want to create a vbModeless dynamic user form during run-time. The user form has just one button, that's it. The form works fine using vbModal but unfortunately with vbModeless I can't get the click event for the button to work. Clicking the button does not call the event. I'm using the following steps/code:
Created an empty user form named UserForm1
Created a module named Modul1 with the following code:
Sub CreateFormControls()
'Create Command Button
Dim Button01 As MSForms.CommandButton
Set Button01 = UserForm1.Controls.Add("Forms.CommandButton.1", "dynButton01", False)
Button01.Visible = True
'Reference click event
Dim ClickEvents As New Class1
Set ClickEvents.ButtonEvent = Button01
'Show User Form
UserForm1.Show vbModeless '-> THIS DOES NOT WORK, only vbmodal works
End Sub
Created a class module named Class1 with the following code:
Public WithEvents ButtonEvent As MSForms.CommandButton
Private Sub ButtonEvent_Click()
MsgBox "Test"
Unload UserForm1
End Sub
Is there a way to get this working with vbModeless or is there a different work around?
Note: I haven't used dynamic forms very much yet, and I copied/modified the shown implementation using an existing code snippet without completely understanding how the button object references the click event e.g. why a separate class is needed and I can't do it within the procedure in Modul1. I assume within lies the reason why it doesn't work opening the form non-modal. A little light on this issue would be appreciated as well.
ClickEvents should be declared at the module level...
Option Explicit
Dim ClickEvents As New Class1 'declared at the module level
Sub CreateFormControls()
'etc
'
'
End Sub

Set userform width from a module by looping through userforms

Been having a very frustrating problem that I can't seem to find a solution for anywhere - help would be greatly appreciated!
I know how to change the width of a userform from within the userform itself (Me.Width).
The problem is that I am writing a module that will format userforms dynamically. The module is passed a form and it does some manipulations on that form. So far everything works as long as I'm referring to objects on the form.
But I'm now trying to refer to the form itself, and when I try to change the width (of the form, not of a control on the form) I get the error: "Object doesn't support this property or method".
I've tried declaring it as both a UserForm and an Object and all of the other code works in both cases, but resizing the width doesn't. I can see in the immediate window that width isn't available, which is obviously why the code won't execute.
Here's the code that I've tried without succses:
Sub frmLoadLayoutTest()
frmLoadLayout frmTest
frmTest.Show
End Sub
Private Sub frmLoadLayout(frmActive As Object) 'Also tried (frmActive as UserForm)
'Setting the width of a control works
frmActive.Controls("labelTest").Width = 100
'Setting the width of the form itself doesn't work
frmActive.Width = 100
End Sub
If anyone can provide an elegant solution, that would be fantastic. Alternatively, is there a way I can refer to the userform by name? (Something like Userform(frm1.name).Width = 100)
Thanks in advance!
Try this:
Sub frmLoadLayoutTest()
Dim frm As frmTest
Set frm = New frmTest '<<< create an instance of the form
frmLoadLayout frm '<<< pass in the instance
frm.Show '<<< show the instance
End Sub
Private Sub frmLoadLayout(frm As Object)
With frm
.Controls("labelTest").Width = 100
.Width = 300
End With
End Sub
See also why it's good practice to avoid the "default instance" and create your own explicit instance of a form before using it:
https://rubberduckvba.wordpress.com/2017/10/25/userform1-show/

Userform to open when sheet opens

A little stuck with VBA, im trying to get my userform "ParcelDataEntry" to open when i select a sheet from my combo box which i have on my front page which will have various other options when i cross this hurdle.
All 54 worksheets have the following code:
Private Sub Worksheet_Open()
ParcelDataEntry.Show
End Sub
I don't think there is a Worksheet_Open event. Instead use the Workbook_SheetActivate event. You should place this code in the ThisWorkbook code module.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Call OpenDataEntryForm
End Sub
Treat your userform like an object and declare and instantiate it accordingly.
Public Sub OpenDataEntryForm()
Dim dataEntryForm As ParcelDataEntry
' Create an instance of the form
Set dataEntryForm = New ParcelDataEntry
' Show the form
dataEntryForm.Show
' Do something here
' If the form was opened as Modal, then the code here will only run
' once the form has been hidden/closed
' Now destroy the object
Set dataEntryForm = Nothing
End Sub

Userform not triggering Initialize or Activate event

I kept a userform control button in my worksheet to fire up a macro, which in turn shows a user form, In the form I wish to display the opened files in checkboxes(using the Workbooks collection).I wish to run a macro that performs action for the user selected files only.
So for the button in my worksheet, I have assigned the following macro
Private Sub Button2_Click()
Load MyForm
MyForm.Show
End Sub
At first I kept the below code in the module where my macro sub is there.Since it's not working, I right clicked on user form and selected view code and kept the below code there.But still it's showing the same static designed user form, not the dynamic.I kept breakpoint at both load Myform and MYform.Show() and I stepped through code.It never went into intialize or activate method at all.
Private Sub MyForm_Activate()
'for checking the whether this method is called or not I am trying to change caption
MyForm.LabelSelectFile.Caption = "dhfdfldkfldzjf;zdfkz;d"
Dim mymyWorkBook As Workbook
For Each mymyWorkBook In Workbooks
'code for creating checkbox based on the file name displayed by the workbook collection
Next mymyWorkBook
End Sub
I can't understand why that event is not getting triggered.Please help me to overcome this.Thanks in advance
Even though the name of the form is MyForm, you still need to use userform.
'~~> in your worksheet
Private Sub Button2_Click()
MyForm.Show
End Sub
'~~> In the userform code area
Private Sub UserForm_Initialize()
'~~> Your code here
End Sub
or
Private Sub UserForm_Activate()
End Sub
The best is to always select the event from the drop down, rather than typing it

Having an MS Office UserForm detect which subroutine called it

In a VBA project of mine I am/will be using a series of reasonably complex userforms, many of which are visually identical but have different subroutines attached to the buttons. As a result I'm not overly keen on the idea of duplicating them multiple times in order to get different functionality out of the same layout. Is it possible to have a userform detect which subroutine called it and use this in flow control? I would like to be able to do something like this:
Private Sub UserForm_Initialize()
If [the sub that called the userform is called "foo"] then
Call fooSub
else
Call barSub
End If
End Sub
My backup plan is to have the calling subroutine set a global variable flag and have the userform check that, but that seems like a rather crude and clumsy solution.
Thanks everyone,
Louis
You can use the tag property of the form. Load the form, set the property, then show the form:
Sub PassCallerToForm()
Load UserForm1
UserForm1.Tag = "foo"
UserForm1.Show
End Sub
Now that the property is set, you can determine what to do in the form:
Private Sub UserForm_Activate()
If Me.Tag = "foo" Then
Call fooSub
Else
Call barSub
End If
End Sub
You can also use public variables:
' in userform
Public Caller As String
Private Sub UserForm_Click()
MsgBox Caller
Caller = Now()
Me.Hide
End Sub
' in caller
Sub callUF()
Dim frm As New UserForm1
frm.Caller = "Test Caller"
frm.Show
MsgBox frm.Caller ' valid after Me.Hide
Set frm = Nothing
End Sub
Personally, I would not have one userform doing two disparate activities. The code would get hard to read pretty quickly, I think. Copying the layout of a userform is pretty trivial.
To copy a userform: Open a blank workbook. In the Project Explorer, drag the userform to the new workbook. Rename the userform in the new workbook. Now drag it back to the original workbook. Change the code in the userform copy.
If you absolutely don't want separate userforms, I recommend setting up a property of the userform. Userforms are just classes except they have a user interface component. In the userform module
Private mbIsFoo As Boolean
Public Property Let IsFoo(ByVal bIsFoo As Boolean): mbIsFoo = bIsFoo: End Property
Public Property Get IsFoo() As Boolean: IsFoo = mbIsFoo: End Property
Public Sub Initialize()
If Me.IsFoo Then
FooSub
Else
BarSub
End If
End Sub
I always write my own Initialize procedure. In a standard module:
Sub OpenForm()
Dim ufFooBar As UFooBar
Set ufFooBar = New UFooBar
ufFooBar.IsFoo = True
ufFooBar.Initialize
ufFooBar.Show
End Sub