Screen Object not found - vba

I have a Project in Excel. I have a module with sub Load to populate the ActiveForm with data in an Excel table that is tagged to go into that respective form. The idea is that whichever Form is active, I can call Load and get the data from the Excel table.
I am trying to use this simple code to get the name of the active form, like I have seen in so many examples
Debug.Print Screen.activeform.Name
However, the Screen object cannot be found. I get "Variable Not Defined" error.
Is this something that can be added via references? I have searched high and low. Or, can I pass a reference to the "Me" to the module?
Here is the code I have in the module to populate whichever form the user opens:
Public Sub Load()
Dim rw As Long
Set wb = ThisWorkbook
Set wsInputs = wb.Worksheets("Inputs")
Set loInputs = wsInputs.ListObjects("tInputs")
With loInputs
For rw = 1 To .DataBodyRange.Rows.Count
If .ListColumns("Form").DataBodyRange.Rows(rw) = screen.activeform Then
screen.activeform.Controls(.ListColumns("Control Name").DataBodyRange.Rows(rw).Value) _
= .ListColumns("Value").DataBodyRange.Rows(rw).Value
End If
Next rw
End With
End Sub
The different forms are just different categories of data for input into text and combo boxes that read back and forth from the form to Excel, of if there is data in Excel and the user opens that form, it is pre-populated.
I can include a screenshot but its just a bunch of labels and input boxes.
Thanks.

I was able to get this to work by having the function accept the form as a parameter:
Public Sub LoadData(frmLoad As Object)
And simply pass Me to the function:
LoadData Me
Perhaps the is poor design but it works. And therefor I don't need to include the LoadData function in each form.
Matt

Related

Detect Button Press Event on an Excel Sheet MultiPage Form (NOT a VBA MultiPage)

I am struggling to figure out how to detect a button press event on a MultiPage form that resides directly on an Excel sheet. In other words, the form is not generated using VBA, it is built directly on the sheet.
I expect the syntax to be something like:
Private Sub MultiPage1_Frame1_CommandButton1_Click()
Do Stuff
End Sub
However, that doesn't work because I think I also need to specify the page in the MultiPage. For example, a text box on the same form can be accessed via:
MultiPage1.Pages(0).Frame1.TextBox1.Text = "Some Text"
Unfortunately,
Private Sub MultiPage1_Pages(0)_Frame1_CommandButton1_Click()
gives a Compile error: Expected: identifier with the zero inside (0) selected.
So, how do I convert
MultiPage1.Pages(0).Frame1.CommandButton1
to a Sub name that will detect the button press event?
Thank you!
I'm not sure but I think you may have stumbled onto a bug.
There is a Microsoft Forms 2.0 Control under More Controls, but I'm pretty sure it's only intended only for use on UserForms.
I tried adding it to a worksheet and got an error. However, once I added one to a UserForm and went back to the worksheet, I was able to add it... but things got "glitchy" for moment, and when I opened the Properties dialog for the bod, the font was poorly rendered.
All the documentation that I looked at (like this, this and this) only have examples of it being used on a UserForm, or in Outlook.
There are many types of ActiveX controls, and not all of them can be used anywhere. As a rule of thumb in Excel, it's best to stick to the controls that are built-in.
Also, from another forum:
Q: It seems that I could not find and add Multipage control into worksheet.
How to add a Multipage control to Excel worksheet?
A: Unless you put it on a UserForm first, you can't display it on a Worksheet. The UserForm provides the user interface to VBA. The MultiPagecontrol is designed to work with this user interface, and not the Excel Worksheet. Is there a problem using the UserForm to display the MutliPage control? Source: Leith Ross
This evidence combined tells me, even if you can get it to work, you shouldn't. There's no predicting how it will behave.
In case you decide to use a MultiPage on a UserForm, note that in your example above, MultiPage1 is the name of the control; that's not referring to "page 1". The control as a whole has a Click event which is not specific to a page:
Private Sub MultiPage1_Click(ByVal Index As Long)
For the sake of completeness, I'll paste in a complete code sample but once again: this is not recommended for a worksheet-based control.
How to: Access a Page in a MultiPage Control
The following example accesses an individual page of a MultiPage in several ways:
Using the Pages collection with a numeric index.
Using the name of the individual page in the MultiPage.
Using the SelectedItem property.
To use this example, copy this sample code to the Script Editor of a form. Make sure that the form contains a MultiPage named MultiPage1 and a CommandButton named CommandButton1.
Sub CommandButton1_Click()
Dim PageName
Set MultiPage1 = Item.GetInspector.ModifiedFormPages("P.2").MultiPage1
For i = 0 To MultiPage1.Count - 1
'Use index (numeric or string)
MsgBox "MultiPage1.Pages(i).Caption = " & MultiPage1.Pages(i).Caption
MsgBox "MultiPage1.Pages.Item(i).Caption = " & _
MultiPage1.Pages.Item(i).Caption
'Use Page object without referring to Pages collection
If i = 0 Then
MsgBox "MultiPage1.Page1.Caption = " & MultiPage1.Page1.Caption
ElseIf i = 1 Then
MsgBox "MultiPage1.Page2.Caption = " & MultiPage1.Page2.Caption
End If
'Use SelectedItem Property
MultiPage1.Value = i
MsgBox "MultiPage1.SelectedItem.Caption = " & _
MultiPage1.SelectedItem.Caption
Next
End Sub
(Source)
Now I'm going to delete that buggy worksheet and reboot; I'd suggest you do the same!
Mikerickson and Jaafar Tribak on MrExcel.com figured it out:
https://www.mrexcel.com/forum/excel-questions/1054446-detect-button-press-event-excel-sheet-multipage-form-not-vba-userform-multipage-2.html
Big thanks to both of them!

Global worksheet variable for userform in excel

I am building a userform that adds data to a worksheet. I have a bunch of sub-routines for my userform, but I'm having issues accessing the variable I set to my worksheet. It's currently a local variable (in a sub) and have tried placing it in a module as discussed here: Can a worksheet object be declared globally in Excel VBA. I've done some further searching but didn't quite get the results I wanted.
I'm quite new to VBA and new to programming in general. I've used Excel quite a bit and want to do more by creating macros and such using VBA. Here's the code I'm currently using:
sub savebutton_click()
Dim trees As Worksheet
Set trees = ThisWorkbook.Sheets("Sheet1")
trees.Cells(1, 1) = Me.TextTreeName
trees.Cells(1, 2) = Me.TextTreeType
End sub
Obviously I cannot access local variables from another subroutine, so I have to make 'trees' global. I created a module and replaced Dim with Public, placed the second line of code in Workbook_Open(), and then tried accessing the 'trees' variable. I get an "Invalid outside procedure" and highlights the code in Workbook_Open() when I hit 'Debug'.
Essentially I just want to be able to access, say, trees.Cells(5,6) from any sub and I'm not sure what else to do with it. Any ideas? Thank you!
It must be a matter of placement ... if you open the VBA IDE and select the ThisWorkbook item in your VBAProject. Double click that item to open it, Select Workbook in the top left dropdown, Select Open in the top right dropdown. This will create your Workbook_Open Sub in the ThisWorkbook object:
Private Sub Workbook_Open()
Set trees = ThisWorkbook.Sheets("Sheet1")
End Sub
Right click your VBAProject and Add Module. In that module you put the global variable:
Public trees As Worksheet
Next you create your form, put the button on that and double click the button. This will generate the button event:
In my case:
Private Sub CommandButton1_Click()
trees.Cells(1, 1) = Me.TextTreeName
trees.Cells(1, 2) = Me.TextTreeType
End Sub
Now if you close the Excel Workbook (save the code and the workbook first) and reopen the Workbook the Workbook_Open() will kick in and set the Worksheet. Now call your Form, and click the button. This will fill the two cells on the given sheet....

Keeping ComboBox Lists Populated

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

VBA Macro Coding

I've been trying to make a Macro, but I'm having trouble figuring it out. Here's what it should do.
Macro function: When the macro is used it should switch to either a sheet called "Products" only if the current tab is NOT the "Products" tab, and if the current tab is the "Products" tab is should go to the previously visited tab.
Use: Let's say I'm on sheet index 3 and use the macro--it should activate the "Products" tab, and if I press it again it should return me to sheet index 3.
I've been trying to use ActiveSheet.Index and Sheets("Products").Index in some way, but I think I need to use something beyond my current knowledge of Visual Basics. I haven't used the Public function when declaring global variables and passing information between stuff much either.
Can someone point me in the right direction or tell me what I should use/look into? Is this even possible in VBA?
What you want is a global variable. Make a module and put in a global variable like such:
Global GblPreviousSheetName As String
Then, in ALL of your sheets, put the following code:
Private Sub Worksheet_Deactivate()
GblPreviousSheetName = Me.Name
End Sub
This will capture whenever a user or code changes sheets and set the Global variable to that sheet name.
Then, in your procedure, do this:
Public Sub Test()
If GblPreviousSheetName = "" Then
GblPreviousSheetName = "Sheet1" 'Put default sheet here (for first time workbook opens)
End If
'Run whatever code you want.
ActiveWorkbook.Sheets(GblPreviousSheetName).Activate
End Sub
Note that if the user changes sheets before pressing your button, it will log this too. If you only wish to log the changes that are made by your code, then instead of putting in the "Worksheet_Deactivate" code, then just set the global variable in your code.

VBA cannot find my macro when it has parameters

I am trying to write a macro that will be attached to a series of buttons in an Office 2010 backstage tab. Depending on the button clicked the Macro should be called with different parameters.
The issue I am having is that if the Macro is defined as having parameters then VBA will display the "Macros" dialog box, with no Macros listed. Removing the parameters from the declaration will allow the macro to run, but it needs the Macros to make sense.
The VBA being used is below:
Sub NewDocs(docType As String, docTemplate As String)
Dim sMyShellCommand As String
sMyShellCommand = "C:\NewDocs.exe " & docType & docTemplate
WordBasic.Shell (sMyShellCommand)
End Sub
Any ideas
If I've got your question right....
Because there is no place in the Macros dialog box for entering parameters, the macros with parameters are simply not shown.
If you want to make them visible in the dialog box, you can enumerate those functions you need (and I hope it is not a big number).
For example,
Sub NewDocs1
Dim docType As String
Dim docTemplate As String
docType = "the type you want"
docTemplate = "the template you want"
NewDocs docType, docTemplate
End Sub
In addition, as you said in the question, you wanted the macro to run when buttons were pressed. Then there is no need to make the macro visible in the dialog box (which saves your labor). Simply associate it with the button with correct parameters.
You can pass arguments from the Macro dialog. For example, if you have this macro
Sub myMacro(n As Long)
MsgBox n
End Sub
To run it, enter
mymacro 1000
... and press the Run button.
You can't call functions or subs with parameters from UI components, just subs without parameters. The best solution is to create a parameter free sub for each button you need to associate with, and call the parameterized sub or function from inside each sub