Author Topic: Word scripting Issue  (Read 5300 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 812
Word scripting Issue
« on: March 06, 2018, 04:52:51 PM »
Hey guys,

I've got the following VBA macro, which works fine in MS Word:

Code - vb.net: [Select]
  1. Option Explicit
  2.  
  3. Sub test()
  4.     Dim r As Range
  5.     ' Written by a japaneese guy/woman, nickname: mana
  6.     Set r = ActiveDocument.Range
  7.  
  8.     With r.Find
  9.         .MatchWildcards = True
  10.        
  11.         .Text = "\[\[*\]\]"
  12.         .Replacement.Font.Color = wdColorRed
  13.         .Execute Replace:=wdReplaceAll
  14.  
  15.         .Text = "\[\["
  16.         .Replacement.Font.Color = wdColorAutomatic
  17.         .Execute Replace:=wdReplaceAll
  18.        
  19.         .Text = "\]\]"
  20.         .Execute Replace:=wdReplaceAll
  21.        
  22.     End With
  23.    
  24. End Sub

The purpose was.. If I had this uncolored content in my word document:

This is some text.. so this [[particular text]] must be put in red.
And theres [[another text that must be put in red]] and some more text. Also theres [[this text]] that must be put in red.


To color in red that specific text ^^.

However my LISP implementation of this macro was not successful, and the only question left was why :
Code - Auto/Visual Lisp: [Select]
  1. ; Doesn't work and for now I don't know why
  2. ; (ColorWithin (getfiled "Specify Word Document" (strcat (getenv "userprofile") "\\Desktop\\") "docx" 16))
  3. (defun ColorWithin ( fp / *error* msg wApp wDocs wDoc wRng wFnd wRep wFon )
  4.   ; (mapcar (function (lambda (x) (set x nil))) '(*error* msg wApp wDocs wDoc wRng wFnd wRep wFon fp))
  5.   (defun *error* ( m )
  6.     (vl-catch-all-apply 'vlax-invoke-method (list wDoc 'Close))
  7.     (vl-catch-all-apply 'vlax-invoke-method (list wApp 'Quit :vlax-false)) ; Sub Quit([SaveChanges], [OriginalFormat], [RouteDocument])
  8.     (foreach x (reverse (list wApp wDocs wDoc wRng wFnd wRep wFon )) (and (eq 'VLA-OBJECT (type x)) (vl-catch-all-apply 'vlax-release-object (list x))))
  9.     (gc) (gc) (and m (princ m)) (princ)
  10.   ); defun *error*
  11.  
  12.   (cond
  13.     ( (not fp) )
  14.     ( (not (setq wApp (vlax-get-or-create-object "Word.Application"))) (prompt "\nUnable to interfere with Word application.") )
  15.     (
  16.       ; ( ; Run
  17.         (setq msg
  18.           (vl-catch-all-apply
  19.             (function
  20.               (lambda nil
  21.                 (vlax-put-property wApp 'Visible :vlax-true) ; word is running in the background, set visible mode to true to see it
  22.                
  23.                 (setq wDocs (vla-get-Documents wApp))
  24.                 (vlax-invoke-method wApp 'ChangeFileOpenDirectory (car (fnsplitl fp)))
  25.                 (setq wDoc (vlax-invoke-method wDocs 'Open (apply 'strcat (cdr (fnsplitl fp))) :vlax-false :vlax-false :vlax-false "" "" :vlax-false "" "" 0 "" ))
  26.                 ; (vlax-invoke-method wDoc 'Select)
  27.                 (setq wRng (vlax-invoke-method wDoc 'Range)) ; Yes it is a method indeed, returns the range object
  28.                 (setq wFnd (vlax-get-property wRng 'Find))
  29.                
  30.                 (vlax-put-property wFnd 'MatchWildcards :vlax-true)
  31.                 (vlax-put-property wFnd 'Text "\\[\\[*\\]\\]")
  32.                 (setq wRep (vlax-get-property wFnd 'Replacement))
  33.                 (setq wFon (vlax-get-property wRep 'Font))
  34.                 (vlax-put-property wFon 'Color 255) ; wdColorRed = 255 ; wdColorAutomatic = -16777216 ; wdRed = 6 ;  wdAuto = 0
  35.                 (vlax-invoke-method wFnd 'Execute 2) ; wdReplaceAll = 2
  36.                
  37.                 (setq wFnd (vlax-get-property wRng 'Find))
  38.                
  39.                 (vlax-put-property wFnd 'MatchWildcards :vlax-true)
  40.                 (vlax-put-property wFnd 'Text "\\[\\[")
  41.                 (setq wRep (vlax-get-property wFnd 'Replacement))
  42.                 (setq wFon (vlax-get-property wRep 'Font))
  43.                 (vlax-put-property wFon 'Color -16777216)
  44.                 (vlax-invoke-method wFnd 'Execute 2) ; wdReplaceAll = 2
  45.                
  46.                 (setq wFnd (vlax-get-property wRng 'Find))
  47.                
  48.                 (vlax-put-property wFnd 'MatchWildcards :vlax-true)
  49.                 (vlax-put-property wFnd 'Text "\\]\\]")
  50.                 (setq wRep (vlax-get-property wFnd 'Replacement))
  51.                 (setq wFon (vlax-get-property wRep 'Font))
  52.                 (vlax-invoke-method wFnd 'Execute 2)
  53.                
  54.                 (vlax-invoke-method wDoc 'Save)
  55.               ); lambda
  56.             ); function
  57.           ); vl-catch-all-apply
  58.         ); setq msg
  59.       ); vl-catch-all-error-p
  60.       ; ) ; Run
  61.       (prompt (strcat "\nError: " (vl-catch-all-error-message msg)))
  62.     )
  63.   ); cond
  64.  
  65.   (*error* nil)
  66. ); defun ColorWithin

Wasn't sure if it required creating multiple Replacement or Font objects, but I tried n variations of this, and it still doesn't work.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: Word scripting Issue
« Reply #1 on: March 06, 2018, 06:00:19 PM »
so you are getting an error or what?

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Word scripting Issue
« Reply #2 on: March 06, 2018, 06:21:53 PM »
Nope, no errors at all - the code just runs (I see my word doc flashing, because of the Visible property) and applies no changes (no coloring).
I even switch the comments/uncomments of rows 16-20 and rows 57-62, in hope to see where it would potentially crash (thats what I normally do).
 :straight:
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: Word scripting Issue
« Reply #3 on: March 06, 2018, 06:48:45 PM »
what will (vlax-get-property wRng "Text") return after line 28?

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: Word scripting Issue
« Reply #4 on: March 07, 2018, 05:10:22 AM »
correct execute call
Code: [Select]
(vlax-invoke-method
  wFnd "Execute" nil :vlax-false :vlax-false :vlax-true :vlax-false :vlax-false :vlax-true 1 :vlax-true nil 2)

Dlanor

  • Bull Frog
  • Posts: 263
Re: Word scripting Issue
« Reply #5 on: March 07, 2018, 06:42:06 AM »
I could be wrong, but you seem to be using regexp notation for working in Autocad. Try changing lines 32, 41 and 50 to match the original since you are working in Word.

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Word scripting Issue
« Reply #6 on: March 07, 2018, 11:04:50 AM »

correct execute call
Code: [Select]
(vlax-invoke-method wFnd "Execute" nil :vlax-false :vlax-false :vlax-true :vlax-false :vlax-false :vlax-true 1 :vlax-true nil 2)

That was the problem!
Didn't realise it was such big of a deal if all the arguments were not supplied for this Execute method.
Thank you, ukrainian hacker! :)

This would be a valuable lesson for one who's trying to translate VBA macros to lisp.


I could be wrong, but you seem to be using regexp notation for working in Autocad. Try changing lines 32, 41 and 50 to match the original since you are working in Word.

I tried this with huge doubt and a small hope if it would work - the result was it didn't (like expected).
For instance the pattern "\[\[*\]\]" from the VBA macro, the literal translation for lisp would be: "\\[\\[*\\]\\]",
hence that Find object in MS Word has similarity with the Regex object (since in regex the syntax would be the same).

(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: Word scripting Issue
« Reply #7 on: March 07, 2018, 11:31:02 AM »
Didn't realise it was such big of a deal if all the arguments were not supplied for this Execute method.
this is not 100% true
execute method has even more arguments than in my example
https://msdn.microsoft.com/en-us/vba/word-vba/articles/find-execute-method-word

in this very case Format argument had to be set to :vlax-true
see https://msdn.microsoft.com/en-us/vba/word-vba/articles/find-format-property-word
it could be done either via Execute's argument or via vlax-put-property

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Word scripting Issue
« Reply #8 on: March 07, 2018, 11:49:33 AM »
Ah I see,
Still looks a bit weird that the values for these properties are different, depending if running the macro in a opened word doc or using lisp from acad.

Next time when I have this problem will try to alert all the properties for the object from the macro and the lisp code, to make sure they match:
Code - Visual Basic: [Select]
  1. MsgBox (ActiveDocument.Range.Find.Text)
Code - Auto/Visual Lisp: [Select]
  1. (alert (vlax-get-property wFind 'Text))

Probably in VBA will look like:
Code - Visual Basic: [Select]
  1. Sub Test()
  2.     Dim fnd As Object
  3.  
  4.     Set fnd = ActiveDocument.Range.Find
  5.  
  6.     With fnd
  7.         MsgBox (.MatchWildcards)
  8.         MsgBox (.MatchWholeWord)
  9.         MsgBox (.Text)
  10.         '... and the rest properties for the find object
  11.    End With
  12.    
  13. End Sub
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: Word scripting Issue
« Reply #9 on: March 07, 2018, 12:04:33 PM »
will try to alert all the properties
just use Inspect tool in VLIDE
it works perfectly with Word's objects

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Word scripting Issue
« Reply #10 on: March 07, 2018, 12:13:03 PM »
will try to alert all the properties
just use Inspect tool in VLIDE
it works perfectly with Word's objects

but does it require importing the ms word library at first? - I guess so (my inspect tool is blank where it lists the props'n'methods)
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: Word scripting Issue
« Reply #11 on: March 07, 2018, 12:30:43 PM »
but does it require importing the ms word library at first? - I guess so (my inspect tool is blank where it lists the props'n'methods)
no, importing is not required
i'd send a screenshot, but not until Monday
having holidays ;)

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Word scripting Issue
« Reply #12 on: March 07, 2018, 12:41:43 PM »
but does it require importing the ms word library at first? - I guess so (my inspect tool is blank where it lists the props'n'methods)
no, importing is not required
i'd send a screenshot, but not until Monday
having holidays ;)

Thanks again for your assistance, and happy holidays! :)
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

BIGAL

  • Swamp Rat
  • Posts: 1409
  • 40 + years of using Autocad
Re: Word scripting Issue
« Reply #13 on: March 08, 2018, 05:29:11 AM »
Grrr both Lee and I posted code that allows searching for words and changing colour just uses the simplicity of mtext, search cadtutor.
A man who never made a mistake never made anything

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Word scripting Issue
« Reply #14 on: March 08, 2018, 05:49:20 AM »
Grrr both Lee and I posted code that allows searching for words and changing colour just uses the simplicity of mtext, search cadtutor.

Ah was it the one with the discussion of the LM:LISPStyler subfunction?
I didn't realise there was something related to my current problem.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg