When I start my Userform, I first chack for a value. If this value is not existing the userform should close.
Try1: UserForm_Inizialize
Public Sub UserForm_Initialize()
Call languagePack
'
'initialize the userform
'
End Sub
Try1: function to choose a languagepack
Private Sub languagePack()
Dim LanguageItems(45) As String
Dim Language_ID As Integer
Language_ID = Outlook.LanguageSettings.LanguageID(msoLanguageIDUI)
Call Language_AS.getLanguage(Language_ID, LanguageItems)
If Not LanguageItems(0) = "" Then
With Me
'--write the array items into the userform objects and vaues
End With
Else
MsgBox "It doesn't exist a Language-Pack for your language! Pleas change to english."
Unload Advanced_Search ' will not work
End If
End Sub
Try1 was to unload the userform in the function languagePack(), but didnt stop run and I get an error. So I tried another thing:
Try2: UserForm_Inizialize
Private close_userform As Boolean
Public Sub UserForm_Initialize()
Call languagePack
If close_userform = Flase Then
'
'initialize the userform
'
else
Unload Advanced_Search ' will not work
end if
End Sub
Try2: function to choose a languagepack
Private Sub languagePack()
Dim LanguageItems(45) As String
Dim Language_ID As Integer
Language_ID = Outlook.LanguageSettings.LanguageID(msoLanguageIDUI)
Call Language_AS.getLanguage(Language_ID, LanguageItems)
If Not LanguageItems(0) = "" Then
With Me
'
'--write the array items into the userform objects and vaues
'
End With
close_userform = False
Else
MsgBox "It doesn't exist a Language-Pack for your language! Pleas change to english."
close_userform = True
End If
End Sub
Whats wrong on Try2? The Boolean close_userform is global so both functions can read the value. But if it reachs the unload it happen nothing. After reaching the end sub I get an error.
The error is: Run-time error '91':
Objective variable or With block variable not set
Macro that starts the Userform
Sub start_Advanced_Search()
Advanced_Search.Show (vbModeless)
End Sub
Pleas help me. Thanks for every command an answer. Kind regards, Nico
Why not make the languagePack sub a function that returns a Boolean instead of writing the result to close_userform. Next use Unload Me instead Unload Advanced_Search
That’s the solution of my problem.
Thanks Tom for your help.
Description:
If there is no language pack for my Userform (I make the language packs), it will close the userform.
The function languagePack() returns a boolean (ture = language pack exists | false = no language pack exists).
This boolean is saved in hasLanguage. With the function getHasLanguage() I can get the value outside of the userform.
This function is used in the sub start_Advanced_Search. With the if function I check if there is a language pack, if not it will unload the userform.
Userform
Private hasLanguage As Boolean
Public Sub UserForm_Initialize()
hasLanguage = languagePack()
If hasLanguage Then
'
'set the defaults...
'
End If
End Sub
Public Function getHasLanguage()
getHasLanguage = hasLanguage
End Function
Private Function languagePack() As Boolean
'array to save the new language
Dim LanguageItems(49) As String
'this value will contain the LanguageID of Outlook
Dim language_ID As Integer
'get LanguageID of Outlook
language_ID = Outlook.LanguageSettings.LanguageID(msoLanguageIDUI)
'call a sub to get the language
Call Language_AS.getLanguage(language_ID, LanguageItems)
'there is a languagepack if the first element of "LanguageItems" is not ""
If Not LanguageItems(0) = "" Then
With Me
'
'set the language of the userform
'
End With
languagePack = True
Else
'there is no languagepack
MsgBox "It doesn't exist a Language-Pack for your language! Pleas change to english."
languagePack = False
End If
End Function
Modul
Sub start_Advanced_Search()
'start the userform
Advanced_Search.Show (vbModeless)
'use the get function
If Not Advanced_Search.getHasLanguage() Then
'unload if flase
Unload Advanced_Search
End If
End Sub
Related
There is a sub, it creates a CourtForm userform and then takes a data from it. The problem appears when said form is closed prematurely, by pressing "X" window button and I get a runtime error somewhere later. For reference, this is what I'm talking about:
In my code I tried to make a check to exit sub:
Private Sub test()
'Create an exemplar of a form
Dim CourtForm As New FormSelectCourt
CourtForm.Show
'The form is terminated at this point
'Checking if the form is terminated. The check always fails. Form exists but without any data.
If CourtForm Is Nothing Then
Exit Sub
End If
'This code executes when the form proceeds as usual, recieves
'.CourtName and .CourtType variable data and then .hide itself.
CourtName = CourtForm.CourtName
CourtType = CourtForm.CourtType
Unload CourtForm
'Rest of the code, with the form closed a runtime error occurs here
End Sub
Apparently the exemplar of the form exists, but without any data. Here's a screenshot of the watch:
How do I make a proper check for the form if it's closed prematurely?
Add the following code to your userform
Private m_Cancelled As Boolean
' Returns the cancelled value to the calling procedure
Public Property Get Cancelled() As Boolean
Cancelled = m_Cancelled
End Property
Private Sub UserForm_QueryClose(Cancel As Integer _
, CloseMode As Integer)
' Prevent the form being unloaded
If CloseMode = vbFormControlMenu Then Cancel = True
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
Code taken from here. I would really recommend to have a read there as you will find a pretty good basic explanation how to use a userform.
One of the possible solutions is to pass a dictionary to the user form, and store all entered data into it. Here is the example:
User form module code:
' Add reference to Microsoft Scripting Runtime
' Assumed the userform with 2 listbox and button
Option Explicit
Public data As New Dictionary
Private Sub UserForm_Initialize()
Me.ListBox1.List = Array("item1", "item2", "item3")
Me.ListBox2.List = Array("item1", "item2", "item3")
End Sub
Private Sub CommandButton1_Click()
data("quit") = False
data("courtName") = Me.ListBox1.Value
data("courtType") = Me.ListBox2.Value
Unload Me
End Sub
Standard module code:
Option Explicit
Sub test()
Dim data As New Dictionary
data("quit") = True
Load UserForm1
Set UserForm1.data = data
UserForm1.Show
If data("quit") Then
MsgBox "Ввод данных отменен пользователем"
Exit Sub
End If
MsgBox data("courtName")
MsgBox data("courtType")
End Sub
Note the user form in that case can be closed (i. e. unloaded) right after all data is filled in and action button is clicked by user.
Another way is to check if the user form actually loaded:
Sub test()
UserForm1.Show
If Not isUserFormLoaded("UserForm1") Then
MsgBox "Ввод данных отменен пользователем"
Exit Sub
End If
End Sub
Function isUserFormLoaded(userFormName As String) As Boolean
Dim uf As Object
For Each uf In UserForms
If LCase(uf.Name) = LCase(userFormName) Then
isUserFormLoaded = True
Exit Function
End If
Next
End Function
I am creating a program which has several UserForms.
At the end of the program I need to clear every Checkbox inside some UserForm. I have created a Function, but it cannot recognise which UserForm it should clear, can you help me there? Here is the code:
Function ClearUserForm(ByVal userf As String)
Dim contr As Control
For Each contr In userf.Controls
If TypeName(contr) = "CheckBox" Then
contr.Value = False
End If
Next
End Function
And I am calling the function like this, for example:
ClearUserForm ("UserForm2")
It seems not to recognize which UserForm it should act upon.
Shai Rado's advice is good and you should have a look at how he creates the object from its 'key'.
I only post this answer to check if you're aware that you could pass the object itself in the call. So your code could be like so:
Option Explicit
Public Sub RunMe()
ClearCBoxes UserForm1
End Sub
Private Sub ClearCBoxes(frm As MSForms.UserForm)
Dim ctrl As Control
For Each ctrl In frm.Controls
If TypeOf ctrl Is MSForms.ComboBox Then
ctrl.Value = False
End If
Next
End Sub
You don't need a Function (since you are not returning any arguments), in your case a Sub will do.
You need to qualify an Object to the User_Form selected by using:
Set objUserForm = UserForms.Add(userf)
Whole code
(Tested)
Option Explicit
Sub ClearUserForm(ByVal userf As String)
Dim contr As Control
Dim objUserForm As Object
Set objUserForm = UserForms.Add(userf)
For Each contr In objUserForm.Controls
If TypeName(contr) = "CheckBox" Then
contr.Value = False
End If
Next
' just to check that all checkboxes are cleared
objUserForm.Show
End Sub
I've got a workbook which runs a macro to show the userform Open1 as it opens, using the (very basic) code:
Private Sub Workbook_Open()
Open1.Show
End Sub
This does its job fine - each time I open the workbook, the userform pops up and runs perfectly.
But, I want the userform to appear the first time the workbook is opened only. Is there a way to allow this to happen?
You could use a dummy module which gets deleted the first time you open the spreadsheet...
Something like:
If ModuleExists("DummyModule") Then
Open1.Show
DoCmd.DeleteObject acModule, "DummyModule"
End If
Function ModuleExists(strModuleName As String) As Boolean
Dim mdl As Object
For Each mdl In CurrentProject.AllModules
If mdl.Name = strModuleName Then
ModuleExists = True
Exit For
End If
Next
End Function
Update: as stated, DoCmd isn't used in excel vba. That will teach me to write code without testing it!
The following updated code will work, but in order to access the VB environment, excel needs to be trusted.
There is a setting in the Trust Center>Macro Settings that you can tick for this code to work under Developer Macro Settings
As such, this may not be the way to go as it opens up the possibility of security issues...
Sub RemoveModule()
If ModuleExists("DummyModule") Then
Open1.Show
Dim vbCom As Object: Set vbCom = Application.VBE.ActiveVBProject.VBComponents
vbCom.Remove VBComponent:=vbCom.Item("DummyModule")
End If
End Sub
Function ModuleExists(strModuleName As String) As Boolean
Dim mdl As Object
For Each mdl In Application.VBE.ActiveVBProject.VBComponents
If mdl.Name = strModuleName Then
ModuleExists = True
Exit For
End If
Next
End Function
Try this:
If Sheets("Hide").Cells(1,1) = "1" Then
Open1.Show
Sheets("Hide").Cells(1,1) = "0"
End if
You must create the sheet Hide, and give the cell A1 the value 1, in that case the form will be shown.
After you create the sheet, hide it with this
Sheets("Hide").Visible = xlVeryHidden
And show it with this
Sheets("Hide").Visible = True
Here's an alternative bit of code that will persist between saves and allow you to reset it. No need to create a hidden sheet.
Put this in a module (invoke the DisplayFormIfFirstTime from your Workbook_Open event handler....)
Option Explicit
Private Const cMoniker As String = "FormHasBeenDisplayed"
Private Sub DisplayFormIfFirstTime()
If HasBeenOpened = False Then DisplayForm
End Sub
Public Sub DisplayForm()
MsgBox "Ok, its not a form but a dialog box...", vbInformation
End Sub
Public Function HasBeenOpened() As Boolean
Dim oName As Name
On Error Resume Next
Set oName = Application.Names(cMoniker)
On Error GoTo 0
If Not oName Is Nothing Then
HasBeenOpened = True
Else
Call Application.Names.Add(cMoniker, True, False)
End If
End Function
'Call this to remove the flag...
Public Sub ResetOpenOnce()
On Error Resume Next
Application.Names(cMoniker).Delete
End Sub
Based on the idea supplied by PaulG, I have coded an upgrade that will check for the name and if not found run a function, add the name and save the workbook for a more seemless approach to this problem...
Placed in ThisWorkbook
Private Sub Workbook_Open()
Run "RunOnce"
End Sub
Placed in a module
Sub RunOnce()
Dim Flag As Boolean: Flag = False
For Each Item In Application.Names
If Item.Name = "FunctionHasRun" Then Flag = True
Next
If Flag = False Then
Call Application.Names.Add("FunctionHasRun", True, False)
Application.DisplayAlerts = False
ActiveWorkbook.Save
Application.DisplayAlerts = True
Call RunOnceFunction
End If
End Sub
Private Function RunOnceFunction()
Open1.Show
End Function
Sub ResetRunOnce()
For Each Item In Application.Names
If Item.Name = "FunctionHasRun" Then
Application.Names.Item("FunctionHasRun").Delete
Application.DisplayAlerts = False
ActiveWorkbook.Save
Application.DisplayAlerts = True
End If
Next
End Sub
I have a macro code behind Worksheet. When button is clicked on the sheet, new user form is initialised and showed to user. If user closes the windows with red X, or form is closed with "hide" function/method, all global variables that are behind Worksheet loses their values. Is it possible to preserve this values?
Worksheet code behind:
Private MeasurementCollection As Collection
Dim CurrentMeasurement As measurement
Dim NewMeasurement As measurement
Private Sub Worksheet_Activate()
Initialize
End Sub
Public Sub Initialize()
Set NewMeasurement = New measurement
Dim DropDownDataQueries As Collection
Set DropDownDataQueries = DBQueries.GetAllUpdateQueries
For i = 1 To DropDownDataQueries.Count
Dim Values As Collection
Set Values = DataBase.GetData(DropDownDataQueries(i))
With Me.OLEObjects("Combo" & i).Object
For Each value In Values
.AddItem value
Next value
End With
Next i
End Sub
Private Sub UpdateDB_Click()
UpdateGeneralData
If (CurrentMeasurement Is Nothing) Then
MsgBox ("Message text")
Else
Dim form As UpdateComentForm
Set form = New UpdateComentForm
form.Show
End If
End Sub
Private Sub Combo1_Change()
If Application.EnableEvents = True Then
If (Combo1.value <> "") Then
NewMeasurement.DN = Combo1.value
Else
NewMeasurement.DN = 0
End If
End If
End Sub
UserForm code
Private Sub UpdateDBData_Click()
If (Komentar.value <> "") Then
Me.Hide
Else
MsgBox ("Prosimo napišite vzrok za spremembe podatkov v belo polje!")
End If
End Sub
Private Sub UserForm_Terminate()
Me.Hide
End Sub
Experiments show that the module-level variables are cleared upon exiting a procedure that involves calling = New Form, provided that the form designer window is opened somewhere in the IDE.
Close all user forms designer windows you might have open in the VBA IDE and try again.
NewMeasurement as been declared but never assigned.
You could do something like Dim NewMeasurement As New measurement to create an instance of the object.
I have a simple Sub to set a checkbox (placed on a worksheet) depending on whether or not a Worksheet is protected.
chkToggleProtect absolutely exists, by I'm getting a compile error on either of the lines where I reference it -
Variable not defined
Any ideas what I'm doing wrong?
Private Sub SetToggleProtect(ByRef isprotected As Boolean)
If isprotected Then
chkToggleProtect.Checked = True
Else
chkToggleProtect.Checked = False
End If
End Sub
The reason is exactly the error thrown: the variable does not exist as far as this sub is concerned. Remember to fully qualify everything.
If this is a Forms checkbox, the following will work:
Private Sub CheckACheckbox(isProtected As Boolean)
Dim cb As CheckBox
If cb.Name = "ModifyMe" Then
If isProtected Then
cb.Value = True
Else
cb.Value = False
End If
End If
End Sub
Modify accordingly to suit.
So after some giggery-pokery with the Immediate windows (my new best friend), I found that I could access the Forms control placed on my worksheet like this -
Private Sub SetToggleProtect(ByRef IsProtected As Boolean)
If IsProtected Then
WS.Shapes("chkToggleProtect").ControlFormat.Value = xlOn
Else
WS.Shapes("chkToggleProtect").ControlFormat.Value = xlOff
End If
End Sub