After much hair pulling, I decided to try and create a way to update dref pipe networks to match style and object layer of the parent pipe network. I couldn't figure out how to find the file where dref is targeting, so I just manually select the source file. Using ODBX, I can extract structure & pipe styles and layer (atm, it only deals with structures - testing simplicity), but when it iterates through the active drawing, where the dref network resides, it finds a matching part, but cannot apply a different style to the structure. I get nothing but "Error: Member not found".
I am curious, Jeff, if you made any progress with something of the sort.
I have a feeling legacy COM just has a bug that won't allow the user to change the structure style. I even made a simple command to do nothing but collect a list of structure styles in the active drawing and apply one of them to a selected structure.
I've attached all my code, for anyone that may be interested; the "test" command is my failed sync attempt and the "css" command is my testing function to choose a style from a list and apply it to a single selected structure (no error checking).
(defun c:test (/ *error* ss i objlst stylelst file odbx parts ass a b c)
(defun *error* (msg)
(and odbx (vlax-release-object odbx))
(if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
(progn (vl-bt) (princ (strcat "\nError: " msg)))
)
)
(cond
;; check if a pipe network exists in drawing and is a reference
((progn
(if (setq ss (ssget "_X" '((0 . "AECC_STRUCTURE"))))
(repeat (setq i (sslength ss))
(setq o (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
(if (eq (vlax-invoke o 'IsReferenceObject) 1) ; is dref part?
(setq objlst (cons (cons (strcat (vla-get-name o) "_" (vlax-get o 'PartSizeName)) o)
objlst
)
)
)
)
)
(not objlst)
)
(alert "No Data Referenced parts in active drawing.")
)
;; get list of structure styles in active drawing
((progn
(vlax-for x (vlax-get (AT:PipeDoc) 'StructureStyles)
(setq stylelst (cons (cons (vla-get-name x) x) stylelst))
)
(not stylelst)
)
(alert "No Part Styles in active drawing.")
)
;; located master network dwg to sync files
((not (setq file (getfiled "Select drawing where master pipe network resides"
(getvar 'DWGPREFIX)
"dwg"
2
)
)
)
)
;; odbx master file
((not
(if (setq odbx (vlax-create-object
(if (< (setq release (atoi (getvar 'ACADVER))) 16)
"ObjectDBX.AxDbDocument"
(strcat "ObjectDBX.AxDbDocument." (itoa release))
)
)
)
(progn (vla-open odbx file) t)
)
)
(alert "File could not be opened.")
)
;; step through odbx drawing, find networks, extract style name
((progn
(vlax-for x (vla-get-block (vla-get-layout (vla-get-modelspace odbx)))
(if (member (vla-get-objectname x) '("AeccDbStructure"))
(setq parts (cons (cons (strcat (vla-get-name x) "_" (vlax-get x 'PartSizeName))
(list (vla-get-name (vlax-get x 'Style))
(vla-get-layer x)
)
)
parts
)
)
)
)
;; (startapp "notepad" (AT:WriteToFile (vl-filename-mktemp nil nil "txt") parts t))
(not parts)
)
(alert "No pipe networks in selected drawing.")
)
(t
(foreach x objlst
(if (setq ass (cdr (assoc (car x) parts)))
(progn
;;; (setq a (cdr x)
;;; b (car ass)
;;; c (cdr (assoc (car ass) stylelst))
;;; )
;;; (startapp "notepad" (AT:WriteToFile (vl-filename-mktemp nil nil "txt") (list a b c) t))
(vl-catch-all-apply 'vlax-put (list (cdr x) 'Style (cdr (assoc (car ass) stylelst))))
(vl-catch-all-apply 'vla-put-layer (list (cdr x) (cadr ass)))
)
)
)
)
)
(*error* nil)
(princ)
)
(defun c:css (/ o stylelst style)
(vlax-for x (vlax-get (AT:PipeDoc) 'StructureStyles)
(setq stylelst (cons (cons (vla-get-name x) x) stylelst))
)
(if (and (setq o (car (entsel "\nSelect c3d structure: ")))
(setq style (car (at:listselect "" "" 15 15 "false" (mapcar 'car stylelst))))
)
(vlax-put (vlax-ename->vla-object o) 'style (cdr (assoc style stylelst)))
)
(princ)
)
(defun AT:WriteToFile (file lst overwrite / fo)
;; Write list to file
;; file - file to write list to (must be in form "c:\\File.txt")
;; lst - list to write to file
;; overwrite - If T, will overwrite; nil to append
;; Alan J. Thompson, 04.28.09
(if (and (vl-consp lst)
(setq fo (open file
(if overwrite
"W"
"A"
)
)
)
)
(progn (foreach x lst (write-line (vl-princ-to-string x) fo))
(close fo)
file
)
)
)
(defun AT:ListSelect (title label height width multi lst / fn fo d item f)
;; List Select Dialog (Temp DCL list box selection, based on provided list)
;; title - list box title
;; label - label for list box
;; height - height of box
;; width - width of box
;; multi - selection method ["true": multiple, "false": single]
;; lst - list of strings to place in list box
;; Alan J. Thompson, 09.23.08 / 05.17.10 (rewrite)
(setq fo (open (setq fn (vl-filename-mktemp "" "" ".dcl")) "w"))
(foreach x (list (strcat "list_select : dialog { label = \"" title "\"; spacer;")
(strcat ": list_box { label = \"" label "\";" "key = \"lst\";")
(strcat "allow_accept = true; height = " (vl-princ-to-string height) ";")
(strcat "width = " (vl-princ-to-string width) ";")
(strcat "multiple_select = " multi "; } spacer; ok_cancel; }")
)
(write-line x fo)
)
(close fo)
(new_dialog "list_select" (setq d (load_dialog fn)))
(start_list "lst")
(mapcar (function add_list) lst)
(end_list)
(setq item (set_tile "lst" "0"))
(action_tile "lst" "(setq item $value)")
(setq f (start_dialog))
(unload_dialog d)
(vl-file-delete fn)
(if (= f 1)
((lambda (s / i s l)
(while (setq i (vl-string-search " " s))
(setq l (cons (nth (atoi (substr s 1 i)) lst) l))
(setq s (substr s (+ 2 i)))
)
(reverse (cons (nth (atoi s) lst) l))
)
item
)
)
)
; IsReferenceObject ()
; IsReferenceStale ()
; IsReferenceSubObject ()
; IsReferenceValid
;;; (vlax-for x (vla-get-block
;;; (vla-get-layout (vla-get-modelspace oDoc))
;;; )
(defun AT:AeccDoc (/ i c)
;; Return and set (as global variable *AeccDoc*) Civil 3D Aecc Document object
;; (will also set global variables for acad object *Acad* and c3d aecc application *AeccApp*)
;; Alan J. Thompson, 2013.11.27, 2014.03.20
(cond (*AeccDoc*)
((progn
(setq i 2.9)
(while (and (<= (setq i (+ i 0.1)) 50.) (not *AeccApp*))
(if (not (vl-catch-all-error-p
(setq c (vl-catch-all-apply
'vla-getinterfaceobject
(list (cond (*Acad*)
((setq *Acad* (vlax-get-acad-object)))
)
(strcat "AeccXUiLand.AeccApplication." (vl-princ-to-string i))
)
)
)
)
)
(setq *AeccApp* c)
)
)
*AeccApp*
)
(setq *AeccDoc* (vlax-get *AeccApp* 'ActiveDocument))
)
)
)
(defun AT:PipeDoc (/ i c)
;; Return and set (as global variable *PipeDoc*) Civil 3D Pipe Document object
;; (will also set global variables for acad object *Acad* and c3d pipe application *AeccApp*)
;; Alan J. Thompson, 2015.02.26
(cond
(*PipeDoc*)
((progn
(setq i 2.9)
(while (and (<= (setq i (+ i 0.1)) 50.) (not *PipeApp*))
(if (not (vl-catch-all-error-p
(setq c (vl-catch-all-apply
'vla-getinterfaceobject
(list (cond (*Acad*)
((setq *Acad* (vlax-get-acad-object)))
)
(strcat "AeccXUiPipe.AeccPipeApplication." (vl-princ-to-string i))
)
)
)
)
)
(setq *PipeApp* c)
)
)
*PipeApp*
)
(setq *PipeDoc* (vlax-get *PipeApp* 'ActiveDocument))
)
)
)