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/forms/code54.html
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 = 2
Const GW_HWNDFIRST = 0
Dim lWinHwnd As Long, sTestName As String * clMaxName, lNumChars As Long
'Ignore case
sClassName = UCase$(sClassName)
sCaption = UCase$(sCaption)
'Find the first child window
lWinHwnd = GetWindow(lParentHwnd, GW_CHILD)
If lWinHwnd = 0 Then
Exit Function
End If
Do
bClassMatches = False
bCaptionMatches = False
lNumChars = clMaxName
If Len(sClassName) Then
'Get the child window classname
lNumChars = GetClassName(lWinHwnd, sTestName, (clMaxName))
If UCase(Left$(sTestName, lNumChars)) = sClassName Then
'Found matching class name
bClassMatches = True
End If
Else
'No class name specified
bClassMatches = True
End If
If Len(sCaption) Then
lNumChars = GetWindowText(lWinHwnd, sTestName, (clMaxName))
If UCase(Left$(sTestName, lNumChars)) = sCaption Then
'Found matching caption
bCaptionMatches = True
End If
Else
'No caption specified
bCaptionMatches = True
End If
If bClassMatches And bCaptionMatches Then
'Found matching dialog, return handle
FindChildWindow = lWinHwnd
Exit Do
ElseIf bSearchChildWindows Then
'Search Child windows
FindChildWindow = FindChildWindow(lWinHwnd, sClassName, sCaption, True)
If FindChildWindow Then
Exit Do
End If
End If
'Try next next child
lWinHwnd = GetWindow(lWinHwnd, GW_HWNDNEXT)
If lWinHwnd = 0 Then
'No more child windows
Exit Do
End If
Loop While lWinHwnd 'Loop until there are no more child windows
End Function