VBA Workbook.Open(File) returns Nothing - vba

EDIT: After lots of help and not having a clue what's going on, it worked using a different method of opening (see #JohnMuggin's help below)--so I un-commented my original code and suddenly it works.
I've only found one other instance of Workbook.Open("file") returning nothing (Link to Q). However, their problem was because of calling Workbook.Open("file") in a user-defined function (to my understanding). Here, I am calling it in a Sub, but am having the same issue and can't find a solution. I am using Excel 2013.
Private Sub CommandButton2_Click()
'Set variables
Dim wb As Workbook 'Workbook to open
Dim wbR As Worksheet 'This is the raw data on the new workbook
Dim wsL As Worksheet 'Worksheet in current file
Dim myFile As String 'File to open
Dim FilePicker As FileDialog
'Set light chain hit worksheet
Set wsL = ThisWorkbook.Worksheets(3)
'Optimizes Speed
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FilePicker = Application.FileDialog(msoFileDialogFilePicker)
'Opens folder-picking window
With FilePicker
.Title = "Select a file."
.AllowMultiSelect = False
If .Show = True Then
myFile = .SelectedItems(1)
Else: GoTo NextCode
End If
End With
'If folder is not selected
NextCode:
myFile = myFile
If myFile = "" Then GoTo ResetSettings
'Set variable equal to opened workbook
Set wb = Workbooks.Open(myFile)
The macro continues, but the last line Set wb = Workbooks.Open(myFile) sets wb as Nothing. This does not produce any errors until I call wb farther down in the code.
An earlier line, Set wsL = ThisWorkbook.Worksheets(3), also sets wsL as Nothing.
I have checked each line and values using the debugger, and have determined myFile is the proper path, file name, and extension.

If you have a copy of the workbook open (in a different folder) with the same name as the one your VBA is trying to open, it fails silently. The ActiveWorkbook solution appears to work - as you have at least one workbook open already - and that is active - but its not the one you think it is.
I imagine it it could be a common mistake - as while developing a VBA project you might have a copy of the target workbook open to check on column numbers etc.

And at the very last try this little sub. If it doesn't open your workbook then there is a problem with the path or filename
Sub opendfghj()
Dim wb As Workbook
Workbooks.Open Filename:="C:\Users\User\Desktop\Templates and Example data\Repeat Tests\file.xlsx"
Set wb = ActiveWorkbook
wb.Worksheets("Sheet1").Range("A1") = "It Works"
End Sub

Related

Opening workbook from file and updating link in original workbook

I'm trying to write a macro in VBA, that will open another Workbook using a PathFile specified in a cell (this works), updates link in workbook in which macro is used (doesn't work) and closes the PathFile workbook (works)
This is a code:
Sub UpdateRaw()
Dim CurrWb As Workbook
Dim FilePath As String
Dim book As Excel.Workbook
Set CurrWb = ActiveWorkbook
FilePath = Range("I1").Value
Dim app As New Excel.Application
app.Visible = True 'so we can see whether correct file is being opened
Set book = app.Workbooks.Open(FilePath)
CurrWb.Activate
Worksheets("Raw_vs_Actual").EnableCalculation = False
Worksheets("Raw_vs_Actual").EnableCalculation = True
book.Close SaveChanges:=False
app.Quit
Set app = Nothing
End Sub
Going step by step I found that command CurrWb.Activate doesn't take me back to my original Workfile. My suspicion is that by opening new Excel Application I can't get back to the CurrWb (ActiveWorkbook). Is there a workaround? I need this so my INDIRECT function doesn't return #REF.
I'm using Excel 2010 in case it's important.
I think Set book = app.Workbooks.Open(FilePath) shall be enough, but if not refresh the workbook:
book.RefreshAll
for opened workbook. For the workbook that contains the macro, use
ThisWorkbook.RefreshAll

How to open document from Macro without Activating

I've been working on a macro where at one point I need to open a document, copy and edit some data, and then return to the previous document to continue with the Macro. I have a fileDialog that I run to let the user choose the document, but the problem is that this then activates the document, causing the screen to flash even with ScreenUpdating off. Is there an alternative to Workbooks.Open I can use that won't activate the new document? A setting in Workbooks.Open I can change to prevent it from activating? A way to stop the screen from flashing upon the document activating? Here is the code for the fileDialog and a few lines on each side:
Set fileDialog = Application.fileDialog(msoFileDialogFilePicker)
Application.ScreenUpdating = False
With fileDialog
.InitialFileName = "C:\Users\User\Documents"
.AllowMultiSelect = False
.Filters.Clear
.Title = dialogTitle
If .Show = False Then
Application.ScreenUpdating = True
MsgBox "No file chosen. Click Import Contact List to try again."
Exit Sub
End If
strPathFile = .SelectedItems(1)
End With
Set wbSource = Workbooks.Open(Filename:=strPathFile)
Any solution would be greatly appreciated.
My assumption is that you want to let the user open a file, leave it open, but make your workbook active afterwards so the opened file remains "in the background" for the user to navigate to later on. You've noticed some annoying flicker and came here for answers.
The only way I could reproduce the behavior you describe, with code similar to yours, is when I opened a file that was already opened in the same Excel session (see 3rd use case below). Notice that your code doesn't close the just opened workbook, so the first time you run it, you're in use case 2 below, and the second time you run it, you're in use case 3 below.
If, however, you can close the workbook at the end of your process, you'll be in the 1st use case below and all should be fine.
Let's see if anybody can come up with solutions to use cases 2 and 3.
This first use case typically doesn't introduce flicker:
Application.ScreenUpdating = False
Application.EnableEvents = False 'For good measure.
Set myWb = Application.Workbooks.Open("... path of some workbook that's not already open ...")
'... Do stuff ...
myWb.Close
Application.EnableEvents = True
Application.ScreenUpdating = True
I can't make the other 2 use cases below behave as desired.
Second use case is when the workbook must be left opened at the end of the process described above, but not active, all without any flickering. Whatever I've tried, the opened workbook becomes the active one upon leaving the code:
Application.ScreenUpdating = False
Application.EnableEvents = False 'For good measure.
Set myWb = Application.Workbooks.Open("... path of some workbook that's not already open ...")
'... Do stuff ...
'myWb.Close 'Here, the workbook is left opened.
ThisWorkbook.Activate 'Trying...
Application.EnableEvents = True
Application.ScreenUpdating = True
ThisWorkbook.Activate 'Trying harder...
'Be my guest...
'Note: Application.OnTime eventually calling ThisWorkbook.Activate doesn't count!
Third use case is an oddity and probably what happens to OP. Take the second use case above but open a workbook that's already opened in the same Excel instance. After a flicker even though ScreenUpdating = False during the operations (not cool), the code will leave with ThisWorkbook as the active one (cool!) .
I've tried playing with myWb.Windows(1).Visible = False, DoEvents, you name it, to no avail. Your comments are welcome.
EDIT (3 years later)
A dirty workaround is to open the workbook, then immediately set its IsAddin property to True. This will remove it from Excel's UI and leave the workbook with executing code at the front, no matter what. The caveat is you now have to manage the opened workbook's visibility (e.g. setting IsAddin = False when the user wishes to see it) and lifetime (e.g. closing it when exiting your application's workbook). But it's doable.
On opening a workbook, you can hide the workbook or activate ThisWorkbook in order no to show the just opened workbook.
Sub OpenAndHide()
Dim wbSource As Workbook
Dim FileDialog As FileDialog
Dim dialogTitle As String
Dim strPathFile As String
Set FileDialog = Application.FileDialog(msoFileDialogFilePicker)
dialogTitle = "Open And Hide"
With FileDialog
.InitialFileName = "C:\Users\User\Documents"
.AllowMultiSelect = False
.Filters.Clear
.Title = dialogTitle
If .Show = False Then
Application.ScreenUpdating = True
MsgBox "No file chosen. Click Import Contact List to try again."
Exit Sub
End If
strPathFile = .SelectedItems(1)
End With
Set wbSource = Workbooks.Open(Filename:=strPathFile)
ThisWorkbook.Activate
'// Hide the workbook
'strPathFile = GetFilenameFromPath(strPathFile)
'Windows(strPathFile).Visible = False
End Sub
Function GetFilenameFromPath(ByVal strPath As String) As String
' Returns the rightmost characters of a string upto but not including the rightmost '\'
' e.g. 'c:\winnt\win.ini' returns 'win.ini'
If Right$(strPath, 1) <> "\" And Len(strPath) > 0 Then
GetFilenameFromPath = GetFilenameFromPath(Left$(strPath, Len(strPath) - 1)) + Right$(strPath, 1)
End If
End Function
You can try
Set wbSource = Workbooks.Open(Filename:=strPathFile)
Workbooks(name of users workbook).Activate
or
Set wbSource = Workbooks.Add(trPathFile)
Hope it helps.

VBA error '91' - cannot find source of error

I'm trying to open a file to access information in the third worksheet. The .FileDialog works fine and I can select a file, but I keep getting run-time error '91' because of the line Set wbR = wb.Worksheets(3) near the bottom of this section of code because wb.Worksheets(3) = <Object variable or With block variable not set>. This leads me to believe my Set wb = Workbooks.Open(myFile) does not work and returns Nothing, but after looking through how other people have opened files using .FileDialog, I can't see how mine is different and wouldn't function. Any help or advice would be much appreciated.
'Set variables
Dim wb As Workbook 'Workbook to open
Dim wbR As Worksheet 'This is the raw data on the new workbook
Dim wsL As Worksheet 'Worksheet in current file
Dim myFile As String 'File to open
Dim FilePicker As FileDialog
'Set light chain hit worksheet
Set wsL = ThisWorkbook.Worksheets(3)
'Optimizes Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve target file
Set FilePicker = Application.FileDialog(msoFileDialogFilePicker)
'Opens folder-picking window
With FilePicker
.Title = "Select a file."
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myFile = Dir(.SelectedItems(1))
End With
'If folder is not selected
NextCode:
myFile = myFile
If myFile = "" Then GoTo ResetSettings
'Set variable equal to opened workbook
Set wb = Workbooks.Open(myFile)
'Ensure Workbook has opened before moving on to next line of code
DoEvents
'Sets worksheet for importing
Set wbR = wb.Worksheets(3)
*the macro continues past this last line but it doesn't get to it yet because of this error
Sorry, I have to use the answer box to do this because there is code involved. But No, you're doing fine. This is how debugging works. Now that we know which lines are not working we will try to find out why. Now try to change
wsL = ThisWorkbook.Worksheets(3)
to
wsL = ThisWorkbook.Worksheets(1)
or
wsL = ThisWorkbook.Worksheets("PUTnameOFsheetHere")
to see if it sets or not. If so then we know there is some kind of problem with WorkSheets(3).
Now we'll try to find why "Set wb = Workbooks.Open(myFile)" is not working. Tunr on your macro recording. Got to "File" on the menu and select "Open." The dialog box will open. Search for your file in the dialog box and open it. Go back to your original workbook and stop recording. Find the recorded macro and you will see the exact line That Excel used to open the file. It should be something like:
Workbooks.Open Filename:="C:\Files\CNC TEST.xlsx"
Now run your script with PF8 and hover over "myFile" after it is initialized. Does it's value match the path and filename of the recorded macro file?

Excel VBA writes data to second workbook, but starts opening read-only versions because " _ is already open

I have some VBA script in one Excel Workbook that has three subs that each either read from a second Workbook. Each of the subs uses the following algorithm (simplified to distill the interaction with the second book):
Public Sub EditRemote()
Dim remoteDataSheet As Worksheet
Dim source As String 'Source worksheet name
Dim target As String 'Target worksheet name
Dim path As String
Dim wkbName As String
source = "CountData"
path = ThisWorkbook.Worksheets("Parameters").Range("B2").Value
wkbName = ThisWorkbook.Worksheets("Parameters").Range("A2").Value
target = "CountData"
Application.EnableCancelKey = xlDisabled
Set localDataSheet = ThisWorkbook.Sheets(source)
If Not WorkbookIsOpen(wkbName) Then
Workbooks.Open (path)
End If
Set remoteDataSheet = Workbooks(wkbName).Sheets(source)
remoteDataSheet.Cells(1,1) = localDataSheet.Cells(1,1)
remoteDataSheet.Cells(1,2) = localDataSheet.Cells(1,2)
Workbooks(wkbName).Close SaveChanges:=True
End Sub
Function WorkbookIsOpen(targetWorkbook As String) As Boolean
Dim testBook As Workbook
On Error Resume Next
Set testBook = Workbooks(targetWorkbook)
If Err.Number = 0 Then
WorkbookIsOpen = True
Else:
WorkbookIsOpen = False
End If
End Function
There is also a pivot table in this Workbook that draws its data from the second file though an external data connection as well. The issue that is plaguing me is that it seems that not initially but after a few operations, these subs stop making the edits properly and instead it opens a read only copy of the second Workbook. When I try to open the second workbook manually I get a message saying that the file is already open and is locked for editing. Right now both files are local to my computer and couldn't be opened by anyone else. What am I missing to be sure that I can make the code work as intended?
I made some modification to your code, ran it a few times, and didn't get your "Read-only" message.
In your code the line of declaring localDataSheet is missing, added Dim localDataSheet As Worksheet , also added Dim remoteWb As Workbook for the remote workbook.
(didn't modify your Funtion WorkbookIsOpen code).
Sub EditRemote Code
Option Explicit
Public Sub EditRemote()
Dim remoteDataSheet As Worksheet
Dim localDataSheet As Worksheet
Dim source As String 'Source worksheet name
Dim target As String 'Target worksheet name
Dim path As String
Dim wkbName As String
Dim remoteWb As Workbook
source = "CountData"
path = ThisWorkbook.Worksheets("Parameters").Range("B2").Value
wkbName = ThisWorkbook.Worksheets("Parameters").Range("A2").Value
target = "CountData"
Application.EnableCancelKey = xlDisabled
Set localDataSheet = ThisWorkbook.Sheets(source)
' check if workbbok already open
If Not WorkbookIsOpen(wkbName) Then
Set remoteWb = Workbooks.Open(path)
Else
Set remoteWb = Workbooks(wkbName) ' workbook is open >> set remoteWb accordingly
End If
Set remoteDataSheet = remoteWb.Sheets(source)
remoteDataSheet.Cells(1, 1) = localDataSheet.Cells(1, 1)
remoteDataSheet.Cells(1, 2) = localDataSheet.Cells(1, 2)
Workbooks(wkbName).Close SaveChanges:=True
End Sub
Just to verify the data in your Excel "Parameters" sheet, the screen-shot below shows the data I used for my testing.
Cell A2 contains the "Clean" workbook name.
Cell B2 contains workbbok "full" name - path + "clean" workbook name.
After some further testing to diagnose the issue, I found that there was nothing wrong with the VBA code, but rather the external data connection to the remote Workbook was locking that Workbook every time I refreshed the data in the pivot table that used the external data connection as its source. It isn't unlocking the file when it is done refreshing, and that leaves the file locked until I close the Workbook with the pivot table. Now I just need to solve that problem.

Command Button to modify cell value in unknown name open workbook

So the issue I'm having is we have a schedule program made via excel, that is set to replace all user names and shift times with "####" and where it would normally display names inputs "Contact blah blah for new version." This occured on 1/1/15. For now they can backdate their computer to a date prior to 1/1/15 and once they type a value in to any cell the worksheet runs and all their data re-appears. We have locations across the country that saves the file every two weeks to Wildcardname.xls I'm looking for a way to program a command button that finds the other random name opened workbook, goes to hidden sheet "help" and changes the value of Cell A184 to "01/01/2016" or any date I plug in. Which would remove the "####" issue and replace it with the originally inputed values. The user could then save the file and carry on.
I was browsing through various help boards and found this..prompts a user to select the workbook. This would be the workbook that needs changed.
http://www.excelforum.com/excel-programming-vba-macros/695467-copy-values-from-a-worksheet-to-another-workbook-source-workbook-name-unknown.html
Sub CopyData()
Dim DstRng As Range
Dim DstWkb As Workbook
Dim DstWks As Worksheet
Dim FileFilter As String
Dim Filename As String
Dim SrcRng As Range
Dim SrcWkb As Workbook
Dim SrcWks As Worksheet
Dim SheetName As String
SheetName = "Output Table"
FileFilter = "Excel Workbooks (*.xls), *.xls"
Filename = Application.GetOpenFilename(FileFilter, , "Open Source Workbook")
If Filename = "False" Then
MsgBox "Open Source File Canceled."
Exit Sub
End If
Set SrcWkb = Workbooks.Open(Filename)
Set SrcWks = SrcWkb.Worksheets(SheetName)
Set SrcRng = SrcWks.Range("A2:H20")
FileFilter = "Excel Workbooks (*.xls), *.xls"
Filename = Application.GetOpenFilename(FileFilter, , "Open Destination Workbook")
If Filename = "False" Then
MsgBox "Open Destination File Canceled."
Exit Sub
End If
Set DstWkb = Workbooks.Open(Filename)
Set DstWks = DstWkb.Worksheets(SheetName)
Set DstRng = DstWks.Range("A2:H20")
SrcRng.Copy Destination:=DstRng
End Sub
Can this be modified to accomplish what I want to complete?
I can't post an image yet, so here's a link to a mock up. Before shot of the program on the left, and on the right is what I want it to look like.
http://i528.photobucket.com/albums/dd330/DLN1223/mockup.jpg
Hopefully this description makes since....
Thanks in advance for your help.
This is what I use:
Dim FileToOpen As Variant
Dim WKbook as workbook
FileToOpen = Application.GetOpenFilename("Excel files (*.xlsx),*.xlsx", , "Select Workbook to Open")
If FileToOpen = False Then Exit Sub 'quit on cancel
Set Wkbook = Workbooks.Open(FileToOpen, False, False)
With this, I can the set the value I want, and save changes
Wkbook.Sheets("help").Range("A184")=#1/1/2016#
Wkbook.Close SaveChanges:=True
depending on the filetype, you may need to change Excel files (*.xlsx),*.xlsx to Excel files (*.xls),*.xls