Author Topic: Good table vs Bad table  (Read 3536 times)

0 Members and 1 Guest are viewing this topic.

jtoverka

  • Newt
  • Posts: 127
Good table vs Bad table
« on: March 06, 2020, 08:24:54 AM »
I am having issues with some of my programs. I have narrowed it down to a bad table. It was inserted via lisp, the original file is fine. I want to know what made it bad.
I have attached a drawing with the bad table, and a drawing with the good table. They look identical, but somehow the good table got corrupted as it was inserted into the drawing. If you try to browse all entities in VLIDE or if you run the following on the table:

Code: [Select]
((lambda ( / ent et)
  (setq ent (car (entsel)))
  (if ent
    (princ (entget ent))
    (princ "\nYou did not select the table!\n")
  )
  (princ)
))

You will get the following error.

Code: [Select]
; error: Exception occurred: 0xC0000005 (Access Violation)
; warning: unwind skipped on exception
; error: Exception occurred: 0xC0000005 (Access Violation)

I am using AutoCAD Electrical 2018.1.2 on Windows 10.

kpblc

  • Bull Frog
  • Posts: 396
Re: Good table vs Bad table
« Reply #1 on: March 06, 2020, 09:33:11 AM »
AutoCAD 2019 x64 Eng (with all updates) : no error.
Sorry for my English.

framednlv

  • Newt
  • Posts: 65
Re: Good table vs Bad table
« Reply #2 on: March 06, 2020, 09:41:50 AM »
Autocad 2018 MEP --> same error
After an audit it works with no error.

jtoverka

  • Newt
  • Posts: 127
Re: Good table vs Bad table
« Reply #3 on: March 06, 2020, 09:44:21 AM »
AutoCAD 2019 x64 Eng (with all updates) : no error.

So I just tried this on another machine, same error.
Could you post the output for the good table and bad table? A text file upload is fine. Much appreciated. Use the following as I would like the xData as well.

Code: [Select]
((lambda ( / ent et)
  (setq ent (car (entsel)))
  (if ent
    (princ (entget ent '("*")))
    (princ "\nYou did not select the table!\n")
  )
  (princ)
))

jtoverka

  • Newt
  • Posts: 127
Re: Good table vs Bad table
« Reply #4 on: March 06, 2020, 10:11:03 AM »
Autocad 2018 MEP --> same error
After an audit it works with no error.

So I did the Audit, it works! Although it didn't tell me what was wrong. I used Lee Mac's elist function with a logfileon. I compared the two logfiles using notepad++ compare plugin. I don't see anything that really sticks out as to what happened.

My question is now this, what is the proper way to insert a table into a drawing via autolisp? What are the conditions that needs to be met? Do I need to create all the textstyles, tablestyles, etc. prior?

BIGAL

  • Swamp Rat
  • Posts: 1444
  • 40 + years of using Autocad
Re: Good table vs Bad table
« Reply #5 on: March 08, 2020, 10:52:04 PM »
Create a table with an existing table style is the easiest way. A table create can be very simple or complex depending on how far you have gone with your default style. I have attached a table make I use but I wont say its good or bad. There are just so many settings to do with a table its hard in one post to say what you need its more about knowing what to customise.

 This is about as simple as possible.
Code: [Select]
; example of creating a table
; By Alan H July 2017
; sum of column row 10 column 1 ie 2nd column
; Example make a table by Alan H

(defun ex_table (/ colwidth numcolumns numrows objtable rowheight sp doc)
(vl-load-com)
(setq sp (vlax-3d-point '(0 0 0))) ; or use getpoint
(setq doc  (vla-get-activedocument (vlax-get-acad-object) ))
;(setq vgms (vla-get-paperspace doc))
(setq vgms (vla-get-modelspace doc)) ; table in modelspace
(setq numrows 5)
(setq numcolumns 5)
(setq rowheight 0.5)
(setq colwidth 30)
(setq objtable (vla-addtable vgms sp numrows numcolumns rowheight colwidth))
(vla-settext objtable 0 0 "TABLE title")
(vla-settext objtable 1 0 "A")
(vla-settext objtable 1 1 "B")
(vla-settext objtable 1 2 "C")
(vla-settext objtable 1 3 "D")
(vla-settext objtable 1 4 "E")
(vla-settext objtable 2 0 "1")
(vla-settext objtable 3 0 "2")
(vla-settext objtable 4 0 "3")
(vla-setcolumnwidth objtable 0 15) ; 0 is first column
(vla-setcolumnwidth objtable 1 30)
(vla-setcolumnwidth objtable 2 60)
(command "_zoom" "e")
(princ)
)
(ex_table)
This is some examples of changing a table.
Code: [Select]
; example of creating a table style
(vl-load-com)
(defun c:CreateTableStyle()
    ;; Get the AutoCAD application and current document
    (setq acad (vlax-get-acad-object))
    (setq doc (vla-get-ActiveDocument acad))

    ;; Get the Dictionaries collection and the TableStyle dictionary
    (setq dicts (vla-get-Dictionaries doc))
    (setq dictObj (vla-Item dicts "acad_tablestyle"))
   
    ;; Create a custom table style
    (setq key "MyTableStyle"
          class "AcDbTableStyle")
    (setq custObj (vla-AddObject dictObj key class))

    ;; Set the name and description for the style
    (vla-put-Name custObj "MyTableStyle")
    (vla-put-Description custObj "This is my custom table style")

    ;; Sets the bit flag value for the style
    (vla-put-BitFlags custObj 1)

    ;; Sets the direction of the table, top to bottom or bottom to top
    (vla-put-FlowDirection custObj acTableTopToBottom)

    ;; Sets the supression of the table header
    (vla-put-HeaderSuppressed custObj :vlax-false)

    ;; Sets the horizontal margin for the table cells
    (vla-put-HorzCellMargin custObj 0.22)

    ;; Sets the supression of the table title
    (vla-put-TitleSuppressed custObj :vlax-false)

    ;; Sets the vertical margin for the table cells
    (vla-put-VertCellMargin custObj 0.22)

    ;; Set the alignment for the Data, Header, and Title rows
    (vla-SetAlignment custObj (+ acDataRow acTitleRow) acMiddleLeft)
    (vla-SetAlignment custObj acHeaderRow acMiddleCenter)

    ;; Set the background color for the Header and Title rows
    (setq colObj (vlax-create-object "AutoCAD.AcCmColor.19"))
    (vla-SetRGB colObj 98 136 213)
    (vla-SetBackgroundColor custObj (+ acHeaderRow acTitleRow) colObj)

    ;; Clear the background color for the Data rows
    (vla-SetBackgroundColorNone custObj acDataRow :vlax-true)

    ;; Set the bottom grid color for the Title row
    (vla-SetRGB colObj 0 0 255)
    (vla-SetGridColor custObj acHorzBottom acTitleRow colObj)

    ;; Set the bottom grid lineweight for the Title row
    (vla-SetGridLineWeight tableStyle acHorzBottom acTitleRow acLnWt025)

    ;; Set the inside grid lines visible for the data and header rows
    (vla-SetGridVisibility custObj acHorzInside  (+ acDataRow acHeaderRow) :vlax-true)

    ;; Set the text height for the Title, Header and Data rows
    (vla-SetTextHeight custObj acTitleRow 1.5)
    (vla-SetTextHeight custObj (+ acDataRow acHeaderRow) 1.0)

    ;; Set the text height and style for the Title row
    (vla-SetTextStyle custObj (+ acDataRow acHeaderRow acTitleRow) "Standard")

    ;; Release the color object
    (vlax-release-object colObj)
  (princ)
)

[/cond]


A man who never made a mistake never made anything

jtoverka

  • Newt
  • Posts: 127
Re: Good table vs Bad table
« Reply #6 on: March 09, 2020, 07:03:24 AM »
Create a table with an existing table style is the easiest way. A table create can be very simple or complex depending on how far you have gone with your default style. I have attached a table make I use but I wont say its good or bad. There are just so many settings to do with a table its hard in one post to say what you need its more about knowing what to customise.

Thank you for this code! I appreciate it.

This weekend I have identified the source of the problem. I am using a routine called purgeTableStyles. Before I save a drawing I purge everything. When I insert the table into the drawing everything works fine until I run the purgeTableStyles routine. The table becomes corrupt. If I go to the home tab, Annotation panel, then open the slide out and click on the edit table styles icon I get a fatal error. The routine I use is shown below. How can I modify it so that it does not corrupt my drawing?

Code: [Select]
(defun purgeTableStyles ( / acade doc dictionaries tableStyles tableStyle)
  (setq acade (vlax-get-acad-object))
  (setq doc (vla-get-activeDocument acade))
    (setq dictionaries (vla-get-Dictionaries doc))
    (setq tableStyles (vla-Item dictionaries "acad_tablestyle"))

  (vlax-for tableStyle tableStyles
    (vl-catch-all-apply 'vla-delete (list tableStyle))
  )
  (princ)
)
(purgeTableStyles)

kpblc

  • Bull Frog
  • Posts: 396
Re: Good table vs Bad table
« Reply #7 on: March 09, 2020, 07:20:30 AM »
Why not to use (vla-purgeall activedoc) ?
Sorry for my English.

Dlanor

  • Bull Frog
  • Posts: 263
Re: Good table vs Bad table
« Reply #8 on: March 09, 2020, 07:33:28 AM »
If you open a new drawing and run the purge command, there are no tables to purge, but always one table style in the drawing "standard", even though the drawing contains no entities. You must assume that trying to delete this tablestyle is causing the error, since you are not checking the name of the table.

jtoverka

  • Newt
  • Posts: 127
Re: Good table vs Bad table
« Reply #9 on: March 09, 2020, 07:43:47 AM »
Why not to use (vla-purgeall activedoc) ?

I don't want to purge all, I want to selectively purge. Furthermore, I don't think that function purges registered applications.

If you open a new drawing and run the purge command, there are no tables to purge, but always one table style in the drawing "standard", even though the drawing contains no entities. You must assume that trying to delete this tablestyle is causing the error, since you are not checking the name of the table.

Do I have to scan the entire drawing to find all of the tablestyles in use prior to purging? I assumed (incorrectly) that an error would be thrown if I tried to purge a tablestyle that was in use. Like trying to purge a layer in use.

Even if I put in a condition to check for the "Standard" tablestyle if I purge a table style that is in use, then the drawing becomes corrupt.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Good table vs Bad table
« Reply #10 on: March 09, 2020, 06:34:38 PM »
;; (purgeTableStyles)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com • http://cadanalyst.slack.com • http://linkedin.com/in/cadanalyst

kpblc

  • Bull Frog
  • Posts: 396
Re: Good table vs Bad table
« Reply #11 on: March 10, 2020, 01:13:09 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun purge-unused-tablestyles (/ adoc lst style)
  2.   (vla-auditinfo adoc :vlax-true)
  3.   (vlax-for def (vla-get-blocks adoc)
  4.     (vlax-for ent def
  5.       (if (and (= (vla-get-objectname ent) "AcDbTable")
  6.                (vlax-property-available-p ent "stylename")
  7.                (not (member (setq style (strcase (vla-get-stylename ent))) lst))
  8.                ) ;_ end of and
  9.         (setq lst (cons style lst))
  10.         ) ;_ end of if
  11.       ) ;_ end of vlax-for
  12.     ) ;_ end of vlax-for
  13.   (setq lst (cons "STANDARD" lst))
  14.   (vlax-for item (vla-item (vla-get-dictionaries adoc) "acad_tablestyle")
  15.     (if (not (member (strcase (vla-get-name item)) lst))
  16.       (vl-catch-all-apply (function (lambda () (vla-delete item))))
  17.       ) ;_ end of if
  18.     ) ;_ end of vlax-for
  19.   ) ;_ end of defun
Sorry for my English.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Good table vs Bad table
« Reply #12 on: March 10, 2020, 08:50:14 AM »
The problem appears to be that AutoCAD won't prevent the deletion of dictionary entries in the "acad_tablestyle" dictionary even if they are in use or active. Such hammer down deletion leaves tables referencing a deleted tablestyle knackered as AutoCAD does not update the table style reference (dxf code 342) in impacted ACAD_TABLE objects. In limited testing AutoCAD (2019) appears to fix it when saving.

I don't have time to better illustrate but if you view the attached image it details the labyrinth of references between associated table objects. (As noted above) When deleting a tablestyle unconditionally (highlighted in yellow) the reference in the table object (highlighted in red) do not appear to get updated, *boom*.

Here's some general use functions I pulled from my library and one penned for the task (max-purge-table-styles). Seems like a lot of code but it's generic (i.e. good library fodder) and relatively robust; speedy.

Code: [Select]
(defun max-get-block-defs-matching ( doc pattern / name result )
    (   (lambda ( pattern )
            (vlax-for b (vla-get-blocks doc)
                (and
                    (eq :vlax-false (vla-get-islayout b))
                    (eq :vlax-false (vla-get-isxref b))
                    (eq 'str (type (setq name (vl-catch-all-apply 'vla-get-name (list b)))))
                    (wcmatch (strcase name) pattern)
                    (setq result (cons b result))
                )
            )
            (reverse result)
        )
        (strcase pattern)
    )   
)

Code: [Select]
(defun max-get-block-refs-matching ( doc pattern / result )
    (vl-catch-all-apply 'eval
       '(   (setq result
                (apply 'append
                    (mapcar 'max-get-block-refs
                        (max-get-block-defs-matching doc pattern)
                    )
                )
            )
        )   
    )
    result
)

Code: [Select]
(defun max-get-block-refs ( block / result )
    (vl-catch-all-apply 'eval
       '(   (setq result
                (vl-remove nil
                    (mapcar
                        (function
                            (lambda ( p / v )
                                (if (eq 331 (car p))
                                    (if (null (vlax-erased-p (setq v (cdr p))))
                                        (if (entget v) (vlax-ename->vla-object v))
                                    )
                                )                                 
                            )
                        )
                        (entget (vlax-vla-object->ename block))
                    )
                )
            )
        )           
    )
    result
)

Code: [Select]
(defun max-item ( collection key / result )
    (vl-catch-all-apply 'eval
       '((setq result (vla-item collection key)))
    )
    result
)

Code: [Select]
(defun max-items ( collection / result )
    (vl-catch-all-apply 'eval
       '((vlax-for x collection (setq result (cons x result))))
    )
    (reverse result)
)

Code: [Select]
(defun max-purge-table-styles ( doc )
    (   (lambda ( in-use / name deleted )
            (foreach style (max-items (max-item (vla-get-dictionaries doc) "acad_tablestyle"))
                (if (not (member (strcase (setq name (vla-get-name style))) in-use))
                    (if (vlax-erased-p (progn (vl-catch-all-apply 'vla-delete (list style)) style))
                        (progn
                            (if *debug* (princ (strcat "\nDeleted table style: \"" name "\".")))
                            (setq deleted (cons name deleted))
                        )
                        (if *debug* (princ (strcat "\nFailed to delete table style: \"" name "\".")))
                    )
                    (if *debug* (princ (strcat "\nTable style: \"" name "\" in use, did not delete.")))
                )
            )
            deleted ;; return list of the tablestyles deleted to the caller
        )
        (mapcar 'strcase
            (append
                (list (getvar 'ctablestyle) "Standard")           
                (mapcar 'vla-get-stylename (max-get-block-refs-matching doc "`*T#*"))
            )       
        )       
    )   
)

Run on your goodtable.dwg:

(setq *debug* t)
(vl-load-com)
(max-purge-table-styles (vla-get-activedocument (vlax-get-acad-object)))

Table style: "BOM" in use, did not delete.
Table style: "Index FedExTB" in use, did not delete.
Table style: "Standard" in use, did not delete.


Cheers.
« Last Edit: March 10, 2020, 10:39:24 AM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com • http://cadanalyst.slack.com • http://linkedin.com/in/cadanalyst

jtoverka

  • Newt
  • Posts: 127
Re: Good table vs Bad table
« Reply #13 on: March 12, 2020, 06:45:15 AM »
That is an excellent, comprehensive explanation. I really appreciate the work put into this post MP.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Good table vs Bad table
« Reply #14 on: March 12, 2020, 08:21:00 AM »
You’re most welcome - thanks for the thanks - cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com • http://cadanalyst.slack.com • http://linkedin.com/in/cadanalyst