1

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.

NameHere
  • 35
  • 1
  • 8
  • Are there any macros in the target document? If so, using Application.EnableEvents = False / True (just like ScreenUpdating) might help. I am specifically thinking about Workbook_Open in the target document; that's also something your own workbook could be intercepting as well if it listens to application-level events. – Excelosaurus Nov 10 '17 at 00:55
  • There are no macros in the document, it just seems that Workbooks.Activate overrides Application.ScreenUpdating = False. I just created a sample to test it out: ` Sub News() Application.ScreenUpdating = False Workbooks("Hours.xlsx").Activate Workbooks("Book1.xlsm").Activate Application.ScreenUpdating = True End Sub` Where Book1.xlsm is a document I just created, and "Hours.xlsx" is just a doc that I have to log hours in without any equations or macros or anything. But even with that, the screen flashes. – NameHere Nov 10 '17 at 01:06
  • There's no `Activate` in your code... I just created a sample as well and there's no way I get any flicker with `ScreenUpdating = False`. – Excelosaurus Nov 10 '17 at 01:08
  • How do you invoke your News() sub and see the flicker? – Excelosaurus Nov 10 '17 at 01:11
  • Workbooks.Open automatically activates the now opened document. I've added Application.EnableEvents = False, but that doesn't seem to have fixed it. I've tried it on a few more test documents, and nothing seems to stop it from flashing when Workbooks.Activate occurs. It's not super noticeable, but I highlighted a row of cells in the target document yellow to make it more obvious. Basically it is flashing over to the other document for a fraction of a second before going back. Any idea what could cause that, and if it's fixable? – NameHere Nov 10 '17 at 01:15
  • I invoke the "News" sub just by hitting "Macros" and then "News" and then "run". – NameHere Nov 10 '17 at 01:16
  • I can now reproduce the issue and will look into it. Note that you almost never have to activate anything to interact with it. See https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba. – Excelosaurus Nov 10 '17 at 01:18
  • you can hide the opened workbook https://stackoverflow.com/questions/11354456/hiding-active-workbook-programmatically-in-excel – Slai Nov 10 '17 at 01:20
  • Can you close the opened workbook after you're done with it in your macro? – Excelosaurus Nov 10 '17 at 01:56
  • @NameHere - I too, by letter and spirit, have this requirement and I too have the same trouble in identifying a logical glitch with this behavior by Excel / VBA. Also, I had a tough time looking up (for days) for an SO post seeking a solution to an issue the same as mine and finally found this to my pleasure. The culprit, for some reason and IMHO, seems to be the `Application.ScreenUpdating = True` that we might set at the end of the procedure. I rewrote the code block as `Application.ScreenUpdating = True` `Set wbSource = Workbooks.Open...` `Application.ScreenUpdating = False` and it works :) – Karthick Ganesan Oct 02 '20 at 10:30

3 Answers3

1

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.

Excelosaurus
  • 2,789
  • 1
  • 14
  • 20
  • Wow, I am honestly blown away that you figured the problem out, I'd all but given up hope. I did in fact still have the document open, because the macro requires the document to be open later after the user inputs the sheet name. Knowing that it staying open is the problem, I reworked the code a bit and now i just close it before the user input and reopen after. Thanks so much for the help! – NameHere Nov 10 '17 at 04:56
  • @Excelosaurus - I seem to have identified the issue as posted in my comment on the OP's question [here](https://stackoverflow.com/questions/47213872/how-to-open-document-from-macro-without-activating#comment113473793_47213872). When you find some time, can you please review and share your observation/comments. – Karthick Ganesan Oct 02 '20 at 10:41
  • @Karthick Ganesan - opening the workbook while `Application.ScreenUpdating = True` defeats OP's objective of zero flickering. – Excelosaurus Oct 03 '20 at 03:42
  • @Excelosaurus - True, I realized my mistake. Now, I did some further drill-down and see something like `wb_Ref_Opened.Windows(1).WindowState = xlMinimized` is close to what OP might've expected. – Karthick Ganesan Oct 16 '20 at 10:14
0

You can try

Set wbSource = Workbooks.Open(Filename:=strPathFile)
Workbooks(name of users workbook).Activate

or

Set wbSource = Workbooks.Add(trPathFile)

Hope it helps.

  • I've tried the first, and even with screen updating set to false it still flashes to the document quickly. I just tried the second, and now am met with a "Compile Error: Named argument not found" error. – NameHere Nov 10 '17 at 01:27
  • I edited the second option. By the way, what's wrong with the application flashes? –  Nov 10 '17 at 01:31
  • Just tested the edited second option, and there isn't an error anymore, but sadly it still doesn't fix the problem; the document still ends up being activated, causing the screen to flash. The only issue with the application flashes is that this will be an end product I give to my boss, and I know he will complain about it. – NameHere Nov 10 '17 at 01:41
0

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

Jim Sjoo
  • 326
  • 2
  • 5
  • Jim, The problem is that even with screen updating off, when I open the document and then go back and activate the original document, the screen flashes. I can't find any way to get that part to go away. – NameHere Nov 10 '17 at 01:43