VBA to save PDF from URL to local folder - vba

I'm trying to cycle through several url's to download the pdf to a local folder.
An example of the url is https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true
This is the vb I've written so far.
Dim sveloc As String
Dim svenme As String
Dim url As String
sveloc = Application.ActiveWorkbook.Path & "\Saved EPCs"
i = 7
Do Until sh01.Cells(i, 27) = "" 'all cells in the list are populated with no gaps
url = sh01.Cells(i, 27)
svenme = sh01.Cells(i, 2)
sveloc = sveloc & "\" & svenme & ".pdf"
ThisWorkbook.FollowHyperlink (url)
'code to open and save the pdf goes here
i = i + 1
Loop
Any help gratefully received as I'm really stumped on this one.
TIA.

Inspired by KJ's answer, without error checking etc. Just wanted to illustrate how you'd use shell to automate the entire process.
sveloc = Application.ActiveWorkbook.Path & "\Saved EPCs"
edgePath = Environ$("PROGRAMFILES(X86)") & "\Microsoft\Edge\Application\msedge.exe"
With CreateObject("WScript.Shell")
i = 7
Do Until Len(sh01.Cells(i, 27)) = 0 'all cells in the list are populated with no gaps
On Error Resume Next
.Run """" & edgePath & """ --profile-directory=Default --headless -print-to-pdf=""" & sveloc & "\" & sh01.Cells(i, 2) & ".pdf" & """ """ & sh01.Cells(i, 27) & """", 1, True
On Error GoTo 0
i = i + 1
Loop
End With

No need for VBA but you can use that to alter the variables so using your example from Windows we can run the build pdf at html runtime via Edge:-
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory=Default --headless -print-to-pdf=C:\Users\WDAGUtilityAccount\Desktop\8309-9619-9729-7796-8423.pdf "https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true"
and as if by magic the file is in less than a second on my desktop
There is no online pdf it is built by the browser. So it is essential to use the browser. You can remove the print header/footer with one extra switch, but cannot change orientation it will be A4 portrait in UK device.
-print-to-pdf-no-header see currently https://source.chromium.org/chromium/chromium/src/+/main:headless/app/headless_shell_switches.cc;l=60
one other switch may be of value if you only want smaller untagged files
-disable-pdf-tagging see https://source.chromium.org/chromium/chromium/src/+/main:headless/app/headless_shell_switches.cc;l=64
If you try to download without browser printing you will just get the raw HTML as needed for web page printing, thus calling browser remote print as above, will generate the desired "designed for the web" graphics copy.
curl -o test.htm https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true
In comments the question was raised how to adapt this approach for change of browser and keeping call simple so I suggest use a cmd or bat file to make that part easier. Thus from vba call something like
Batchfile 8309-9619-9729-7796-8423
#echo off
set "browser=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
set "filedir=C:\Users\WDAGUtilityAccount\Desktop"
set "urlpath=https://find-energy-certificate.service.gov.uk/energy-certificate"
"%browser%" --profile-directory=Default --headless --print-to-pdf="%filedir%\%~1.pdf" -print-to-pdf-no-header "%urlpath%/%~1?print=true"
However, beware calling pdf generations too fast, add a small wait between calls, even on multithreaded CPU writing PDF's at same time often leads to disasters, due to graphics resource conflicts.

Related

excel vba won't execute .bat but manually executing bat works fine

Hi I have a perfectly working bat named: start.bat
containing:
start C:\Users\*user*\Documents\*path*\hidebat.vbs
and once it is manually opened it works perfectly, meaning it opens hidebat.vbs, which opens a .bat minimized which uploads files to my cloud. Hence it's verified.
I've added
pause
to the start.bat to see what it does and when I tell excel to open the start.bat it will open cmd and display the exact command as required, but it will not execute the hidebat.vbs.
I expect that there is somehow some path constraint or environment constraint when it is run from excel that prevents it to actually reach out of that limited environment.
Within excel I have tried calling the .bat in 3 different ways with:
Dim path As String
path = Application.ActiveWorkbook.path
path = path & "\"
Dim MY_FILENAME3 As String
MY_FILENAME3 = path & "start.bat"
1.
retVal = Shell(MY_FILENAME3, vbNormalFocus)
' NOTE THE BATCH FILE WILL RUN, BUT THE CODE WILL CONTINUE TO RUN.
If retVal = 0 Then
MsgBox "An Error Occured"
Close #FileNumber
End
End If
2.
PathCrnt = ActiveWorkbook.path
Call Shell(PathCrnt & "start.bat")
3.
Dim batPath As String: batPath = path
Call Shell(Environ$("COMSPEC") & " /c " & batPath & "start.bat", vbNormalFocus)
Does anybody have any clue on why it will not execute the .bat file, or what I could do to ensure it will run correctly?
Note. I think it is because it opens the default path, so I'm gonna tell it to "cd" to the actual path where the excel is saved and where the .bat files are.
Yes that was it, the path was set to some random/standard/working/current path by command, so I had to add:
Print #FileNumber, "cd " & path
to the excel macro
so that start.bat looked like:
cd *path*
start *path*\hidebat.vbs
Hope this helps future me's.

Equivalent to Run Method(VBA) in OpenOffice Calc

I have been trying to convert a VBA for Excel code to OpenOffice Calc (basic) and now Im having trouble accessing an external program (and it´s database) to generate an output which I will use later in my code. In other words, I give an input, call the program and later I want an output file.
In VBA:
Prog = Worksheets("Settings").Cells(2, 2) & IPRODB & " -i " & DateiAll_in
Wait = True
Set sh = CreateObject("WScript.Shell")
RetVal = sh.Run(Prog, 0, Wait)
Worksheets("Settings").Cells(2, 2) is the program's path and IPRODB is the database's path, "-i" seems to be a command to the program and DateiAll_in is the Input file (.csv) I created before in the code.
The OpenOffice basic offers the function Shell(Pathname, Windowstyle, Param, bSync) to open external programs but It would not be the same since in the "run method" in VBA I am running a macro containing the program, its´s Database and Input File. (expression.Run(MacroName, varg1,varg2, (...))
Is there any alternative to the Shell function or can I use it in the same way as I used the "run method" in VBA?
From the OpenOffice.org forums (didn't test it myself):
Dim oSvc as object
oSvc = createUnoService("com.sun.star.system.SystemShellExecute")
Rem Launch notepad
oSvc.execute(ConvertToUrl("C:\windows\notepad.exe"), "", 0)
I used the Shell function. In the first argument of the function I added all the equivalents of "Worksheets("Settings").Cells(2, 2) & IPRODB & " -i " & DateiAll_in". I substituted Worksheets("Settings").Cells(2, 2) for the direct path of the program only because it was easier. So it worked with this code below:
Shell("C:\Program Files\*******\*****\*****.exe & IPRODB & "-i" & DateiAll_in",1,,True)

Visio 300+ pages, split into 300+ separate docs, or print to pdf, export to jpg/gif

I created 300+ page Visio drawing by importing data to create 300+ "org charts".
I say "org charts' bc they are actually drawings of a Crystal Report as 'CEO' and its datasource tables and fields as "employees".
I now have one huge Visio file with 300+ pages, each page is one report and its datasources. But my goal is to get 300+ separate documents each named appropriately. Using vba i can rename each page as desired or obtain desired name from page.
Ideally i want to have pdf files, not visio files but in pinch would do, and last desirable would be as jpg/gif.
I have tried:
exporting/saving each page as jpg/gif/html but get 920 error.. i am totally stumped after exhaustive search on how to modify resolution for each page to avoid 920 error, i mean what is the 'perfect' resolution required? very vague documentation available.
Sub ExportPagesAsFiles()
Dim PagsObj As Visio.Pages
Dim PagObj As Visio.Page
Dim ExportName As String
Dim ExportPath As String
Set PagsObj = ActiveDocument.Pages
'Open "C:\temp\exportLog.txt" For Output Shared As #1
For Each PagObj In PagsObj
ExportPath = "c:\Report_Visio\"
ExportName = ExportPath & PagObj.Name & ".jpg"
' ".gif"
' ".wmf"
' ".html"
'Print #1, ExportName
PagObj.Export ExportName
Next PagObj
'Close #1
End Sub
printing to pdf printer but hit pdf software dialogue (CutePDF). I have no admin rights to modify system registry and I am on Windows 7 machine and sendkeys is outlawed.
vba to create new doc, copy/paste page drawing into it, name new doc, save it with name. But some Visio quirk only copy paste page objects but not the captions and data behind them so they are blank shapes. Copying entire page contents is not clear to me after exhaustive search.
vba to save copy of 300+ doc with name of first page, then delete rest of pages. Open original 2nd time, save as second page, then delete rest of pages, and repeat 300+ times. I quit this after 10 or so pages and 3 hours.
Seems every possible solution path hits pitfalls, swamps, cliffs ..
As a general note, there is either very spartan, or obtusely technical, Visio information available on internet. With any other Office product, there are loads of info, examples, etc in forums etc. But Visio its crickets.
So wonder if any Visio developers can help me choose and navigate these solution paths!
Thanks.
Edit to add: I am using Visio Standard 2003 version
Edit to add Visio export to file code used
You can try to use PDFCreator (its open source).
It's a virtual printer, that prints to PDF, JPG, BMP, PNG (very useful for charts) and many other formats.
It has auto save option, configurable filenames and it can save printed document pages as separate files.
Some screenshots from application that configures virtual printer (this is PDFCreator 0.9.6).
Printing each page to separate file
Auto-save options:
I've decided to take a different approach.
I used VBA and Access to create each Visio page separately, instead of creating a 300+ page Visio doc. Visio's Org Chart import data wizard is powerful but leaves one stuck for options to get individual pages out, as I outlined above.
So, in Access, I looped through 300+ report records, selecting each report's data, one at a time, creating Visio drawing for that report, naming Visio file as report name and then saving and closing it.
Then I ended up with 300+ Visio files, each one showing a report's datasource tables and fields. Good enough.
Using VBA to create chart from data 'orgwiz' http://office.microsoft.com/en-ca/visio-help/make-visio-organization-charts-from-personnel-files-HA001077464.aspx
The code is
Set objVisio = CreateObject("Visio.Application")
Set objAddOn = objVisio.Addons.ItemU("OrgCWiz")
strCommand = "/DATASOURCE=c:\temp\MyDatabase.mdb, " _
& " TABLE=MyVisioDataSource, " _
& " DBQUALIFIER=Microsoft.Jet.OLEDB.4.0 " _
& " /NAME-FIELD=Data_Object_Name " _
& " /UNIQUEID-FIELD=Data_Object_ID " _
& " /MANAGER-FIELD=Data_Object_Parent_ID " _
& " /DISPLAY-FIELDS=" & strDisplayFields _
& " /CUSTOM-PROPERTY-FIELDS=" & strPropertyFields _
& " /SYNC-ACROSS-PAGES " _
& " /HYPERLINK-ACROSS-PAGES " _
& " /SHAPE-FIELD=MASTER_SHAPE " _
& " /PAGES=" & strReportName
objAddOn.Run ("/S-INIT")
Dim cmdArray, i
cmdArray = Split(strCommand, "/")
For i = LBound(cmdArray) To UBound(cmdArray)
objAddOn.Run ("/S-ARGSTR /" + cmdArray(i))
Next
objAddOn.Run ("/S-RUN ")

Can't KILL file using Word 2007 VBA if it's DOC format

The following code works for DOCX files, but gives "Access Denied" on DOC files:
Public Sub SaveGraded()
oldnamepath = ActiveDocument.FullName
oldname = GetFileName(ActiveDocument.Name)
oldExtension = getextension(ActiveDocument.FullName)
newname = oldname & "_GRADED" & "." & oldExtension
ActiveDocument.SaveAs filename:=newname
Kill oldnamepath
End Sub
Indeed, it's one of those weird things with Word, it'll hold a .doc file open exclusively much longer than a .docx.
You can use a loop to continually test delete until it works - don't use Kill for this since you can't trap it, use VBScript FileSystemObject.DeleteFile (str Name, bool Force), which is more reliable anyway - or you can use ActiveDocument.Close and reopen it. However I've noticed that even this doesn't always work and you sometimes have to follow that by Application.Quit; goodbye script execution unless you're automating it from an external application, which is what I do.

VB6 app printing Crystal Report to Adobe Distiller PDF - how to set PDF filename?

I've got a legacy app that I'm maintaining. It's a VB6 app that calls a Crystal Report (Crystal 8 it looks like) and then prints programmatically to the default printer, which is set up as Acrobat Distiller (v5.0). When it prints to PDF, it's automatically placing the resulting PDF in a folder (c:\pdf) and naming it as the first 5 characters of the crystal report filename. What's happening is that two reports with the same characters at the front of the filename are getting printed one after another, and the second is overwriting the first.
Are there settings somewhere for how distiller produces output? Can I adjust the output path, or the filename? Where/why is it only using the first five characters of the report filename as output? Or is that a Crystal function?
Is there a way to define the output PDF filename when printing from Crystal? It is printing the report like so:
With CrPt
.Connect = "DSN=" & Trim(sServerName) & ";UID=usernam;PWD=password;DSQ=database"
.ReportFileName = sReport
.Formulas(0) = "version=""" & App.Major & "." & App.Minor & "." & App.Revision & """"
.Destination = crptToPrinter
.Action = 1
End With
Any ideas?
I assume this is just a code snippet and there's more to the entire process. Try searching your entire VB6 code for Sreport. If you can find how Sreport is defined, that may answer your question.
I'm guessing somewhere is a line that says something like,
Sreport="C:\pdf\" & left(somevar,5)
Change that 5 to a 10 and you're good to go.