Global worksheet variable for userform in excel - vba

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....

Related

Use a part of macro code independently

I have one doubt!
I have a code for consolidation of 22 sheets in a workbook.
Now I want to prepare separate buttons for each sheet so that if the user wants they can consolidate only sheets required by them and not all 22 sheets.
I only know the way by creating 22 separate module having part of the codes related to each sheet. Is there any other concise way to do it which do not make me prepare 22 separate modules?
Code example:
sheets("AT").select
"whatever code that was required"
Sheets("DE").select
"whatever code that was required"
and so on....
Do let me know if question is not clear.
You only need a single module. When you click a button on a sheet it will be on the activesheet. Therefore you will only need to act on the activesheet and not every sheet in the workbook.
If I was doing the job I would create a userform with a List of worksheet names that the user can select and then the module will step through each selected worksheet name in the list and do whatever actions you need. A checkbox for whole workbook action would also be useful.
Make a new Userform with a commandbutton and also a list box called "myListBox" and ensure that the MultiSelect property is set to multi and not single then add the following code. This will step through each sheet in the workbook and adds the name to the listbox. Once you select a number of names and click the command button it will print the selected names to the Immediate window
Private Sub UserForm_Initialize()
Dim wks As Worksheet
For Each wks In ActiveWorkbook.Worksheets
Me.myListBox.AddItem wks.Name
Next
End Sub
Private Sub CommandButton1_Click()
For i = 0 To myListBox.ListCount - 1
If myListBox.Selected(i) Then
Debug.Print myListBox.List(i)
End If
Next i
End Sub

VBA is skipping code when a userform reference is reached? Attempting to write to another wbk

I'm using a userform to collect data and add it to an empty line in a workbook.
Structure of code is as follows:
Main sub s_OpenWriteToTargetFile is called from userform mainForm.
It checks availability of the target workbook.
It opens the target workbook.
It calls sub "s_WriteLines". Everything is OK up to this point.
Sub s_WriteLines should load textbox values from mainForm into various variables and paste them into the target workbook.
For some reason, code execution jumps out of s_WriteLines as soon as it reaches With MainForm..., and it returns to the mother sub.
s_WriteLines sub
Sub s_WriteLines
Dim a,b as integer
With mainForm
a = .tb_a.Value
b = .tb_b.Value
End With
End Sub
I can't wrap my head around it. Does this have something to do with the modality of the userform?
As AcsErno suggested in the comments, there was a on error resume next that I didn't notice, and it kept me from learning that the form is failing to load a rowsource property of a combobox.
The rowsource was specified as follows:
mainForm.cb_Wiresize.RowSource = wiresizesWSheet.Name & "!" & wiresizesFinalRange.Address
The workbook that is opened to be written in also becomes active, and then the range that I specified as rowsource refers to a worksheet that doesn't exist - because I specified it only as "worksheet + range", instead of "workbook + worksheet + range".
To expand on my question, how can I refer to the specific workbook object using the syntax posted above? I tried different formulations but none worked.

Cannot close workbook after running sub with userform

I have a macro that opens a userform to capture a start and end date. After clicking OK on the userform, a file dialog box opens to select an Excel Workbook to open.
Immediately after I run the below sub, I can't close the workbook that is opened by using the 'X' in the top-right corner. I also can't save the workbook by clicking the save icon.
However, if I click on another workbook or switch to a different sheet in the workbook that was opened, and then click back to the one opened by the sub everything works as it's supposed to.
Also, I replace the userform with two input boxes, to capture each of the two dates, I am able to close the workbook that is opened with no issue.
Maybe there's something funny with the userform code?
This is all that is in the userform.
Private Sub Ok_button_Click()
call module1.forecast
unload userform1
end Sub
And this is the main sub.
Sub forecast()
dim start_SFY as long
dim end_SFY as long
dim filesToOpen as object
dim wb as workbook
Application.ScreenUpdating= False
start_SFY = userform1.textbox1.value
end_SFY = userform1.textbox2.value
set filesToOpen = application.fileDialog(msoFileDialogOpen)
filesToOpen.show
set wb = application.workbooks.open(filesToOpen.selecteditems(1),false)
Application.ScreenUpdating= True
End Sub
Here's the sub showing userform1
Sub run_userform()
userform1.show
End Sub
Also, here is the Excel version:
Excel 2013 64-bit (15.04753.1003) Part of Microsoft Office 365 ProPlus
Can someone maybe try to replicate the issue that I'm having? I'm wondering if this is an issue related to my employer's version of Excel or something?
This sort of thing has never happened to me before.
Also, I can close the program with VBA. It's just when trying to click the 'X' that it won't close.
Update:
I was able to get the code, with no changes, to work fine at home on Excel 2016. I'm going to get a coworker to test on their system today.
When I was home, I didn't put a button to call the sub on a worksheet. I called it from the VBA editor. After some testing this morning, it seems that the button is the issue. If I call the sub from the VBA editor, I can close the opened workbook. However, if I use a command button (form control, not ActiveX as I get an error saying, "Cannot draw object" whenever I try to add any kind of ActiveX object to a worksheet) the opened workbook will not close.
I think I have found the problem
This issue seems to be with the 'form control command button'. ActiveX was disabled in the Trust Center. When I enabled it and created a command button, I was able to close the opened workbook. I then tried the command form button again, and could not close the opened workbook. I was also successfully able to close the opened workbook when I ran the sub from the sub listbox in the developer tab, and when I place the sub in the Excel Ribbon and ran it from there.
Any idea as to why the control form command button would cause this issue?
The root of the problem is the change to using multiple excel interfaces in 2013. Microsoft addresses the issue in the Solutions for SDI Issues section of this page.
A workbook cannot be closed by clicking the red "X" Close button when
that workbook is programmatically opened via a modal user form. To
work around this issue, it is suggested that you add the following
code to the user form Layout event procedure and then open the user
form as modeless
Private Sub UserForm_Layout()
Static fSetModal As Boolean
If fSetModal = False Then
fSetModal = True
Me.Hide
Me.Show 1
End If
End Sub
Another option is to open the workbook window, activate any other
window, and then reactivate the workbook window. You should now be
able to close the workbook using the Close button.
So these are the two options they present and one I came up with.
Option 1) You can switch your dialog to modeless using their code, or by setting the ShowModel property to false in your userform.
Option 2) As you discovered, manually switching between workbooks after opening via modal userform resyncs everything. Not a good solution for the users of my code, and I don't recommend relying on it.
Option 3) It's worth mentioning, if you don't open the file via the userform then there's no issue. So if last thing the userform needs to do is open the file, you can easily save the file path in a string, unload the troublesome userform and move the workbooks.open call after closing. Here's an example of what I mean
Public EDIT_FILE_DIRECTORY As String
Public Sub Main()
fileOpenerForm.Show
If EDIT_FILE_DIRECTORY <> "" Then
Call Workbooks.Open(EDIT_FILE_DIRECTORY)
End If
End Sub
And in the userform something along these lines, where the filename is created based on userform parameters and a listbox selection:
Private Sub OpenSelectedWorkbooks_Button_Click()
Dim workbookName As String
workbookName = selectionList.Item(Me.FileSelection_ListBox.ListIndex + 1)
EDIT_FILE_DIRECTORY = ROOT_DIR & GetSelectedSubfolder & "\" & workbookName
Unload Me
End Sub
Try fileOpenerForm Show 0 to open open it with Modal = False (Makes the macro run while the Userform is visible)
Do not forget to add fileOpenerForm.Hide later on.
Also Load fileOpenerForm and Unload fileOpenerForm may be useful

Dialog box that selects a worksheet in Excel

I'm trying to build a macro that will duplicate a worksheet from one workbook into a worksheet in another workbook. Is there a way I can use VBA code to allow me to manually select which worksheet I shall be duplicating?
Right now the macro works, as long as I have the full worksheet name typed into the actual VBA code. Ideally, I'd like the macro to allow me to select the worksheet through a dialog box. I know you can just copy/paste the sheet or its contents, but the guys I'm working for don't want to do that, due to the size.
You can use Worksheets collection to populate the ListBox in a user form. This should get you started:
Code in the user form (!):
Private Sub UserForm_Initialize()
Dim v As Worksheet
For Each v In Worksheets
UserForm1.lstWorksheets.AddItem v.Name
Next
End Sub
Private Sub cmdSelectWorksheet_Click()
MsgBox "You selected " & lstWorksheets.Value
End Sub

VBA Select a sheet when the workbook is opened

The following program doesn't work when I open my workbook. What are the possible reasons?
' Select the first sheet when the workbook is opened.
Private Sub Workbook_Open()
Sheet4.Select
Sheet4.Range("B1").Select
End Sub
If you hit alt+F11 to go to the VBA code editor. On the left side, under the file name you will see the different sheets, and whatever modules you might have in there. If you go under the ThisWorkbook module
and place your code there, it will automatically run when you start up the Excel File.
you are using the "Select" Method without an Activating a Sheet First!
Yes, when you have closed your workbook last time, the current sheet will remain in the memory index and when you will again open the same workbook, the pointer search for the most recent sheet used based on the index no.
'Here is the code
Private Sub Workbook_Open()
Sheet4.Activate
Sheet4.Select
Sheet4.Range("B1").Select
End Sub
using "Select Method" without Activating the Parent Object is a Crime. lol
Hope this will help you.