Author Topic: Determine Prog-ID  (Read 1516 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 648
Determine Prog-ID
« on: February 23, 2018, 08:56:46 AM »
Is it possible to determine the name of the prog-id, by knowing the library we've accessed from VBAIDE?

I'm trying to study from some VBA codes, more precisely translate them into lisp codes.

The problem is this:

Case #1
Say you access VBAIDE inside the excel application, but how does one find-out that the prog-id for the application he uses is "Excel.Application" ?
So next time you use VBA inside some other application you would know?
For instance use VBA from Word, to manipulate into Excel and vice-versa.

Case #2
Because in some code I'm trying to understand, the dude just starts with:
Code: [Select]
' Reference required: "VBE - Tools - References - Acrobat"
Dim AcroApp As New Acrobat.AcroApp, PartDocs() As Acrobat.CAcroPDDoc

That really confuses me, because the VBA code is lacking of CreateObject function, which in LISP would be (vlax-create-object progid) :
Code: [Select]
CreateObject("progid")
I'm guessing he accesses the Acrobat Applicaiton, for which I don't know the prog-id and I rely on luck to find the proper object, by using M.Puckett's _FindProjIDs subfoo.


John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9132
Re: Determine Prog-ID
« Reply #1 on: February 23, 2018, 09:31:57 AM »
Code - vb.net: [Select]
  1. object.ProgID

https://msdn.microsoft.com/en-us/library/aa263181(v=vs.60).aspx

But to help you answer your larger question:
You have several options for "accessing <stuff>". You can use the "COM object" or "Automation" (Note: `Automation' is `COM' light.) You probably want to read up on `Automation'.

After a quick google I found this, which should help you visualize how you `access stuff' in VBA.
http://access.mvps.org/access/modules/mdl0006.htm
“Common sense is not so common.” ~Voltaire

--> Donate to TheSwamp.org <--

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9132
Re: Determine Prog-ID
« Reply #2 on: February 23, 2018, 10:25:35 AM »
After some further searching (decided to find something on wikipedia for you).
https://en.wikipedia.org/wiki/OLE_Automation

Also, here is a link I have bookmarked on the subjects you may glean info from.
https://support.microsoft.com/en-us/help/196776/office-automation-using-visual-c
“Common sense is not so common.” ~Voltaire

--> Donate to TheSwamp.org <--

Grrr1337

  • Swamp Rat
  • Posts: 648
Re: Determine Prog-ID
« Reply #3 on: February 23, 2018, 12:10:51 PM »
Thank you, John! - I'll spend some time reading the links from your 2nd post.

A question appeared though, regarding your first post
Code - vb.net: [Select]
  1. object.ProgID
From the reference:
"Returns the ProgID (programmatic ID) for the control represented by the VBControl object."

Performed a test:
Code - vb.net: [Select]
  1. Sub Test()
  2.  Set x = New AcroApp 'Included it as reference, its a object which is member under that (Acrobat) library
  3.  MsgBox (x.GetLanguage) '<- Ok
  4.  MsgBox (x.progID) '<- Errors: object doesn't support this property/method
  5. End Sub
  6.  

If 'AcroApp' do not have this property, Then what are VBControl object(s) ?
Later I found this
But in my module (VBAIDE from Excel) the definition 'VBControl' is not recognised.

Can anyone provide example how to pull-out ProgID property from such object?

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9132
Re: Determine Prog-ID
« Reply #4 on: February 23, 2018, 01:39:38 PM »
It could be Accrobat. Not sure off the top of my head. I'd try the same with Outlook or something.

> VBControl object
*Pthhh!* I don't remember exactly, but I think that is more generic and has to do with the stuff on your form for example. Like getting a count from a list box object. ...Microsoft's wording is nice isn't it; they give everything a super vague term.

“Common sense is not so common.” ~Voltaire

--> Donate to TheSwamp.org <--

MP

  • Seagull
  • Posts: 17234
Re: Determine Prog-ID
« Reply #5 on: February 23, 2018, 02:56:08 PM »
(_FindProjIDs "acr*")

("AcroPDF.PDF.1")

(setq BurtLancaster (vlax-create-object "AcroPDF.PDF.1"))

#<VLA-OBJECT IAcroAXDocShim 000000003c0d17e8>

(vlax-dump-object BurtLancaster t)

; IAcroAXDocShim: IAcroAXDocShim Interface
; Property values:
;   messageHandler = nil
;   src = ""
; Methods supported:
;   execCommand (1)
;   GetVersions ()
;   goBackwardStack ()
;   goForwardStack ()
;   gotoFirstPage ()
;   gotoLastPage ()
;   gotoNextPage ()
;   gotoPreviousPage ()
;   LoadFile (1)
;   postMessage (1)
;   Print ()
;   printAll ()
;   printAllFit (1)
;   printPages (2)
;   printPagesFit (3)
;   printWithDialog ()
;   setCurrentHighlight (4)
;   setCurrentHightlight (4)
;   setCurrentPage (1)
;   setLayoutMode (1)
;   setNamedDest (1)
;   setPageMode (1)
;   setShowScrollbars (1)
;   setShowToolbar (1)
;   setView (1)
;   setViewRect (4)
;   setViewScroll (2)
;   setZoom (1)
;   setZoomScroll (3)


O.o
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

MP

  • Seagull
  • Posts: 17234
Re: Determine Prog-ID
« Reply #6 on: February 23, 2018, 03:04:09 PM »
So very weird! Immediately upon pressing send on the previous post rec'd an email from Adobe: "The art of integrating online and offline data".  :uglystupid2:
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

Grrr1337

  • Swamp Rat
  • Posts: 648
Re: Determine Prog-ID
« Reply #7 on: February 23, 2018, 03:29:55 PM »
Thanks Michael,
I've recently found that object, but thought that the prog-id name is weird - so decided to ask if theres alternative route to look into the progid (by knowing the library).

Anyway if anyone is interested what I wanted to translate to LISP, is this Sub
Code - vb.net: [Select]
  1. ' ZVI:2013-08-27 http://www.vbaexpress.com/forum/showthread.php?47310-Need-code-to-merge-PDF-files-in-a-folder-using-adobe-acrobat-X
  2. ' Reference required: VBE - Tools - References - Acrobat

Which would provide additional answer here, without requiring ghostscript or anything else (if acrobat is already installed).

So very weird! Immediately upon pressing send on the previous post rec'd an email from Adobe: "The art of integrating online and offline data".  :uglystupid2:

That could be your FBI man, emailing.  :lol:

MP

  • Seagull
  • Posts: 17234
Re: Determine Prog-ID
« Reply #8 on: February 24, 2018, 05:13:28 PM »
You're welcome Grrr. Interesting link (and site). If I hadn't a hundred different pins in the air I'd be tempted to Puckettize it (as my work colleagues call it). re: FBI: :-D
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

Grrr1337

  • Swamp Rat
  • Posts: 648
Re: Determine Prog-ID
« Reply #9 on: February 26, 2018, 05:18:00 PM »
If I hadn't a hundred different pins in the air I'd be tempted to Puckettize it (as my work colleagues call it). re: FBI: :-D

Now wondering if "I have some tools in my Puckett" is one of them.  :-D



BTW looks like I was needing these two:
Code: [Select]
(setq AcroApp (vlax-get-or-create-object "AcroExch.App"))
(setq PartDocs (vlax-get-or-create-object "AcroExch.PDDoc"))

I'm so close translating that VBA code, (well not a 100% translation, since I don't understand how he treats the PartDocs as a collection when it isn't one).


MP

  • Seagull
  • Posts: 17234
Re: Determine Prog-ID
« Reply #10 on: February 26, 2018, 06:04:49 PM »
Cue the monks.
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

Lee Mac

  • Seagull
  • Posts: 12109
  • London, England
Re: Determine Prog-ID
« Reply #11 on: February 26, 2018, 06:28:14 PM »
..since I don't understand how he treats the PartDocs as a collection when it isn't one).

In the linked code PartDocs is an array in which each element is a CAcroPDDoc object.

After a cursory glance, the code essentially accepts a comma-delimited string of PDF filenames to be merged, parses this string into an array a and resizes the PartDocs array to the same size as a. Then, for every filename in a, if the file exists, add the PDF document object to the PartDocs array.

The If i section within the For loop tests whether i is greater than zero (since zero=false in VBA), and if so, merges the PDF doc at index i with that at index 0.


Grrr1337

  • Swamp Rat
  • Posts: 648
Re: Determine Prog-ID
« Reply #12 on: February 26, 2018, 06:34:14 PM »
Cue the monks.

Should've defined it as Migrane :

Code - Auto/Visual Lisp: [Select]
  1. ;|
  2. (Merge ; Creates a file, but it contains only the first PDF file (I was testing on single-paged PDFs)
  3.   (strcat (getenv "userprofile") "\\Desktop\\Hale 515\\PDFs") ; in
  4.   (strcat (getenv "userprofile") "\\Desktop\\" "MergedPDFS.pdf") ; out
  5. )
  6. |;
  7.  
  8. ; in - folder that contains .pdf files
  9. ; out - path\\filename.pdf
  10. (defun Merge ( in out / *error* L n PartDocs ni n r )
  11.  
  12.  (defun *error* ( m )
  13.    (and PartDocs (vl-catch-all-apply 'vlax-invoke-method (list PartDocs 'Close)))
  14.    (and AcroApp (vl-catch-all-apply 'vlax-invoke-method (list AcroApp 'CloseAllDocs)))
  15.    (and AcroApp (vl-catch-all-apply 'vlax-invoke-method (list AcroApp 'Exit)))
  16.    (foreach x (list AcroApp AcroPDDoc) (and (eq 'VLA-OBJECT (type x)) (vl-catch-all-apply 'vlax-release-object (list x))))
  17.    (gc) (gc) (and m (princ m)) (princ)
  18.  ); defun *error*
  19.  
  20.  (setq AcroApp (vlax-get-or-create-object "AcroExch.App"))
  21.  (setq L ((lambda (pat) (mapcar '(lambda (x) (strcat pat "\\" x)) (vl-directory-files pat "*.pdf" 1))) in))
  22.  
  23.  ; Not Sure how to adjust 'n'
  24.  (setq n (length L))
  25.  ; (setq n 0)
  26.  
  27.  (foreach x L ; The issue is within this loop
  28.    (setq PartDocs (vlax-get-or-create-object "AcroExch.PDDoc"))
  29.  
  30.    (eq :vlax-true (vlax-invoke-method PartDocs 'Open x))
  31.    (setq ni (vlax-invoke-method PartDocs 'GetNumPages))
  32.    ; Function InsertPages(nInsertPageAfter As Long, iPDDocSource As Object, lStartPage As Long, lNumPages As Long, lInsertFlags As Long) As Boolean
  33.    (if (eq :vlax-true (vlax-invoke-method PartDocs 'InsertPages (1- n) PartDocs 0 ni :vlax-true)) ; << maybe the arguments are incorrect
  34.      (progn
  35.        (setq n (+ n ni))
  36.  
  37.      ); progn
  38.      (progn
  39.        (setq n (+ 1 (vlax-invoke-method PartDocs 'GetNumPages)))
  40.  
  41.      ); progn
  42.    ); if
  43.    ; (vlax-invoke-method PartDocs 'Close)
  44.    ; (vlax-release-object PartDocs)
  45.  ); foreach
  46.  (setq r
  47.    (eq :vlax-true
  48.      (vlax-invoke-method PartDocs 'Save
  49.        1 ; PDSaveFull
  50.        out
  51.      ); vlax-invoke-method
  52.    ); eq
  53.  ); setq r
  54.  (*error* nil) r
  55. ); defun Merge

BTW thanks for the input Lee, but I'll read it tommorow.. because this is like drinking vodka.

MP

  • Seagull
  • Posts: 17234
Re: Determine Prog-ID
« Reply #13 on: February 26, 2018, 06:48:34 PM »
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

Grrr1337

  • Swamp Rat
  • Posts: 648
Re: Determine Prog-ID
« Reply #14 on: February 27, 2018, 06:00:43 AM »
Paging the monks.

http://youtu.be/5qHNQxZGZKU

Ah, completely unaware about the existance of this band.


In the linked code PartDocs is an array in which each element is a CAcroPDDoc object.

Eventually got it what was the CAcroPDDoc object:
Code: [Select]
(setq o (vlax-get-or-create-object "AcroExch.PDDoc")) ; returns #<VLA-OBJECT CAcroPDDoc 0000000ef9a24a58>
Tho, didn't realised that in that VBA code PartDocs is an array - if so: looks like it cannot be obtained in LISP.
Oh, or do you mean that he manually creates a safearray for vla-objects, and fills it with CAcroPDDoc objects later?


After a cursory glance, the code essentially accepts a comma-delimited string of PDF filenames to be merged, parses this string into an array a

I kinda got that (while I was looking at his first code-suggestion there).. although rather prefer'd to work with full .pdf filepath


and resizes the PartDocs array to the same size as a.

So this was the ReDim function about.


Then, for every filename in a, if the file exists, add the PDF document object to the PartDocs array.

This is valuable info, at first I tried to add individual PDF document objects - then I thought that this seems unusual, to create the same object within a loop without releasing it.
So thats why my lisp code differs.. but after looking at a bunch of similar vba-acrobat-scripting codes I realised I'm mistaken.


The If i section within the For loop tests whether i is greater than zero (since zero=false in VBA), and if so, merges the PDF doc at index i with that at index 0.

That was the most frustrating part of the code, for me.
In the end I started looking for the "most simple suggestion" on the web, just to see how the InsertPages works.
Stopped at this simple example, about how to merge two PDF docs, Sub Button1_Click and looks like I got it!



 :-D So now guys we have a LISP sub to merge PDFs:

Code - Auto/Visual Lisp: [Select]
  1. ;| Examples:
  2. (MergePDFs
  3.   (strcat (getenv "userprofile") "\\Desktop\\Hale 515\\PDFs") ; in
  4.   (strcat (getenv "userprofile") "\\Desktop\\" "MergedPDFS.pdf") ; out
  5. )
  6. (MergePDFs
  7.   (list ; in
  8.     (getfiled "Specify PDF file" (strcat (getenv "userprofile") "\\Desktop\\") "pdf" 16)
  9.     (strcat (getenv "userprofile") "\\Desktop\\I_Dont_Exist.pdf")
  10.     (getfiled "Specify PDF file" (strcat (getenv "userprofile") "\\Desktop\\") "pdf" 16)
  11.     (getfiled "Specify PDF file" (strcat (getenv "userprofile") "\\Desktop\\") "pdf" 16) ; You can cancel and provide nil if you want to
  12.   ); list
  13.   (strcat (getenv "userprofile") "\\Desktop\\" "MergedPDFS.pdf") ; out
  14. )
  15. |;
  16. ; in - folder that contains .pdf files, or a list of ("<dir1>\\<filename1>.pdf" "<dir2>\\<filename2>.pdf" ..)
  17. ; out - path\\filename.pdf - Overwrites the existing (if theres one)
  18. ; If successful, Returns assoc list of '((<FilePath\\Filename.pdf> PageCount) ..)
  19. (defun MergePDFs ( in out / *error* AcroApp L PD r )
  20.  ; http://www.theswamp.org/index.php?topic=53974.msg586248#msg586248
  21.  (defun *error* ( m )
  22.    (and L (foreach x (mapcar 'car L) (vl-catch-all-apply 'vlax-invoke-method (list x 'Close)) (vl-catch-all-apply 'vlax-release-object (list x))))
  23.    (and AcroApp
  24.      (vl-catch-all-apply 'vlax-invoke-method (list AcroApp 'CloseAllDocs))
  25.      (vl-catch-all-apply 'vlax-invoke-method (list AcroApp 'Exit))
  26.      (vl-catch-all-apply 'vlax-release-object (list AcroApp))
  27.    ); and
  28.    (gc) (gc) (and m (princ m)) (princ)
  29.  ); defun *error*
  30.  
  31.  (and in out
  32.    (or (setq AcroApp (vlax-get-or-create-object "AcroExch.App")) (prompt "\nUnable to interfere with Acrobat object.") )
  33.    (cond
  34.      ( (eq 'STR (type in)) ; folder provided
  35.        (setq L ((lambda (pat / tmp) (if (setq tmp (vl-directory-files pat "*.pdf" 1)) (mapcar (function (lambda (x) (list (vlax-get-or-create-object "AcroExch.PDDoc") (strcat pat "\\" x)))) tmp))) in))
  36.      )
  37.      ( (vl-consp in) ; list of .pdf filepaths'n'names provided
  38.        (setq L (mapcar (function (lambda (x) (list (vlax-get-or-create-object "AcroExch.PDDoc") x))) in))
  39.      )
  40.    ); cond
  41.    (setq L (apply (function append) (mapcar (function (lambda (x) (if (eq :vlax-true (vlax-invoke-method (car x) 'Open (cond ((cadr x)) ("")))) (list (append x (list (vlax-invoke-method (car x) 'GetNumPages))))))) L)))
  42.    (setq PD (caar L))
  43.    (progn
  44.      (foreach x (cdr L) ; L - assoc list of (#<VLA-OBJECT> <FilePath> <PagesCount>)
  45.        (if (eq :vlax-false (vlax-invoke-method PD 'InsertPages (1- (vlax-invoke PD 'GetNumPages)) (car x) 0 (caddr x) :vlax-true))
  46.          (prompt (strcat "\nCannot insert pages from \"" (cadr x) "\""))
  47.        )
  48.      )
  49.      (or (eq :vlax-true (vlax-invoke-method PD 'Save 1 out)) ; 1 = PDSaveFull
  50.        (prompt "\nCannot save the modified document")
  51.      ); or
  52.    ); progn
  53.    (setq r (mapcar 'cdr L))
  54.  ); and
  55.  
  56.  (*error* nil) r
  57. ); defun MergePDFs

Again thanks alot for your help, and I'll try to adjust my eyes more for the VBA coding, altho still more comfortable in writing LISP.

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9132
Re: Determine Prog-ID
« Reply #15 on: February 27, 2018, 07:28:32 AM »
This thread quickly morphed into more of a Lisp question then a VB(A) one (I'm beginning to think I spent my time answering the wrong question). ...Shall I move this thread to the appropriate forum?
“Common sense is not so common.” ~Voltaire

--> Donate to TheSwamp.org <--

Grrr1337

  • Swamp Rat
  • Posts: 648
Re: Determine Prog-ID
« Reply #16 on: February 27, 2018, 09:28:59 AM »
This thread quickly morphed into more of a Lisp question then a VB(A) one (I'm beginning to think I spent my time answering the wrong question). ...Shall I move this thread to the appropriate forum?

You answered just right, John - its my fault that I tilted the question to what I was exactly trying to do (translate VBA code to LISP).
Still we were inspecting/commenting VBA codes, despite my attempts to write its LISP alternative.

Just to wrap-up in a nutshell the main question/answer + the conclusion I did. :

• Main question:

Is it possible to determine the name of the prog-id, by knowing the library we've accessed from VBAIDE?


• Answer & Discussion:

Code - vb.net: [Select]
  1. object.ProgID
https://msdn.microsoft.com/en-us/library/aa263181(v=vs.60).aspx

A question appeared though, regarding your first post
Code - vb.net: [Select]
  1. object.ProgID
From the reference:
"Returns the ProgID (programmatic ID) for the control represented by the VBControl object."

Performed a test:
<code>

If 'AcroApp' do not have this property, Then what are VBControl object(s) ?
Later I found this
But in my module (VBAIDE from Excel) the definition 'VBControl' is not recognised.

Can anyone provide example how to pull-out ProgID property from such object?

> VBControl object
*Pthhh!* I don't remember exactly, but I think that is more generic and has to do with the stuff on your form for example. Like getting a count from a list box object. ...Microsoft's wording is nice isn't it; they give everything a super vague term.


• Conclusion:

The conclusion I did that its not possible to know/pull-out directly the prog-id from the main 'VB Control' object by knowing its library, since this Progid property doesn't seem to work/exist.
The closest solution is to use a subfunction like _FindProjIDs to find progids with approximately appropriate names and then check if the expected properties/methods/events (from the library) are allowed.
BTW I don't know if VBAIDE has a tool to list the prog-ids, but I was able to find a VBA alternative to Michael's subfoo (although I think he probably already has it as VBA aswell [deep in his puckett]).