open pdf to specific page via macro

Hi, I am attempting to convert a VBA macro from Excel to Libreoffice. The function of the macro is fairly simple- it picks up data from the current cell and, using that information, opens a PDF file then advances to a specific page number. However, the code to open the PDF and move to specific page uses windows features to walk through open windows and the code doesn't work for Libreoffice. I've done a bit of research and experimentation but have yet to find any good references or examples to open the PDF to a specific page. Below is the VBA code I am attempting to migrate - any suggested references or examples appreciated.

' Input Variables: ' ~~~~~~~~~~~~~~~~ ' sFile : Fully qualified path, filename & extension of the PDF file ' lPage : Page number to view ' ' Usage: ' ~~~~~~ ' Call ChangePDFPage("C:\Users\Daniel\Documents\AccessTechniques.pdf", 65) ' ' Revision History: ' Rev Date(yyyy/mm/dd) Description ' **************************** ' 1 2018-11-25 Initial Release '--------------------------------------------------------------------------------------- Public Function ChangePDFPage(sFile As String, lPage As Long)

Dim hwndParent&
Dim hwndChild&
Dim sFileName             As String

'Dim sTempWindowText As String
'Dim sTempRetVal As Long

On Error GoTo Error_Handler

sFileName = Right(sFile, Len(sFile) - InStrRev(sFile, "\")) 'Get just the filename from the full path/filename/ext

hwndParent = FnFindWindowLike("*" & sFileName & "*")

If hwndParent = 0 Then
'This means that we can't find an instance of Adobe with the specified File, so we could use the traditional approach for the first time
Call OpenPDF(sFile, lPage)

Else
PostMessage hwndParent, WM_CLOSE, 0, ByVal 0&
Call OpenPDF(sFile, lPage)
GoTo skipchild

hwndChild = GetWindow(hwndParent, GW_CHILD)        'Find the 1st Child window handle - Zoom %
hwndChild = GetWindow(hwndChild, GW_HWNDNEXT)        'Find the next window handle - Page No.

'an use PostMessage instead if wanted
Call SendMessage(hwndChild, WM_SETTEXT, 0&, lPage)        'Enter our page number into the Adobe Reader Page number textbox
Call SendMessage(hwndChild, WM_KEYDOWN, VK_RETURN, 0) 'Submit an Enter key to actually switch to the input page
Call SendMessage(hwndChild, WM_KEYUP, VK_RETURN, 0)


skipchild:

End If


Error_Handler_Exit: On Error Resume Next Exit Function

Error_Handler: MsgBox "The following error has occured" & vbCrLf & vbCrLf & _ "Error Number: " & Err.Number & vbCrLf & _ "Error Source: ChangePDFPage" & vbCrLf & _ "Error Description: " & Err.Description & _ Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _ , vbOKOnly + vbCritical, "An Error has Occured!" Resume Error_Handler_Exit End Function

'Purpose : Enumerates all the child windows and returns the handle of a child window with ' a matching caption or class name. 'Inputs : lParentHwnd The handle to a parent window ' [sClassName] The class name to search for. ' [sCaption] The caption to search for. ' [bSearchChildWindows] Searchs within each child window for a matching window 'Outputs : Returns the handle of child window or zero if not found 'Source : https://visualbasic.happycodings.com/... Public Function FindChildWindow(ByVal lParentHwnd As Long, Optional ByVal sClassName As String, Optional ByVal sCaption As String, Optional bSearchChildWindows As Boolean = False) As Long Dim bClassMatches As Boolean, bCaptionMatches As Boolean Const clMaxName As Long = 255 Const GW_CHILD = 5 Const GW_HWNDNEXT ...

edit retag close merge delete

Just try open Reader with key /A "page=<pagenum>"

( 2021-01-26 08:45:52 +0200 )edit

JohnSUN - thanks. I went to the referenced link and it appears to be how to use a command line for Acrobat. My need is to automate starting acrobat from a CALC sheet. Have you seen any references on how to run a command line such a acrobat from a CALC macro?

( 2021-01-26 13:46:00 +0200 )edit

Sort by » oldest newest most voted

This is written a little shorter than you wrote in your question - just use Shell:

Sub getParamsAndRunAcrobat(oEvent As Variant)
Dim oData As Variant
oData = ThisComponent.getCurrentController().getActiveSheet().getCellRangeByName("B1:B2").getDataArray()
Call OpenPDF(oData(0)(0), oData(1)(0))
End Sub

Sub OpenPDF(sFile As String, lPage As Long)
Shell (ConvertToURL(PATH_TO_READER), 3, " /A ""page=" + lPage + """ """ + sFile + """")
End Sub


Demo file - C:\fakepath\ShellAcrobat.ods

more

JohnSUN - PERFECT! Now the fun starts to get the rest of the VBA macro converted. THANKS!

( 2021-01-26 23:30:11 +0200 )edit

The solution for Windows using acrobat reader proposed by johnSun, whom I thank for the idea, can be extended to linux-ubuntu with the standard document viewer "evince"

Sub Main
xEvince ("/ media /...../ test.pdf", 2)
End Sub

sub xEvince (sFileFullPath, iPageNumber)
Shell ("evince --page-label =" + cstr (iPageNumber) + "  " + sFileFullPath)
end sub


The sub xEvince opens the pdf file requested on the iPageNumber page passed as a parameter

I used as a test a pdf file created with libreoffice writer containing TOC, bookmarks and single hyperlinks to local bookmarks by activating "tagged pdf" and "export bookmark" in the export form. The pdf exported from writer maintains the TOC with relative automatic links to the headings of the original document and preserves both the bookmarks and the hyperlink functionality

While with 'evince' it is possible to open a pdf in correspondence of a page, I have not found any command to open the pdf in correspondence of a bookmark

However, I believe that it is possible to bypass the problem, in the case of pdf exported by writer By scanning the writer document with a macro to search for bookmarks, it is possible obtain the list of pairs (bookmark-page number) to be used to open the pdf each time in correspondence with the page containing the bookmark

Even when the TOC and hyperlinks imported from libreoffice work in the pdf, and therefore the imported bookmarks work, the bookmarks are not always also visible from evince in the side panel

When it appears, using the command from the terminal:

gvfs-info -a "metadata :: evince :: bookmarks" fileFullPath.ext


all pairs (page number-bookmark name) detected by 'evince' are displayed with the format:

metadata :: evince :: bookmarks: [(0, 'bookName0'), (2, 'bookName1')]


Page numbering in this list is 0 based (page 1 corresponds to 0)

more