Output MS Publisher to PRN files
I needed a method to programatically check a series of directories for .pub and save as .prn for later batch processing to .pdf through Distiller. There were hundreds, and I just couldn't make myself do it by hand... After a little Googling, I found some useful code snippets from MS, and Google groups. Comments and credits were left intact in the functions I borrowed, as well as my own. Hope someone finds this as useful as I did.
Option Explicit Function GetFiles(strPath As String, _ dctDict As Scripting.Dictionary, _ Optional blnRecursive As Boolean) As Boolean ' This procedure returns all the files in a directory into ' a Dictionary object. If called recursively, it also returns ' all files in subfolders. Dim fsoSysObj As Scripting.FileSystemObject Dim fdrFolder As Scripting.Folder Dim fdrSubFolder As Scripting.Folder Dim filFile As Scripting.File ' Return new FileSystemObject. Set fsoSysObj = New Scripting.FileSystemObject On Error Resume Next ' Get folder. Set fdrFolder = fsoSysObj.GetFolder(strPath) If Err <> 0 Then ' Incorrect path. GetFiles = False GoTo GetFiles_End End If On Error GoTo 0 ' Loop through Files collection, adding to dictionary. For Each filFile In fdrFolder.Files dctDict.Add filFile.Path, filFile.Path Next filFile ' If Recursive flag is true, call recursively. If blnRecursive Then For Each fdrSubFolder In fdrFolder.SubFolders GetFiles fdrSubFolder.Path, dctDict, True Next fdrSubFolder End If ' Return True if no error occurred. GetFiles = True GetFiles_End: Exit Function End Function Function CountInString(ByVal strCountIn As String, ByVal strCountThis As String) As Long Dim lngLoop As Long Dim lngCount As Long For lngLoop = 1 To Len(strCountIn) If Mid$(strCountIn, lngLoop, Len(strCountThis)) = strCountThis Then lngCount = lngCount + 1 End If Next lngLoop CountInString = lngCount End Function Function Dir_Make(S As String) As Boolean ' Makes a Directory, and each Branch if necessary. ' Example: Status = Dir_Make("C:\Dir1\Dir2\Dir3") ' Returns True if successful ' For Excel 2k due to Split() Function ' By: Dana DeLouis: d...@msn.com ' 6/7/99 Dim V As Variant Dim j As Integer Dim sDir As String Dim drv As String Dim fs As Object Const vblf2 = vbLf & vbLf '// Check for invalid Windows Characters... S = Trim(S) j = 0 j = j + InStr(1, S, "/") j = j + InStr(3, S, ":") ' the ":" in C: j = j + InStr(1, S, "*") j = j + InStr(1, S, "?") j = j + InStr(1, S, ">") j = j + InStr(1, S, "<") j = j + InStr(1, S, "|") j = j + InStr(1, S, """") If j > 0 Then MsgBox "Folder " & S & vbLf & "has invalid Characters / : * ? < > |" Exit Function End If '// Set fs = CreateObject("Scripting.FileSystemObject") With fs drv = .GetDriveName(S) & Application.PathSeparator ' ie C: '// Valid Drive? (as in A:\, C:\, D:\ ...etc) If Not .DriveExists(drv) Then MsgBox "Drive letter " & drv & " not valid !" & vblf2 & S Exit Function ' ->False End If '// Is Drive Ready (as in no Floppy in A:)? If Not .GetDrive(drv).IsReady Then MsgBox "Drive " & drv & " is not Ready !" & vblf2 & S Exit Function ' ->False End If '// Unable if CD-Rom If .GetDrive(drv).DriveType = 4 Then MsgBox "Unable: " & drv & " is a CD-ROM !" & vblf2 & S Exit Function ' ->False End If '// Break apart string s V = Split(Trim(S), "\") '// First test each branch for a File with no Extension! sDir = drv For j = 1 To UBound(V) sDir = .BuildPath(RTrim$(sDir), V(j)) If .FileExists(sDir) Then MsgBox "Unable because: " & vbLf & sDir & vblf2 & " ...is a File!" Exit Function ' ->False ElseIf Not .FolderExists(sDir) Then Exit For ' Does not exist..No need to continue End If Next j 'Everything looks Ok, so make Directories sDir = drv For j = 1 To UBound(V) sDir = .BuildPath(RTrim$(sDir), V(j)) If Not .FolderExists(sDir) Then .CreateFolder sDir Next j End With Set fs = Nothing Dir_Make = True End Function Sub TestGetFiles() ' Call to test GetFiles function. Dim strPub As String Dim dctDict As Scripting.Dictionary Dim varItem As Variant Dim strSrcPath As String Dim strOutPath As String Dim intHCnt As Integer Dim intOutPos As Integer Dim intPathCnt As Integer Dim AppPub As Application Dim DocPub As Document Dim strDestPath As String Dim strFile As String Dim strName As String Dim intEnd As Integer Dim intPos As Integer Dim strFinalOutPath As String strDestPath = "e:\lol\out\" strSrcPath = "e:\lol\publisher\" strPub = "pub" ' Create new dictionary. Set dctDict = New Scripting.Dictionary ' Call recursively, return files into Dictionary object. If GetFiles(strSrcPath, dctDict, True) Then Set AppPub = New Publisher.Application ' Print items in dictionary. For Each varItem In dctDict 'check to see if this is a publisher file If Right(varItem, 3) = strPub Then ' strip out the full filename intPos = InStrRev(varItem, "\", , vbTextCompare) ' increment the counter to not swallow our "\" intPos = intPos + 1 ' and get our filename strFile = Mid(varItem, intPos) ' now strip off the .pub extension intEnd = Len(strFile) - 4 strName = Left(strFile, intEnd) intOutPos = InStr(18, varItem, "\", 1) intHCnt = CountInString(varItem, "\") If intHCnt > 3 Then intPathCnt = intOutPos - 17 strOutPath = Mid(varItem, 18, intPathCnt) Dir_Make (strDestPath & strOutPath) End If ' consider using a replace function to get rid of ' commas and periods Set DocPub = AppPub.Open(varItem) AppPub.ActiveWindow.Visible = True strFinalOutPath = strDestPath & strOutPath 'set it to lower case strName = LCase(strName) strName = Replace(strName, ",", "_") strName = Replace(strName, "&", "_and_") With DocPub .ActivePrinter = "Acrobat Distiller" .PrintOut _ PrintToFile:=strFinalOutPath & strName & ".prn" .Close End With Else Debug.Print "this is crap" End If Next End If End Sub
Comments