I have a folder containing 1650 HTML files that, due to local authorities, must be also printed in paper form.
I have tried with classic ctrl+A (even if I was trying on smaller quantities) and then I have looked for PRINT label in the right click menu, but there's any.
If I choose to print multiple jpg or pdf files, the PRINT voice appears.
How am I supposed to print multiple html files? A batch file? (I have no knowledge about how to).
I have also thought to convert html to pdf, but had no success with PDF Creator and PDF Architect.
Any of you with some experience to share?
I have wrtten some code mixing the one given by Tim and what I found on stackoverflow, but had no success.
Here it is:
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "C:\Users\mainUser\Desktop\ft"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
strFileName = objFile.Name
If objFSO.GetExtensionName(strFileName) = "html" Then
On Error Resume Next
Const OLECMDID_PRINT = 6
Const OLECMDEXECOPT_DONTPROMPTUSER = 2
Const PRINT_WAITFORCOMPLETION = 2
Dim objExplorer
Set objExplorer = CreateObject("InternetExplorer.Application")
objExplorer.Navigate objFolder.Path +"\"+ objFile.Name
objExplorer.Visible = 1
Do while objExplorer.ReadyState <> 4
WScript.Sleep 1000 'milliseconds
Loop
oIExplorer.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER
End If
Next
It just opens one html in internet explorer. I thought it would have open all the files, and already in PRINT "mode".
I think I am missing something.
See this thread for looping through files in a directory: How to do something to each file in a directory with a batch script
Then you can use the native PRINT command so your batch file could be as simple as this:
for /f "delims=|" %%f in ('dir /b c:\') do PRINT %%f
In light of the comments below:
Ahh. Then you will likely have to automate IE to print the page. Play with a VBScript along these lines:
Const OLECMDID_PRINT = 6
Const OLECMDEXECOPT_DONTPROMPTUSER = 2
Const PRINT_WAITFORCOMPLETION = 2
objStartFolder = "C:\Users\mainUser\Desktop\ft"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(objStartFolder)
Set objExplorer = CreateObject("InternetExplorer.Application")
Set oShell = CreateObject("Shell.Application")
For Each objFile In objFolder.Files
strFileName = objFile.Name
If objFSO.GetExtensionName(strFileName) = "html" Then
handle = objExplorer.Hwnd
objExplorer.Navigate objFolder.Path + "\" + objFile.Name
For Each Wnd In oShell.Windows
If handle = Wnd.Hwnd Then Set objExplorer = Wnd
Next
Do While objExplorer.Busy
WScript.Sleep 1000 'milliseconds
Loop
objExplorer.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER
End If
Next
Set oShell = Nothing
Set objFSO = Nothing
Set objFolder = Nothing
Set objExplorer = Nothing
3rd Update:
I fixed the code above. I apologize.Its been some time since I've worked with IE. Apparently IE treats each tab as a new instance of IE, and loading a document "creates" a new tab. As a result, we have to load the page and then find our IE window again so we can set it back to the variable.
Related
all.
I have some thousands of html files that i have to attach to email messages and send. Problem is that the files have images embeded in img tags, so when the user receives and opens the file attached, it is displayed wrong.
The first idea I had to solve this problem was to open each file in a browser and then print to PDF.
I've come with two approaches, and none of it works as expected:
1 - Opening html file in internet explorer and then using the PDFcreator object to print, messes with some barcode coded in the html, turning the pdf created useless.
2 -Opening html file in internet explorer and then using "Microsoft Print to PDF" virtual printer saves the file as expected - all images, right barcodes - but it prompts for a file name and save path for each file before saving.
Second approach seems to return a better result. Actually it just is not practical.
So, is there any way to avoid the "Microsoft Print to PDF" printer prompt, setting path and file name programmatically in excel vba?
And how do i make ExecWB wait before starting a new loop?
PDFcreator approach:
Sub PrintViaPDFCREATOR()
'Creates PDF Creator object, killing any if already opened:
Dim pdfjob As PDFCreator.clsPDFCreator
Do
DoEvents
bRestart = False
Set pdfjob = New PDFCreator.clsPDFCreator
If pdfjob.cStart("/NoProcessingAtStartup") = False Then
Shell "taskkill /f /im PDFCreator.exe", vbHide
Set pdfjob = Nothing
bRestart = True
End If
Loop Until bRestart = False
Dim IE As InternetExplorer
Set IE = New InternetExplorer
IE.Visible = True
Dim FSO As Scripting.FileSystemObject
Dim objfolder As Scripting.Folder
Dim objfiles As Scripting.Files
Dim F As Scripting.File
FilePath = ThisWorkbook.Path & "\MyFolder\"
Set FSO = New Scripting.FileSystemObject
Set objfolder = FSO.GetFolder(FilePath)
Set objfiles = objfolder.Files
For Each F In objfiles
IE.Navigate2 F.Path
Do While IE.readyState <> 4
DoEvents
Loop
'PDF creator Settings
With pdfjob
.cOption("UseAutoSave") = 1
.cOption("UseAutosaveDirectory") = 1
.cOption("AutosaveDirectory") = FilePath
.cOption("AutosaveFilename") = Replace(F.Name, ".htm", ".pdf")
.cOption("AutosaveFormat") = 0 ' 0 = PDF
.cClearCache
End With
'Prints without prompt :)
IE.ExecWB 6, 2, "", ""
'Hold on til Job is finished
Do Until pdfjob.cCountOfPrintjobs = 1
DoEvents
Loop
pdfjob.cPrinterStop = False
'Check if there is any file in the queue
Do Until pdfjob.cCountOfPrintjobs = 0
DoEvents
Loop
Next
pdfjob.cClose
Set pdfjob = Nothing
End Sub
Issue with this code: There is some barcodes in the html file composed by many divs of 1 to 2px borders. By this method, the pdf has unrecognizable barcodes. It seems like it merges some of the "bars" during conversion, making it unreadeable to optic scanner.
Microsoft Print to PDF approach:
Sub PrintViaMicrosoftToPDF()
'Save the current active printer for later reset:
Dim OldPrinter
OldPrinter = Trim(Split(Application.ActivePrinter, "in")(0))
'Define the new active printer
CreateObject("WScript.Network").SetDefaultPrinter "Microsoft Print to PDF"
Dim objShell
Set objShell = CreateObject("WScript.Shell")
Dim IE As InternetExplorer
Set IE = New InternetExplorer
IE.Visible = True
Dim FSO As Scripting.FileSystemObject
Dim objfolder As Scripting.Folder
Dim objfiles As Scripting.Files
Dim F As Scripting.File
FilePath = ThisWorkbook.Path & "\MyFolder\"
Set FSO = New Scripting.FileSystemObject
Set objfolder = FSO.GetFolder(FilePath)
Set objfiles = objfolder.Files
For Each F In objfiles
IE.Navigate2 F.Path
Do While IE.readyState <> 4
DoEvents
Loop
'Prints but prompts :(
IE.ExecWB 6, 2, "", ""
Next
'Reset Printer
CreateObject("WScript.Network").SetDefaultPrinter OldPrinter
End Sub
Issue with this code: It prints the right document in pdf, but the user has to choose save path and file name.
If there is other way of sending the html files attached to eamil message with the embeded images without conversion, or with other approches regarding to file conversion, i'm gradly accepting too.
But i'm limited to Excel/Vba.
Thanks in advance.
I have many html files in c:\temp\ which need to be converted in the same directory to .docx files.
I have Office 2013. So i guess it doesnt need any converter but instead only opening html in word in the background and saving it as a .docx.
I found a script which is converting doc to pdf:
vbscript to convert word doc to pdf
Const wdExportAllDocument = 0
Const wdExportOptimizeForPrint = 0
Const wdExportDocumentContent = 0
Const wdExportFormatPDF = 17
Const wdExportCreateHeadingBookmarks = 1
if Wscript.Arguments.Count > 0 Then
' Get the running instance of MS Word. If Word is not running, Create it
On Error Resume Next
Set objWord = GetObject(, "Word.Application")
If Err <> 0 Then
Set objWord = CreateObject("Word.Application")
End If
On Error GoTo 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(WScript.Arguments(0))
Set objDoc = objWord.Documents.Open(WScript.Arguments(0),,TRUE)
'Export to PDF using preferred settings
pdf = objWord.ActiveDocument.ExportAsFixedFormat( _
WScript.Arguments(1), _
wdExportFormatPDF, False, wdExportOptimizeForPrint, _
wdExportAllDocument,,, _
wdExportDocumentContent, _
False, True, _
wdExportCreateHeadingBookmarks _
)
'Quit MS Word
objWord.DisplayAlerts = False
objWord.Quit(False)
set objWord = nothing
set objFSO = nothing
Else
msgbox("You must select a file to convert")
End If
Changing the const wdExportFormatPDF to wdFormatDocumentDefault = 16 throws an error.
Any idea how to open and save as all files in the c:\temp directory?
The ExportAsFixedFormat method saves a document as PDF or XPS format..
Read more about it here.
For saving your file as docx, just use the SaveAs method.
It is available for Office 2013 and later
objWord.ActiveDocument.SaveAs ("C:\SomeDir\yourFileName.docx")
Starting with this as the code:
Const ForReading = 1
Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objSourceFile = objFSO.OpenTextFile("Path\file.csv", ForReading)
Set objDestinationFile = objFSO.OpenTextFile("Path\Database.csv", ForAppending)
'Loop start files in dir
Do Until objSourceFile.AtEndOfStream
strLine = objSourceFile.ReadLine
arrFields = Split(strLine, ",")
If arrFields(0) <> """""" Then
strContents = strContents & arrFields(1) & ","
End If
Loop
strContents = strContents & vbCrLf
objSourceFile.Close
objDestinationFile.Write strContents
'Move source file to processed directory
'Loop end files in dir
objDestinationFile.Close
Which is fine for one file at a time, but I'm trying to append many files into the single file.
Appreciate any tips.
Thanks.
Edit: So this was a request that started with a single file which turned into having to migrate many files. The original CSV needed to have its format changed and then placed into another easier to use CSV.
The issue is that there many files and each source file has to be modified before placing it into the destination file. I am new to VB Scripting and I was trying to be concise with my text. Thanks.
I appreciate the help.
I have a VBA function that creates a FileSystemObject instance, and uses it to read the contents of a directory and perform some stuff based on conditional logic.
In the function, I use a loop that reads the contents of the dir. My question is: What happens when a new file is added to the dir after the loop has been opened but before it is closed? Does the operating system know to include this file in the collection of files? Or is a 'snapshot' of sorts taken of the dir when the loop is opened, causing the newly-added file to be overlooked?
Please correct me on any improper terminology I may have used above.
My code is below:
Function fn_FileCheckType()
'load INI data
fn_ReadINI
'does filename end with .xls or .xlsx?
'read files from iDumpFolder
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")
Dim objFolder As Object
Set objFolder = fs.GetFolder(iDumpFolder)
Dim objFile As Object
For Each objFile In objFolder.files
If (objFile.Name Like "*.xls" Or objFile.Name Like "*.xlsx") Then
'do nothing
Debug.Print objFile.Name & " is valid."
Else
'copy to invalid file archive and delete from inbox
objFile.Copy (iInvalidArchive & "\" & objFile.Name)
MsgBox (objFile.Name & " is not saved as .xls or .xlsx. Please modify and re-import.")
objFile.Delete
End If
Next 'objFile
'Cleanup
Set objFolder = Nothing
Set objFile = Nothing
Set fs = Nothing
End Function
The following VBA code indicates that the .Files collection is a "snapshot" of the files in a folder at the moment that the collection is referenced. Before running the code I placed two files in the test folder: b.txt and c.txt. The Debug.Assert statement suspends the code immediately after entering the loop for the first time. While paused, I added the files a.txt and d.txt and then hit F5 to resume execution. The code only lists the two files that were originally in the folder.
Option Compare Database
Option Explicit
Public Sub FilesCollectionTest()
Dim fso As New FileSystemObject, objFolder As Folder, objFile As File, i As Long
Set objFolder = fso.GetFolder("C:\__tmp\zzzTest")
i = 1
For Each objFile In objFolder.Files
Debug.Assert i > 1
Debug.Print objFile.Name
i = i + 1
Next
Set objFile = Nothing
Set objFolder = Nothing
Set fso = Nothing
End Sub
The way you have your example written objFolder.files is re-evaluated on every iteration and would thus pick up any change. But, I was a little surprised to see that if you so something like
Dim fso As New FileSystemObject
Dim files, f
Set files = fso.GetFolder("C:\~\My test Folder").files
For Each f In files
debug.print f.name
Next f
Debug.Print ' break point here
Debug.Print
That even if you are not in the loop Files is refreshed. I put a breakpoint on the firs Print after the loop, added a file to my folder then hit F8, and Files updated to the right file count.
I have this script in my hta application between </head> and <body>.
And it does work: it resizes and opens the wav files. But before it opens the wav files, I want it to load a file kind of like an ad popup if you will that will open as another hta window. How would I add the necessary lines of code to make it open say ad.hta before playing the .wav files?
<script language="VBScript">
Sub Window_OnLoad
Dim width,height
width=470
height=400
self.ResizeTo width,height
Set objVoice = CreateObject("SAPI.SpVoice")
Set objFile = CreateObject("SAPI.SpFileStream.1")
objFile.Open "111(2).wav"
objVoice.Speakstream objFile
Set objVoice = CreateObject("SAPI.SpVoice")
Set objFile = CreateObject("SAPI.SpFileStream.1")
objFile.Open "11537.wav"
objVoice.Speakstream objFile
End Sub
</script>
I have tried this:
Const NORMAL_WINDOW = 1
Set objShell = CreateObject("Shell.Application")
objShell.ShellExecute "notepad.exe", "test.txt", , , NORMAL_WINDOW
Putting that just after the
self.ResizeTo width,height
The resulting action is in this order:
Program Opens,
Error continue running scripts shows
Text file opens
Audio Plays
But the program wont do what its supposed to do after that.
My text to speech function breaks.
I figured it out
i did have to use
Const NORMAL_WINDOW = 1
Set objShell = CreateObject("Shell.Application")
objShell.ShellExecute "notepad.exe", "test.txt", , , NORMAL_WINDOW
Got it working