sync with Adobe Acrobat Reader within an IE Window
Moderators: JRL, Dorian (MJT support)
sync with Adobe Acrobat Reader within an IE Window
Hi, I have automated the printing of several PDF files by having Macro Scheduler 'click' on HTML links [to the PDF files] within a webpage. Everything works great except for one thing... I need to synchronize with Adobe Acrobat reader having the PDF fully loaded before sending Print keystrokes (ie. Ctrl-P). The way I am syncing is 'wait>10', however, sometimes this is too long, or worse, not long enough. I have tried using 'WaitReady>1' but still, sometimes the PDF file does not fully load before I try sending the Print Command. I have also tried 'WaitScreenText>Done' but there are two occurences of 'Done' for every PDF file - once when the initial new webpage opens, and the second, when the PDF file is completely loaded. As the first 'Done' [when the webpage opens] can appear and disappear quickly, sometimes this is 'missed'. Is there a more certain way of waiting for the new webpage to open and the PDF file to fully load before sending commands to the PDF window? I am using IE8 and Adobe Acrobat reader 9 is installed on the PC. Thanks very much for any assistance you can provide.
I would try to use the command line options to print.How do I use the Windows command line with Acrobat and Adobe Reader?
You can display and print a PDF file with Acrobat and Adobe Reader from the command line.
Note:All examples below use Adobe Reader, but apply to Acrobat as well. If you are using Acrobat, substitute Acrobat.exe in place of AcroRd32.exe on the command line.
AcroRd32.exe pathname — Start Adobe Reader and display the file. The full path must be provided.
This command can accept the following options.
/n Start a separate instance of Acrobat or Adobe Reader, even if one is currently open.
/s Suppress the splash screen.
/o Suppress the open file dialog box.
/h Start Acrobat or Adobe Reader in a minimized window.
AcroRd32.exe /p pathname — Start Adobe Reader and display the Print dialog box.
AcroRd32.exe /t path "printername" "drivername" "portname" — Start Adobe Reader and print a file while suppressing the Print dialog box. The path must be fully specified.
The four parameters of the /t option evaluate to path, printername, drivername, and portname (all strings).
printername — The name of your printer.
drivername — Your printer driver’s name, as it appears in your printer’s properties.
portname — The printer’s port. portname cannot contain any "/" characters; if it does, output is routed to the default port for that printer
You could also look into using HTTPRequest> command to first download the entire PDF to a local disk file before issuing the printing commands mentioned above.
*** Edit ****
This was tested to work by me on version 12.0.8
Code: Select all
/// Start of Script ///
HTTPRequest>http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/Acrobat_SDK_developer_faq.pdf#page=24,c:\temp.pdf,GET,,result,,,,
Run>"C:\Program Files\Adobe\Reader 8.0\Reader\acrord32.exe" /t c:\temp.pdf "\\prog-win2k8\HP LaserJet 1100 (MS)" "hpp1100" "//"
/// End of Script ///
Thanks for the reply... need another alternative
Hi, thanks for the reply. I had actually started by trying httprequest but turned out this will not work due to the way the website has their pages setup - the webpages navigate to other pages where the actual page is unknown to public viewers... also, thanks for the pdf command line interface but the pdf files are only accessible through the links on the webpage... are there any other synchronization options? Would a LibFunc call to a routine similar to a 'waitReady>1' be a possibility? Thanks very much for your taking the time with your help.
actual page is unknown to public viewers
Not Likely.
There is a direct link or else the browser would not be able to read it.
Look in the HTML source of the webpage to find the link. Or else post the URL and I will find it for you.
If the content is being served dynamically, then scripting IE would be the next choice.
Use this tip as a guide
http://www.mjtnet.com/forum/viewtopic.php?t=1511
or download the plugin
WebRecorder
http://www.mjtnet.com/dldfile.htm?file= ... ebRecorder
And it writes most of the code for you.
don writes...
Thanks again for your interest in my issue. As stated, the webpages being navigated to are not known - the only webpages known are the login page and menu page, thereafter, the webpages are served up dynamically. I have looked at the source and there is no trace as to where the main page links to, just alot of calls to included javascript... for example, the link that opens a pdf is in the source as:
Lic View
Clicking the above link opens a new instance of IE and the URL is not displayed, nor are any controls, menus, etc. Acrobat and the PDF are loaded into the new IE webpage.
Also, fyi, I am already using the IE object and utilizing the vbs code to loop while IE is busy. This only appears to work for the newly opened IE window and not the actual loading of the PDF document which is being done by Acrobat.
I believe I need a way of determining when Acrobat, within the webpage, is not busy.
Apologies, but access to the website is restricted and requires a username and password to enter, however, I have posted, below, the code I have written to more fully document what is a working prototype with only the one synchronization issue...
Not to bore you with the details but the VB functions in the code are
ViewTableRows - returns the count of rows in the table I am processing, OR, returns the contents of a specific cell within the table (ie. an anchor tag that opens a pdf file)
ClickLink - returns the count of the anchor tags to each of 5 different document types within the table I am processing (ie. # of 'Lic View' links, # of 'SN Label' links, # of 'SEULA' links, # of 'Prod Label' links, and # of 'UPC Label' links), OR, clicks a specific link [that opens a pdf file] NOTE in this subroutine, the "do while IE.Busy" loop after the link is clicked
After a specific link is clicked using the vbscript ClickLink function, the code branches to the 'PrtLic' subroutine to control the printing of the PDF file. 'PrtLic' is also below.
VBSTART
Function ViewTableRows(URL, getCount, r, c)
Dim IE
Dim objInstances, objIE
Dim rrows
Dim ccells
Dim ttables
Dim ItemNr
Dim IEfnd
IEfnd = 0
Set objInstances = CreateObject("Shell.Application").windows
If objInstances.Count > 0 Then '/// make sure we have instances open.
For Each objIE In objInstances
If InStr(objIE.LocationURL,URL) > 0 then
Set IE = objIE
IEfnd = 1
End if
Next
End if
if IEfnd = 1 then
if getCount=1 then
fndcnt = 0
ViewTableRows = fndcnt
Set ttables = IE.document.getElementsbyTagname("table")
'msgbox("ttables.length = " & ttables.length)
For ItemNr = 0 to ttables.length - 1
set rrows = ttables(ItemNR).rows
resultsTblFnd = 0
for k = 0 to rrows.length - 1
set ccells = ttables(ItemNr).rows.item(k).cells
if ccells.length = 16 then
if resultsTblFnd = 0 then
if trim(ccells(0).innerHTML) = "Lic View" and _
trim(ccells(1).innerHTML) = "SN Label" and _
trim(ccells(2).innerHTML) = "SEULA" and _
trim(ccells(3).innerHTML) = "ProductLabel" and _
trim(ccells(4).innerHTML) = "UPC Label" and _
trim(ccells(13).innerHTML) = "Qty" then
resultsTblFnd = 1
end if
else
if k > 1 then
fndcnt = fndcnt + 1
end if
end if
end if
next
resultsTblFnd = 0
Next
'msgbox("fndcnt="&fndcnt)
ViewTableRows = fndcnt
else
ViewTableRows = "00000"
Set ttables = IE.document.getElementsbyTagname("table")
'msgbox("ttables.length = " & ttables.length)
For ItemNr = 0 to ttables.length - 1
set rrows = ttables(ItemNR).rows
resultsTblFnd = 0
for k = 0 to rrows.length - 1
set ccells = ttables(ItemNr).rows.item(k).cells
if ccells.length = 16 then
if resultsTblFnd = 0 then
if trim(ccells(0).innerHTML) = "Lic View" and _
trim(ccells(1).innerHTML) = "SN Label" and _
trim(ccells(2).innerHTML) = "SEULA" and _
trim(ccells(3).innerHTML) = "ProductLabel" and _
trim(ccells(4).innerHTML) = "UPC Label" and _
trim(ccells(13).innerHTML) = "Qty" then
resultsTblFnd = 1
end if
else
if k = r + 2 then
ViewTableRows = ccells(c).innerHTML
set ccells=nothing
set rrows=nothing
set tables=nothing
set IE=nothing
set objIE=nothing
set objInstances=nothing
Exit Function
end if
end if
end if
next
resultsTblFnd = 0
Next
end if
set ccells=nothing
set rrows=nothing
set tables=nothing
else
msgbox("ie not found!")
end if
set IE=nothing
set objIE=nothing
set objInstances=nothing
End Function
Function ClickLink(URL, getCount, startidx, linktext)
Dim IE
Dim objInstances, objIE
Dim anchors
Dim ItemNr
Dim IEfnd
ClickLink = ""
IEfnd = 0
Set objInstances = CreateObject("Shell.Application").windows
If objInstances.Count > 0 Then '/// make sure we have instances open.
For Each objIE In objInstances
If InStr(objIE.LocationURL,URL) > 0 then
Set IE = objIE
IEfnd = 1
End if
Next
End if
if IEfnd = 1 then
Set anchors = IE.document.getElementsbyTagname("a")
if getCount=1 then
fndcnt = 0
For ItemNr = 0 to anchors.length - 1
text1 = anchors.Item(ItemNr).innertext
if trim(text1) "" then
text2 = trim(ucase(replace(text1, " ", "")))
If instr(1,text2,trim(ucase(linktext))) > 0 Then
fndcnt = fndcnt + 1
End If
End If
next
ClickLink = fndcnt
else
ClickLink = "99999NONE"
linktext=escape(trim(ucase(replace(replace(linktext,"`",chr(39)),"^",chr(34)))))
For ItemNr = 0 to anchors.length - 1
//find the anchor tag that matches the linktext in the table
text1 = escape(trim(ucase(anchors.Item(ItemNr).outerhtml)))
If trim(text1) "" then
If instr(1,linktext,text1) > 0 Then
//found it
anchors.Item(ItemNr).click
curidx = right("00000" & ItemNr,5)
'ClickLink = curidx & linktext
ClickLink = curidx & "NONE"
ItemNr = anchors.length
End If
End If
next
do while IE.Busy
loop
end if
set anchors=nothing
else
msgbox("JsRL not found:" & chr(13) & chr(10) & URL)
End If
Set IE = nothing
Set objIE=nothing
Set objInstances = nothing
End Function
VBEND
SRT>PrintLic
Let>LicWindow=https://tools.xxxxx.com/emco/getPDF?forPrinting=YES*
WaitWindowOpen>%LicWindow%
//wait for the new IE window to open
If>WST_RESULT=FALSE
BlockInput>0
MessageModal>TimedOut At Step 001
Exit
EndIf
setfocus>%LicWindow%
WaitScreenText>Done
//this wait will either detect the Done when IE is done or the Done when
//Acrobat is done loading
Wait>10
//This is the problem Wait - I would rather sync with Acrobat being done
//opening the document and ready for commands
Press CTRL
Send>p
Release CTRL
//invoke Acrobat's Print dialog
Let>waitWindow=Print*
gosub>WfW
Wait>2
setfocus>Print*
Send>%LPrinter%
Wait>2
Press Enter
//select the printer name from Acrobat's Print dialog
WaitWindowOpen>Progress
//Acobat opens a window to display progress formatting the document for output
WaitWindowClosed>Progress
If>WW_RESULT=FALSE
BlockInput>0
MessageModal>TimeOut Waiting For Progess* To Close
Exit
EndIf
Wait>2
//Give some time for Acrobat Print to complete
Press CTRL
Send>w
Release CTRL
//Close the IE window [and Acrobat]
WaitWindowClosed>%LicWindow%
If>WW_RESULT=FALSE
BlockInput>0
MessageModal>TimeOut Waiting For %LicWindow% To Close
Exit
EndIf
END>PrintLic
//Start of Main Code
Let>JsURL=someURL
Let>LicLink=LicView
VBEval>ClickLink("%JsURL%",1,0,"%LicLink%"),results
Let>totReqLic=results
// get the total # of 'Lic View' links on the page
VBEval>ViewTableRows("%JsURL%",1,0,0),results
Let>returnedrows=%results%
// get the total # of rows in the table I am processing
Let>rcnt=0
Let>reqQty=1
while>rcntViewTableRows("%JsRL%",0,%rcnt%,0),results
//get the link to click from the table [row,col]
If>%results%-
VBEval>ClickLink("%JsURL%",0,%reqQty%,"%results%"),results2
//click the link
gosub>PrintLic
//print the document that opens via clicking the link
EndIf
Add>rcnt,1
EndWhile
Lic View
Clicking the above link opens a new instance of IE and the URL is not displayed, nor are any controls, menus, etc. Acrobat and the PDF are loaded into the new IE webpage.
Also, fyi, I am already using the IE object and utilizing the vbs code to loop while IE is busy. This only appears to work for the newly opened IE window and not the actual loading of the PDF document which is being done by Acrobat.
I believe I need a way of determining when Acrobat, within the webpage, is not busy.
Apologies, but access to the website is restricted and requires a username and password to enter, however, I have posted, below, the code I have written to more fully document what is a working prototype with only the one synchronization issue...
Not to bore you with the details but the VB functions in the code are
ViewTableRows - returns the count of rows in the table I am processing, OR, returns the contents of a specific cell within the table (ie. an anchor tag that opens a pdf file)
ClickLink - returns the count of the anchor tags to each of 5 different document types within the table I am processing (ie. # of 'Lic View' links, # of 'SN Label' links, # of 'SEULA' links, # of 'Prod Label' links, and # of 'UPC Label' links), OR, clicks a specific link [that opens a pdf file] NOTE in this subroutine, the "do while IE.Busy" loop after the link is clicked
After a specific link is clicked using the vbscript ClickLink function, the code branches to the 'PrtLic' subroutine to control the printing of the PDF file. 'PrtLic' is also below.
VBSTART
Function ViewTableRows(URL, getCount, r, c)
Dim IE
Dim objInstances, objIE
Dim rrows
Dim ccells
Dim ttables
Dim ItemNr
Dim IEfnd
IEfnd = 0
Set objInstances = CreateObject("Shell.Application").windows
If objInstances.Count > 0 Then '/// make sure we have instances open.
For Each objIE In objInstances
If InStr(objIE.LocationURL,URL) > 0 then
Set IE = objIE
IEfnd = 1
End if
Next
End if
if IEfnd = 1 then
if getCount=1 then
fndcnt = 0
ViewTableRows = fndcnt
Set ttables = IE.document.getElementsbyTagname("table")
'msgbox("ttables.length = " & ttables.length)
For ItemNr = 0 to ttables.length - 1
set rrows = ttables(ItemNR).rows
resultsTblFnd = 0
for k = 0 to rrows.length - 1
set ccells = ttables(ItemNr).rows.item(k).cells
if ccells.length = 16 then
if resultsTblFnd = 0 then
if trim(ccells(0).innerHTML) = "Lic View" and _
trim(ccells(1).innerHTML) = "SN Label" and _
trim(ccells(2).innerHTML) = "SEULA" and _
trim(ccells(3).innerHTML) = "ProductLabel" and _
trim(ccells(4).innerHTML) = "UPC Label" and _
trim(ccells(13).innerHTML) = "Qty" then
resultsTblFnd = 1
end if
else
if k > 1 then
fndcnt = fndcnt + 1
end if
end if
end if
next
resultsTblFnd = 0
Next
'msgbox("fndcnt="&fndcnt)
ViewTableRows = fndcnt
else
ViewTableRows = "00000"
Set ttables = IE.document.getElementsbyTagname("table")
'msgbox("ttables.length = " & ttables.length)
For ItemNr = 0 to ttables.length - 1
set rrows = ttables(ItemNR).rows
resultsTblFnd = 0
for k = 0 to rrows.length - 1
set ccells = ttables(ItemNr).rows.item(k).cells
if ccells.length = 16 then
if resultsTblFnd = 0 then
if trim(ccells(0).innerHTML) = "Lic View" and _
trim(ccells(1).innerHTML) = "SN Label" and _
trim(ccells(2).innerHTML) = "SEULA" and _
trim(ccells(3).innerHTML) = "ProductLabel" and _
trim(ccells(4).innerHTML) = "UPC Label" and _
trim(ccells(13).innerHTML) = "Qty" then
resultsTblFnd = 1
end if
else
if k = r + 2 then
ViewTableRows = ccells(c).innerHTML
set ccells=nothing
set rrows=nothing
set tables=nothing
set IE=nothing
set objIE=nothing
set objInstances=nothing
Exit Function
end if
end if
end if
next
resultsTblFnd = 0
Next
end if
set ccells=nothing
set rrows=nothing
set tables=nothing
else
msgbox("ie not found!")
end if
set IE=nothing
set objIE=nothing
set objInstances=nothing
End Function
Function ClickLink(URL, getCount, startidx, linktext)
Dim IE
Dim objInstances, objIE
Dim anchors
Dim ItemNr
Dim IEfnd
ClickLink = ""
IEfnd = 0
Set objInstances = CreateObject("Shell.Application").windows
If objInstances.Count > 0 Then '/// make sure we have instances open.
For Each objIE In objInstances
If InStr(objIE.LocationURL,URL) > 0 then
Set IE = objIE
IEfnd = 1
End if
Next
End if
if IEfnd = 1 then
Set anchors = IE.document.getElementsbyTagname("a")
if getCount=1 then
fndcnt = 0
For ItemNr = 0 to anchors.length - 1
text1 = anchors.Item(ItemNr).innertext
if trim(text1) "" then
text2 = trim(ucase(replace(text1, " ", "")))
If instr(1,text2,trim(ucase(linktext))) > 0 Then
fndcnt = fndcnt + 1
End If
End If
next
ClickLink = fndcnt
else
ClickLink = "99999NONE"
linktext=escape(trim(ucase(replace(replace(linktext,"`",chr(39)),"^",chr(34)))))
For ItemNr = 0 to anchors.length - 1
//find the anchor tag that matches the linktext in the table
text1 = escape(trim(ucase(anchors.Item(ItemNr).outerhtml)))
If trim(text1) "" then
If instr(1,linktext,text1) > 0 Then
//found it
anchors.Item(ItemNr).click
curidx = right("00000" & ItemNr,5)
'ClickLink = curidx & linktext
ClickLink = curidx & "NONE"
ItemNr = anchors.length
End If
End If
next
do while IE.Busy
loop
end if
set anchors=nothing
else
msgbox("JsRL not found:" & chr(13) & chr(10) & URL)
End If
Set IE = nothing
Set objIE=nothing
Set objInstances = nothing
End Function
VBEND
SRT>PrintLic
Let>LicWindow=https://tools.xxxxx.com/emco/getPDF?forPrinting=YES*
WaitWindowOpen>%LicWindow%
//wait for the new IE window to open
If>WST_RESULT=FALSE
BlockInput>0
MessageModal>TimedOut At Step 001
Exit
EndIf
setfocus>%LicWindow%
WaitScreenText>Done
//this wait will either detect the Done when IE is done or the Done when
//Acrobat is done loading
Wait>10
//This is the problem Wait - I would rather sync with Acrobat being done
//opening the document and ready for commands
Press CTRL
Send>p
Release CTRL
//invoke Acrobat's Print dialog
Let>waitWindow=Print*
gosub>WfW
Wait>2
setfocus>Print*
Send>%LPrinter%
Wait>2
Press Enter
//select the printer name from Acrobat's Print dialog
WaitWindowOpen>Progress
//Acobat opens a window to display progress formatting the document for output
WaitWindowClosed>Progress
If>WW_RESULT=FALSE
BlockInput>0
MessageModal>TimeOut Waiting For Progess* To Close
Exit
EndIf
Wait>2
//Give some time for Acrobat Print to complete
Press CTRL
Send>w
Release CTRL
//Close the IE window [and Acrobat]
WaitWindowClosed>%LicWindow%
If>WW_RESULT=FALSE
BlockInput>0
MessageModal>TimeOut Waiting For %LicWindow% To Close
Exit
EndIf
END>PrintLic
//Start of Main Code
Let>JsURL=someURL
Let>LicLink=LicView
VBEval>ClickLink("%JsURL%",1,0,"%LicLink%"),results
Let>totReqLic=results
// get the total # of 'Lic View' links on the page
VBEval>ViewTableRows("%JsURL%",1,0,0),results
Let>returnedrows=%results%
// get the total # of rows in the table I am processing
Let>rcnt=0
Let>reqQty=1
while>rcntViewTableRows("%JsRL%",0,%rcnt%,0),results
//get the link to click from the table [row,col]
If>%results%-
VBEval>ClickLink("%JsURL%",0,%reqQty%,"%results%"),results2
//click the link
gosub>PrintLic
//print the document that opens via clicking the link
EndIf
Add>rcnt,1
EndWhile
Find the javascript function that is being executed...... i.e. getPDFForPrint()
and look at it to determine the link it is creating.
All the javascript code will be in your browser cache if it is downloaded as separate from the main HTML pages.
If the javascript is "inline" it will be between tags like so:
If it is external, look for tags like this one. Then look in the browser cache for the file referenced. In this example the file is called "urchin.js"
and look at it to determine the link it is creating.
All the javascript code will be in your browser cache if it is downloaded as separate from the main HTML pages.
If the javascript is "inline" it will be between tags like so:
If it is external, look for tags like this one. Then look in the browser cache for the file referenced. In this example the file is called "urchin.js"
Thanks for all your help and assistance!
Thanks for all your help and assistance! I really was not looking forward to changing the code to perform httpreqests, finding the links, downloading the pdfs, and printing using Acrobat Reader at the command prompt, etc., and, fortunately, the new day brought a different approach... it turns out that the 'do while ie.busy' loop was targeting the original page [where all the links are listed] and not the page being opened by clicking on the link. (I realized this when I put a msgbox into the vbscript code to display "done busy" when the loop exited...) From there, I changed the vbscript to check the appropriate [new] window opening for done-ness [with a second 'do while ie.busy' loop] , gave a wait>2 for good measure, and then wait for Acrobat to finish by checking with WaitScreenText>Done. I ran the code several times over and, even though I realize this is not as fail-safe as re-coding using all the great suggestions, I think it is much more sync'ed than when I started and I am happy with the results. This forum rocks! Thank you very much adroege for your input and great ideas! I will definitely utilize your suggestions for future IE and Acrobat automation projects!