Keeping ComboBox Lists Populated - vba

I have created a Word 2010 VBA Macro Sub with a UserForm. The Sub searches for ==Codes== in a form document, places the found ==code== as a label into the Userform and then allows the user to replace the ==code== with his or her input in the Combobox (part of the same UserForm).
Each string of inputted data is then saved to the Combobox list in the UserForm for later selection if needed.
This works fine until this Macro/Userform expires because a searched document is completed (or cancelled).
I would then like to open the next form document, and in the new launch of this same Macro/Sub retain the former combobox list of data (as options to fill this next opened document - for instance, the code ==Client Name== will come up frequently, and I'd rather select a combobox list entry rather than having to type the client name over and over)
But I can't seem to keep the combobox list in the new launch of this Macro Sub populated with the previous combobox data - even if I isolate this routine as a separate module and pre-define the variables with "Public" dimensions.
So, before I knock myself out trying to figure this out ... just a simple question:
Once a Macro terminates are all of the Public variables "dropped"? When I used to program in DOS WP.51 Macros you could keep data strings in the RAM endlessly (until you "killed" them, or closed WP)
If the Public variable are not "dropped", could someone give me a sample of code by which Public variables could be retained and populated into a duplicately launched combobox userform.
Any ideas, howsoever brief, would help
Thanks much in advance. . .
Mike

Not entirely sure what you're trying to do, but what I'd recommend is the following (Assuming that the form is named, "UserForm1" and then "UserForm2":
1) Create a Module that you use to open the form using:
Sub test()
UserForm1.Show
'Rest of things that you want to do...you will be able to access the values in your combobox in userform1
UserForm2.Show
End Sub
2) In your UserForm1, include a button that will close the form and include the following code:
Sub btn_Exit_Click()
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
Cancel = True
MsgBox "The X is disabled, please use a button on the form.", vbCritical
End If
End Sub
This will allow you to maintain control of the UserForm and ensure that you can keep the values. It may be possible to disable the Closing button, but I wasn't able to figure it out (my experience with forms is mostly in Access and those have different properties).
Hiding the form keeps the values so that you can look at them whereas when the user closes the form you lose the values that were in it.
*Note: Code to disable the X button taken from VBA Express

Related

Pause VBA Word macro, allow user to make a selection, and restart where it left off

I have a requirement for VBA script in Microsoft Word to pause so that the user can select text that will be copied to the clipboard so that it can exported to an Excel file. The user will make a number of selections and finally indicate he/she is done when the contents of the clipboard will be copied to a template Excel file.
I have the code working to copy each selection to the clipboard and then all rows to the Excel file. But I need assistence in figuring out how to pause the code to allow the user to make the selection and then restart the code to copy the selection to the clipboard. I am able to get the userform with toggle switch to switch states and labels when pressed. But have not figured out how to pause the VBA code to allow the user to navigate to the next section of the Word document for the next selection.
The Stakeoverflow question/answer below appears to address this requirement but I have not been able to get it to work. It appears that the code is incomplete.
Pause VBA macro, allow user to make a selection, and restart where it left off
Can someone provide example VBA code that accomplishes this?
Your assistence is much appreciated as I have been beating my head against the wall and it is starting to hurt!
There's no way in VBA to "pause" a macro. Code must run to completion... Unless there's a command for user input.
Input can be requested via the InputBox and MsgBox methods, but those block access to the document because they're modal. A UserForm, however, can be set to display as non-modal, meaning it stays on top, but doesn't block access to the document or the application features. Since you're already working with a UserForm, this can be implemented relatively easily.
In the small example below, the Continue button runs the code to perform an action on the user selection. When Done is clicked the entire code is exited and the form unloaded.
Code behind the user form
Option Explicit
Private Sub cmdContinue_Click()
Debug.Print Selection.Range.Text
End Sub
Private Sub cmdDone_Click()
Me.Hide
End Sub
Private Sub UserForm_Activate()
'Position the form near the top-left of the window
'So that the user can work with the document
Me.Top = Application.ActiveWindow.Top + 50
Me.Left = Application.ActiveWindow.Left + 50
End Sub
Code in a regular module
Option Explicit
Sub DisplayModeless()
Dim frm As frmModelessForInput
Set frm = New frmModelessForInput
frm.Show False 'Display as non-modal
Set frm = Nothing
End Sub

Running Macros from Toolbar/Running one macro from another

I am trying to develop a macro for a publisher document. This macro will, when run, show a pop-up allowing the user to select one of three types of clients, and add different bullet points to a text box depending on which option was selected. I'm having two different problems which I suspect are coming from the same source. Problem number one is that I can't get the button on my User Form to run a different macro when the button is clicked. Problem two is that I've added my macros to one of the toolbars, and nothing happens when I click on them. In both cases, it's simply not running the macro. What am I doing wrong?
UserForm1
Private Sub CommandButton1_Click()
Application.Run ("ShapeTest")
End Sub
Private Sub UserForm_Initialize()
With ListBox1
.AddItem ("Federal")
.AddItem ("State")
.AddItem ("Local")
End With
End Sub
ThisDocument
Private Sub GenerateStatement()
UserForm1.Show
End Sub
Private Sub ShapeTest()
MsgBox ("Hello!")
Application.ActiveDocument.Pages(1).Shapes(1).TextFrame.TextRange.InsertAfter`enter code here`(Chr(13) & "My Text")
End Sub
Why are you using Application.Run("ShapeTest") rather than simply ShapeTest?
I don't have enough information to be 100% sure, but the following should work: To make ShapeTest callable from the userform you do two things:
1) Move it from ThisDocument to a general code module (first Insert/Module in the editor).
2) Eliminate the word Private in front of Sub ShapeTest()-- you don't want this to be a private sub since you want code outside of the module to be able to use it.
On edit: Alternatively -- you could keep ShapeTest() where it is in ThisDocument, get rid of the Private qualifier and in the userform code refer to ShapeTest as ThisDocument.ShapeTest. I prefer using the first method since I tend to like to keep as much code as possible in general code modules (reserving things like ThisDocument for event handlers) but OTOH my VBA experience is mostly Excel with a smattering of Word and there might be reasons to keep the code in ThisDocument in Publisher. I don't know Publisher, but a problem that I have run into in Word at times is I have sometimes accidentally put code in the Normal template that I wanted to go in the document's project. If something similar is possible in Publisher you should double check where your code is living.

Userform.Show on a form button will not recognize userform, getting Error 424

I know very little about VBA, but I'm trying to design a userform for an excel workbook. The idea is click the button, bring up the userform, enter info, hit OK, and your info is formatted correctly and inserted into the worksheet.
I have 3 userforms that all work fine, but any macro I create that references one of them just does not recognize that that particular userform exists.
The code I'm having a problem with is pretty straightforward:
Private Sub LiquidFormButton_Click()
LiquidEntryUserform.Show
End Sub
Edit (Update): So I tried making a new userform, with a different name. I copied and pasted all of the controls from the object over to the new userform, changed the name of the macro to bring up the userform, and voila, it works. However, now the userform itself doesn't do anything because none of the controls actually have any codes behind them telling them what to do. That's fine, I'll just copy over the codes from the broken form and BOOM now it doesn't work. Soooo something in the very very simple coding within the userform itself is preventing it from being shown, even though the new userform AND the broken one both, in fact, do everything else they need to do besides show up. I'll post the full userform code up later on after some dabbling. Thank you!
You should 'instantiate' the form like so
Private Sub LiquidFormButton_Click()
Dim liquid as LiquidEntryUserform ' define a liquid var of the correct type
Set liquid = new LiquidEntryUserform ' create the Form
liquid.Show 'show it
' here you can still access variables
' on the form
If liquid.TextBox1.Text = "700" Then
'do things
End if
End Sub
My project looks like this:
You can use the Object Browser (View|Object Browser or hit F2) to find the Forms and Classes you have in your project:
I had a similar experience after making some changes to a UserForm. I noticed something was actually working immediately prior to the 424 error occurring. Using F8 to step thru my code, it turned out I was asking a control to be configured - that I had deleted!!
I was using this code in the MS XL Objects worksheet (the button is on the associated worksheet)...
Private Sub cmdTransactions_Click()
frmTransactions.Show
End Sub
to bring up the UserForm and this code in the Forms module...
Private Sub UserForm_Initialize()
: : :
Row_Number = [mostrecent].Value
Cells(Row_Number + 1, 2).Select <<< this bit was happening (.Select works for me!!)
: : :
cmdReset.Enabled = False <<< a control in the UserForm
chkDeposit.Enabled = False <<< this control had been deleted!! Remarked out but un-Remarked for clarity
: : :
End Sub
Hope that might help someone.

Application.Quit in UserForm attempts to run rest of macro before exiting

My question is: using VBA in Excel 2013 how can I gracefully close an entire instance of Excel when the user decides they don't want to fill out a UserForm and clicks quit or cancel?
Currently, if the user clicks quit or cancel, I check to see if my instance is the only one open. If it is not, I can use ThisWorkbook.Close and I think I will be okay. However, if it is, I do not want the application to still be present, so I used Application.Quit. This, though, tries to finish running the macro, throws errors (originally "type mismatch" because I unload the form), and only closes after I click "Debug" or "End" (which it does so fast for either I cannot actually debug). I'm ignoring the first case for now and just trying to exit the entire application. It's a very long macro with a lot of subroutines and functions, so for debugging and posting here, I have shortened it. The type mismatch error no longer occurs, but I believe that was a consequence of the actual error: code running after the command to close the application is called.
First, here's the code that starts everything:
Private Sub CommandButton1_Click()
Call form_variables
frm_REQUEST.Show
Call a_REQUEST_main
End Sub
The subroutine
form_variables
is a subroutine that creates public variables so I can store the data from the UserForm.
frm_REQUEST.Show
initializes (including calling a function that finds another workbook, extracts a list, does some formatting, closes the workbook and enters the list into the userforms drop down box) and shows the form, and finally
a_REQUEST_main
uses the public variables (where UserForm data is stored) and does its thing (but shouldn't do anything if the UserForm is closed).
The code that is executed when .Show is called is:
Private Sub UserForm_Initialize()
' Get job numbers from other workbook
Dim job_selection_list As Variant
job_selection_list = get_job_list()
With frm_REQUEST.Job_Number_ComboBox
.List = job_selection_list
End With
' set focus on Job Numbers
JN_combobox.SetFocus
End Sub
Private Sub cancel_button_Click()
Set job_selection_list = Nothing
Unload Me
Application.Quit
End Sub
Private Sub submit_button_Click()
' Values from userform saved as global (?) variables so other subroutines can access.
End Sub
I stepped through the program and saw that, once Application.Quit is called in the UserForm, the macro, in the main subroutine, steps to
Call a_REQUEST_main
but it should really just close everything out. I tried doing "save" commands, and changing the order of things, and read about objects needing to be set to nothing (hence the setting of the job_selection_list which is created when the drop down list is initialized), but I cannot seem to get this to work, or find anything online. Can anyone provide some guidance or let me know of a better way to close an excel instance? Help me Stack-Overflow Kenobi, you're my only hope!
Thanks.
Just add a variable to account for when the user closes the form
in the form
'hold flag if users cancels form
Public btnCancel As Boolean
Private Sub CommandButton1_Click()
Unload Me
btnCancel = True
End Sub
'set the flag each time the form active
Private Sub UserForm_Activate()
btnCancel = False
End Sub
then in your code
Call form_variables
frm_REQUEST.Show
If frm_REQUEST.btnCancel Then
Application.Quit
Else
Call a_REQUEST_main
End If
Put Application.Quit in the form's Terminate event handler instead of in the button's Click event handler.
The reason is that clearly the procedure will keep running even if the form has unloaded. So use the events to your advantage.
Putting it in the Click event will unload the form, but the procedure will keep running which of course may raise errors or other undesired effects.
Note: You may be prompted to save/discard changes (if any) to the workbook.

EXCEL VBA regarding functions & userforms

I am new in Excel VBA programming therefore I've met a few difficulties within my very own project.
Long story short, I have 10 UserForm(s), and 10 TextBox(s) in each UserForm with the same TextBox name.
Is it possible for me to create a function that I can call it in every UserForm so that I don't have to manually code it for every UserForm(s). Regarding the function, it will reset the value of TextBox, as well as bring it back to the 'initial' state.
That's all for my question. Any help would be highly appreciate.Thanks in advance.
Create a Sub in a Module that you call from each form
eg
Sub TextBoxInit(tb As MSForms.TextBox)
tb.Text = ""
End Sub
Call it in each UserForm as you see fit
eg
Private Sub Userform_Initialize()
Module1.TextBoxInit TextBox1
End Sub
Tan,
You should think about making use of Class Modules. I actually just learned about them recently, and they are a very effective way to manage multiple userforms with similarly constructed controls.
Go Here: VBA USERFORM: PREVENT COMBOBOX ESCAPE ON KEYDOWN
Or Here: EXCEL VBA: dblClick, Repetitive Code Improvement
The basics of how these Class Modules work is that you create your own object, you write the code for it, and you assign your desired userform controls as that object type (class). For instance, if you had 20 textboxes which performed the same way (they rebooted their own values), you would just write that identical code in the class module section. Bam! That's pretty much it (you'd also have to write a paragraph of code to loop through & assign which textboxes you'd want this functionality for).
It might take a while to understand, but it will significantly improve your project.