Assign workbook to variable - excel

I want to set ActiveWorkbook to a variable When workbook opens simultaneously ActiveWorkbook assign to a variable and that variable i can use in whole VBA excel project.
I tried to assigned in ThisWorkbook excel object on Workbook_open() function but it does not work.I provide that code below.
Private Sub Workbook_Open()
On Error Resume Next
Set WRBK = ActiveWorkbook
#If Mac Then
#Else
'unprotectVBProjProp
UnlockVBA ' Sujith ID: 12482
AddReferences ' Sujith ID: 12482
' protectVBProjProp
#End If
'MsgBox "xla Workbook opened"
Set eventInstance = New bwEvents
End Sub
So how can i set activeworkbook to a variable??

I am not so sure what are all the commands in the middle, like #If Mac Then , and UnlockVBA.
If you want to set the ActiveWorkbook to object WRBK, you will need to define WRBK in a regulare module as Public, and then use something like the code below:
Code in ThisWorkbook Module
Private Sub Workbook_Open()
Set WRBK = ActiveWorkbook
TestWorkbookName ' call sub <-- this is just to test the the workbook was assigned correctly
End Sub
Code in Regular Module
Option Explicit
Public WRBK As Workbook
Sub TestWorkbookName()
MsgBox WRBK.Name
End Sub

Related

Check if Workbook variable has been set

I have a sub with an optional workbook argument. I want an If to check whether that variable was passed, and if not set the variable to the active worksheet.
Sub SaveWorkbook(NewPathName As String, Optional Workbook As Workbook)
'This is very simplified, the real thing has various other parameters
If IsNull(Workbook) Then Set Workbook = ActiveWorkbook
'Then loads more stuff
End Sub
Things I have tried include:
IsNull(Workbook)
IsEmpty(Workbook)
Workbook = Nothing
None trigger the If statement so the code attempts to continue with Workbook set to Empty, and then hits errors.
Do not use the word "Workbook" as the variable name. Try it like this:
Sub SaveWorkbook(NewPathName As String, Optional wb As Workbook)
If wb Is Nothing Then
MsgBox "workbook not set"
Set wb = ActiveWorkbook
End If
MsgBox wb.Name
End Sub
In VBA the isMissing function only works, if you declare the parameter as Variant. See in the description
This should work:
Sub SaveWorkbook(NewPathName As String, Optional Workbook As Variant)
'This is very simplified, the real thing has various other parameters
If isMissing(Workbook) Then Set Workbook = ActiveWorkbook
'Then loads more stuff
End Sub

UserForm_Initialize - Need help troubleshooting Run-time error '91: Object variable or With block variable not set

I can't seem to figure out why my UserForm code fails at the very end of the procedure. The end result is perfect. Here is what I'm trying to accomplish...
1) Using the active workbook, the procedure identifies the sheet names in the workbook and displays them in the Listbox, which is located on the userform.
UserForm Pic
2) Once the sheet is selected, the user will click the "Select Sheet" CommandButton
3) The CommanButton activates the sheet, renames the sheet to "LegacyBillHist"
4) The form closes, and cell A2 is selected
I get the Run-time error 91 message on the very last line.
I've tried a few different approaches to resolve the issue, but I can't seem to figure this one out using the info in StackOverflow and other sites. Any help would be greatly appreciated.
Here is the code..
Option Explicit
Private Sub CommandButton1_Click()
Worksheets(ListBox1.Value).Activate
ActiveSheet.Name = "LegacyBillHist"
Unload BillSelect
End Sub
Public Sub UserForm_Initialize()
Dim wb As Workbook
Dim sh As Worksheet
Set wb = ActiveWorkbook
For Each sh In wb.Sheets
ListBox1.AddItem sh.Name
Next sh
Load BillSelect
BillSelect.Show
sh.Range("A2").Select
End Sub
Mathieu
Great info. I ended up changing my approach significantly. However, I have a different problem that I haven't been able to figure out. Here is the Code...I got it from the article you referenced...
Option Explicit
Private cancelled As Boolean
Public Property Get IsCancelled() As Boolean
IsCancelled = cancelled
End Property
Private Sub CommandButton2_Click()
OnCancel
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = VbQueryClose.vbFormControlMenu Then
Cancel = True
OnCancel
End If
End Sub
Private Sub OnCancel()
cancelled = True
Hide
End Sub
Private Sub CommandButton1_Click()
Dim wb As Workbook
Dim ws As Worksheet
Worksheets(ListBox1.Value).Activate
ActiveSheet.Name = "LegacyBillHist"
Set wb = ActiveWorkbook
Set ws = wb.Sheets("LegacyBillHist")
ws.Activate
ws.Range("A1").Select
UserForm1.Hide
End Sub
Private Sub UserForm_Initialize()
Dim wb As Workbook
Dim lastSheet As Worksheet
Dim sh As Worksheet
Set wb = ActiveWorkbook
For Each sh In wb.Worksheets
ListBox1.AddItem sh.Name
Set lastSheet = sh
Next
UserForm1.Show
End Sub
Everything works great up to the End Sub under the CommandButton1 routine. Instead of hiding UserForm1, it reopens the form.
I tried incorporation the code you provided, but it keeps cycling through until I get the Out of stack space error 28. Perhaps I'm not putting it in the correct sequence.
Private Sub UserForm_Initialize()
Dim wb As Workbook
Dim lastSheet As Worksheet
Dim sh As Worksheet
Set wb = ActiveWorkbook
For Each sh In wb.Worksheets
ListBox1.AddItem sh.Name
Set lastSheet = sh
Next
With New UserForm1'<~ forms are objects too; avoid using their global state
.Show
End With
End Sub
Appreciate all the help.
For Each sh In wb.Sheets
ListBox1.AddItem sh.Name
Next sh
The object sh only ever makes sense inside the For...Next loop.
In theory, as per language specifications, sh should indeed still hold a reference to the last item in the iterated collection:
When the <for-each-statement> has finished executing, the value of <bound-variable-expression> is the data value of the last element in <collection>.
https://learn.microsoft.com/en-us/openspecs/microsoft_general_purpose_programming_languages/MS-VBAL/b132463a-fd25-4143-8fc7-a443930e0651
However it appears when VBA was implemented, that bullet point wasn't: a For Each variable that is Nothing before the loop, will still be Nothing after the loop - and any member call made against Nothing will always raise error 91.
To be honest, I think it's better that way, too: it forces your code to be more explicit:
Dim lastSheet As Worksheet
Dim sh As Worksheet
For Each sh In wb.Worksheets '<~ note: 'Sheets' collection can have charts, not just worksheets
ListBox1.AddItem sh.Name
Set lastSheet = sh
Next
With New BillSelect '<~ forms are objects too; avoid using their global state
.Show
End With
lastSheet.Activate
lastSheet.Range("A1").Select
Note: Newing-up the BillSelect can surface hidden bugs in your form code, read this article for more info.
The Initialize handler shouldn't be doing this work, especially if you don't New up the form and use its default instance: you do not control when that default instance gets created, VBA does.
Given this code:
UserForm1.Show
If no code ever referred to UserForm1 before, then the Initialize handler runs at UserForm1, before the reference is returned to the caller and the .Show call runs; if the form's default instance isn't destroyed, then the next time the form is shown, the initialize handler will not run again, because the instance is already initialized.
Consider implementing your logic in the Activate handler instead, which will make the logic run after the .Show call is entered, and every time the form is activated (and since that's a modal dialog, that means every time the form is actually shown).

How to get Workbook Name after opening the workbook using workbooks.open?

Workbooks.Open "C:\abc.xlsx"
Workbooks("abc").Worksheets("Sheet1").Range("A1:B7").Clear
In the above code I am opening the workbook using Workbooks.Open in first line. In the second line I am accessing the opened workbook using the workbook name.
How can I access the opened workbook without the filename in second line?
(I want to create a function and I don't want to pass both the file paths and filenames separately)
You need to use references and reference the workbook and the sheet for example:
Option Explicit
Sub OpenWorkbook()
Dim wb As Workbook, ws As Worksheet
Set wb = Workbooks.Open("C:\abc.xlsx", UpdateLinks:=False, ReadOnly:=True)
Set ws = wb.Sheets("Sheet1")
ws.Range("A1:B7").ClearContents
End Sub
Note that the parameters on the openworkbook such as Updatelinksand ReadOnly can be modified to True or Falseas you need to.
Create an object of type Excel.Workbook and open the workbook into that.
Like so
Dim w as Excel.Workbook
set w= Workbooks.Open ("C:\abc.xlsx")
and then you can say
w.worksheets.add.....
etc
You can shorten your code:
Option Explicit
Sub OpenWb()
Dim ws As Worksheet
Set ws = Workbooks.Open("C:\abc.xlsx").Worksheets("Sheet1")
With ws '<- Use With Statement to avoid sheet repetition
.Range("A1:B7").ClearContents
End With
End Sub
You can try this
Option Explicit
Sub TEST()
Dim WB As Workbook
Set WB = Workbooks.Open(Filename:="C:\abc.xlsx")
For Each WB In Workbooks
If WB.Name = "abc.xlsx" Then
WB.Worksheets(Sheet1).Range("A1:B7").ClearContents
Exit Sub
End If
Next
End Sub

Automatically run macro if the user inserted a new worksheet

I would like my macro to run automatically if it detects that the user inserted a new worksheet into the workbook (existing & new).
Sub macro_run()
Dim Newws As Worksheet
Dim wb As Excel.Workbook
Dim sample1 As Worksheet
With ThisWorkbook
Set sample1 = .Sheets("Template")
For Each wb In Application.Workbooks
If Newws = sample1 Then
Application.Run "PERSONAL.XLSB!Opennew"
End If
Next wb
End With
End Sub
As mentioned in the comments you need to handle WorkbookNewSheet at Application level.
'-- Create a new Class.
'-- Name it clsGlobalHandler.
'-- Following Code goes in that class
'/ Create a variable to hold Application Object
Public WithEvents xlApp As Application
'/ Handle NewSheet event. Invoked whenever a new sheet is added
Private Sub xlApp_WorkbookNewSheet(ByVal Wb As Workbook, ByVal Sh As Object)
MsgBox Sh.Name
End Sub
'-- Create a new module
'-- Following code goes there
Option Explicit
'/ A new instance for the Class that we created.
Dim oGh As New clsGlobalHandler
'/ To start tracking sheet additions call this method first. Most likely in WorkBook_Open
'/ Once called any new sheet across the app insatnce will be intercepted.
Sub SetGlobalHandler()
Set oGh.xlApp = Application
End Sub
'/ Call this to remove the global handler.
Sub ResetGlobalHandler()
Set oGh.xlApp = Nothing
End Sub

excel 2007 Workbook_open not working

I am trying to clear Print Area And Autofilter when excel opens:
Am total novice in Excel vba so Assmebled the followingcode from googling around
This code I have put in ThisWorkbook of Personal.xlsb in the XLstart folder and ofcourse the macro security has been set to enable all macros
Option Explicit
Public WithEvents xlApp As Excel.Application
Private Sub Workbook_Open()
Set xlApp = Application
End Sub
Private Sub Workbook_Close()
Set xlApp = Nothing
End Sub
Private Sub xlApp_WorkbookOpen(ByVal Wb As Workbook)
Application.EnableEvents = False
Call ClrPrntArea
Application.EnableEvents = True
End Sub
Here is the ClrPrntArea
Sub ClrPrntArea()
Dim ws As Object
For i = 1 To ActiveWorkbook.Worksheets.count
With Worksheets(i)
.PageSetup.PrintArea = ""
.PageSetup.FitToPagesWide = 1
End With
Next
End Sub
I will also be putting another macro call to module in personal xlsb for resetting the autofiter once above starts working..Any inputs will be really helpfull
in PERSONAL.xlsb, module ThisWorkbook, try the below; it's nearly the same code as in your request, with some modif's:
application object declared Private
event routine uses the local WB object variable handed over as parameter, instead of the ActiveWorkbook object
replaced For ... Next by For Each ... Next and working with local object variables
trap processing of PERSONAL.xlsb itself
Once you're happy remove all the MsgBox statements (and the Else), they are just to show what is happening and when.
Private WithEvents Excel_App As Excel.Application
' runs when Excel_App encounters a Workbook_Open() event
Private Sub Excel_App_WorkbookOpen(ByVal WB As Workbook)
Dim WS As Worksheet
If WB.Name <> "PERSONAL.xlsb" Then
MsgBox "PERSONAL.xlsb: Excel_App_WorkbookOpen(): " & WB.Name
For Each WS In WB.Worksheets
WS.PageSetup.PrintArea = ""
WS.PageSetup.FitToPagesWide = 1
If WS.FilterMode Then
WS.ShowAllData
End If
Next
Else
MsgBox "PERSONAL.xlsb: Excel_App_WorkbookOpen(): myself"
End If
End Sub
' runs when PERSONAL.xlsb is opened
' assign current Excel application to object variable Excel_App
Private Sub Workbook_Open()
MsgBox "PERSONAL.xlsb: Workbook_Open()"
Set Excel_App = Application
End Sub
Note:
When the event handler doesn't start when you double-click an Excel file (e.g. on your desktop), close all Excel applications and inspect the task manager for additional orphaned Excel processes which need to be killed. It happened to me while playing around with this code

Resources