function "openfile" returning workbook ends with run-time error '91' - vba

I want to open and refer to a workbook via the function below. Only the function produces the run-time error '91': object variable or with block variable not set just before jumping back into the main code.
When I put the exact code (just not as function) into my main code it works perfectly.
But I don't want to have the whole function in my main code because I think it's unnecessary and ugly.
Maybe someone can help me make my code nicer and better comprehensible!
Thank you already!
This is the relevant part of my main sub:
Sub main_sub()
Dim WBtest As Workbook
Dim WBpath As String
WBpath = ThisWorkbook.Sheets("Control").Range("A6").Value 'read path
WBtest = openfile(WBpath) 'I call my function here
End Sub
This is the function that produces the error
The function is supposed to return the (newly) opened workbook
Public Function openfile(path As String) As Workbook 'path is fullpath
Dim wb As Workbook
Dim alreadyopen As Boolean
For Each wb In Workbooks 'loop over all Workbooks
If wb.FullName = path Then 'check if file is already open
alreadyopen = True
Set openfile = wb
End If
Next wb
If alreadyopen = False Then
'file not yet opened --> open it
Set openfile = Workbooks.Open(path)
End If
'MsgBox openfile.name 'this returns the right name
End Function
When I write all of it in my main sub it works (but is ugly, so I don't want it there!)
This works:
Sub main_sub()
Dim WBtest As Workbook
Dim WBpath As String
Dim wb As Workbook 'for loop
Dim alreadyopen As Boolean
WBpath = ThisWorkbook.Sheets("Control").Range("A6").Value 'read path
For Each wb In Workbooks 'loop over all Workbooks
If wb.FullName = WBpath Then
alreadyopen = True
Set WBtest = wb
End If
Next wb
If alreadyopen = False Then
'file not yet opened --> open it
Set WBtest = Workbooks.Open(WBpath)
End If
End Sub
I have a similar problem later in my code, where I want to have a function return a workbook, too. So this seems to be the problem.
How does a function return a workbook?
I have found similar functions returnins worksheets. Those work. Why not with workbooks?
Thank you so much for your help!

The different between both approaches is that, in the first one, you are forgetting the Set bit. Thus, solution:
Set WBtest = openfile(WBpath) 'I call my function here

Related

VBA open workbook, exits code

I try to open a workbook of the type '.xlsm' using
Private Function readFiles(ByVal lv_path As String, ByRef lx_wrkShDes As Worksheet)
'On Error GoTo ErrorHandling
Dim lx_objectExcel As New Excel.Application
Dim lx_wrkBkSrc As Workbook
Dim lx_wrkShSrc As Worksheet
Dim lx_shrPathObj As Object
Dim lv_shrPath As String
Set lx_shrPathObj = CreateObject("scripting.filesystemobject")
lv_shrPath = Replace(lx_shrPathObj.GetFile(lv_path).ShortPath, mv_longFilePathHelper, "")
Set lx_wrkBkSrc = Workbooks.Open(Filename:=lv_shrPath, ReadOnly:=True)
'Using lx_objectExcel.Workbooks.Open WORKS but not Workbooks.Open
'lx_objectExcel.Workbooks.Open(Filename:=lv_shrPath, ReadOnly:=True)
If Not Library.DoesSheetExist(lx_wrkBkSrc, mv_workSheetName) Then
GoTo ErrorHandling
End If
Set lx_wrkShSrc = lx_wrkBkSrc.Sheets(mv_workSheetName)
'Rest of the function
End Function
It opens the workbook and exits the VBA code immediately.
I tried this https://support.microsoft.com/en-us/help/555263, but same results.
It does not exit if I use new instance of Excel using
lx_objectExcel.Workbook.open('path')
I do not want to use a new instance as paste special is not suitable with new instance and opening 100s of Workbooks this way consumes lot of time.
Replace:
Workbook.open('path')
With
Workbooks.Open("PathName")
Referring to the Workbook.Open method, the correct syntax for your action is the following
Workbooks.Open("WorkbookPath")
The following code totally works for me
Dim targetWorkbook As Workbook
Set targetWorkbook = Workbooks.Open("YourWorkbookPath")
You are not using it properly. If this still doesn't work, make sure to send the correct path for your file.
tried this code with 2 xlsm files (MASTER and SLAVE) and it works fine form me. Office 2013
Dim sText As String
Dim objWB As Excel.Workbook
sText = ThisWorkbook.Worksheets("Sheet1").Range("A1").Value
Set objWB = Application.Workbooks.Open(ThisWorkbook.Path & "\SLAVE.XLSM")
objWB.Worksheets("Sheet1").Range("A1").Value = sText
MsgBox "DONE!"

VBA on open workbook exits code? [duplicate]

I try to open a workbook of the type '.xlsm' using
Private Function readFiles(ByVal lv_path As String, ByRef lx_wrkShDes As Worksheet)
'On Error GoTo ErrorHandling
Dim lx_objectExcel As New Excel.Application
Dim lx_wrkBkSrc As Workbook
Dim lx_wrkShSrc As Worksheet
Dim lx_shrPathObj As Object
Dim lv_shrPath As String
Set lx_shrPathObj = CreateObject("scripting.filesystemobject")
lv_shrPath = Replace(lx_shrPathObj.GetFile(lv_path).ShortPath, mv_longFilePathHelper, "")
Set lx_wrkBkSrc = Workbooks.Open(Filename:=lv_shrPath, ReadOnly:=True)
'Using lx_objectExcel.Workbooks.Open WORKS but not Workbooks.Open
'lx_objectExcel.Workbooks.Open(Filename:=lv_shrPath, ReadOnly:=True)
If Not Library.DoesSheetExist(lx_wrkBkSrc, mv_workSheetName) Then
GoTo ErrorHandling
End If
Set lx_wrkShSrc = lx_wrkBkSrc.Sheets(mv_workSheetName)
'Rest of the function
End Function
It opens the workbook and exits the VBA code immediately.
I tried this https://support.microsoft.com/en-us/help/555263, but same results.
It does not exit if I use new instance of Excel using
lx_objectExcel.Workbook.open('path')
I do not want to use a new instance as paste special is not suitable with new instance and opening 100s of Workbooks this way consumes lot of time.
Replace:
Workbook.open('path')
With
Workbooks.Open("PathName")
Referring to the Workbook.Open method, the correct syntax for your action is the following
Workbooks.Open("WorkbookPath")
The following code totally works for me
Dim targetWorkbook As Workbook
Set targetWorkbook = Workbooks.Open("YourWorkbookPath")
You are not using it properly. If this still doesn't work, make sure to send the correct path for your file.
tried this code with 2 xlsm files (MASTER and SLAVE) and it works fine form me. Office 2013
Dim sText As String
Dim objWB As Excel.Workbook
sText = ThisWorkbook.Worksheets("Sheet1").Range("A1").Value
Set objWB = Application.Workbooks.Open(ThisWorkbook.Path & "\SLAVE.XLSM")
objWB.Worksheets("Sheet1").Range("A1").Value = sText
MsgBox "DONE!"

Copy range from workbook to another without open

I'm trying to copy a range of values from a workbook to another by using a dialog box to select the file I'd like to copy the data from.
I'd like also not to open the "copyFrom" workbook in the process. The problem lies in passing the file path in the string "filename" to the workbook variable "copyFrom".
Option Explicit
Private Sub butt_copy_Click()
Call copy1
End Sub
Private Sub copy1()
Dim fileName As String, copyFrom As Workbook
fileName = Application.GetOpenFilename()
copyFrom = filename
Sheet1.Range("A1:A20") = copyFrom.Sheets(Sheet1).Range("A1:A20")
End Sub
Just a comment to add to the algorithm;
It opens the file and reads from it, but does not close. This makes it "READ_ONLY" for all other users!
I suggest that at the end of the code: add this for saving original file unchanged.
Application.DisplayAlerts = False
app.Workbooks.Close savechanges:=False
Application.DisplayAlerts = True
Try Below. But i have some Clarification like where will you run the code from
Application.Visible=False
Set copyFrom = Application.Workbooks.Open(fileName)
Then Try below. Worked Perfectly for me
Private Sub copy1()
Dim app As New Excel.Application
Dim fileName As String, copyFrom As Workbook
app.Visible = False
fileName = app.GetOpenFilename()
Set copyFrom = app.Workbooks.Open(fileName)
MsgBox copyFrom.Sheets(1).Cells(1, 1)
'Sheet1.Range("A1:A20") = copyFrom.Sheets(Sheet1).Range("A1:A20")
End Sub

Referencing External Workbook VBA through Variable and If Statement

Currently my code looks like this and it works fine
Dim WorkbookVar As Workbook
Dim Path As String
Path = "C:\Path.xlsx"
Set WorkbookVariable = Workbooks.Open (Filename:=MCDistroNumberPath)
But I would like it to go a step further and have an if statement saying If this workbook is already open Then skip it and start running the rest of my macro.
How would I go about doing that?
Consider putting it into its own function like below.
Public Function GetOrOpenWorkbook(ByVal sFullPath As String) As Workbook
Dim wbReturn As Workbook
On Error Resume Next
Set wbReturn = Workbooks(Dir(sFullPath))
On Error GoTo 0
If wbReturn Is Nothing Then
Set wbReturn = Workbooks.Open(sFullPath)
End If
Set GetOrOpenWorkbook = wbReturn
End Function
Sub test()
Dim wb As Workbook
Set wb = GetOrOpenWorkbook("C:\Path\Path.xlsx")
End Sub
The Dir function will return just the file name without the path. If a workbook with that name is already open, it will return that workbook. If not, it attempts to open it.

Workbook.Close() causes "Run-time error 9"

I am somewhat new to VBA, and I am trying to make a Sub() which reads data from a different Excel Workbook. It works by opening the workbook, reading from it, and then I would like to close the workbook again. The last part is what causes the following error:
Run-time error '9':
Subscript out of range
I fail to see why I get this error, when trying to close a file. I hope you guys can assits. It works if I comment out the Close() part...
Code
Option Explicit
Sub Test()
Dim Path, Filename
Dim sh1 As Worksheet, sh2 As Worksheet, sh3 As Worksheet, transmitWorkbook As Workbook, revieveWorkbook As Workbook
'Define a variable for the workbook which is to recieve data
Set revieveWorkbook = ActiveWorkbook
Path = "C:\Test Folder\"
Filename = "FileToReadFrom.xlsx"
'Open workbook which is to transmit, if its not already open
If Is_WorkBook_Open(Path & Filename) Then
Set transmitWorkbook = Workbooks(Path & Filename)
Else
Set transmitWorkbook = Workbooks.Open(Path & Filename)
End If
revieveWorkbook.Sheets(1).Range("A1").Value = transmitWorkbook.Sheets(2).Range("F9").Value
revieveWorkbook.Sheets(1).Range("B1").Value = Month(transmitWorkbook.Sheets(2).Range("H9").Value)
Workbooks(Path & Filename).Close SaveChanges:=False
End Sub
As mentioned in a comment by Jeeped, the path name is not used to close workbooks again. The correct code is
Workbooks(Filename).Close SaveChanges:=False
Thanks you everyone for their help.