Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

using Lisp to add a hyperlink to a specific attribute

30 REPLIES 30
Reply
Message 1 of 31
Anonymous
2140 Views, 30 Replies

using Lisp to add a hyperlink to a specific attribute

I have searched the site and reviewed one program, but this doesn't seem to fit the bill for me.

 

As an old Lisp writer, I'm looking for some hints to point me in the right direction.  I haven't used hyperlinks in my programs yet, so this will be new to me.

 

The goal:

 

(I provide a text file with a list of drawings and the path to each drawing.)

 

1. Make a selection set of all attributes on drawing

2. Compare each item in the selection set to the list of drawings.

3. If an attributes matches an entry on the drawing list, then a hyperlink is to be added to the attribute, which points to the drawing (using stored path).

 

I can already do this with plain ole text, but it is getting a little complex with attributes.

 

The idea is to run a script that will turn drawing references into hyperlinks on every drawing in the construction package.

 

thanks.

30 REPLIES 30
Message 2 of 31
pbejse
in reply to: Anonymous

can you kindly post your code for "plain ole text" and then we'll pick up form there

 

Message 3 of 31
Anonymous
in reply to: Anonymous

Here's the text version as of now. After looking thru it this morning, I see I did not make it cycle thru the entire dwg-list, but to only grab the first dwg and its path. (this was to make debuggin easier, now that it works, I'll complete the program)

 

Anyway, this program works for text.  I would like something like this, but will work for attributes. It would not have to be implemented in this program, but could be stand-alone.

 

(DEFUN C:hyperlnk ()
(command "attreq" "1")
(setq dwgnum (getvar "DWGNAME"))

 

; make selection set which includes any piece of free text
(setq SSLTXT (ssget "x" '((0 . "text"))))

 

; if selection set exists then proceed, else quit
(if SSLTXT
(progn

 

(print "selection set obtained")

 

; get the number of text elements selected and store as SSLTXTLEN
(setq SSLTXTLEN (sslength SSLTXT))
;(print SSLTXTLEN)

 

; repeat the next section for as many text elements in selection set
; the counter "COUNTER" is incremented each time to keep track of how many times this is running
; the drawing-list file is opened for each text element in selection set, but closed after the dwg-list is exhausted
(setq COUNTER 0)       
(repeat SSLTXTLEN
;(print COUNTER)
(setq DWGLST (open "c:/scripts/drawings/dwglst.txt" "r"))

 

; select next piece of text (as entity) in original selection set
(setq ENT (ssname SSLTXT COUNTER))
(setq ENTTXT (entget ENT))
(setq THETXT (cdr (assoc 1 ENTTXT))) ; the actual text
;(print THETXT)

 

; this next selection will need to be repeated for ever pair in dwglst (but does not right now)
(setq DWG (read-line DWGLST))
(setq PATH (read-line DWGLST))
;(print DWG)
;(print PATH)

 

; if THETXT=DWG, then make a hyperlink that is assigned to EN which points to PATH+DWG+".dwg"
(if (= THETXT DWG)
(progn
;(print "THIS IS A MATCH!!!")
(setq TEMP (strcat PATH "\\" DWG ".DWG"))
;(print TEMP)
(command "-hyperlink" "" "" ENT "" TEMP "" "")

 

);progn
;(print "NO MATCH")
); fi

 

(close DWGLST)
(setq COUNTER (+ COUNTER 1))
); repeat

 

);progn
);fi
 
); DEFUN

Message 4 of 31
pbejse
in reply to: Anonymous

Cool beans Smiley Happy

 

I'll have a look later

 

keep you posted

 

 

Message 5 of 31
pbejse
in reply to: Anonymous

alrigth vrod2000, I think i got a handl on this, but first, questions for you

 

  • is the attribute textstring an exact match to the string from the text file? (can you post an example of the source text file )
  • on the block with attributes, is there more than 1 tagstring to compare to the pattern from the text file? (one attribute value/ one hyperlnk) it woould help if you can tell me the Tag name of the attribute..
  • your attribute block. (assuming its a title block) is it located on modelpsace (some people still do it that way) or paperspace? is there more thatn 1 layout tab?

But i guess you dont really need to tell all this, as you're no doubt an experience programmer Smiley Happy

so,

 

(defun c:tryme ( / blk result hpt)
  
;;			sample by pBe 2011			::
(setq blk (car (entsel "\nSelect Block: ")))

;;	for instance you run your read-line routine here	;;
;;	What I would do is read the file in its entirety	;;
;;	and assign it to a list variable			;;

;;	an example of the list result on reading the file	;;
(setq
  result
   '(("Filename1.dwg" "..\\test_folder\\")
     ("Filename2.dwg" "..\\test_folder\\")
     ("Filename3.dwg" "..\\other_folder\\")))
  
;;								;;
  
(foreach at_str
	(vlax-invoke
	    (vlax-ename->vla-object blk)
	    'GetAttributes)
	(if	(setq hpt  (assoc 
          	(vla-get-textstring at_str) result))
          	(vla-add (vla-get-hyperlinks at_str)
                  (strcat (cadr hpt) (car hpt)) "File Hyperlink")
          )
  )
  (princ)
)

 

I've attached a sample block for you to try. open the file and run this on the block

 

Hope this helps

 

 

 

 

 

Message 6 of 31
Anonymous
in reply to: Anonymous

I'll check out the program later today or tomorrow. I just came in and a checking package is already waiting for me this early!

 

Answers to your questions....if I can explain it good enough for understanding...

 

1. The hyperlinked filename is the exact same name as the compared attribute to the dwg-list.  The only thing I do is strcat a ".dwg" to the end of the compared name. (What I am doing is searching within a drawing, and anything that is a valid drawing-filename gets hyperlinked to that drawing, with the proper path.)

 

2. I never though much about modelspace versus paperspace.  I suppose that since I am trying to get this to work on some installation details, I will say paperspace is the place where these attributes will reside. However, it would be great if the program did its job in both paperspace and modelspace.

 

3. A sample of the comaprison file-list follows;

 

***************************************

E-001-I-40100

..\ wiring diagrams

E-001-I-40101

..\ wiring diagrams

E-001-I-40102

..\ wiring diagrams

E-001-M-30300

..\ PIDs

E-001-M-30301

..\ PIDs

EOF

EOF

*****************************************

 

Note: I put 2 "EOF" markers at the end of the list, since I find it easy to code wihout running into EOF errors. I'm sure there is a cleaner way, but I am "old school" and this works.

 

4. I could provide the name of the block and the name of the attribute tags, however, I would like this program to search any block and any attribute tag.  That way, no matter how a draftsman places the data on the drawing, the program will search it out and hyperlink it to the matching drawing file.

 

5. As a final note (just FYI), another program (maybe BAT file) will actually build the comparison list on a daily basis. The BAT program will have a list of directories embedded inside it.  The BAT program will list out the drawing files within the directories and build the dwg-list in the format as depicted in #3 (see above). That way as new drawings are created or removed, they will be included (or removed) from the drawing-list.

 

6. What follows is the final version of my text to hyperlink version. It works great!  I left in my debugging "print" statements for fun, but they are commented out. Feel free to use!

 

************************************************************************

 

(DEFUN C:hyperlnk ()
; This program will scan through all text elements on a drawing and comapre it to a drawing list (DWGLST).
; The DWGLST is in the format as follows;
; drawing name (as shown on other drawings, which must match the filename - ".dwg")
; path to the drawing
; (repeat as many drawings you have)
; EOF
; EOF
; (note: indicate end of data file with 2 "EOF" as shown above.)
; by Vic Rodrigue, Jr.
; March 2011


(setq dwgnum (getvar "DWGNAME"))

 

; make selection set which includes any piece of free text
(setq SSLTXT (ssget "x" '((0 . "text"))))

 

; if selection set exists then proceed, else quit
(if SSLTXT
(progn

 

; (print "selection set obtained")

 

; get the number of text elements selected and store as SSLTXTLEN
(setq SSLTXTLEN (sslength SSLTXT))
; (print SSLTXTLEN)

 

; repeat the next section for as many text elements in selection set
; the counter "COUNTER" is incremented each time to keep track of how many times this is running
; the drawing-list file is opened for each text element in selection set, but closed after the dwg-list is exhausted
(setq COUNTER 0)       
(repeat SSLTXTLEN
; (print COUNTER)
; you can change the path indicated below to wherever your drawing list resides
(setq DWGLST (open "c:/scripts/drawings/dwglst.txt" "r"))

 

; select next piece of text (as entity) in original selection set
(setq ENT (ssname SSLTXT COUNTER))
(setq ENTTXT (entget ENT))
(setq THETXT (cdr (assoc 1 ENTTXT))) ; the actual text
; (print THETXT)

 

; this next selection will need to be repeated for ever set in dwglst

(setq STOPME 0); reset file indexer
; repeat this section until either a match of dwgname=text is found, or the dwg-list is exhausted
(while (= STOPME 0)
   (progn

 

   (setq DWG (read-line DWGLST))
   (if (= "EOF" DWG)
      (setq STOPME 1)
   );fi
   (setq PATH (read-line DWGLST))
   ; (print DWG)
   ; (print PATH)

 

   ; if THETXT=DWG, then make a hyperlink that is assigned to EN which points to PATH+DWG+".dwg"
   (if (= THETXT DWG)

 

   (progn
   ; (print "THIS IS A MATCH!!!")
   (setq TEMP (strcat PATH "\\" DWG ".DWG"))
   ; (print TEMP)
   (command "-hyperlink" "" "" ENT "" TEMP "" "")
   (setq STOPME 1)
   );progn

 

   ; (print "NO MATCH")

 

   ); fi

 

   ); progn
); while

 

(close DWGLST)
(setq COUNTER (+ COUNTER 1))
); repeat

 

); progn
); fi
 
); DEFUN

 

*****************************************************************

 

-Vic

Message 7 of 31
pbejse
in reply to: Anonymous

If I may.

instead of reading the text file (dwglst.txt)  for every text entity, I woould suggest reading it once (read previous post) and use hat list for pattern matching

 

(defun c:tryme2 (/ DWGLST nw_lst THETXT)
	(vl-load-com)
	  	(setq DWGLST (open "c:/scripts/drawings/dwglst.txt" "r"))
		(while (setq str (read-line DWGLST))
	          	(if (not (eq str ""))
	  		(setq nw_lst (cons 
	                   	(list  str
	                                   (read-line DWGLST))
	                        	nw_lst
	                  	)
	                  )
	             )
	  	)
	  	(close Dwglst)
(if  (ssget "x" '((0 . "text")))
  		(vlax-for txt (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))
                  (if (setq THETXT (assoc (vla-get-textstring txt) nw_lst))
			(vla-add  (vla-get-hyperlinks txt)
                    	(strcat (cadr THETXT)(strcat "\\" (car THETXT) ".dwg")) "File Hyperlink")
        		)            	
		)
  	)
(princ)
  )

 

Note: (the format I used for the text fil)

E-001-I-40100
..\ wiring diagrams
E-001-I-40101
..\ wiring diagrams
E-001-I-40102
..\ wiring diagrams
E-001-M-30300
..\ PIDs
E-001-M-30301
..\ PIDs

 <----- extra return for the last entry

 

No spaces between entry. no EOF marker

 

Try it...

Message 8 of 31
Anonymous
in reply to: Anonymous

...about that last post...I'll look into the building a list as a means of storing an array of values.  That is something that I could have used a few times in the past, but never did it.  If I have time, I'll add it to the program, just for the experience, otherwise I'll leave it as-is.  It functions. Done. 🙂

 

I like the "EOF" better than the (extra carriage return).  It is something that you can easily see in the file. I'm pretty sure my program will end properly with only (1) "EOF", but I just threw in a second one knowing it would not hurt.

 

******************

 

I was not able to get your sample program to work (the one a few posts back). It reads...

 

"Select Block: ; error: no function definition: VLAX-ENAME->VLA-OBJECT".

 

Just to cut to the chase, is there a command line input that I can type in, to add the hyperlink to the attribute? It appears that it can only be added with the dialogue box.

 

 

Message 9 of 31
pbejse
in reply to: Anonymous

add

 

(defun c:tryme ( / blk result hpt)
(vl-load-com).....

 

this and the previous post doesnt go through the dialog box. (that is if you can make it to work on your end)

Smiley Happy

 

You dont need to follow my advise, but seeing how your code reads the text file over and over again for every text string. makes me wonder how will it fair with large numbers of entities and a very long dwglist.

 

Anyhoo, just my 2 cents

 

 

 

 

 

Message 10 of 31
Anonymous
in reply to: Anonymous

OK, I got your sample program to function.  However, the final drawing cannot find the hyperlink destination.

 

I tried all kinds of things to no avail.

 

***

 

I tried "attedit" then right-clicked on the attributes.  Then "insert field". For hyperlinks that get manuaaly inserted, the hyperlink is already placed, but in this example it is not even present.

 

It appears that some hyperlink was assigned to the attributes that match the criteria, but I cannot tell where it is looking or what file it is looking for.

 

Perhaps a print statement that prints what destination is being assigned?

 

 

Message 11 of 31
pbejse
in reply to: Anonymous

The only fault i see is the path where the link points to the drawing itself

I tried it on my end. works all the time

 

Check the path again my friend.

To check, do one of the attributes like you would normally do, then check the hyperlink path on that one. see if it match your strcat function

 

What do you mean by this?

Perhaps a print statement that prints what destination is being assigned?

you need a function for this?

 

AND . One more thing. textstring pattern matching is case sensitive

BTW what error are you getting anyway?

 

 

 

 

Message 12 of 31
Anonymous
in reply to: pbejse

well....for one, I cannot query the attribute (after the process has been done) to determine what the hyperlink is.   So, since the hyperlink destination cannot be found, I'm not sure where to find the issue.  That is why I was asking about printing the path and dwgfilename to the screen. (So I would know what is being actively set as the hyperlink path and the hyperlink itself)

 

The error I'm getting (which is not really an error), is a "Hyperlink destination not found" message.  This is when I click on the attribute while holding down ctrl.   Sounds like either the filename is not correct, or the pathname.  I have tried several variations of each in different combinations, and not sure where the fault lies.

 

Are you able to use ATTEDIT on the attribute, then right-click on the attribute, then see the hyperlink that is assigned to the attribute?

 

 

Message 13 of 31
pbejse
in reply to: pbejse

(defun c:givemethepath nil
(vl-load-com)
(print (vla-get-URL
(vla-item 
(vla-get-hyperlinks 
	(vlax-ename->vla-object (car (nentsel)))) 0)))
  (princ)
  )

 

command: givemethepath (select the attribute with Hyperlink)

 

check with the result with the return value from your strcat function

 

Message 14 of 31
Anonymous
in reply to: pbejse

Allright, now we are cooking with grease!

 

One of my issues was a case-sensitive issue.

 

The other issue, is that the routine does not overwrite an existing hyperlink. So, whenever I changed up the dwgname or pathname in the routine and reloaded/re-ran it, it did not do anything new.

 

The last piece of the puzzle...can it be made to overwrite an existing hyperlink?

 

so, so close....

Message 15 of 31
pbejse
in reply to: Anonymous

Of course, first check for existence of HYperlink on the object if T delete , then add the new one

Love to stay but the bus is leaving..   Smiley Wink

 

keep m e posted buddy

 

 

 

Message 16 of 31
pbejse
in reply to: Anonymous

vrod,

 

Were you able to make the modification in the code? post here whatever  you got working on and we'll finalize it

 

Smiley Wink

 

Message 17 of 31
Anonymous
in reply to: pbejse

I was not able to add the code to delete the hyperlink (if exist).  I have not programmed using the type of code that you are using. (That "VL" stuff). That is why I was having trouble just querrying values.

 

I haven't spent time adding onto the program yet, as the main part is not able to perform my desired task.

 

Close, but no cigar.

Message 18 of 31
pbejse
in reply to: pbejse

I see, granting there is no Hyperlink on the attribute yet, does the code works?  were you able to fix the "Hyperlink destination not found" issue?  (filepath)

 

I can write a code for deleteting the existing Hyperlink but i need to know how far you've gone or what routine you're using now?, did you use the code for attribute i posted or did you stick with the one you are using? If the latter in what format did you use for thedrawing list file? did you keep the EOF flag?

 

we're too close to give up now my friend

 Smiley Happy

 

 

 

 

 

 

Message 19 of 31
Anonymous
in reply to: pbejse

Yes, I was able to have it work on a first pass.  No problems at all.

 

The final issue is having it overwrite an existing hyperlink.

 

When I code something new, I work on the main part of the program first. Once that is worked out, I flesh out the rest.  That way, if I cannot work out the key part of the program, I can shift gears and do something different. 

 

Currently, I am not reading in my drawing list at all.  Rather, I'm just using the code you had given me, and have simply changed the hard-coded data to reflect 3 of my drawing numbers and pathnames.

 

I do not follow the key part of the code you have provided, so that means when I use it, I will have to read my data into a list, just so I can use it in your code. No biggie there.

 

I had figured that if I could not get this to function, I can always fall back on using only the text-hyperlink program that I wrote. It just would be nice to have this work for attributes as well.

 

 

 

Message 20 of 31
pbejse
in reply to: Anonymous

Here, I tried to match your code as close as possible

Hope thi s works for you, I'm pretty sure you can put it all together

 

(defun c:HyperL  (/ blks dwglist str nw_lst blk hpt htp cntr)
  (vl-load-com)
  (if (setq blks (ssget '((0 . "INSERT") (66 . 1))))
    (progn
      (setq dwglst (open "c:/scripts/drawings/dwglst.txt" "r") cntr -1)
      (while (setq str (read-line DWGLST))
        (if (not (eq str "EOF"))
          (setq nw_lst (cons (list (strcase str) (read-line DWGLST)) nw_lst))))
      (close Dwglst)
      (while (setq blk (ssname blks (setq cntr (1+ cntr))))
        (foreach
           at_str  (vlax-invoke
                     (vlax-ename->vla-object blk)
                     'GetAttributes)
          (if
            (setq hpt (assoc (strcase (vla-get-textstring at_str)) nw_lst))
             (progn
               (if (> (vla-get-count
                        (setq htp (vla-get-hyperlinks at_str)))
                      0)
                 (vla-delete (vla-item htp 0))) ;if Hyperlink Exist
               (vla-add
                 (vla-get-hyperlinks at_str)
                 (strcat (cadr hpt) (car hpt) "*.dwg")
                 "File Hyperlink")))    ;if
          );foreach
        );while
      );progn
    );if ssget
  (princ))

 

The text file format is like this

Filename1
..\TrialFolder\Drawing Folder\
Filename2
..\TrialFolder\Drawing Folder\
Filename3
..\TrialFolder\Other Drawing Folder\
Filename4
..\TrialFolder\Drawing Folder\
EOF

 

I include the strcase function in there to take care of the pattern matching

Now if your text doesnt include the last  "\", then this line should read

 

(strcat (cadr hpt) (car hpt) "*.dwg")
(strcat (cadr hpt) "\\" (car hpt) "*.dwg")

 

Hope this helps

 

 

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost