merging pdf files

181 views
Skip to first unread message

internet...@foobox.com

unread,
Jul 31, 2020, 9:33:58 AM7/31/20
to
For many years I have used Stephen Lebans ReportToPdf that has worked well until now.

I am needing to transfer the system to 64 bit Windows and the library StrStorage.dll fails to load.

It is used in
Public Declare PtrSafe Function MergePDFDocuments Lib "StrStorage.dll" _
(ByVal PDFMaster As String, _
ByVal PDFChild As String _
) As Boolean


I am not that familiar with the workings of libraries but I am assuming that MergePDFDocuments in a function within the StrStorage.dll

I have downloaded what I think is a newer version of StrStorage.dll but it fails to load.
hLibStrStorage = LoadLibrary(CurrentDBDir() & "StrStorage.dll")
The file exists and is in the correct place

I am assuming that it is for 32 bit systems.


Has anyone any knowledge of this?

Is there another way of merging pdf documents without buying the full version of Acrobat?

Jim

samxj...@gmail.com

unread,
Jul 31, 2020, 10:02:05 AM7/31/20
to

internet...@foobox.com

unread,
Jul 31, 2020, 11:51:28 AM7/31/20
to
On Friday, 31 July 2020 15:02:05 UTC+1, samxj...@gmail.com wrote:
> PDFTK will do that. https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/

On first look it appears to be a command line system.

Is there an API, or object library so that I can merge pdf files from my VBA code in Access?

Jim

Albert Kallal (Access MVP)

unread,
Aug 2, 2020, 12:40:57 AM8/2/20
to
On Friday, July 31, 2020 at 7:33:58 AM UTC-6, internet...@foobox.com wrote:

> For many years I have used Stephen Lebans ReportToPdf that has worked well until now.

Yes, a lot of us used that utility. and before Access/Office 2007, we also used his PDF creator.

Thankfully, now (even with runtime) we can create PDF's from Access - even the runtime, and NOT require any PDF drivers or even software to be installed - nice!

>
> I am needing to transfer the system to 64 bit Windows and the library StrStorage.dll fails to load.

All recent versions of windows (for quite a long time name) have be OS x64 bits.

However, until rather recent, office installs remained x32 bits.

> I am not that familiar with the workings of libraries but I am assuming that MergePDFDocuments in a function within the StrStorage.dll

It was in one of the two .dll's, can't remember. However that .dll is a x32 bit windows .dll.

> I have downloaded what I think is a newer version of StrStorage.dll but it fails to load.
> hLibStrStorage = LoadLibrary(CurrentDBDir() & "StrStorage.dll")
> The file exists and is in the correct place
>
> I am assuming that it is for 32 bit systems.

You are correct. It is a win x32 bit file. Since you now using VBA and office x64 bits?
Then of course you can't use those .dll's anymore.
And the wonderful Stephan's? He not been around the access scene for a good 13 or more years.


> Has anyone any knowledge of this?

Yes, I very much know this stuff!

>
> Is there another way of merging pdf documents without buying the full version of Acrobat?

Yes, I created a .net .dll that can work with x32 or x64 bits.
I also use the "load library" approach that Stephan used for his PDF stuff.

I just simply don't have the time to correctly put up a web page.

But I have a loader, one for x64 bits, and one for x32.
This loader can load any .net .dll. For .net, x32 or x64 bits does NOT matter (if the code was compiled using ANY CPU).
However the loader must match.

To use:
You have to place the .dll nloader and the Pmerge.dll in your front end folder (same as PDF merge).
Now since the two loader.dll's are VERY small, then you might as well make a habit of placng both in the folder.

So, we have a total of 3 files:
nloader.dll - x32 bit loader
nloader64.dll - x64 bit loader
Pmerge.dll - new .net PDF merge

So, place the above 3 files in the folder.

The VBA code to merge is now this:

Dim MyPdf As Object
Set MyPdf = CreateObjectNET("Pmerge.dll", "Pmerge.Pmerge")


MyPdf.Add "c:\test4\p1.pdf"
MyPdf.Add "c:\test4\p2.pdf"

MyPdf.OutPutDoc = "c:\test4\P1ANDP2.pdf"

MyPdf.Merge

So, I only merged 2 files, but you can have 2 or 10 files.
There is also a
MyPdf.Clear
That just clears out the files if you want to merge again (and if you JUST created the MyPDF object, then no need for clear.

So, only 3 tiny .dll's.
And it AUTOMATIC works for x32 or x64 - you don't have to do anything or change the code. It will work for both x32 and x64.

the example assumes Access 2010 or later (I have the VBA test for x64 bits - so, if for SOME strange reason someone wants to use this in a pre-access 2010? It WILL work fine, but you have to remote the #Win64 test/check I have, since only 2010 and later has this built in test/check in VBA for x32/x64.

You can download from my skydrive - it is a sample accDB and the above 3 .dll's.

To use in YOUR application? You just need to import the ONE code module.
(NetLoader).

So, this example:
Super easy, super simple to use.
No registration, no installer.
It just works.

Here is a skydrive link to the zip file - do try it - perhaps post back. As I stated I don't have time to write up a web page. So, you have to just take your time, and look at the sample code. However, the sample code above is all you really need.
Please do give it a try, and at least throw the community a dog bone here that this worked for you.

Link:
https://1drv.ms/u/s!Avrwal_LV4qxhphvq4_Ce9EmZFMbEA?e=Je7dmU

Now, the above is actually based on PDFSharp - it has MANY cool features:
Modify, merge, and split existing PDF files. However, I have only exposed the merge feature, but there are quite a fw more features that I could "just" expose.

Good luck! - post back if this works for you.
Albert D. Kallal (Access MVP 2003-2017)
Edmonton, Alberta Canada
pleaseNoS...@msn.com

internet...@foobox.com

unread,
Aug 2, 2020, 10:49:57 AM8/2/20
to
Absolutely brilliant ! Many thanks Albert.

However I needed to make a small modification.

I had it up and running quickly on my 32 bit machine but when I transferred it to a client’s new environment the is 64 bit it failed to use the correct .dll It still tried to use nloader.dll instead of nloader64.dll

I found that the cause of this was one line in the following function:

Public Function CreateObjectNET(strDll As String, strClass As String) As Object
Static bIsLoaded As Boolean ' local static - for one time load
Dim loaderDLL As String ' use x64 or x32 .net loader

#If Win64 Then
loaderDLL = "nloader64.dll"
#Else
loaderDLL = "nloader.dll"
#End If

If bIsLoaded = False Then

If LoadLib("nloader.dll") = False Then ‘ locked in to 32


If LoadLib(loaderDLL) = False Then ‘ changed to use defined string variable



This is easily done when testing on one system. Once I changed the line of code above to reflect whether to use the 32 or 64 version it worked.

At the moment I have simply replaced an existing function of mine that merges two files together. I now intend to collect all the files needed and merge them in one go. Should work well.


Thank you again Albert for your very clear, instructive reply. Your explanations are always most informative based on evident knowledge and experience.

I highly recommend your code (with the one minor correction!!! ) to everyone.

Jim

Albert Kallal (Access MVP)

unread,
Aug 2, 2020, 12:34:22 PM8/2/20
to
On Sunday, August 2, 2020 at 8:49:57 AM UTC-6, internet...@foobox.com wrote:
> Absolutely brilliant ! Many thanks Albert.
>
> However I needed to make a small modification.
> If bIsLoaded = False Then
>
> If LoadLib("nloader.dll") = False Then ‘ locked in to 32
>
>
> If LoadLib(loaderDLL) = False Then ‘ changed to use defined string variable
>
> This is easily done when testing on one system. Once I changed the line of code above to reflect whether to use the 32 or 64 version it worked.
>
> At the moment I have simply replaced an existing function of mine that merges two files together. I now intend to collect all the files needed and merge them in one go. Should work well.
>
> I highly recommend your code (with the one minor correction!!! ) to everyone.
>
> Jim

Darn - there is a bug you ALREADY fixed!!! (thank you)

In fact before posting? I spooled up a vm with x64 Access. Tested, found that issue and fixed it. So I VERY much did test this on x64 (I did not hope this would work - but did test). But, I did not re-zip the file.

But, in this public forum?
A fix is a fix.
A find is a find by you.

And the amount of code is quite simple - Similar to Stephan's code (actually a bit less).

So, I have re-zipped it with the fix.

But, two things:
You confirmed it worked.
It will/can work seamless for BOTH x32 and x64.

Do note that you could leave out the one of the two loader dll that you don't need, but since it is oh so very small (9k), then it really don't matter (less human memory to remember which dll you could leave out as opposed to why not just deploy both).

Also:
KEEP very much in mind that the loader is NOT limited to just that Pmerge.dll file.

If you have any .net COM useable object? That loader will work. So, the loader allows you to consume any .net .dll that been written as a .net COM object.

I use the loader for Access to Sage 300, sage50 and QuickBooks interfaces. I only added the two .dll switch code for this post since those accounting packages don't have x64 bit versions. So this loader allows you to consume .net objects. The accounting interfaces have a .net interface. So, this is the "same" idea as Lebans code, but the .dll you are loading is a .net one. And .net .dll's WHEN compiled to "ANY cpu" have this magic ability to swap/switch bit size. However, the nloader.dll is in fact windows code - so it can't flip, but Pmerge can!

So this trick loader means you can now with ease call/consume .net objects.

Thank you kindly for the bug fix - I'll re-zip and re-up load this.

And if I have some time? I think I should write up a web page. Now that the transition to x64 office is occurring? Then I suspect we see more and more problems in this area.

Regards,

Albert Kallal (Access MVP)

unread,
Aug 2, 2020, 4:37:45 PM8/2/20
to
Because I have re-uploaded the same file, then skydrive will re-gen the link.
So for future use - here is the link again with the suggested bug fix.
https://1drv.ms/u/s!Avrwal_LV4qxhphwzWnJvwd7HhEjbg?e=xVsZDO

internet...@foobox.com

unread,
Aug 3, 2020, 3:50:02 AM8/3/20
to
Albert, you say:
"So, I only merged 2 files, but you can have 2 or 10 files."
I assume that this is only illustrative and that there is no limit to the number of files.

Am I correct?

Jim

On Sunday, 2 August 2020 05:40:57 UTC+1, Albert Kallal (Access MVP) wrote:

Ron Paii

unread,
Aug 3, 2020, 9:55:57 AM8/3/20
to
First, Allen thanks for the dll info.

I am having trouble with your sample database. I get a err.lastDllError 203 after executing hLibDynaPDF = LoadLibrary(CurrentProject.Path & "\" & strDll). It's returning a non-zero value. because of this MyCreateObject(CurrentProject.Path & "\" & strDll, strClass) returns nothing.

dll error 203, The system could not find the environment option that was entered.

Do I need to register any of the COM objects?

Access 2016 32bit on Windows 8.1 64bit
references are
Visual Basic For Applications
Microsoft Access 16.0 Object Library
Microsoft Office 16.0 Access database engine Object Library
OLE Automation

I also tried it on Access 2010 32bit on Windows 7 64bit

Ron Paii

unread,
Aug 3, 2020, 11:02:50 AM8/3/20
to
Sorry,
Thank you Albert.

Albert Kallal (Access MVP)

unread,
Aug 3, 2020, 12:28:33 PM8/3/20
to
@Ron,

No worries. I have re-uploaded the sample.

It should work for either x32 or x64 Access.
You do NOT have to register anything.

There is not any limit to the number of files you can add.

Also, as a FYI? Do you have an idea as to why the sample failed for you?

it should just work - un-zip the folder - and run the simple sub in the module.

As I noted, you can use that loader routine to load any .net .dll (as long as it was created as a COM visible object).

It sounds like it is working for you - but if there was a failure for you - I might be able to avoid whatever occurred in the future for others.

Regards,
Albert

Ron Paii

unread,
Aug 3, 2020, 3:18:23 PM8/3/20
to
It works in Windows 10 but not 8.1 or 7
Windows 10 added some new environment variables.

DriverData
FPS_BROWSER_APP_PROFILE_STRING
FPS_BROWSER_USER_PROFILE_STRING
HOMEDRIVE
HOMEPATH
HOMESHARE
LOGONSERVER

Any chance nLoader is using one of these?







Albert Kallal (Access MVP)

unread,
Aug 3, 2020, 3:59:05 PM8/3/20
to
On Monday, August 3, 2020 at 1:18:23 PM UTC-6, Ron Paii wrote:
> It works in Windows 10 but not 8.1 or 7
> Windows 10 added some new environment variables.
>
> DriverData
> FPS_BROWSER_APP_PROFILE_STRING
> FPS_BROWSER_USER_PROFILE_STRING
> HOMEDRIVE
> HOMEPATH
> HOMESHARE
> LOGONSERVER
>
> Any chance nLoader is using one of these?

No, path name and environment stuff should not matter.
it would be that .net 4.0 is not installed. Win 7, and early win 8's don't have that.
They have by default .net 3.5.

I could/can re-compile with .net 3.5. The problem is the IL merge utility I am using only goes back to 4.0.

So, I am faced with a choice:
Dump use of IL merge, and you have one more extra .dll. So, in place of 3 .dll's, you have 4.

I have re-compiled the .dll to 3.5, but the merge routines used .net 4. This "might" work for you.

Link here:
https://1drv.ms/u/s!Avrwal_LV4qxhphxjbS7y-SNd_42cg?e=sOLSdk

So, you can try the new download, but I not oh so sure this will work.

If it does not work?

Then I think the most compatible, and best chance of having to do zero to the target computers?

A re-compile to .net 3.5. But I have to DUMP the use of ILmerge.
All this means is that there will be extra .dll you have to deploy.

From above, you ONLY should need to re-place "Pmerge.dll" in the location that you are testing.
(and you should exit access - you find the .dll is locked if you running code).

So, try the new Pmerge.dll - if it works, then great.
If not?
Well, then I'll have to include one extra .dll in this.

In fact, I might as well do that right now.

So, here is a 100% .net 3.5 version. It is called PdfMerge35
https://1drv.ms/u/s!Avrwal_LV4qxhphyIggu-rUjMGqPOg?e=BYKkpT

If that last one don't work - then again I could pull the .net version all the way back to 2.0 - that would be on all these machines.

R
Albert

Ron Paii

unread,
Aug 4, 2020, 8:28:05 AM8/4/20
to
.Net installs on test computers
Win7: 3.51
Win8.1: 3.5 & 4.5
Win10: 3.5 & 4.8

The 1st new download worked on windows 7 and 10 but not 8.1
The 2nd new version did not work on 7 or 8.1 or 10

7 is Access 2010 full
8.1 is Access 2016 full
10 is Access 2016 runtime, I added a form with a button to test.

I will try testing on other 8.1 computers later this week and get back to you.

Thank you for all your work on this.

internet...@foobox.com

unread,
Aug 4, 2020, 11:48:10 AM8/4/20
to
You've done some excellent testing Ron

I was fortunate in that Albert's first version worked for me. I am using Windows 10 and Access 2016. The only problem was that I am transferring a database from 32bit to 64bit

JIm

Albert Kallal (Access MVP)

unread,
Aug 5, 2020, 1:18:46 PM8/5/20
to
Been busy.
I also did some R&D on what is intstalled on those computers.
However, (double darn!!!).
While I did re-compile Pmerge to .net 3.5?
I FORGOT to re-compile the nloader.dll!
It was at .net 4.5!!!
The MOST wide spread and pre-installed .net seems to be 4.0.
So, I will re-compile both Pmerge and the nloader.dll to .net 4.0
As noted, my VERY bad - since I did not re-compile the nloader.
As a FYI:
i tend to leave the nloader at the highest possible .net version (4.5, or even 4.72).
The REASON for this is I use the nloader for those accounting interfaces and deployment to customers machines
This approach means can deploy a .net 3.5 ALL THE WAY UP TO 4.7 WITHOUT having to change nloader.
But this means that the target machine will requite 4.5 or 4.7 to be installed. But this has backwards compatibility all the way back to 3.5
(but ONE MUST have ,net 4.7 or 4.5 installed - then I am free to deploy .net .dlls of near any version). So all I do is tell the customer to ensure that later .net is installed on those machines, and then the .net .dll (pmerge or whatever I am using will work).

So, here is a 4.0 version. I am betting this will likely work on all machines.

So, the testing you done here is VERY valuable to everyone - including me. (it was Monday I was last here in this group).
So, give this version a try:
Pmerge40.zip
I given it a different name. And both nloader and Pmerge are set to .net 4.0. This version thus out of the box should have the most wide spread chance of working. I REALLY need to put up a web page for this utility - but I just don't have the time.

So,
Merge 4.0 link here:
MergePDF40.zip
https://1drv.ms/u/s!Avrwal_LV4qxhphziHQQOAI0Oq2dQQ?e=DUtuon

Try above - I am betting it should work on most machines. However, there is a also a manifest setting for msaccess.exe, but I'll leave this issue for another day.

So, my BIG WHOPPER mistake was NOT a re-compile of the nloader (I don't usually bother).
So, previous nloaders were ALL 4.5 - that less then ideal.

So, try above. I will write out a web page for this - and will kindly list out the versions it works for.
R
Albert

lucte...@gmail.com

unread,
Feb 10, 2021, 3:02:03 PMFeb 10
to
Op woensdag 5 augustus 2020 19:18:46 UTC+2 schreef Albert Kallal (Access MVP):
Hi,
I try to use your program MergePDF. I've installed the 3 dll's en try TestMerge2. I received an error on the command PDF.add "c:....". Error 91 Objectvariable not set.
Do you have an idea wath's wrong?

Thanks

Albert Kallal (Access MVP)

unread,
Feb 11, 2021, 6:04:10 PMFeb 11
to
Ok, for some reason my ILMerge utility is NOT working.

So, you have to add 4 .dll's (my sorry - but I am just TOO busy). If someone has some time - they can ILMERGE the pdfSharp.dll and the Pmerge.dll into ONE .dll. However, ILMERGE is JUST not working.

But, try this new download - it will work - but you have to include a extra .dll (pdfSharp.dll).

But, it should work - .

Try this link and re-download -

https://1drv.ms/u/s!Avrwal_LV4qxhpl5KXAreJujnoxu_g?e=DRr1A3

R
Albert

Keith Tizzard

unread,
Jun 24, 2021, 11:44:08 AMJun 24
to
I have been using, and still am, this MergePDF set of routines successfully for some time.

However I get an error when trying to merge one particular pdf file with others. The error is:
GetInteger: Object is not an integer

The code is :
Dim MyPdf As Object
Set MyPdf = CreateObjectNET("Pmerge.dll", "Pmerge.Pmerge")


MyPdf.Add theOutputFilePathname
MyPdf.Add thePdfPathname

MyPdf.OutPutDoc = tempPathName

MyPdf.Merge

with the error occurring on MyPdf.Merge


The offending file appears normal and can be viewed with Acrobat or similar pdf reader.

Any ideas about what in the pdf file is causing this problem?

Jim

musicloverlch

unread,
Aug 24, 2021, 12:37:09 PMAug 24
to
The link doesn't work for me. I would love to try it out. Thanks.

Keith Tizzard

unread,
Aug 24, 2021, 1:42:29 PMAug 24
to
Your post appears to be in the very link I suggested. Look higher up the list

musicloverlch

unread,
Aug 25, 2021, 12:23:19 PMAug 25
to
The OneDrive link to the DLLs doesn't work anymore.

Keith Tizzard

unread,
Aug 25, 2021, 12:39:36 PMAug 25
to
Try the one in Albert's post of 11 Feb 2021
Here it is:
Ok, for some reason my ILMerge utility is NOT working.

So, you have to add 4 .dll's (my sorry - but I am just TOO busy). If someone has some time - they can ILMERGE the pdfSharp.dll and the Pmerge.dll into ONE .dll. However, ILMERGE is JUST not working.

But, try this new download - it will work - but you have to include a extra .dll (pdfSharp.dll).

But, it should work - .

Try this link and re-download -

https://1drv.ms/u/s!Avrwal_LV4qxhpl5KXAreJujnoxu_g?e=DRr1A3



musicloverlch

unread,
Sep 10, 2021, 10:20:46 AMSep 10
to
Thank you soooooooooooooooo much!

Albert Kallal (Access MVP)

unread,
Nov 11, 2021, 2:09:08 PMNov 11
to
On Friday, September 10, 2021 at 8:20:46 AM UTC-6, musicloverlch wrote:
> Thank you soooooooooooooooo much!

I been busy, but there is a better link to the PDF merge here:

http://www.kallal.ca/Articles/Pdf/Merge.html

Regards,
Albert
Reply all
Reply to author
Forward
0 new messages