ReportSpecs MDE Source Code (1 Viewer)

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
This is a long shot but I figured I might as well try.

I made use of the ReportUtilities suite developed by Stephan Lebans in a project to convert an Access report to Word document.
This references ReportSpecs MDE developed by Steve Arbaugh (Attac Consulting).
It worked perfectly and saved me countless hours of work.

However, I've now discovered that the customer is running Access 64-bit, which prevents me from using ReportSpecs MDE as it was compiled with Access 32-bit.

My only hope is tracking down the source code of ReportSpecs.
Does anyone happen to know if this is available somewhere?
 

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
I've not heard of this utility but attac consulting still exist and have an active website. However Steve Arbaugh passed away in 2017
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
I have sent an email to Attac Consulting but thought I'd post here as well.
However, their website must be quite out-of-date then as it still has Steve Arbaugh listed at the Managing Principal and CEO.
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
This utility is simply used to determine the top margin, bottom margin, right margin, left margin, paper size, user paper width, and user paper height of a report.
I'm hoping I can find another method of determining these details without too much difficulty.
 

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
Apologies. Rechecked. Different person with same name

Just read your last reply. Most /all of those items should be easy enough to obtain though I'm not quite clear what the last two mean

If you use the database documenter tool on the report(s) it will tell you the property names you're looking for.
 
Last edited:

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 04:22
Joined
Jul 9, 2003
Messages
16,271
My only hope is tracking down the source code of ReportSpecs.
Does anyone happen to know if this is available somewhere?

I assume you are looking at this webpage:- http://www.lebans.com/ReportUtilities.htm

It is stated:-
NEW RELEASE Feb. 04/2001- For A97! ReportUtilities.zip is a suite of Report Utilities as outlined below. No restrictions. Open the README file before use! Full Source code included!

Now the only trouble with that file is it's in an earlier version of MS Access. So assuming that it is as stated, and has the full Source Code, all you need do is get somebody to convert it to a later version of MS Access.
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 04:22
Joined
Jul 9, 2003
Messages
16,271
I have sent an email to Attac Consulting but thought I'd post here as well.
However, their website must be quite out-of-date then as it still has Steve Arbaugh listed at the Managing Principal and CEO.

I'm not quite clear on where you've sent your email, but regarding getting your enquiry to the website answered, please note there is a message on the far left hand side:-

Repeated HERE:-

RETIRED! September 2009
I have officially retired from all things Access. Please do not send Email requesting support as I will not respond.
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
If you use the database documenter tool on the report(s) it will tell you the property names you're looking for.

Is there a way to programatically call on the database documenter?

I assume you are looking at this webpage:- http://www.lebans.com/ReportUtilities.htm

It is stated:-
NEW RELEASE Feb. 04/2001- For A97! ReportUtilities.zip is a suite of Report Utilities as outlined below. No restrictions. Open the README file before use! Full Source code included!

Now the only trouble with that file is it's in an earlier version of MS Access. So assuming that it is as stated, and has the full Source Code, all you need do is get somebody to convert it to a later version of MS Access.

Yes, those are the Report Utilities I am referring to. The source code for Report Utilities is provided but they rely on an MDE, which is compiled with Access 32-bit.
The source code for this MDE is not provided, presumably because it was written by someone else. This is my issue.

I'm not quite clear on where you've sent your email, but regarding getting your enquiry to the website answered, please note there is a message on the far left hand side:-

Repeated HERE:-

RETIRED! September 2009
I have officially retired from all things Access. Please do not send Email requesting support as I will not respond.
The MDE file was not written by Stephan Lebans, rather it was written by Steve Arbaugh (Attac Consulting). I emailed Attac Consulting.
 

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
No idea how to call the documenter using VBA but you wouldn't want to do so.
You just want to know the property names of each item.

Have you managed to convert Stephen's MDB file for 64-bit? I ask as he usually makes use of many APIs, some of which are quite obscure.
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
Have you managed to convert Stephen's MDB file for 64-bit? I ask as he usually makes use of many APIs, some of which are quite obscure.
Not yet, that's my next hurdle. I was optimistically (foolishly) hoping it would just work if I just stuck "PtrSafe" in front of all of the "Declare" statements.
 

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
No chance.
You will need to change Long to LongPtr on all handles/pointers e.g. hwnd

Out of interest I downloaded the utility and tried to run it using A2010 32-bit.
However, I can't even set the MDE reference as it seems to be an A97 MDE.

I think it may be easier to just start again and use VBA to collect the required property values
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
You will need to change Long to LongPtr on all handles/pointers e.g. hwnd
Well then, I'm optimistically hoping it will just work if I do that as well.

Out of interest I downloaded the utility and tried to run it using A2010 32-bit.
However, I can't even set the MDE reference as it seems to be an A97 MDE.
I was able to run it with Access 2016 32-bit. Did you download the A2K version?

I think it may be easier to just start again and use VBA to collect the required property values
I figured I'd end up having to do this in the end but thought I'd try the easier softer way first.
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
Steve graciously provided me with the source code!
Is there a way to upload it here for the next poor sap to come looking for it?

Now for the fun task of making all of the API calls in both the Report Utilities and ReportSpecs 64-bit compatible.
I'll post my progress (and requests for aid) here.
 

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
If you're sure he's happy with that you can zip the ACCDB version and attach it to this thread. If it seems to be useful to many people it can be added to sample databases or the code repository later.
Suggest upload when you've successfully created a version which is both 32-bit and 64-bit compatible. Good luck and thanks for the offer.
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
You will need to change Long to LongPtr on all handles/pointers e.g. hwnd

I added PtrSafe keyword to all Declare statements and decided to give it a try before I moved on to LongLong/LongPtr replacements. It seems to work without issue.
Is this because I just happen to be lucking out with numbers that do not exceed 32-bit?

Declare statements:
Code:
Private Declare PtrSafe Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As Long) As Long
Private Declare PtrSafe Function CreateIC Lib "gdi32" Alias "CreateICA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As Long) As Long
Private Declare PtrSafe Function DeleteDC32 Lib "gdi32" Alias "DeleteDC" (ByVal hDC As Long) As Long
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function SetMapMode Lib "gdi32" (ByVal hDC As Long, ByVal nMapMode As Long) As Long

Private Declare PtrSafe Function GlobalAlloc32 Lib "kernel32" Alias "GlobalAlloc" (ByVal wflags As Long, ByVal dwBytes As Long) As Long
Private Declare PtrSafe Function GlobalFree32 Lib "kernel32" Alias "GlobalFree" (ByVal hMem As Long) As Long
Private Declare PtrSafe Function GlobalLock32 Lib "kernel32" Alias "GlobalLock" (ByVal hMem As Long) As Long
Private Declare PtrSafe Function GlobalUnlock32 Lib "kernel32" Alias "GlobalUnlock" (ByVal hMem As Long) As Long
Private Declare PtrSafe Sub hmemcpy32 Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal dwBytes As Long)

Private Declare PtrSafe Function PrintDlg32 Lib "COMDLG32.DLL" Alias "PrintDlgA" (pPrintDLG As udtPrintDlg) As Long
Private Declare PtrSafe Function CommDlgExtendedError32 Lib "COMDLG32.DLL" Alias "CommDlgExtendedError" () As Long

Private Declare PtrSafe Function GlobalAlloc32 Lib "kernel32" Alias "GlobalAlloc" (ByVal wflags As Long, ByVal dwBytes As Long) As Long
Private Declare PtrSafe Function GlobalFree32 Lib "kernel32" Alias "GlobalFree" (ByVal hMem As Long) As Long
Private Declare PtrSafe Function GlobalLock32 Lib "kernel32" Alias "GlobalLock" (ByVal hMem As Long) As Long
Private Declare PtrSafe Function GlobalUnlock32 Lib "kernel32" Alias "GlobalUnlock" (ByVal hMem As Long) As Long
Private Declare PtrSafe Sub hmemcpy32 Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal dwBytes As Long)
Private Declare PtrSafe Function DeleteDC32 Lib "gdi32" Alias "DeleteDC" (ByVal hDC As Long) As Long

Private Declare PtrSafe Function api_FindWindow32 Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Any) As Long
Private Declare PtrSafe Function api_LockWindow32 Lib "user32" Alias "LockWindowUpdate" (ByVal hwndLock As Long) As Long
Private Declare PtrSafe Function api_DestroyWindow32 Lib "user32" Alias "DestroyWindow" (ByVal hwnd As Long) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wFlag As Long) As Long
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare PtrSafe Sub SetWindowPos Lib "user32" (ByVal hwnd&, ByVal hWndInsertAfter&, ByVal x&, ByVal y&, ByVal cx&, ByVal cy&, ByVal wflags&)
Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWndWindow&) As Long
Private Declare PtrSafe Function ShowWindow& Lib "user32" (ByVal hwnd&, ByVal ShowState%)
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hWndChid As Long, ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function CloseWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare PtrSafe Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare PtrSafe Function GetDeskTop Lib "user32" Alias "GetDesktopWindow" () As Long
Private Declare PtrSafe Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare PtrSafe Function GetWindowText& Lib "user32" Alias "GetWindowTextA" (ByVal hwnd&, ByVal lpstrTitleBuff$, ByVal intCharstoCopy%)
 

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
No. It means you haven't used the APIs that need converting Long to LongPtr.
A very quick glance indicates there are quite a few changes needed but I haven't checked properly.
For example all instances of hWnd need to be LongPtr

When you do something that requires one of those APIs, it will either fall over or just do nothing. So you may or may not notice any issues in the near future
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
No. It means you haven't used the APIs that need converting Long to LongPtr.

That was my first thought so I put a breakpoint on an API call that uses a handle to see if it was invoked.
The following APIs are definitely called:

Code:
Private Declare PtrSafe Function api_FindWindow32 Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Any) As Long

Private Declare PtrSafe Function api_DestroyWindow32 Lib "user32" Alias "DestroyWindow" (ByVal hwnd As Long) As Long
 

PleasantB

Registered User.
Local time
Yesterday, 21:22
Joined
Dec 12, 2018
Messages
37
Suggest you download a copy of Ron Bruin's API Viewer for Excel.
That tool is incredibly handy.

I was able to find x64 equivalents of all API calls except the following:
Code:
Private Declare Sub hmemcpy32 Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal dwBytes As Long)

However, based on all of the other translations I've seen, I think the following would work:
Code:
Private Declare PtrSafe Sub hmemcpy32 Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal dwBytes As LongPtr)
 
Last edited:

isladogs

MVP / VIP
Local time
Today, 04:22
Joined
Jan 14, 2017
Messages
18,209
Its very useful ...apart from the odd API it doesn't cover.
I've never seen that API before. Suggest you do an online search and failing that, suggest you test that API code carefully both with and without the dwbytes adjustment
 

Users who are viewing this thread

Top Bottom