How to hide publishing progress bar for ExportAsFixedFormat

后端 未结 1 781
[愿得一人]
[愿得一人] 2021-01-25 14:27

I am trying to convert Excel file to PDF using interop.excel, while executing ExportAsFixedFormat \'publishing\' progress bar displays on the site. Is

相关标签:
1条回答
  • 2021-01-25 15:04

    It took me a few days to figure out, but finally here is a workarround which uses some WinAPI functions to observe windows events. While the hook is active, every new window is compared to whether its class is the same one as the PDF save dialog class. If that's the case, the window gets hidden.

    Thanks for solution ideas go to some chinese guys: http://www.itjie.wang/officebase/516998.html

    Usage requirement:
    OS (= Operating System) must be Windows because of WinAPI usage.

    Warning:
    If the "SetWinEventHook" isn't stopped again due to some errors, it is better to restart your system, otherwise you could run into some serious problems with Windows.

    Note:
    By default, the PDF save dialog doesn't appear regularly. It depends on the time necessary to save the PDF file. If it takes longer the save popup will show up. If it takes shorter the save popup won't show up. Anyway, you don't have to worry about whether the save dialog would appear or not, the code already does this for you.

    Instruction:
    In your Excel workbook, if you don't already have a module, create a new one (name doesn't matter) & paste following code:

    ' WINDOWS API FUNCTIONS:
    Private Declare Function SetWinEventHook Lib "user32" (ByVal eventMin As Long, ByVal eventMax As Long, ByVal hmodWinEventProc As Long, ByVal pfnWinEventProc As Long, ByVal idProcess As Long, ByVal idThread As Long, ByVal dwFlags As Long) As Long
    Private Declare Function UnhookWinEvent Lib "user32" (ByVal hWinEventHook As Long) As Long
    Private Declare Function apiGetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassname As String, ByVal nMaxCount As Long) As Long
    Private Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
    
    ' CONSTANT VARIABLES:
    Private Const SW_HIDE = 0
    Private Const DLG_CLSID = "CMsoProgressBarWindow"
    Private Const EVENT_SYSTEM_FOREGROUND = &H3&
    Private Const WINEVENT_OUTOFCONTEXT = 0
    
    ' GLOBAL VARIABLES:
    Dim long_WinEventHook As Long
    
    Public Function StartEventHook() As Long
     long_WinEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, 0&, AddressOf WinEventFunc, 0, 0, WINEVENT_OUTOFCONTEXT)
     StartEventHook = long_WinEventHook
    End Function
    
    Public Sub StopEventHook()
     Dim b_unhooked As Boolean
     If long_WinEventHook = 0 Then
      MsgBox "WinEventHook couldn't be stopped! " & _
      "Variable 'long_WinEventHook' is empty! " & _
      "Better restart Windows now!"
      Exit Sub
     End If
     b_unhooked = UnhookWinEvent(long_WinEventHook)
     If b_unhooked = True Then
     Else
      MsgBox "WinEventHook couldn't be stopped! " & _
      "Variable 'b_unhooked' is false! " & _
      "Better restart Windows now!"
     End If
    End Sub
    
    ' CALLBACK FUNC OF "SetWinEventHook" (DEFINE ACTIONS TO RUN ON THE EVENTS):
    ' http://stackoverflow.com/questions/20486944/detecting-in-vba-when-the-window-containing-an-excel-instance-becomes-active
    Public Function WinEventFunc(ByVal HookHandle As Long, ByVal LEvent As Long, ByVal hWnd As Long, ByVal idObject As Long, ByVal idChild As Long, ByVal idEventThread As Long, ByVal dwmsEventTime As Long) As Long
     'This function is a callback passed to the win32 api
     'We CANNOT throw an error or break. Bad things will happen
     On Error Resume Next
     Dim l_handle As Long
     Dim s_buffer As String
     Dim b_visible As Boolean
     Dim i_bufferLength As Integer
     s_buffer = String$(32, 0)
     i_bufferLength = apiGetClassName(hWnd, s_buffer, Len(s_buffer))
     If Left(s_buffer, i_bufferLength) = DLG_CLSID Then
      b_visible = apiShowWindow(hWnd, SW_HIDE)
      WinEventFunc = hWnd
     End If
    End Function
    

    In your VBA code, when you want to save your excel workbook as PDF, you would call above macros like this:

    ' ADD WINDOWS EVENT HOOK BEFORE SAVING:
    Application.Run XL_WB.Name & "!StartEventHook"
    
    ' SAVE EXCEL AS PDF:
    ' https://msdn.microsoft.com/de-de/library/microsoft.office.tools.excel.worksheetbase.exportasfixedformat.aspx
    XL_WB.ExportAsFixedFormat _
     Type:=xlTypePDF, _
     Filename:="C:\PDF.pdf", _
     Quality:=xlQualityStandard, _
     IncludeDocProperties:=True, _
     IgnorePrintAreas:=False, _
     OpenAfterPublish:=False
    
    ' REMOVE WINDOWS EVENT HOOK AFTER SAVING:
    Application.Run XL_WB.Name & "!StopEventHook"
    

    In the above VBA code example "XL_WB" is a variable. You have to adjust it to your needs. For example use "ActiveSheet" instead.

    From following other websites users also asked for help with that particular problem:

    • https://social.msdn.microsoft.com/Forums/office/en-US/e6078904-0715-46a2-8937-c38626464425/exportasfixedformat-progress-bar-can-you-hide-it?forum=exceldev
    • http://www.vbaexpress.com/forum/archive/index.php/t-41431.html
    • http://www.excelbanter.com/showthread.php?t=446463
      ...
    0 讨论(0)
提交回复
热议问题