Split PDF into new files per page - Excel VBA - excel

I am trying to split a pdf into multiple new files per page.
I found this code on Excel Forum
I modified it to to suit my folder path and file.
I have also added the Acrobat.tdl library to references.(Don't have the actual acrobat pro installed. Followed the steps suggested in this link)
However, when I try to run the code, I get the error - Run-time error '429': ActiveX component can't create object.
The error occurs on the line Set PDDoc = CreateObject("AcroExch.pdDoc")
Here is the full code:
Sub SplitPDF()
Dim PDDoc As Acrobat.CAcroPDDoc, newPDF As Acrobat.CAcroPDDoc
Dim PDPage As Acrobat.CAcroPDPage
Dim thePDF As String, PNum As Long
Dim f As String, i As Integer, Result As Variant, NewName As String
f = ThisWorkbook.Path & "\"
thePDF = f & "CDE_9740240D_2020-09-08.pdf"
Set PDDoc = CreateObject("AcroExch.pdDoc")
Result = PDDoc.Open(thePDF)
If Not Result Then
MsgBox "Can't open file: " & thePDF
Exit Sub
End If
'...
PNum = PDDoc.GetNumPages
For i = 0 To PNum - 1
Set newPDF = CreateObject("AcroExch.pdDoc")
newPDF.Create
NewName = f & " Page_" & i & "_of_" & PNum & ".pdf"
newPDF.InsertPages -1, PDDoc, i, 1, 0
newPDF.Save 1, NewName
newPDF.Close
Set newPDF = Nothing
Next i
End Sub
Can someone please help me make this code work.

Related

page sizing & handling on acrobar pro dc via vba excel

I have managed convert a list of images onto pdf, then gathered them in a single file and then print them as multiple pages 10 columns x 14 rows so I can print in a single sheet 140 original images.
All of these with sendkeys method which was absolutely madness and frustrating but at the end it works pretty fine, the only handicap is that I have to do this almost everyday and once I run the sendkeys macro I can't do nothing with my computer until it ends which could probably be hours
I'm trying to do this in a less "messy" way
I have managed to convert the images in pdf easely with this code I modified from a search on internet (just in case someone find it usefull for him/her)
Sub png_to_pdf()
Dim Acroapp As New Acrobat.Acroapp
Dim pddoc As New Acrobat.AcroPDDoc
Set Acroapp = CreateObject("AcroExch.App")
Set pddoc = CreateObject("AcroExch.pddoc")
aux_pngtopdf "F:\ES-VAL\PURCH-U\CARLOS\qr", pddoc
End Sub
Private Sub aux_pngtopdf(ByVal xFolderName As String, ByVal pddoc As Object)
Dim xFileSystemObject As Object
Dim xFolder As Object
Dim xSubFolder As Object
Dim xFile As Object
Dim xfilepdf As String
Set xFileSystemObject = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFileSystemObject.GetFolder(xFolderName)
For Each xFile In xFolder.Files
If Right(xFile, 3) = "png" And Application.CountIf(Columns(10), Mid(xFolderName, 29, 9)) = 0 And Application.CountIf(Columns(11), Mid(xFolderName, 29, 9)) = 0 Then
pddoc.Open xFile
xfilepdf = Left(xFile, Len(xFile) - 3) & "pdf"
pddoc.Save PDSaveFull, xfilepdf
End If
Next xFile
For Each xSubFolder In xFolder.subfolders
If Len(xSubFolder) < 250 Then
aux_pngtopdf xSubFolder.Path, pddoc
End If
Next xSubFolder
Set xFile = Nothing
Set xFolder = Nothing
Set xFileSystemObject = Nothing
End Sub
I'm changing the code I found (I don't really remember if here or if in any other site) to merge all the pdf into a single one and it seems it would be fine
Sub merge_pdf()
Const DestFile As String = "MergedFile.pdf" ' <-- change to suit
Dim MyPath As String, MyFiles As String
Dim a() As String, i As Long, f As String
Dim j As Integer
j = 4
' Choose the folder or just replace that part by: MyPath = Range("E3")
With Application.FileDialog(msoFileDialogFolderPicker)
'.InitialFileName = "C:\Temp\"
.AllowMultiSelect = False
If .Show = False Then Exit Sub
MyPath = .SelectedItems(1) & "\" & Cells(j, 3).Value
DoEvents
End With
' Populate the array a() by PDF file names
If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
ReDim a(1 To 2 ^ 14)
f = Dir(MyPath & "*.pdf")
While Len(f)
If StrComp(f, DestFile, vbTextCompare) Then
i = i + 1
a(i) = f
End If
f = Dir()
Wend
' Merge PDFs
If i Then
ReDim Preserve a(1 To i)
MyFiles = Join(a, ",")
Application.StatusBar = "Merging, please wait ..."
Call aux_MergePDFs(MyPath, MyFiles, DestFile)
Application.StatusBar = False
Else
MsgBox "No PDF files found in" & vbLf & MyPath, vbExclamation, "Canceled"
End If
End Sub
Private Sub aux_MergePDFs(MyPath As String, MyFiles As String, Optional DestFile As String = "MergedFile.pdf")
Dim a As Variant, i As Long, n As Long, ni As Long, p As String
Dim Acroapp As New Acrobat.Acroapp, PartDocs() As Acrobat.CAcroPDDoc
If Right(MyPath, 1) = "\" Then p = MyPath Else p = MyPath & "\"
a = Split(MyFiles, ",")
ReDim PartDocs(0 To UBound(a))
On Error GoTo exit_
If Len(Dir(p & DestFile)) Then Kill p & DestFile
For i = 0 To UBound(a)
' Check PDF file presence
If Dir(p & Trim(a(i))) = "" Then
MsgBox "File not found" & vbLf & p & a(i), vbExclamation, "Canceled"
Exit For
End If
' Open PDF document
Set PartDocs(i) = CreateObject("AcroExch.PDDoc")
PartDocs(i).Open p & Trim(a(i))
If i Then
' Merge PDF to PartDocs(0) document
ni = PartDocs(i).GetNumPages()
If Not PartDocs(0).InsertPages(n - 1, PartDocs(i), 0, ni, True) Then
MsgBox "Cannot insert pages of" & vbLf & p & a(i), vbExclamation, "Canceled"
End If
' Calc the number of pages in the merged document
n = n + ni
' Release the memory
PartDocs(i).Close
Set PartDocs(i) = Nothing
Else
' Calc the number of pages in PartDocs(0) document
n = PartDocs(0).GetNumPages()
End If
Next
If i > UBound(a) Then
' Save the merged document to DestFile
If Not PartDocs(0).Save(PDSaveFull, p & DestFile) Then
MsgBox "Cannot save the resulting document" & vbLf & p & DestFile, vbExclamation, "Canceled"
End If
End If
exit_:
' Inform about error/success
If Err Then
MsgBox Err.Description, vbCritical, "Error #" & Err.Number
ElseIf i > UBound(a) Then
MsgBox "The resulting file is created:" & vbLf & p & DestFile, vbInformation, "Done"
End If
' Quit Acrobat application
Acroapp.Exit
Set Acroapp = Nothing
End Sub
But I don't have any clue on how to print several pages of the pdf into a single one. Not interested in only 16 pages per sheet (since the images I try to print are QR codes 12mmx12mm so it fits pretty fine 140 of them in a single sheet) which could be more or less easy if you set adobe pdf as your default printer and setup it to print 16 pages per sheet (I also found part of a code that could fit to this purpose)
Any clue will be apreciated
Thanks

VBA codes not running after re-installed windows10

I have already run these codes successfully more than 200 times as I download files on daily basis.
Also having another copies of same code in different drives as reference in case of any issue.
Last night I re-installed my Win10 and office 2019 pro plus both are updated to latest.
And now the codes are not running.
I am not a hard core programmer, not able to understand what's wrong with them. Do I need to install any reference library or .net framework or something else.
The codes stopped at
"Name oldFullName As newfullname"
2 files are there do be downloaded and renamed
The codes get 1st file successfully but, do not rename it so not going to 2nd loop to download 2nd file and to further rename that.
Public IsExit As Boolean
Global Path As String
Private Sub Download_AllZip()
Path = ThisWorkbook.Worksheets("Downloads").Range("C3").Value
Application.ScreenUpdating = FALSE
Application.EnableEvents = FALSE
Dim LR As Long
Dim Fileurl As String, Filename As String, y As String, z As String 'msg as string
Dim r As Long
LR = Sheets("Downloads").Range("C6").Row
For r = 5 To LR
Fileurl = Sheets("Downloads").Range("C" & r).Value
If InStr(1, Fileurl, ".zip") <> 0 Then
filepath = Path
End If
Dim Obj1 As Object
Set Obj1 = CreateObject("Microsoft.XMLHTTP")
Obj1.Open "GET", Fileurl, FALSE
Obj1.send
If Obj1.Status = 200 Then
Set Obj2 = CreateObject("ADODB.Stream")
Obj2.Open
Obj2.Type = 1
Obj2.Write Obj1.responseBody
Obj2.SaveToFile (filepath & getfilename(Fileurl)), 2 ' 1 = no overwrite, 2 = overwrite
Call UnzipFileRename(filepath & getfilename(Fileurl), filepath, Sheets("Downloads").Range("D" & r).Value)
Obj2.Close
y = (y & vbCr & Sheets("Downloads").Range("D" & r).Value & " = Downloaded & Converted To .CSV in " & filepath)
ThisWorkbook.Sheets("Downloads").Range("E" & r).Value = "Downloaded" '/STATUS
Else
z = (z & vbCr & Sheets("Downloads").Range("D" & r).Value & " = Failed To Download")
ThisWorkbook.Sheets("Downloads").Range("E" & r).Value = "Failed" '/STATUS
End If
Next r
End Sub
Function getfilename(filepath As String)
Dim v_string() As String
v_string = Split(filepath, "/")
getfilename = v_string(UBound(v_string))
End Function
Private Sub UnzipFileRename(zipFullName As Variant, unzipPath As Variant, newName As String)
Dim ShellApp As Object, oldFullName As String, newfullname As String, n As Variant
Set ShellApp = CreateObject("Shell.Application")
'/get file name
For Each n In ShellApp.Namespace(zipFullName).Items
a = a + 1
oldFullName = unzipPath & n.Name
newfullname = unzipPath & newName
If a = 1 Then Exit For
Next n
'/delete previous version to avoid any issues
DeleteFile oldFullName
DeleteFile newfullname
'/unzip the file
ShellApp.Namespace(unzipPath).CopyHere ShellApp.Namespace(zipFullName).Items
'/rename the file
Name oldFullName As newfullname
'/delete zip file
DeleteFile CStr(zipFullName)
End Sub
Private Sub DeleteFile(PathAndName As String)
On Error Resume Next
Kill PathAndName
On Error GoTo 0
End Sub

Create folder and subfolder

I have an Excel file with hundreds of Customer names and several article numbers.
I want to check if a folder with selected customer name exists and create a folder if it is missing.
Once the customer folder is found or created, check if there is a folder for each article number and if it is missing, create one.
I found code that seems to do all that and more posted by Scott Holtzman.
I have referenced Microsoft Scripting Runtime as the code requests.
Both of the "If not" statements are marked red and the pop-up window only says "Compile error".
I checked the syntax of "If not" statements and it seems to be correct.
'requires reference to Microsoft Scripting Runtime
Sub MakeFolder()
Dim strComp As String, strPart As String, strPath As String
strComp = Range("A1") ' assumes company name in A1
strPart = CleanName(Range("C1")) ' assumes part in C1
strPath = "C:\Images\"
If Not FolderExists(strPath & strComp) Then
'company doesn't exist, so create full path
FolderCreate strPath & strComp & "\" & strPart
Else
'company does exist, but does part folder
If Not FolderExists(strPath & strComp & "\" & strPart) Then
FolderCreate strPath & strComp & "\" & strPart
End If
End If
End Sub
Function FolderCreate(ByVal path As String) As Boolean
FolderCreate = True
Dim fso As New FileSystemObject
If Functions.FolderExists(path) Then
Exit Function
Else
On Error GoTo DeadInTheWater
fso.CreateFolder path ' could there be any error with this, like if the path is really screwed up?
Exit Function
End If
DeadInTheWater:
MsgBox "A folder could not be created for the following path: " & path & ". Check the path name and try again."
FolderCreate = False
Exit Function
End Function
Function FolderExists(ByVal path As String) As Boolean
FolderExists = False
Dim fso As New FileSystemObject
If fso.FolderExists(path) Then FolderExists = True
End Function
Function CleanName(strName as String) as String
'will clean part # name so it can be made into valid folder name
'may need to add more lines to get rid of other characters
CleanName = Replace(strName, "/","")
CleanName = Replace(CleanName, "*","")
' etc...
End Function
Take a look at the below example, it shows one of the possible approaches using recursive sub call:
Option Explicit
Sub TestArrays()
Dim aCustomers
Dim aArticles
Dim sCustomer
Dim sArticle
Dim sPath
sPath = "C:\Test"
aCustomers = Array("Customer01", "Customer02", "Customer03", "Customer04", "Customer05")
aArticles = Array("Article01", "Article02", "Article03", "Article04", "Article05")
For Each sCustomer In aCustomers
For Each sArticle In aArticles
SmartCreateFolder sPath & "\" & sCustomer & "\" & sArticle
Next
Next
End Sub
Sub TestFromSheet()
Dim aCustomers
Dim aArticles
Dim i
Dim j
Dim sPath
sPath = "C:\Test"
With ThisWorkbook.Sheets(1)
aCustomers = .Range(.Range("A1"), .Range("A1").End(xlDown)).Value
aArticles = .Range("B1:B10").Value
End With
For i = LBound(aCustomers, 1) To UBound(aCustomers, 1)
For j = LBound(aArticles, 1) To UBound(aArticles, 1)
SmartCreateFolder sPath & "\" & aCustomers(i, 1) & "\" & aArticles(j, 1)
Next
Next
End Sub
Sub SmartCreateFolder(sFolder)
Static oFSO As Object
If oFSO Is Nothing Then Set oFSO = CreateObject("Scripting.FileSystemObject")
With oFSO
If Not .FolderExists(sFolder) Then
SmartCreateFolder .GetParentFolderName(sFolder)
.CreateFolder sFolder
End If
End With
End Sub
Sub TestArrays() checks and creates folders for customers and articles from the hardcoded arrays, and Sub TestFromSheet() gets customers and articles from the first worksheet, as an example customers range from A1 up to the last element, so it should be more than one element there, and articles set to fixed range B1:B10, like shown below:
The StrComp Issue
You cannot use StrComp, its a reserved word, actually a string function. I lost about 15 minutes the other day on this issue.
VBA says: Returns a Variant (Integer) indicating the result of a string comparison.
If you want to shorthand a bunch of that code, use MKDIR to create each level of folder\subfolder with error pass-over.
Option Explicit
Sub main()
Dim pth As String
pth = "c:\test\abc\123\test_again\XYZ\01-20-2019"
'folder may or may not exist
makeFolder pth
'folder definitely exists
End Sub
Sub makeFolder(fldr As String)
Dim i As Long, arr As Variant
'folder may or may not exist
arr = Split(fldr, Chr(92))
fldr = arr(LBound(arr))
On Error Resume Next
For i = LBound(arr) + 1 To UBound(arr)
fldr = Join(Array(fldr, arr(i)), Chr(92))
MkDir fldr
Next i
On Error GoTo 0
'folder definitely exists
End Sub
To rename an existing file to a new location WITH creation of all subdirectories, you can use:
File_Name_OLD = File_Pad_OLD & "Test.txt"
File_Pad_NEW = "e:\temp\test1\test2\test3\"
File_Name_NEW = File_Pad_NEW & "Test.txt"
X = File_Pad_NEW
A = 1
Do Until A = 0
A = InStr(X, "\")
Y = Y & Left(X, A)
X = Mid(X, A + 1)
If Dir(Y, 16) = "" Then MkDir Y
Loop
Name File_Name_OLD As File_Name_NEW
This is creating the new path with subdirectories and renames the old file to the new one.

How to loop through files in a folder Excel Mac 2016

I'm trying to combine several excel files into one. For this I've been using and modifying an old answer I found here, but I ran into trouble while running it on Excel 2016 for Mac (it worked ok with Excel 2011 for Mac, with some changes).
In Excel 2016 (Mac), the following code runs through the loop once, after which it prints the name of the first file in the selected folder, but then it stops.
In Excel 2011 (Mac), it correctly prints the names of all files in the selected folder.
Sub wat()
Dim FilesFolder As String, strFile As String
'mac excel 2011
'FilesFolder = MacScript("(choose folder with prompt ""dis"") as string")
'mac excel 2016
FilesFolder = MacScript("return posix path of (choose folder with prompt ""dat"") as string")
If FilesFolder = "" Then Exit Sub
strFile = Dir(FilesFolder)
Do While Len(strFile) > 0
Debug.Print "1. " & strFile
strFile = Dir
Loop
MsgBox "ded"
End Sub
So, I'm pretty new at this, but it looks to me like strFile = Dir is not working properly.
I looked at the Ron deBruin page:
Loop through Files in Folder on a Mac (Dir for Mac Excel)
but to be honest that was a little too complicated for me to comprehend and modify to my needs.
Any help is appreciated, and thanks for the patience!
Option Explicit
Sub GetFileNames()
'Modified from http://www.rondebruin.nl/mac/mac013.htm
Dim folderPath As String
Dim FileNameFilter As String
Dim ScriptToRun As String
Dim MyFiles As String
Dim Extensions As String
Dim Level As String
Dim MySplit As Variant
Dim FileInMyFiles As Long
Dim Fstr As String
Dim LastSep As String
'mac excel 2016
'Get the directory
On Error Resume Next 'MJN
folderPath = MacScript("choose folder as string") 'MJN
If folderPath = "" Then Exit Sub 'MJN
On Error GoTo 0 'MJN
'Set up default parameters to get one level of Folders
'All files
Level = "1"
Extensions = ".*"
'Set up filter for all file types
FileNameFilter = "'.*/[^~][^/]*\\." & Extensions & "$' " 'No Filter
'Set up the folder path to allow to work in script
folderPath = MacScript("tell text 1 thru -2 of " & Chr(34) & folderPath & _
Chr(34) & " to return quoted form of it's POSIX Path")
folderPath = Replace(folderPath, "'\''", "'\\''")
'Run the script
ScriptToRun = ScriptToRun & "do shell script """ & "find -E " & _
folderPath & " -iregex " & FileNameFilter & "-maxdepth " & _
Level & """ "
'Set the String MyFiles to the result of the script for processing
On Error Resume Next
MyFiles = MacScript(ScriptToRun)
On Error GoTo 0
'Clear the fist four columns of the current 1st sheet on the workbook
Sheets(1).Columns("A:D").Cells.Clear
'Split MyFiles and loop through all the files
MySplit = Split(MyFiles, Chr(13))
For FileInMyFiles = LBound(MySplit) To UBound(MySplit)
On Error Resume Next
Fstr = MySplit(FileInMyFiles)
LastSep = InStrRev(Fstr, Application.PathSeparator, , 1)
Sheets(1).Cells(FileInMyFiles + 1, 1).Value = Left(Fstr, LastSep - 1) 'Column A - Directory
Sheets(1).Cells(FileInMyFiles + 1, 2).Value = Mid(Fstr, LastSep + 1, Len(Fstr) - LastSep) 'Column B - file name
Sheets(1).Cells(FileInMyFiles + 1, 3).Value = FileDateTime(MySplit(FileInMyFiles)) 'Column C - Date
Sheets(1).Cells(FileInMyFiles + 1, 4).Value = FileLen(MySplit(FileInMyFiles)) 'Column D - size
On Error GoTo 0
Next FileInMyFiles
'Fit the contents
Sheets(1).Columns("A:D").AutoFit
End Sub

How to get poster size in Excel Macro

How to get the size of the posters by using vba excel. I am using windows 7 operating system.
Images are present on some other path. Ex. d:\posterbank\a.jpeg,b.jpeg and excel file contains only names like a.jpeg, b.jpeg.
I want to check if these posters are there if yes need to check size of these.
A = LTrim(RTrim(Sheets(sheetno).Range("m" & rowno).Value))
postername = Left(A, Len(A) - 4) & ".bmp"
If filesys.fileExists(Poster_SPath & "\" & postername) Then
Else: Call appendtofile(vbrLf & "Not found " & Eng_Title & " " & postername, Logfile_Path & "\" & "log.txt")
End If
This should get you started :) I have taken the example of 1 picture, I am sure you can amend it to loop the relevant cells and pick up the values :)
TRIED AND TESTED
'~~> Path where images reside
Const FilePath As String = "C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\"
Sub Sample()
Dim Filename As String
'~~> Replace this with the relevant cell value
Filename = "Sunset.JPG"
'~> Check if file exists
If FileFolderExists(FilePath & Filename) = True Then
'~~> In sheet 2 insert the image temporarily
With Sheets("Sheet2")
.Pictures.Insert(FilePath & Filename).Select
'~~> Get dimensions
MsgBox "Picture demensions: " & Selection.Width & " x " & Selection.Height
'~~> Delete the picture
Selection.Delete
End With
End If
End Sub
Public Function FileFolderExists(strFullPath As String) As Boolean
On Error GoTo EarlyExit
If Not Dir(strFullPath, vbDirectory) = vbNullString Then FileFolderExists = True
EarlyExit:
On Error GoTo 0
End Function
This Worked for Me
Option Explicit
Type FileAttributes
Name As String
Dimension As String
End Type
Public Function GetFileAttributes(strFilePath As String) As FileAttributes
' Shell32 objects
Dim objShell As Shell32.Shell
Dim objFolder As Shell32.Folder
Dim objFolderItem As Shell32.FolderItem
' Other objects
Dim strPath As String
Dim strFileName As String
Dim i As Integer
' If the file does not exist then quit out
If Dir(strFilePath) = "" Then Exit Function
' Parse the file name out from the folder path
strFileName = strFilePath
i = 1
Do Until i = 0
i = InStr(1, strFileName, "\", vbBinaryCompare)
strFileName = Mid(strFileName, i + 1)
Loop
strPath = Left(strFilePath, Len(strFilePath) - Len(strFileName) - 1)
' Set up the shell32 Shell object
Set objShell = New Shell
' Set the shell32 folder object
Set objFolder = objShell.Namespace(strPath)
' If we can find the folder then ...
If (Not objFolder Is Nothing) Then
' Set the shell32 file object
Set objFolderItem = objFolder.ParseName(strFileName)
' If we can find the file then get the file attributes
If (Not objFolderItem Is Nothing) Then
GetFileAttributes.Dimension = objFolder.GetDetailsOf(objFolderItem, 36)
End If
Set objFolderItem = Nothing
End If
Set objFolder = Nothing
Set objShell = Nothing
End Function
Not tested, but using this as reference, it looks like it should be possible to load the image like this.
set myImg = loadpicture(Poster_SPath & "\" & postername & ".bmp")
And then get the width and height like this.
myImg.height
myImg.width

Resources