Use of an if statement with open workbook variable - excel

I am trying to simplify some code, and wondered whether I would be able to use an If statement to set a different open workbook variable, depending on a few conditions of a defined range.
basically something like
dim ws as worksheet: set ws = Thisworkbook.worksheet("worksheet name")
dim r as range: set range = ws.range("A cell which has an if statement in it to display a number based on another cells contents")
dim wb as workbook
this is where I want to vary the actual workbook set as wb
if r.value = 1 then
set wb = Open a workbook
elseif r.value = 2 then
set wb = Open another workbook
Ideally I would then do the same for ws2 which would be the specific worksheet variable for the specified workbook above
Not sure if this method will work and wondered if I was on the right track. I have code which opens a workbook, finds values in various rows, inserts rows, copies cell contents., between two ws variables, etc. And it works, but I need ot add more workbook options and Id rather not have multiple macros with the only difference being the variable for the second workbook to open and work with.

Its OK - tried the above and it seems to work fine - just lacked a bit of confidence I suppose.

Related

How to pass main workbook to another macro function?

I have to macro function, where the second one calls for the first one in the loop.
I want to remember the main workbook and worksheet where the macro function was executed.
I wrote the following code%
Dim main_book As Workbook
Dim main_sheet As Worksheet
Set main_book = ActiveWorkbook
Set main_sheet = ActiveSheet
Dim table1 As Range
MsgBox main_book.Name
Set table1 = main_book.main_sheet.Range("A1", "J2")ˇ
But the last row returns an error, however if I hardcode the name of the workbook and worksheet everything works just fine. Can't find a solution and reason for this error

VBA: multiple workbooks open with similarly named tabs: how to refer to specific workbook?

Say I have two workbooks open with two tabs both named "Tab1". If in VBA, I want to refer to something on a tab, one would say "Tab1!" followed by what one is referring to, e.g. "Tab1!R1C1", etc.
However, how does the code know what Tab1 I am referring to in this case?
If it's worth mentioning, the code I am running is inside one of the workbooks. So will it always default back to that workbooks tab 1? If not, what does it do, and if yes, how would I make it refer to the tab 1 of the other workbook?
For context, I need to do this in the case of calling the method "ChangePivotCache" and give it a SourceData.
Without the code it's difficult to say definitively, but lets assume that you're using a range object. When you put "Tab1!R1C1" into that range object it uses the workbook of it's parent to make the determination. Most (if not all) methods that take a range argument like that will require that some parent of theirs is a workbook or worksheet.
In general if you're working with multiple workbooks best practice is to assign an object to them as you open them. That object can then be used to anchor any range calls you make. Either by calling directly from it or making children from it.
For example:
set workbook_code_is_in = Thisworkbook
set another_workbook = Application.Workbooks.Open(...)
set active_workbook = Activeworkbook
The first line will set workbook_code_is_in to the workbook that the code is located in.
The second line will set another_workbook to whatever you open.
The third line will set active_workbook to whatever workbook currently has focus. This is dangerous and prone to errors. It's very possible for a user to click a different workbook while a script is running and make the Activeworkbook an unintended one.
Referring to a Second Workbook
If you only have two workbooks open, then you refer to the workbook containing this code with ThisWorkbook and you can refer to the other workbook by using a For Each...Next loop to compare the workbooks' names.
Option Explicit
Sub ReferToSecondWorkbook()
Dim wb1 As Workbook: Set wb1 = ThisWorkbook ' workbook containing this code
If Workbooks.Count <> 2 Then
MsgBox "You need to have only two workbooks open.", vbCritical
Exit Sub
End If
Dim wb2 As Workbook
For Each wb2 In Workbooks
If StrComp(wb2.Name, wb1.Name, vbTextCompare) <> 0 Then ' different
Exit For
' Else ' it is 'wb1'
End If
Next wb2
Dim ws1 As Worksheet: Set ws1 = wb1.Worksheets("Tab1")
Dim ws2 As Worksheet: Set ws2 = wb2.Worksheets("Tab1")
Debug.Print "First: ", ws1.Name, wb1.Name
Debug.Print "Second: ", ws2.Name, wb2.Name
End Sub

Sheet declaration goes wrong

I have been using vba for a while and i noticed an annoying bug.
When i use more than 1 sheets in a macro if i set the worksheets everything works just fine until i get an error. After that the worksheet names are messed up and usually uses both declaration for as one sheet.
Dim loc_path, sp_path As String
Dim loc_wb As Workbook
Dim sp_wb As Workbook
Dim loc_ws As Worksheet
Dim sp_ws As Worksheet
loc_path = "path1"
sp_path = "path2"
Set sp_wb = Workbooks.Open(sp_path, ReadOnly:=False)
Set sp_ws = sp_wb.Sheets(1)
Set loc_wb = Workbooks.Open(loc_path, ReadOnly:=False)
Set loc_ws = loc_wb.Sheets(1)
After that i just call another macro and pass the worksheet or sheets. In an example i pass only the sp_ws to the macro and display the first cells value in a msgbox. Before error it works fine, but after an error if i run it again it will display the loc_ws sheets first cells value.
Is there anything wrong with my code or it is just a bug in VBA?

Object Required - With wb.Sheets

I was looking for a way to find data in a column and using google i found this page.
How to find text in a column and saving the row number where it is first found - Excel VBA
and one of the codes i am trying to use what came from that page
With WB.Sheets("ECM Overview")
Set FindRow = .Range("A:A").Find(What:="ProjTemp", LookIn:=xlValues)
End With
i have change the code to fit my sheet but i keep getting an Object Required
i try setting the
Dim ws As Worksheet
Dim wb As Workbook
but then i just get other goofy errors not sure what im doing wrong here
the code im using for my sheet
With wb.Sheets("RR LOG")
Set FindRow = .Range("H:H").Find(What:=ProRRnumber, LookIn:=xlValues)
End With
It looks to me like you may not have set wb as anything.
Before the With statement, try adding code like:
Set wb = ActiveWorkbook
Or, if you want to explicitly assign wb to the name of a workbook, try:
Set wb = Workbooks("Book1.xlsx")
Replace Book1.xlsx with the name of the workbook you are referencing.

Declaring variable workbook / Worksheet vba

I know this might come off as a trivial question, but I can't seem to declare a workbook or a worksheet as a variable in VBA. I have the following code, but I can't figure out what I am doing wrong, it should be straight forward. Normally I don't have any problems declaring variables such as Dim i As Integer etc.
sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheet("name")
wb.ws.Select
End Sub
When I run the above code, I receive a type missmatch error.
Use Sheets rather than Sheet and activate them sequentially:
Sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheets("Sheet1")
wb.Activate
ws.Select
End Sub
If the worksheet you want to retrieve exists at compile-time in ThisWorkbook (i.e. the workbook that contains the VBA code you're looking at), then the simplest and most consistently reliable way to refer to that Worksheet object is to use its code name:
Debug.Print Sheet1.Range("A1").Value
You can set the code name to anything you need (as long as it's a valid VBA identifier), independently of its "tab name" (which the user can modify at any time), by changing the (Name) property in the Properties toolwindow (F4):
The Name property refers to the "tab name" that the user can change on a whim; the (Name) property refers to the code name of the worksheet, and the user can't change it without accessing the Visual Basic Editor.
VBA uses this code name to automatically declare a global-scope Worksheet object variable that your code gets to use anywhere to refer to that sheet, for free.
In other words, if the sheet exists in ThisWorkbook at compile-time, there's never a need to declare a variable for it - the variable is already there!
If the worksheet is created at run-time (inside ThisWorkbook or not), then you need to declare & assign a Worksheet variable for it.
Use the Worksheets property of a Workbook object to retrieve it:
Dim wb As Workbook
Set wb = Application.Workbooks.Open(path)
Dim ws As Worksheet
Set ws = wb.Worksheets(nameOrIndex)
Important notes...
Both the name and index of a worksheet can easily be modified by the user (accidentally or not), unless workbook structure is protected. If workbook isn't protected, you simply cannot assume that the name or index alone will give you the specific worksheet you're after - it's always a good idea to validate the format of the sheet (e.g. verify that cell A1 contains some specific text, or that there's a table with a specific name, that contains some specific column headings).
Using the Sheets collection contains Worksheet objects, but can also contain Chart instances, and a half-dozen more legacy sheet types that are not worksheets. Assigning a Worksheet reference from whatever Sheets(nameOrIndex) returns, risks throwing a type mismatch run-time error for that reason.
Not qualifying the Worksheets collection is an implicit ActiveWorkbook reference - meaning the Worksheets collection is pulling from whatever workbook is active at the moment the instruction is executing. Such implicit references make the code frail and bug-prone, especially if the user can navigate and interact with the Excel UI while code is running.
Unless you mean to activate a specific sheet, you never need to call ws.Activate in order to do 99% of what you want to do with a worksheet. Just use your ws variable instead.
Third solution:
I would set ws to a sheet of workbook wb as the use of Sheet("name") always refers to the active workbook, which might change as your code develops.
sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
'be aware as this might produce an error, if Shet "name" does not exist
Set ws = wb.Sheets("name")
' if wb is other than the active workbook
wb.activate
ws.Select
End Sub
Just coming across the same problem.
What you need to do is to declare ws as Object
Also it should be:
Set ws = wb.Sheets("Sheet1")
And should not be:
Set ws = Sheet("Sheet1")
The code below are working to me.
sub kl()
Dim wb As Workbook
Dim ws As Object
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
MsgBox ws.Name
End Sub
Try changing the name of the variable as sometimes it clashes with other modules/subs
Dim Workbk As Workbook
Dim Worksh As Worksheet
But also, try
Set ws = wb.Sheets("name")
I can't remember if it works with Sheet
to your surprise, you do need to declare variable for workbook and worksheet in excel 2007 or later version. Just add single line expression.
Sub kl()
Set ws = ThisWorkbook.Sheets("name")
ws.select
End Sub
Remove everything else and enjoy.
But why to select a sheet? selection of sheets is now old fashioned for calculation and manipulation.
Just add formula like this
Sub kl()
Set ws = ThisWorkbook.Sheets("name")
ws.range("cell reference").formula = "your formula"
'OR in case you are using copy paste formula, just use 'insert or formula method instead of ActiveSheet.paste e.g.:
ws.range("your cell").formula
'or
ws.colums("your col: one col e.g. "A:A").insert
'if you need to clear the previous value, just add the following above insert line
ws.columns("your column").delete
End Sub
I had the same issue. I used Worksheet instead of Worksheets and it was resolved. Not sure what the difference is between them.
Dim ws as Object
Set ws = Worksheets("name")
when declaring the worksheet as worksheet instead of an ojbect I had issues working with OptionButtons (Active X) in this worksheet (I guess the same will be with any Active-X element. When declared as object everything works fine.
Lots of answers above! here is my take:
Sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set ws = Sheets("name")
Set wb = ThisWorkbook
With ws
.Select
End With
End Sub
your first (perhaps accidental) mistake as we have all mentioned is "Sheet"... should be "Sheets"
The with block is useful because if you set wb to anything other than the current workbook, it will ececute properly

Resources