Wednesday, September 12, 2007

AutoCAD hyperlink command advanced

If the basics is not enough here comes most everything else worth knowing about hyperlinks in AutoCAD.

Here is a sample code that can be used in CUI (Customize User Interface) as a Double Click Action macro instead of the default one ^C^C_properties. If the object has a hyperlink it will be opened and if not the Properties palette will be opened.

^C^C(if (setq path (cdr (cadadr (assoc -3 (entget (ssname (ssget "P") 0) '("PE_URL")))))) (command "BROWSER" path) (command "PROPERTIES"))

If you want to create a hyperlink to a named location in a non-AutoCAD file add a pound sign (#) after the name of the file that the hyperlink is linked to. Here is a sample for Excel:
C:\Documents\MyBook1.xls#Sheet1!C10
It will open MyBook1.xls, sheet1 and locate the cell C10.
or to Word:
C:\Documents\MyDocument.doc#MyBookmark
C:\Documents\MyDocument.doc#3
    (opens page 3)
or a PDF file in Adobe Reader or Adobe Acrobat
C:\Documents\myFile.pdf#page=3

To find all objects that are hyperlinked use QSELECT and since there is no operator to select all objects with a hyperlink you can select Not Equal and enter a Value you know does not exist.

 image

With the -HYPERLINK command you can insert hyperlinks on objects and this can be automated like this with AutoLISP:
(command "-HYPERLINK" "I" "O" ent "" "" "Detail 1" "Detail 1")

Using the -HYPERLINK Insert option:

Command: -hyperlink
Enter an option [Remove/Insert] <Insert>: i
Enter hyperlink insert option [Area/Object]: O
Select objects: 1 found
Select objects:
Enter hyperlink <current drawing>:
Enter named location <none>: Detail 1
Enter description <none>: Detail 1

Notice that you have an Area option. That will ask you for First corner and Other corner and create a 3D Polyline on the layer URLLAYER. The URLLAYER is automatically created. When is this useful. For example if you plot to DWF you will find that you can click anywhere in that area and the 3D Polyline will not be visible.

image

Using the -HYPERLINK Remove option:

Command: -hyperlink
Enter an option [Remove/Insert] <Insert>: R
Select objects: Specify opposite corner: 7 found
Select objects:
1.  TANK 3 (TANK 3)
2.  TANK 2 (TANK 2)
3.  http://www.jtbworld.com (jtbworld.com)
4.  http://www.jtbworld.com (jtbworld.com)
5.  http://www.jtbworld.com (jtbworld.com)
6.  TANK 1 (TANK 1)
7.  http://www.jtbworld.com (jtbworld.com)

Enter number, hyperlink, or * for all: http://www.jtbworld.com
4 hyperlinks deleted.

With the DETACHURL command you can delete hyperlinks from objects and this can be automated like this:
(command "DETACHURL" ent "")

If a drawing has had hyperlinks the Registered application PE_URL can be purged.

Command: -purge
Enter type of unused objects to purge
[Blocks/Dimstyles/LAyers/LTypes/MAterials/Plotstyles/SHapes/textSTyles/Mlinestyles/Tablestyles/Visualstyles/Regapps/All]: r
Enter name(s) to purge <*>:
Verify each name to be purged? [Yes/No] <Y>: Y
Purge registered application "PE_URL"? <N> Y

HYPERLINKBASE - Specifies the path used for all relative hyperlinks in the drawing. If no value is specified, the drawing path is used for all relative hyperlinks.

Or use DWGPROPS and on the Summary tab, enter a relative path in Hyperlink Base.

HYPERLINKOPEN - Asks for a hyperlink and opens it or navigates to that location that could be a named view or layout tab.

Command: HYPERLINKOPTIONS
Display hyperlink cursor, tooltip, and shortcut menu? [Yes/No] <Yes>:

PASTEASHYPERLINK - Inserts data from the Clipboard as a hyperlink. Example. Copy a file in Explorer and run the command or select Edit>Paste as Hyperlink and then select one or several objects. Now a hyperlink to the document will be inserted on the object(s).

AutoLISP

And now into more details how to use entget to find the information. The hyperlink information is attached as xdata.

If you want to know how many hyperlinked objects there are use:
(sslength (ssget "x" '((-3 ("PE_URL")))))

Command: (assoc -3 (entget (car (entsel)) (list "PE_URL")))
Select object:
(-3 ("PE_URL" (1000 . "http:// www.autodesk.com") (1002 . "{") (1000 . "Autodesk") (1002 . "{") (1071 . 0) (1002 . "}") (1002 . "}")))

And this is an example how the hyperlink is to the view named Detail 1 in the current drawing.

Command: (assoc -3 (entget (car (entsel)) (list "PE_URL")))
Select object:
(-3 ("PE_URL" (1000 . "") (1002 . "{") (1000 . "Detail text display") (1000 . "Detail 1") (1002 . "{") (1071 . 1) (1002 . "}") (1002 . "}")))

To make sure the option Convert Hyperlink to DWF is always set the code below is needed.

(defun markHlinkDWF ()
  (setq mysel (ssget "_X" '((-3 ("PE_URL")))))
  (setq iMaxSel (sslength mysel))
  (setq iCnt 0)
  (while (< iCnt iMaxSel)
    (setq my_entname (ssname mysel iCnt))
    (setq my_ent (entget my_entname '("PE_URL")))
    ;; get the entity including Xdata for hlinks
    (setq my_xdata1 (assoc -3 my_ent))
    ;; open up the XData
    (setq my_xdata_URL (nth 1 my_xdata1))
    (setq my_new_xdata_URL (subst '(1071 . 1) '(1071 . 0) my_xdata_URL))
    ;; enable flag for convert DWG to DWF
    (setq my_new_xdata1 (subst my_new_xdata_URL my_xdata_URL my_xdata1))
    ;; update XData
    (setq my_ent (subst my_new_xdata1 my_xdata1 my_ent))
    (entmod my_ent)
    ;; set the entity
    (setq iCnt (+ iCnt 1))
  )
  nil
)
(defun validate	()
  (setq mysel (ssget "_X" '((-3 ("PE_URL")))))
  (setq iMaxSel (sslength mysel))
  (setq iCnt 0)
  (setq iFailCnt 0)
  (while (< iCnt iMaxSel)
    (setq my_entname (ssname mysel iCnt))
    (setq my_ent (entget my_entname '("PE_URL")))
    ;; get the entity including Xdata for hlinks
    (setq my_xdata1 (assoc -3 my_ent))
    ;; open up the XData
    (setq my_xdata_URL (nth 1 my_xdata1))
    (if	(/= (member '(1071 . 0) my_xdata_url) nil)
      (setq iFailCnt (+ iFailCnt 1))
    )
    (setq iCnt (+ iCnt 1))
  )
  (if (> iFailCnt 0)
    (progn
      (setq
	my_str (strcat (itoa iFailCnt) " hyperlink(s) not updated.")
      )
      (princ my_str)
      nil
    )
  )
)

(setq Hyplink (markHlinkdwf))
(setq Hyplinkval (validate))

Here is how a hyperlink can be attached to an object.

(if (null (tblsearch "appid" "PE_URL"))
  (regapp "PE_URL")
)

(entmod
  (append (entget (car (entsel)))
    (list (list -3 (cons "PE_URL" (list
      ; URL
      (cons 1000 "http:// www.autodesk.com")
      ; Tooltip
      (cons 1002 "{")
      (cons 1002 "}")
    ))))
  )
)

There are other methods as well using Visual LISP extensions to AutoLISP (vl-load-com).

You can look at using:
vla-get-HyperlinkBase
vla-get-HyperlinkDisplayCursor
vla-get-HyperlinkDisplayTooltip
vla-get-Hyperlinks
vla-put-HyperlinkBase
vla-put-HyperlinkDisplayCursor
vla-put-HyperlinkDisplayTooltip

VBA

VBA Hyperlinks Example from the AutoCAD Developer Documentation

Sub Example_HyperLinks()
    ' This example creates a Circle object in model space and
    ' adds a new Hyperlink to its Hyperlink collection
    
    Dim Hyperlinks As AcadHyperlinks
    Dim Hyperlink As AcadHyperlink
    Dim circleObj As AcadCircle
    Dim centerPoint(0 To 2) As Double
    Dim radius As Double
    Dim HLList As String
    
    ' Define the Circle object
    centerPoint(0) = 0: centerPoint(1) = 0: centerPoint(2) = 0
    radius = 5#
    
    ' Create the Circle object in model space
    Set circleObj = ThisDrawing.ModelSpace.AddCircle(centerPoint, radius)

    ThisDrawing.Application.ZoomAll
    
    ' Get reference to the Circle's Hyperlinks collection
    Set Hyperlinks = circleObj.Hyperlinks
    
    ' Add a new Hyperlink complete with all properties
    Set Hyperlink = Hyperlinks.Add("AutoDesk")
    Hyperlink.URL = "www.autodesk.com"
    Hyperlink.URLDescription = "Autodesk Main Site"
    Hyperlink.URLNamedLocation = "MY_LOCATION"
    
    ' Read and display a list of existing Hyperlinks and
    ' their properties for this object
    For Each Hyperlink In Hyperlinks
        HLList = HLList & "____________________________________" & vbCrLf   ' Separator
        HLList = HLList & "URL: " & Hyperlink.URL & vbCrLf
        HLList = HLList & "URL Description: " & Hyperlink.URLDescription & vbCrLf
        HLList = HLList & "URL Named Location: " & Hyperlink.URLNamedLocation & vbCrLf
    Next
    
    MsgBox "The circle has " & Hyperlinks.count & " Hyperlink: " & vbCrLf & HLList
End Sub

VBA HyperlinkBaseExample from the AutoCAD Developer Documentation

Sub Example_HyperlinkBase()
	' This example shows how to access drawing properties
            
	' Add and display standard properties
	ThisDrawing.SummaryInfo.Author = "John Doe"
	ThisDrawing.SummaryInfo.Comments = "Includes all ten levels of Building Five"
	ThisDrawing.SummaryInfo.HyperlinkBase = "http://www.autodesk.com"
	ThisDrawing.SummaryInfo.Keywords = "Building Complex"
	ThisDrawing.SummaryInfo.LastSavedBy = "JD"
	ThisDrawing.SummaryInfo.RevisionNumber = "4"
	ThisDrawing.SummaryInfo.Subject = "Plan for Building Five"
	ThisDrawing.SummaryInfo.Title = "Building Five"

	Author = ThisDrawing.SummaryInfo.Author
	Comments = ThisDrawing.SummaryInfo.Comments
	HLB = ThisDrawing.SummaryInfo.HyperlinkBase
	KW = ThisDrawing.SummaryInfo.Keywords
	LSB = ThisDrawing.SummaryInfo.LastSavedBy
	RN = ThisDrawing.SummaryInfo.RevisionNumber
	Subject = ThisDrawing.SummaryInfo.Subject
	Title = ThisDrawing.SummaryInfo.Title
	MsgBox "The standard drawing properties are " & vbCrLf & _
		    "Author = " & Author & vbCrLf & _
		    "Comments = " & Comments & vbCrLf & _
		    "HyperlinkBase = " & HLB & vbCrLf & _
		    "Keywords = " & KW & vbCrLf & _
		    "LastSavedBy = " & LSB & vbCrLf & _
		    "RevisionNumber = " & RN & vbCrLf & _
		    "Subject = " & Subject & vbCrLf & _
		    "Title = " & Title & vbCrLf

	' Add and display custom properties
	Dim Key0 As String
	Dim Value0 As String
	Dim Key1 As String
	Dim Value1 As String
	Dim CustomPropertyBranch As String
	Dim PropertyBranchValue As String
	Dim CustomPropertyZone As String
	Dim PropertyZoneValue As String

	CustomPropertyBranch = "Branch"
	PropertyBranchValue = "Main"
	CustomPropertyZone = "Zone"
	PropertyZoneValue = "Industrial"

	' Add custom properties
	If (ThisDrawing.SummaryInfo.NumCustomInfo >= 1) Then
		ThisDrawing.SummaryInfo.SetCustomByIndex 0, CustomPropertyBranch, PropertyBranchValue
	Else
		ThisDrawing.SummaryInfo.AddCustomInfo CustomPropertyBranch, PropertyBranchValue
	End If

	If (ThisDrawing.SummaryInfo.NumCustomInfo >= 2) Then
		 ThisDrawing.SummaryInfo.SetCustomByKey CustomPropertyBranch, "Satellite"
	Else
		 ThisDrawing.SummaryInfo.AddCustomInfo CustomPropertyZone, PropertyZoneValue
	End If

	'Get custom properties
	ThisDrawing.SummaryInfo.GetCustomByIndex 0, Key0, Value0
	Key1 = CustomPropertyZone
	ThisDrawing.SummaryInfo.GetCustomByKey Key1, Value1

	MsgBox "The custom drawing properties are " & vbCrLf & _
		    "First property name = " & Key0 & vbCrLf & _
		    "First property value = " & Value0 & vbCrLf & _
		    "Second property name = " & Key1 & vbCrLf & _
		    "Second property value = " & Value1 & vbCrLf
End Sub

4 comments:

  1. Restored comment
    by Benson
    Also in VBA in may be necessary to clear a hyperlink if a new description needs to be added (in the case below this is strDescription):
    'Get reference to the objects Hyperlinks collection
    Set HyperLinks = Object.HyperLinks
    'add a new hyperlink

    If HyperLinks.count = 0 Then
    Set Hyperlink = HyperLinks.Add("No Data On Object")
    Else
    Set Hyperlink = HyperLinks.Item(0)
    End If
    Hyperlink.URLDescription = strDescription

    www.herculedesign.com

    ReplyDelete
  2. hey i see u have a code written at the start to automatically open the file when the object is double clicked instead of the properties tab. but where do u put that code it says CUI but i have no idea where that is or where IN the CUI to put the code. could you please help me

    ReplyDelete
  3. Run CUI.
    Locate Double Click Actions.
    Then select what object you want to edit. Take Circle as an example. Click on the + so you can see and click on Properties. Now you will see the Properties on the right hand. There you will find "Macro".
    Do this for all object types you want.

    ReplyDelete
  4. Is it possible to keep AutoCad from minimizing when you open a hyperlink?

    Thanks!

    ReplyDelete