Author Topic: Table Rector Help Needed  (Read 1917 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Table Rector Help Needed
« on: August 19, 2020, 02:56:50 PM »
I am trying to setup a reactor that automatically renumbers/inserts blocks after a table has been edited. My code is below, after editing the table, I get the error: Automation Error. Object was notifying

I am not super familiar with reactors yet, but I am sure that I am doing something obviously wrong here, can someone please advise?

Code: [Select]
(vl-load-com)
;Supporting Functions

;;Ranjit Singh
;;7/11/17
;;Sets Cell Style
(defun FixStyle  (x tblobj c / rows r)
  (setq r 1
        rows (vla-get-rows tblobj)
  )
  (while (< r rows)
    (vl-catch-all-apply 'vla-setcellstyle (list tblobj r c x))
    (setq r (1+ r))
  )
  (princ)
)

;The following fixes row heights
(defun FixHeight (tblobj / rows r)
  (setq rows (- (vla-get-rows tblobj) 1))
 
  (while (> rows -1)
    (vla-setrowheight tblobj rows 0.01)
    (setq rows (- rows 1))
  )
)

(defun ChangeAttr (TableObject Row Column BlockName Value / BlockCollection Bk AttID EachBk)
  (setq BlockCollection (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
        Bk (vla-item BlockCollection BlockName)
  )
  (vlax-for EachBk Bk
    (if (= (vla-get-objectname EachBk) "AcDbAttributeDefinition")
      (Setq AttID (vla-get-objectid EachBk))
    )
  )
  (vla-setblockattributevalue TableObject Row Column AttID Value)
)

;Add block to table - from https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/block-in-table/m-p/7827041/highlight/true#M366009
(defun InsertBlockTable (tableobject row column blockname / bk fg id bkid)
  (setq bk (vla-item (vla-get-blocks
       (vla-get-activedocument (vlax-get-acad-object))
     )
     blockname
   )
  )
  (if (vlax-method-applicable-p
tableobject
'setblocktablerecordid32
      )
    (setq id (vla-get-objectid32 bk)
  fg t
    )
    (setq id (vla-get-objectid bk))
  )
  ((if fg
     vla-setblocktablerecordid32
     vla-setblocktablerecordid
   )
    tableobject row column id :vlax-false)
)

;Makes a Note Table based on type:
;GN = General Notes
;RN = Reference Notes
(defun MakeTable (Pt tType / ActDoc *Space* insPt tableObj NoteRactor)
  (setq ActDoc (vla-get-activedocument (vlax-get-acad-object))
        *Space* (vlax-get-property ActDoc (nth (vla-get-ActiveSpace ActDoc)'("PaperSpace" "ModelSpace")))
        insPt (vlax-3d-point Pt)
  )
  (setq tableObj (vla-Addtable *Space* insPt 2 2 10 30))
  (vla-put-HeaderSuppressed tableObj :vlax-true)
  (vla-put-StyleName tableObj "BEI_Notes")
  (Vla-unmergecells tableObj 0 0 1 1)
  (vla-setcolumnwidth tableObj 0 0.51587034)
  (vla-setcolumnwidth tableObj 1 3.75097081)
  ;Adjust to go through every row
  (if (= tType "GN")
    (progn
      (vla-put-layer tableObj "$GN")
      (FixStyle "GN_Number" tableObj 0)
      (FixStyle "Data" tableObj 1)
      (vla-setText tableObj 0 1 "\\LGENERAL NOTES")
      (vla-setText tableObj 1 1 "PLEASE MODIFY THE TEXT HERE AND AS YOU ADD ROWS THEY WILL BE AUTOMATICALLY NUMBERED.")
      (InsertBlockTable tableObj 1 0 "genn10")
    )
    (progn
      (vla-put-layer tableObj "$RN")
      (FixStyle "RN_Number" tableObj 0)
      (FixStyle "Data" tableObj 1)
      (vla-setText tableObj 0 1 "\\LREFERENCE NOTES")
      (vla-setText tableObj 1 1 "PLEASE MODIFY THE TEXT HERE AND AS YOU ADD ROWS THEY WILL BE AUTOMATICALLY NUMBERED.")
      (InsertBlockTable tableObj 1 0 "1m10")
    )
  )
  (FixHeight tableObj)
  (setq NoteReactor (vlr-object-reactor (list TableObj) "Notes Changed" '((:vlr-objectclosed . AutoRenumberNotes))))
  (vlr-pers NoteReactor)
  (princ)
)

(defun AutoRenumberNotes (Obj Rct Arg)
  (RenumberNotes Obj)
)

(defun c:MakeRN (/ Pt)
  (setq Pt (getpoint "\nPlease select insertion point:"))
  (MakeTable Pt "RN")
)

(defun c:MakeGN (/ Pt)
  (setq Pt (getpoint "\nPlease select insertion point:"))
  (MakeTable Pt "GN")
)

(defun c:ReNumber (/ TableObject)
  (setq TableObject (vlax-ename->vla-object (car (entsel "\nSelect table: "))))
  (if (/= TableObject nil)
    (RenumberNotes TableObject)
  )
)

(defun RenumberNotes (TableObject / row rows TLayer bName cCellType)
  (setq rows (vla-get-rows TableObject)
        row 1
        TLayer (vla-get-layer TableObject)
  )
  (if (= TLayer "$GN")
    (setq bName "genn10")
    (setq bName "1m10")
)
  (while (< row rows)
    (setq cCellType (vla-getcelltype TableObject Row 0))
    (if (/= cCellType acblockcell)
      (InsertBlockTable TableObject Row 0 bName)
    )
    (ChangeAttr TableObject Row 0 bName (rtos Row 2 0))
    (setq row (+ row 1))
  )
)

;End of Supporting Functions
;Add Automatic reactors



cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Table Rector Help Needed
« Reply #1 on: August 19, 2020, 06:05:59 PM »
I think I may have actually figured this one out, now can anyone take a look through this code and let me know if there is something obvious I am overlooking?
Code: [Select]
(vl-load-com)
;Supporting Functions

;;Ranjit Singh
;;7/11/17
;;Sets Cell Style
(defun FixStyle  (x tblobj c / rows r)
  (setq r 1
        rows (vla-get-rows tblobj)
  )
  (while (< r rows)
    (vl-catch-all-apply 'vla-setcellstyle (list tblobj r c x))
    (setq r (1+ r))
  )
  (princ)
)

;The following fixes row heights
(defun FixHeight (tblobj / rows r)
  (setq rows (- (vla-get-rows tblobj) 1))
 
  (while (> rows -1)
    (vla-setrowheight tblobj rows 0.01)
    (setq rows (- rows 1))
  )
)

(defun ChangeAttr (TableObject Row Column BlockName Value / BlockCollection Bk AttID EachBk)
  (setq BlockCollection (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
        Bk (vla-item BlockCollection BlockName)
  )
  (vlax-for EachBk Bk
    (if (= (vla-get-objectname EachBk) "AcDbAttributeDefinition")
      (Setq AttID (vla-get-objectid EachBk))
    )
  )
  (vla-setblockattributevalue TableObject Row Column AttID Value)
)

;Add block to table - from https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/block-in-table/m-p/7827041/highlight/true#M366009
(defun InsertBlockTable (tableobject row column blockname / bk fg id bkid)
  (setq bk (vla-item (vla-get-blocks
       (vla-get-activedocument (vlax-get-acad-object))
     )
     blockname
   )
  )
  (if (vlax-method-applicable-p
tableobject
'setblocktablerecordid32
      )
    (setq id (vla-get-objectid32 bk)
  fg t
    )
    (setq id (vla-get-objectid bk))
  )
  ((if fg
     vla-setblocktablerecordid32
     vla-setblocktablerecordid
   )
    tableobject row column id :vlax-false)
)

;Makes a Note Table based on type:
;GN = General Notes
;RN = Reference Notes
(defun MakeTable (Pt tType / ActDoc *Space* insPt tableObj NoteRactor)
  (setq ActDoc (vla-get-activedocument (vlax-get-acad-object))
        *Space* (vlax-get-property ActDoc (nth (vla-get-ActiveSpace ActDoc)'("PaperSpace" "ModelSpace")))
        insPt (vlax-3d-point Pt)
  )
  (setq tableObj (vla-Addtable *Space* insPt 2 2 10 30))
  (vla-put-HeaderSuppressed tableObj :vlax-true)
  (vla-put-StyleName tableObj "BEI_Notes")
  (Vla-unmergecells tableObj 0 0 1 1)
  (vla-setcolumnwidth tableObj 0 0.51587034)
  (vla-setcolumnwidth tableObj 1 3.75097081)
  ;Adjust to go through every row
  (if (= tType "GN")
    (progn
      (vla-put-layer tableObj "$GN")
      (FixStyle "GN_Number" tableObj 0)
      (FixStyle "Data" tableObj 1)
      (vla-setText tableObj 0 1 "\\LGENERAL NOTES")
      (vla-setText tableObj 1 1 "PLEASE MODIFY THE TEXT HERE AND AS YOU ADD ROWS THEY WILL BE AUTOMATICALLY NUMBERED.")
      (InsertBlockTable tableObj 1 0 "genn10")
    )
    (progn
      (vla-put-layer tableObj "$RN")
      (FixStyle "RN_Number" tableObj 0)
      (FixStyle "Data" tableObj 1)
      (vla-setText tableObj 0 1 "\\LREFERENCE NOTES")
      (vla-setText tableObj 1 1 "PLEASE MODIFY THE TEXT HERE AND AS YOU ADD ROWS THEY WILL BE AUTOMATICALLY NUMBERED.")
      (InsertBlockTable tableObj 1 0 "1m10")
    )
  )
  (FixHeight tableObj)
  (setq NoteReactor (vlr-object-reactor (list TableObj) "Notes Changed" '((:vlr-objectclosed . AutoRenumberNotes))))
  (vlr-pers NoteReactor)
  (princ)
)

(defun AutoRenumberNotes (Obj Rct Arg / NewObj NoteReactor)
  (if (/= (vlax-erased-p Obj) T)
    (progn
      (setq NewObj (vla-copy Obj))
      (vla-delete Obj)
      (setq Obj nil)
      (RenumberNotes NewObj)
      (setq NoteReactor (vlr-object-reactor (list NewObj) "Notes Changed" '((:vlr-objectclosed . AutoRenumberNotes))))
      (vlr-pers NoteReactor)
    )
  )
)

(defun c:MakeRN (/ Pt)
  (setq Pt (getpoint "\nPlease select insertion point:"))
  (MakeTable Pt "RN")
)

(defun c:MakeGN (/ Pt)
  (setq Pt (getpoint "\nPlease select insertion point:"))
  (MakeTable Pt "GN")
)


(defun c:ReNumber (/ TableObject)
  (setq TableObject (vlax-ename->vla-object (car (entsel "\nSelect table: "))))
  (if (/= TableObject nil)
    (RenumberNotes TableObject)
  )
)

(defun RenumberNotes (TableObject / row rows TLayer bName cCellType)
  (setq rows (vla-get-rows TableObject)
        row 1
        TLayer (vla-get-layer TableObject)
  )
  (if (= TLayer "$GN")
    (setq bName "genn10")
    (setq bName "1m10")
)
  (while (< row rows)
    (setq cCellType (vla-getcelltype TableObject Row 0))
    (if (/= cCellType acblockcell)
      (InsertBlockTable TableObject Row 0 bName)
    )
    (ChangeAttr TableObject Row 0 bName (rtos Row 2 0))
    (setq row (+ row 1))
  )
)

;End of Supporting Functions
;Add Automatic reactors



Also, I tried to give credit where credit is due, but if you see your code there with no credit, please let me know.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Table Rector Help Needed
« Reply #2 on: September 10, 2020, 05:09:14 PM »
I have made quite a bit of progress, I do have a question though, how would I remove a reactor when an object is deleted? I have attached the current code due to the length.


cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Table Rector Help Needed
« Reply #4 on: September 10, 2020, 05:50:35 PM »
vlr-remove
http://help.autodesk.com/view/OARX/2020/ENU/?guid=GUID-2580A278-39B4-4BBA-99B4-20DA9565DCCD
Yes, I understand that much, but how do I do it while the object is being erase the :vlr-objecterased seems to happen after the object is erased, so that doesn't give me a chance to remove it before someone erases it. I do get I can do that on the part where I am deleting it, but I am referring to someone else erasing it.

Tharwat

  • Swamp Rat
  • Posts: 707
  • Hypersensitive
Re: Table Rector Help Needed
« Reply #5 on: September 10, 2020, 06:00:25 PM »
Sorry, I did not take a look at your uploaded file but based on your description so you can check if the object was erased that is appended into the list of the reactor then remove the reactor before it runs otherwise run normally.

vlax-erased-p
http://help.autodesk.com/view/OARX/2020/ENU/?guid=GUID-423F047A-F8B8-4DD0-ABEC-52E3C7B336B5

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Table Rector Help Needed
« Reply #6 on: September 11, 2020, 12:09:59 PM »
Sorry, I did not take a look at your uploaded file but based on your description so you can check if the object was erased that is appended into the list of the reactor then remove the reactor before it runs otherwise run normally.

vlax-erased-p
http://help.autodesk.com/view/OARX/2020/ENU/?guid=GUID-423F047A-F8B8-4DD0-ABEC-52E3C7B336B5
I did this, but I still get a bunch of errors if the object was erased, I am thinking I may have to abandon the reactor portion for a variety of reasons and use a command to renumber the notes.

Tharwat

  • Swamp Rat
  • Posts: 707
  • Hypersensitive
Re: Table Rector Help Needed
« Reply #7 on: September 11, 2020, 12:50:38 PM »
Working with reactors considered a very advanced way of programming so you need to be aware of every line of codes to be able to have a full control via reactors otherwise you would encounter lots of errors.

To check if an object was erased, if your reactor obtains the a bunch of objects as a list of vla-objects then once the reactor triggers and there must be a checkup of codes in the reactor function to check if any of the objects were erased then ignore the process otherwise process and continue...