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.
Related
So I'm experiencing some weird behavior while trying to open a new workbook (checkwb). When the new workbook opens it opens a "Print Setup" dialog box for every single page in the workbook. Furthermore, after clicking "OK" ~200 times the code runs fine, but if I close checkwb and try to run the code again it is unable to open checkwb until I close Excel entirely and reopen, at which point the print dialogs reappear. Here's my (incomplete) code:
Sub Check()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim homewb As Workbook
Dim checkwb As Workbook
Dim ws As Worksheet
Dim namestr As String
Dim checkarray() As Double
Set homewb = Workbooks("BranchTable Calc B31.3.xlsm")
Set checkwb = Workbooks.Open("Z:\Agrium\Redwater\E130040CP ~ Pipe Spec
Update\M-Mech\20-Eng\Calcs\Final WT Calcs All Specs\New Bechtel Agrium
comments.xlsm")
For Each ws In homewb.Sheets
If ws.Name = "Cover" Or ws.Name = "Pipe Dims" Then
Else:
namestr = ws.Name & " Weld"
checkarray() = GetCheckValues(checkwb, namestr)
End If
Next
checkwb.Close
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I've read weird errors like this can occur from corrupted files but the code shouldn't be able to open the file at all if it was corrupt by my understanding.
Setting the page view for all sheets in the target workbook to "Normal" mode fixed this problem. Thanks to Ricardo Rodrigues for the tip!
I am trying to create a sort of user interface in Excel and need to find a simple solution to copy a worksheet from a selected workbook to a specific workbook. So far I've written the code below but I don't know how to reference the selected workbook in code.
Users are going to need to copy the worksheet ( it's called Storyboard and name never changes ) from many different workbooks ( with different names ) to the workbook with the VBA.
Right now another workbook can be selected, but I cannot refer to that workbook in the codes.
Also, there are some macros on the workbooks that users going to select, how can I disable them after opening?
Here is the code so far;
Sub Storyboard_Ekle()
Dim DosyaSec As Office.FileDialog
Set DosyaSec = Application.FileDialog(msoFileDialogFilePicker)
With DosyaSec
.AllowMultiSelect = False
.Title = "Lütfen yeni eklenecek Storyboard dosyasini seçiniz."
.Filters.Clear
.Filters.Add "Excel Macro-Enabled Workbook", "*.xlsm"
.Filters.Add "Excel Workbook", "*.xlsx"
.Filters.Add "All Files", "*.*"
If .Show = True Then
YeniSB = .SelectedItems(1)
End If
Dim YeniStoryBoard As Workbook
Dim AnaDosya As Workbook
Dim YeniStoryBoard_Sheet As Worksheet
Dim AnaDosya_Sheet As Worksheet
Application.ScreenUpdating = False
Set AnaDosya = ThisWorkbook
Application.EnableEvents = False
Set YeniStoryBoard = Workbooks.Open(YeniSB)
YeniStoryBoard.Worksheets("Storyboard").Copy After:=ThisWorkbook.Worksheets("Kunye")
YeniStoryBoard.Close
Set YeniStoryBoard_isim = Sheets("Storyboard")
YeniStoryBoard_isim.Name = "StoryboardXXYYZZ"
Application.EnableEvents = True
End With
End Sub
Thank you so much. :)
I think you should using this solution to disable them after opening
Application.EnableEvents = False 'disable Events
Set YeniStoryBoard = Workbooks.Open(YeniSB) 'open workbook
Application.EnableEvents = True 'enable Events
To ensure disable event of workbook, You can use additional statements
YeniStoryBoard.Application.EnableEvents = False
'Do something
YeniStoryBoard.Application.EnableEvents = True
YeniStoryBoard.Close
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?
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
I have a script that opens an excel file and runs a macro, then quits the file. Since the file is in read only mode, and the script makes temporary changes to the file, when the script calls myExcelWorker.Quit() excel asks if I want to save my changes and I must click 'no'. Is there any way to exit the program and skip this box?
' Create a WshShell to get the current directory
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
' Create an Excel instance
Dim myExcelWorker
Set myExcelWorker = CreateObject("Excel.Application")
myExcelWorker.Visible = True
' Tell Excel what the current working directory is
' (otherwise it can't find the files)
Dim strSaveDefaultPath
Dim strPath
strSaveDefaultPath = myExcelWorker.DefaultFilePath
strPath = WshShell.CurrentDirectory
myExcelWorker.DefaultFilePath = strPath
' Open the Workbook specified on the command-line
Dim oWorkBook
Dim strWorkerWB
strWorkerWB = strPath & "\BugHistogram_v2.xlsm"
Set oWorkBook = myExcelWorker.Workbooks.Open(strWorkerWB)
' Build the macro name with the full path to the workbook
Dim strMacroName
strMacroName = "CreateImagesButton_Click"
on error resume next
' Run the calculation macro
myExcelWorker.Run strMacroName
if err.number <> 0 Then
' Error occurred - just close it down.
End If
err.clear
on error goto 0
' oWorkBook.Save ' this is ignored because it's read only
myExcelWorker.DefaultFilePath = strSaveDefaultPath
' Clean up and shut down
Set oWorkBook = Nothing
' Don’t Quit() Excel if there are other Excel instances
' running, Quit() will
' shut those down also
if myExcelWorker.Workbooks.Count = 0 Then
myExcelWorker.Quit
End If
myExcelWorker.Quit()
Set myExcelWorker = Nothing
Set WshShell = Nothing
ActiveWorkbook.Close False (to close the workbook)
Application.Quit (to quit Excel - doesn't prompt to save changes)
From Microsoft Support's How to suppress "Save Changes" prompt when you close a workbook in Excel:
To force a workbook to close without saving any changes, type the
following code in a Visual Basic module of that workbook:
Sub Auto_Close()
ThisWorkbook.Saved = True
End Sub
Because the Saved property is set to True, Excel responds as though the workbook has already been saved and no changes have
occurred since that last save.
The DisplayAlerts property of the program can be used for the same
purpose. For example, the following macro turns DisplayAlerts off,
closes the active workbook without saving changes, and then turns
DisplayAlerts on again.
Sub CloseBook()
Application.DisplayAlerts = False
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Sub
You can also use the SaveChanges argument of the Close method.
The following macro closes the workbook without saving changes:
Sub CloseBook2()
ActiveWorkbook.Close savechanges:=False
End Sub
The answer you have above is for VBA - you can address this in your VBS directly by using
oWorkBook.Close False
Set oWorkBook = Nothing
in place of
Set oWorkBook = Nothing