Leaderboard
Popular Content
Showing content with the highest reputation since 04/17/2025 in Posts
-
Hi In this new version, it's possible to enter the text before the first text you want to insert from the keyboard or, as before, select it on the screen. Additionally, it will now increment numeric, alphabetic, or alphanumeric text strings without any restrictions (except for non-alphanumeric characters, of course). @leonucadomi As for your suggestion to extend the code's functionality to block attributes, I may do something about this in the future. However, I'm sure there must be simpler routines that would do the job just as well. There are several block experts on this forum who will probably have something to say about this. But if not, I'll try to do it myself. ;************************ G L A V C V S ************************* ;************************** F E C I T *************************** (defun c:txtIncrem (/ tam capa ind para a c cl txsel le l s dameTexto obtcad ent loc tipC nC ps add errores error0 ) (defun errores (mens) (setq *error* error0) (prin1) ) (defun dameTexto (cad / v r l daleVuelta) ;;; WRITE HERE THE CODE YOU NEED TO CUSTOMIZE THE TEXT YOU WANT TO ENTER OR CREATE (defun daleVuelta (a) (cond ((and (> a 64) (< a 91)) (if (> (setq a (+ a 1)) 90) (setq a -65) a)) ((and (> a 96) (< a 123)) (if (> (setq a (+ a 1)) 122) (setq a -97) a)) ((and (> a 47) (< a 58)) (if (> (setq a (+ a 1)) 57) (setq a -48) a)) ) ) (foreach v (reverse (vl-string->list cad)) (if (or (not r) (minusp r)) (setq l (cons (abs (setq r (daleVuelta v))) l)) (setq l (cons v l)) ) ) (vl-list->string (if (minusp r) (cons (if (= r -48) 49 (car l)) l) l)) ) (setq error0 *error* *error* errores ) (princ (setq s "Select PREVIOUS number text or type it... ")) (while (not para) (setq l (grread T 13 2)) (if (not (listp (cadr l))) (if (member (car l) '(2 3 11 25)) (cond ((or (= (cadr l) 13) (= (car l) 25)) (if (and c (not (wcmatch c "*.*"))) (setq ind c para T) (if (not c) (setq para T)) ) ) ((> (cadr l) 31) (setq c (if c (strcat c (chr (cadr l))) (chr (cadr l)))) (prompt (strcat "\r" s c)) ) ((= (cadr l) 8) (if (setq c (if c (substr c 1 (- (strlen c) 1)))) (prompt (strcat "\r" s c)) ) ) ) ) (if (= (car l) 3) (if (and (setq e (nentselp (cadr l))) (= (cdr (assoc 0 (setq le (entget (setq e (car e)))))) "TEXT")) (if (not (wcmatch (setq ind (cdr (assoc 1 le))) "*.*")) (setq capa (cdr (assoc 8 le)) a (cdr (assoc 40 le)) cl (cdr (assoc 62 le)) para T) (princ "\n*** The selected object is not valid. Please, try again... ***") ) ) ) ) ) (setq para nil) (if (not capa) (while (not para) (if (and (setq e (car (entsel "\nLAYER/HEIGHT: Select a sample text object (ENTER or RIGHT CLICK to type it)... "))) (setq l (entget e)) ) (if (= (cdr (assoc 0 l)) "TEXT") (setq capa (cdr (assoc 8 l)) a (cdr (assoc 40 l)) para T) (princ "\n*** The selected object is not a TEXT. Please, try again... ***") ) (if (not capa) (if (setq capa (getstring "\nType Layer name: ")) (if (tblsearch "layer" capa) (if (not (setq a (getreal "\nType Height: "))) (setq capa (princ "\n*** A valid height has not been specified. Please, type it again... ***") capa nil) (setq para T) ) (setq capa (princ "\n*** Specified layer does not exist. Please, type it again... ***") capa nil) ) ) ) ) ) ) (setq tx (dameTexto ind)) (while (and (setq l (grread T (if s 4 13) (if s 2 0))) (member (car l) '(5 3))) (prompt (strcat "\rSelect text to modify or insert new text \"" tx "\" (RIGHT CLICK for exit)")) (setq tam (* (getvar "pickbox") (/ (GETVAR "VIEWSIZE") (CADR (GETVAR "SCREENSIZE")))) para nil) (if (setq s (ssget "_C" (list (- (car (setq p (cadr l))) tam) (- (cadr p) tam)) (list (+ (car p) tam) (+ (cadr p) tam)) (list (cons 0 "TEXT")) ) ) (cond ((= (car l) 3) (entmod (subst (cons 1 tx) (assoc 1 (setq le (entget (ssname s 0)))) le)) (setq tx (dameTexto tx)) ) ;;; HERE MORE CASES ?... ) (cond ((= (car l) 3) (entmake (list '(0 . "TEXT") (cons 8 capa) (cons 62 (if cl cl 256)) (cons 40 a) (cons 1 tx) (cons 10 (list (car p) (cadr p) 0.0)) ) ) (setq tx (dameTexto tx)) ) ;;; HERE MORE CASES ?... ) ) ) (princ) )2 points
-
(defun c:GLVScopi (/ cj cj1 n e mx my para) (if (setq cj (ssget '((0 . "*TEXT")))) (while (not para) (setq cj1 (ssadd)) (while (setq e (ssname cj (setq n (if n (1+ n) 0)))) (setq tx (cdr (assoc 1 (setq l (entget e)))) mx (if mx (min (cadr (assoc 10 l)) mx) (cadr (assoc 10 l))) my (if my (min (caddr (assoc 10 l)) my) (caddr (assoc 10 l))) ) (entmake (subst (cons 1 (strcat (chr (+ (ascii (substr tx 1 1)) 1)) (substr tx 2))) (assoc 1 l) l)) (ssadd (entlast) cj1) ) (command "_move" cj1 "" (list mx my)) (setq cj cj1 cj1 nil n nil mx nil my nil) ) ) (princ) ) @Ish I edited it from my smartphone, so I couldn't test it. Check it yourself if it works.2 points
-
I'll update all of this to also allow you to enter the initial reference number from the keyboard, as @Nikon wanted. I'll post it soon.2 points
-
Hi Something like This? (defun c:GLVScopi (/ cj cj1 n e mx my) (if (setq cj (ssget '((0 . "*TEXT")))) (progn (setq cj1 (ssadd)) (while (setq e (ssname cj (setq n (if n (1+ n) 0)))) (setq tx (cdr (assoc 1 (setq l (entget e)))) mx (if mx (min (cadr (assoc 10 l)) mx) (cadr (assoc 10 l))) my (if my (min (caddr (assoc 10 l)) my) (caddr (assoc 10 l))) ) (entmake (subst (cons 1 (strcat (chr (+ (ascii (substr tx 1 1)) 1)) (substr tx 2))) (assoc 1 l) l)) (ssadd (entlast) cj1) ) (command "_move" cj1 "" (list mx my)) ) ) (princ) )2 points
-
I think the file that keeps your vlisp config is saved in : c:\Users\[*your-user-name*]\AppData\Roaming\Autodesk\AutoCAD 2017\R21.0\enu\VLIDE.DSK your autocad version is probably different , like ...\Autocad 2015\Rxx.0\enu\VLIDE.DSK maybe (setq dsk-filename (findfile "VLIDE.DSK")) will work. In my case it returns "C:\\temp\\lisp\\VLIDE.DSK" , I have write acces there but just put it there as backup / to study. This folder is at the top of my support path but I doubt it's the one loaded / saved on exit by the editor. Anyways , first warning : before you go crazy like a dragon and experiment , make sure you first make a backup , maybe more than one. In this file your have 2 lines : - one beginning with : (*edit-file-history* "C:/Temp/Lisp/_Cad-tutor/xxx.lsp" "C:/Temp/Lisp/_Cad-tutor/yyy.lsp" .......) - and multiple sections for every file open : (editor :CAPTION "xxx.lsp" :FILENAME "C:/Temp/Lisp/_Cad-tutor/xxx.lsp" :POINT 26786 :APEX 2162692 :SIZE 42468643 :STATE :MINIMIZED :RO nil :FGC nil :BGC nil :LXC T :LEX-ID :AL :CLV nil :TW 8 :LM 10 :CONTEXT :AUTOLISP ) (editor :CAPTION "yyy.lsp" :FILENAME "C:/Temp/Lisp/_Cad-tutor/yyy.lsp" :POINT 3528 :APEX 4259848 :SIZE 37946548 :STATE :MINIMIZED :RO nil :FGC nil :BGC nil :LXC T :LEX-ID :AL :CLV nil :TW 8 :LM 10 :CONTEXT :AUTOLISP ) etc etc... So ... the other first thing you could / should to is to check if you have / AutoCad has acces rights in the folder bladiebla...\enu\VLIDE,DSK I'm not sure I recommend trying to edit this file , but there it is , a possible way to get a grip on your digital Gremlin.1 point
-
Welcome to CADTutor! I have moved your thread to the CAD Management Forum. Please post in the most appropriate Forum. All of your links but the last one are dead ends. I use similar to this when I do Architecture drawings or usually when I use AutoCAD Architecture, I use the layers that it creates for which objects I am creating. Standard CAD Layers for Architectural Drawings Are you using AutoCAD Architecture or just vanilla AutoCAD?1 point
-
Just a comment in this situation these two do the same task. (vlax-put-property (vlax-put Another "Textgap" 'Textgap1 point
-
If 'oldGap' is '(cdr (assoc 0 entData)))' then it will always be different from 0.425 because oldGap= "DIMENSION" If you want to get the current value of "TextGap" from the object contained in 'dim' you should call '(vlax-get-property (vlax-ename->vla-object dim) "TextGap")' But not '(cdr (assoc 0 entData))'1 point
-
if this is on a company computer / network this may be caused by not having write access to the right folder , or , if your profile (registry) is reset (wiped) every time / morning you log in. Last one is easy enough to test. After you log in and open a lisp file , close AutoCad and start it again and see if your lisp files are still there or that AutoCad suddenly developed Alzheimer. You could also check your shortcut on your desktop. If it contains a /P parameter, it may start up with a fixed profile. First thing I always do is make my AutoCad local again. If you start AutoCad from your windows start button , this probably won't have a startup profile attached to it. So lots of options to explore before begging IT and bend over.1 point
-
Now this code works very well. Thank you very much!1 point
-
Like This (defun c:Ch-DimTxtOff ( / ss entData n) (setq ss (ssget '((0 . "DIMENSION")))) (while (and (setq dim (ssname ss (setq n (if n (1+ n) 0)))) (= (cdr (assoc 0 (entget dim))) "DIMENSION")) (vlax-put-property (vlax-ename->vla-object dim) "TextGap" 0.425) ) (princ) )1 point
-
You just need to replace the entire block under 'progn' with (vlax-put-property (vlax-ename->vla-object dim) "TextGap" 0.425)1 point
-
The problem is that there's no DXF code 147 to control the text gap. That's controlled directly from the coordinate associated with code 11. From VLA, you can control the gap using the "TextGap" property.1 point
-
Okay I guess it was also necessary to update from 'if' to 'while' I edited that a few minutes ago, too.1 point
-
(defun c:Ch-DimTxtOff ( / ss entData n) (setq ss (ssget '((0 . "DIMENSION")))) (while (and (setq dim (ssname ss (setq n (if n (1+ n) 0)))) (= (cdr (assoc 0 (entget dim))) "DIMENSION")) (progn (setq entData (entget dim)) (setq entData (subst (cons 147 0.425) (assoc 147 entData) entData)) (entmod entData) ) ) (princ) ) I just added the code to define 'dim' I haven't checked anything else.1 point
-
1 point
-
1 point
-
In the below post I demonstrate a concept program to facilitate mirroring a block without mirroring the text it contains: https://www.theswamp.org/index.php?topic=46271.msg513250#msg5132501 point
-
from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax import traceback import wx # wxPython import openpyxl as xl from openpyxl.drawing.image import Image as xlImage from openpyxl.utils.cell import get_column_letter @Ap.Command() def doit(): try: db = Db.curDb() ps, id, _ = Ed.Editor.entSel("\nSelect a table: ", Db.Table.desc()) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) wb = xl.Workbook() ws = wb.active table = Db.Table(id) opts = Db.TableIteratorOption.kTableIteratorSkipMerged for cell in table.cells(opts): if table.cellType(cell.row, cell.column) == Db.CellType.kBlockCell: blk = table.blockTableRecordId(cell.row, cell.column) img: wx.Image = Gs.Core.getBlockImage(blk, 64, 64, 1.0, [0, 0, 0]) img.SetMaskColour(0, 0, 0) img.SetMask(True) imgpath = "E:\\temp\\Icons\\{}.png".format(blk.handle()) img.SaveFile(imgpath, wx.BITMAP_TYPE_PNG) xlimg = xlImage(imgpath) xlimg.width = 64 xlimg.height = 64 cellref = "{}{}".format(get_column_letter(cell.column + 1), cell.row + 1) ws.add_image(xlimg, cellref) else: ws.cell( row=cell.row + 1, column=cell.column + 1, value=table.textString(cell.row, cell.column), ) wb.save("E:\\temp\\logo.xlsx") except Exception as err: traceback.print_exception(err)1 point
-
You can thing of those as name spaces of ObjectARX. Rx = AcRx, the most base classes for all AutoCAD objects Ge = AcGe, Geometry classes, Points, Vectors, Curves Gi = AcGi , has the class AcGiDrawable, mostly responsible for drawing entities on your screen Gs = AcGs, Graphics system, access to drawing devices and of course getBlockImage Ap = Application level stuff such as the document manager Db = AcDb, the database (.DWG) Ed = AcEd, Editor, selection sets, entsel, getPoint Ax = all of the ActiveX stuff Br = AcBr, access to 3d geometry Brx = stuff specific to BricsCAD. there’s also BrxBim and BrxCv They are all in PyRx, and are loaded in the ARX, so its ok to just include them all Also the .NET documentation is relevant, see Unmanaged to Managed Class Mappings https://help.autodesk.com/view/OARX/2024/ENU/?guid=GUID-390A47DB-77AF-433A-994C-2AFBBE9996AE1 point
-
Nice! Autofit to the rescue! Note that PyRx has a full GUI in wxPython (wx), so you can use that instead of ctypes if you want. Then there’s also alert from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax, Brx import traceback import wx @Ap.Command() def doit(): try: wx.MessageBox("Now you have done it") Ed.Core.alert("Now you have done it") except Exception as err: traceback.print_exception(err) Welcome to Python1 point
-
@Danielm103 1. about aligning the image to the center of the cell: I changed the X offset value (A process of trial and error and depends on the length of the header text): {"x_offset": 35, "y_offset": 0, "x_scale": 0.8, "y_scale": 0.8} 2. the first column was invisible because "val" for those cells was empty after the header's row and those tow lines return empty string after the first row which set the column width to 0: w, h =table.calcTextExtents(val,table.textStyle(cell.row, cell.column)) ws.set_column(cell.column,cell.column, w, cell_format) so I did this change with "autofit": else: #val = table.textString(cell.row, cell.column) #try to get a text width #w, h =table.calcTextExtents(val,table.textStyle(cell.row, cell.column)) ws.set_column(cell.column,cell.column, 1, cell_format)#minimum width,autofit wil set at the end ws.write(cell.row, cell.column, table.textString(cell.row, cell.column)) ws.autofit() wb.close() here is the final code I'm using: #https://www.cadtutor.net/forum/topic/97450-export-table-with-blocks-to-excel-with-python/ from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax, Brx import traceback import pathlib import xlsxwriter import ctypes import wx @Ap.Command() def Py_tablewithimagetoexcel_xlsxwriter(): try: db = Db.curDb() ps, id, _ = Ed.Editor.entSel("\nSelect a table: ", Db.Table.desc()) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) xlpath = pathlib.Path(db.getFilename()).parent xlname = pathlib.Path(db.getFilename()).stem fpt = "{}/{}.xlsx".format(xlpath, xlname) wb = xlsxwriter.Workbook(fpt) # create workbook ws = wb.add_worksheet() # create worksheet in workbook ws.set_default_row(40) # set default row height to 39.6 cell_format = wb.add_format() # add format cell_format.set_align("center") cell_format.set_align("vcenter") table = Db.Table(id) opts = Db.TableIteratorOption.kTableIteratorSkipMerged for cell in table.cells(opts): if table.cellType(cell.row, cell.column) == Db.CellType.kBlockCell: ws.set_column(cell.column,cell.column, 15.44, cell_format) blk = table.blockTableRecordId(cell.row, cell.column) bname = getEffectiveNameFromBtrId(blk) img: wx.Image = Gs.Core.getBlockImage(blk, 64, 64, 1.0, [0, 0, 0]) img.SetMaskColour(0, 0, 0) img.SetMask(True) imgpath = "{}/{}.png".format(xlpath, bname) img.SaveFile(imgpath, wx.BITMAP_TYPE_PNG) ws.insert_image( cell.row, cell.column, imgpath, {"x_offset": 35, "y_offset": 0, "x_scale": 0.8, "y_scale": 0.8}, ) else: #val = table.textString(cell.row, cell.column) #try to get a text width #w, h =table.calcTextExtents(val,table.textStyle(cell.row, cell.column)) ws.set_column(cell.column,cell.column, 1, cell_format)#keep format,set minimum width,autofit will set at the end ws.write(cell.row, cell.column, table.textString(cell.row, cell.column)) ws.autofit() wb.close() ctypes.windll.user32.MessageBoxW(0, fpt , "Files Saved", 1) except Exception as err: traceback.print_exception(err) def getEffectiveNameFromBtrId(btrid: Db.ObjectId): rec = Db.BlockTableRecord(btrid) if rec.isAnonymous(): ids = rec.getBlockReferenceIds() if len(ids) > 0 and Brx.DbProperties.isValid(ids[0], "EffectiveName~Native"): val = Brx.DbProperties.getValue(ids[0], "EffectiveName~Native") return val.getString() return rec.getName() Thanks for all your help!! aridzv.1 point
-
1 point
-
1 point
-
Lee Mac is a brilliant resource.... Google "Lee Mac Browse for Folder" to get another of his excellent LISPs (and also a handy link to donate if you like his stuff) It includes the line: fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir) which you could look at to modify this line above: Folder (vlax-invoke-method ShlObj 'BrowseForFolder 0 Message 0) Think it just needs "dir" adding and remember to use double "\\" in the file path, miht also need to add a check that the hard coded folder exists (still, IT have odd habits)1 point
-
These don't make any sense to me ? 4059 +45899 * 0.452 828MM 25.27 M 3.06 +45.90 * 0.45 0.83 M 25.27 M Explain more what it is you want do 1 line per step.1 point
-
Thanks!!! hope bricscad support will help. for me at least there is no pressure. Right now we know how to build a table in AutoCAD that contains values that Python knows how to work with. and I do belive bricscad will help. aridzv.1 point
-
getEffectiveNameFromBtrId helper works for AutoCAD, however BricsCAD doesn’t have a direct API to do this for parametric blocks, I’m investigating alternatives. vla-get-effectivename, "EffectiveName~Native" are designed to give us the name from a block reference blk = table.blockTableRecordId(cell.row, cell.column) gives us a Block table record id, not a reference I have a working solution with the help of Bricsys support that should give us what we need, it’s a bit of a kludge though1 point
-
Yes, that is possible, might need a few more details though. Second thing to ask, what are your LISP abilities like, do you want to create the solution if we give you hints and help along the way or will you need more guidance?1 point
-
Lisp functions take a resbuf argument. A resbuf in python is a list of tuples Each tuple (Typed value) has a data type and a value, you can also use integers as ARX does Rx.LispType: kAngle kDottedPair kDouble kInt16 kInt32 kListBegin kListEnd kNil kNone kObjectId kOrientation kPoint2d kVector2d kPoint3d kVector3d kT_atom kText kVoid kSelectionSet you can also use integers as ARX does #define RTNONE 5000 /* No result */ #define RTREAL 5001 /*Real number */ #define RTPOINT 5002 /* 2D point X and Y only */ #define RTSHORT 5003 /* Short integer */ #define RTANG 5004 /* Angle */ #define RTSTR 5005 /* String */ #define RTENAME 5006 /* Entity name */ #define RTPICKS 5007 /* Pick set */ #define RTORINT 5008 /* Orientation */ #define RT3DPOINT 5009 /* 3D point - X, Y, and Z */ #define RTLONG 5010 /* Long integer */ #define RTVOID 5014 /* Blank symbol */ #define RTLB 5016 /* list begin */ #define RTLE 5017 /* list end */ #define RTDOTE 5018 /* dotted pair */ #define RTNIL 5019 /* nil */ #define RTT 5021 /* T atom */ #define RTMODELESS 5027 /* interrupted by modeless dialog */1 point
-
maybe a useful example, check if two curves overlap the lisp: (defun c:doit (/ c1 c2) (setq c1 (car (entsel "pick curve 1\n"))) (setq c2 (car (entsel "pick curve 2\n"))) (check_overlap c1 c2) ) the python from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax import traceback @Ap.LispFunction() def check_overlap(resbuf): try: cv1 = None cv2 = None # check the resbuf if len(resbuf) != 2: return None if resbuf[0][0] != Rx.LispType.kObjectId: return None if resbuf[1][0] != Rx.LispType.kObjectId: return None # get the geometry dbc1 = Db.Curve(resbuf[0][1]) cv1 = dbc1.getAcGeCurve() dbc2 = Db.Curve(resbuf[1][1]) cv2 = dbc2.getAcGeCurve() # do the check cc = Ge.CurveCurveInt3d(cv1, cv2) return cc.overlapCount() > 0 except Exception as err: traceback.print_exception(err) and the results1 point
-
Create a lisp function by using the “@Ap.LispFunction()” example from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax import traceback @Ap.LispFunction() def lfunc(resbuf): try: #iterate the resbuf for type, value in resbuf: print(type, value) return resbuf except Exception as err: traceback.print_exception(err)1 point
-
Hi @Danielm103 what I was asking that I used lisp to write a defun command name that loads the correct dvb then runs the correct module. I want the equivalent to the 2 line answer, you already have python code saved but not loaded. The python arx is preloaded on start up. Say what you would put in a menu button, Ribbon etc.1 point
-
1 point
-
O.K., Got it.... here is the final code with the "getEffectiveNameFromBtrId" function. @Danielm103 -MANY MANY THANKS FOR YOUR HELP. #https://www.cadtutor.net/forum/topic/97450-export-table-with-blocks-to-excel-with-python/ from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax import traceback from openpyxl.drawing.image import Image as xlImage from openpyxl.utils.cell import get_column_letter from openpyxl.styles import Alignment import openpyxl as xl import pathlib import ctypes import wx @Ap.Command() def Py_tablewithimagetoexcel(): try: db = Db.curDb() ps, id, _ = Ed.Editor.entSel("\nSelect a table: ", Db.Table.desc()) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) # paths xlpath = pathlib.Path(db.getFilename()).parent xlname = pathlib.Path(db.getFilename()).stem #fpt = "{}/{}.png".format(xlpath, xlname) fpt = "{}\{}.xlsx".format(xlpath, xlname) wb = xl.Workbook() ws = wb.active table = Db.Table(id) opts = Db.TableIteratorOption.kTableIteratorSkipMerged for cell in table.cells(opts): # format all cells currentCell = ws.cell(cell.row + 1, cell.column + 1) currentCell.alignment = Alignment(horizontal="center", vertical="center") if table.cellType(cell.row, cell.column) == Db.CellType.kBlockCell: blk = table.blockTableRecordId(cell.row, cell.column) bname = getEffectiveNameFromBtrId(blk) print (bname) print (blk) img: wx.Image = Gs.Core.getBlockImage(blk, 64, 64, 1.0, [0, 0, 0]) img.SetMaskColour(0, 0, 0) img.SetMask(True) imgpath = "{}/{}.png".format(xlpath, bname)#blk.handle() img.SaveFile(imgpath, wx.BITMAP_TYPE_PNG) xlimg = xlImage(imgpath) xlimg.width = 64 xlimg.height = 64 cellref = "{}{}".format(get_column_letter(cell.column + 1), cell.row + 1) ws.add_image(xlimg, cellref) ws.row_dimensions[cell.row + 1].height = 64 else: ws.cell( row=cell.row + 1, column=cell.column + 1, value=table.textString(cell.row, cell.column), ) #nested function def as_text(value): if value is None: return "" return str(value) # make another pass to set the widths + a little extra for column_cells in ws.columns: length = max(len(as_text(cell.value)) for cell in column_cells) ws.column_dimensions[column_cells[0].column_letter].width = length * 1.25 wb.save("{}/{}.xlsx".format(xlpath, xlname)) ctypes.windll.user32.MessageBoxW(0, fpt , "Files Saved", 1) except Exception as err: traceback.print_exception(err) def getEffectiveNameFromBtrId(btrid: Db.ObjectId): rec = Db.BlockTableRecord(btrid) if rec.isAnonymous() and rec.hasXData("AcDbBlockRepBTag"): for dfx, val in rec.xData("AcDbBlockRepBTag"): if dfx == 1005: hnd = Db.Handle(val) dynid = rec.database().tryGetObjectId(False, hnd) dynrec = Db.BlockTableRecord(dynid) return dynrec.getName() return rec.getName() aridzv.1 point
-
new code that add the name, wait for the next release of you need effectiveName from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax import traceback from openpyxl.drawing.image import Image as xlImage from openpyxl.utils.cell import get_column_letter from openpyxl.styles import Alignment import openpyxl as xl import pathlib import wx @Ap.Command() def doit(): try: db = Db.curDb() ps, id, _ = Ed.Editor.entSel("\nSelect a table: ", Db.Table.desc()) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) # paths xlpath = pathlib.Path(db.getFilename()).parent xlname = pathlib.Path(db.getFilename()).stem wb = xl.Workbook() ws = wb.active table = Db.Table(id) opts = Db.TableIteratorOption.kTableIteratorSkipMerged for cell in table.cells(opts): # format all cells currentCell = ws.cell(cell.row + 1, cell.column + 1) currentCell.alignment = Alignment(horizontal="center", vertical="center") if table.cellType(cell.row, cell.column) == Db.CellType.kBlockCell: blkid = table.blockTableRecordId(cell.row, cell.column) blkrec = Db.BlockTableRecord(blkid) #open the block img: wx.Image = Gs.Core.getBlockImage(blkid, 64, 64, 1.0, [0, 0, 0]) img.SetMaskColour(0, 0, 0) img.SetMask(True) #change to effectiveName next release imgpath = "{}/{}.png".format(xlpath, blkrec.name()) img.SaveFile(imgpath, wx.BITMAP_TYPE_PNG) xlimg = xlImage(imgpath) xlimg.width = 64 xlimg.height = 64 cellref = "{}{}".format(get_column_letter(cell.column + 1), cell.row + 1) ws.add_image(xlimg, cellref) ws.row_dimensions[cell.row + 1].height = 64 else: ws.cell( row=cell.row + 1, column=cell.column + 1, value=table.textString(cell.row, cell.column), ) #nested function def as_text(value): if value is None: return "" return str(value) # make another pass to set the widths + a little extra for column_cells in ws.columns: length = max(len(as_text(cell.value)) for cell in column_cells) ws.column_dimensions[column_cells[0].column_letter].width = length * 1.25 wb.save("{}/{}.xlsx".format(xlpath, xlname)) except Exception as err: traceback.print_exception(err)1 point
-
I’m going to add this to the API https://github.com/CEXT-Dan/PyRx/issues/2781 point
-
If you hurry, you'll make people laugh... I am replacing the formula string with (setq volume (/ (* height (+ area1 area2 (sqrt (* area1 area2)))) 3)) The code now works like a Swiss watch. ;; Thanks GLAVCVS 17.04.2025 ;; https://www.cadtutor.net/forum/topic/97474-select-a-dimension-value-as-the-height-of-the-pyramid/ ;; Calculating the volume of a truncated pyramid or a truncated cone /_\ \_/ (defun c:PyramidConeVolumeTDIM (/ ent obj txt radius area1 area2 volume insPoint to) (vl-load-com) (defun getHeightFromText () (setq ent (entsel "\nSelect the text object containing the height: ")) (setq obj (vlax-ename->vla-object (car ent))) (if (= (setq to (CDR (ASSOC 0 (entget (car ent))))) "TEXT") (setq txt (vla-get-TextString obj)) (if (= to "DIMENSION") (if (= (setq txt (vla-get-textOverride obj)) "") (setq txt (rtos (vla-get-measurement obj) 2 2)) txt ) (progn (alert "No valid object") nil) ) ) (setq height (distof txt 2)) ) (defun getCircleArea (circle) (setq radius (vla-get-Radius circle)) (* pi radius radius) ) (defun selectBase () (setq ent (entsel "\nSelect a polyline or circle as the base: ")) (setq obj (vlax-ename->vla-object (car ent))) (if (eq (vla-get-ObjectName obj) "AcDbCircle") (getCircleArea obj) (vlax-curve-getArea obj) ) ) (setq area1 (selectBase)) (princ (strcat "\nArea A1: " (rtos area1 2 3))) (setq area2 (selectBase)) (princ (strcat "\nArea A2: " (rtos area2 2 3))) (getHeightFromText) (princ (strcat "\nHeight H: " (rtos height 2 3))) ;; Calculating the volume in mm3 (setq volume (/ (* height (+ area1 area2 (sqrt (* area1 area2)))) 3)) (setq volume_m3 (/ volume 1e9)) (princ (strcat "\nThe volume of a truncated pyramid or cone (m3): " (rtos volume_m3 2 3))) (setq insPoint (getpoint "\nSpecify the insertion point of the result: ")) (command "_.TEXT" insPoint "2.5" "0" (strcat "Volume (m3): " (rtos volume_m3 2 3))) (princ) )1 point
-
Here: your code modified to make it work. But there's one problem: you haven't specified the volume calculations correctly. I think I should leave this to you. (defun c:PyramidConeVolumeT (/ ent obj txt radius area1 area2 volume insPoint to) (vl-load-com) (defun getHeightFromText () (setq ent (entsel "\nSelect the text object containing the height: ")) (setq obj (vlax-ename->vla-object (car ent))) (if (= (setq to (CDR (ASSOC 0 (entget (car ent))))) "TEXT") (setq txt (vla-get-TextString obj)) (if (= to "DIMENSION") (if (= (setq txt (vla-get-textOverride obj)) "") (setq txt (rtos (vla-get-measurement obj) 2 2)) txt ) (progn (alert "No valid object") nil) ) ) (setq height (distof txt 2)) ) (defun getCircleArea (circle) (setq radius (vla-get-Radius circle)) (* pi radius radius) ) (defun selectBase () (setq ent (entsel "\nSelect a polyline or circle as the base: ")) (setq obj (vlax-ename->vla-object (car ent))) (if (eq (vla-get-ObjectName obj) "AcDbCircle") (getCircleArea obj) (vlax-curve-getArea obj) ) ) (setq area1 (selectBase)) (princ (strcat "\nArea A1: " (rtos area1 2 3))) (setq area2 (selectBase)) (princ (strcat "\nArea A2: " (rtos area2 2 3))) (getHeightFromText) (princ (strcat "\nHeight H: " (rtos height 2 3))) ;; Calculating the volume in mm3 (setq volume (* (/ height 3) (+ area1 (sqrt (* area1 area2)) area2))) ;; Converting volume to m3 (setq volume_m3 (/ volume 1e9)) (princ (strcat "\nThe volume of a truncated pyramid or cone (m3): " (rtos volume_m3 2 3))) (setq insPoint (getpoint "\nSpecify the insertion point of the result: ")) (command "_.TEXT" insPoint "2.5" "0" (strcat "Volume (m3): " (rtos volume_m3 2 3))) (princ) )1 point
-
You've moved a lot of things around in this code compared to the original you posted. So it's hard to get it to work.1 point
-
1 point
-
You may need to copy the code again: I changed something.1 point
-
Hi Replacing your function with this one... is that enough? (defun getHeightFromText () (setq ent (entsel "\nSelect the text object containing the height: ")) (setq obj (vlax-ename->vla-object (car ent))) (if (= (setq to (CDR (ASSOC 0 (entget (car ent))))) "TEXT") (setq txt (vla-get-TextString obj)) (if (= to "DIMENSION") (if (= (setq txt (vla-get-textOverride obj)) "") (setq txt (rtos (vla-get-measurement obj) 2 2)) txt ) (progn (alert "No valid object") nil) ) ) (setq height (distof txt 2)) )1 point
-
Something I noticed, one of your objects is black, so you might want to set the bk color and mask to the color of BricsCAD’s background color so it’s not xor'ed out... it seems okay though img: wx.Image = Gs.Core.getBlockImage(id, 256, 256, 1.0, [33, 40, 48]) img.SetMaskColour(33, 40, 48)1 point
-
Just a comment, using ssget may end up with A1 A3 A2 as order as ssget gets in creation order, may still be better to do pick pick. Does the number go above 26 ? If so this is helpful based on Excel columns. ; Number2Alpha - Converts Number into Alpha string ; Function By: Gilles Chanteau from Marseille, France ; Arguments: 1 ; Num# = Number to convert ; Syntax example: (Number2Alpha 731) = "ABC" (NUMBER2ALPHA 1) "A" (NUMBER2ALPHA 27) "AA"1 point
-
My $0.05, I would add a width to the edit boxes as they are all over the place. mc_dialog : dialog { label = "NHAP THONG SO MAT CAT DOC"; : column { : edit_box { label = "Ty le ngang 1/?"; key = "hf"; } : edit_box { label = "Ty le dung 1/?"; key = "vf"; } : edit_box { label = "Cao do so sanh (m)"; key = "level"; } : edit_box { label = "Ly trinh diem dau (m)"; key = "st"; } : edit_box { label = "Chieu cao Text Title"; key = "th"; } : edit_box { label = "Chieu cao Text cao do"; key = "th1"; } : edit_box { label = "File du lieu TXT"; key = "file"; } : button { label = "Chon File..."; key = "chonfile"; } } : row { : button { label = "Ve"; is_default = true; key = "accept"; } : button { label = "Thoat"; key = "cancel"; } } } Have a look at writing the dcl as part of the lisp code, you use write line and the (setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w")) to write a temporary file just delete the file at end of dcl use. Have a look at Multi getvals.lsp will write a dcl for you based on a list of edit boxes. Around 3 lines of code to make a dcl. You can set file name so can see the dcl code. Then use the rlx code to make lisp code. Convert dcl 2 lisp rlx.lspMulti GETVALS.lsp1 point
-
Sorry, I noticed your running BricsCAD 2021? If so, I’m sorry to say only v24-v25 is supported. Or maybe you forgot to update your profile? 1, head over to https://github.com/CEXT-Dan/PyRx?tab=readme-ov-file#installation and have look at the project 2, Download and install 3.12.10 x64 from https://www.python.org/downloads/windows/ (all users is NOT checked, and PATH is checked) 3, Open up PowerShell and type “pip install cad-pyrx” without the quotes. 4, in BricsCAD, type “appload”, navigate to: “AppData\Programs\Python\Python312\Lib\site-packages\pyrx\RxLoaderV25.0.brx” 5, Make sure it’s loaded, type “pyload” at the bricscad prompt 6, if the load dialog box shows, then were successful so far 7, close bricscad 8, back in powershell type “pip install openpyxl” , this will install the excel library. 9, copy paste the sample code above into a file into a text file, “myfirstmodule.py” 10, using a text editor, edit the paths in the sample, maybe rename the “doit” command 11, open BricsCAD, type in “pyload”, load your module, run your new command If you get this far, you might want to grab a python editor like VsCode and install the python plugins1 point
-
Lee has some cool ones for this task: https://www.lee-mac.com/objectalign.html https://www.lee-mac.com/autoblockbreak.html1 point
-
just my old code. Converts a field still in the tables (defun C:CFT ()(ConvField->Text t)) (defun C:CFTAll ()(ConvField->Text nil)) (defun C:CFTSEL( / *error* Doc ss CountField) (vl-load-com) (defun *error* (msg)(princ msg)(vla-endundomark doc)(princ)) (setq Doc (vla-get-activedocument (vlax-get-acad-object))) (vla-startundomark Doc) (if (setq ss (ssget "_:L")) (progn (setq CountField 0) (foreach obj (mapcar (function vlax-ename->vla-object) (vl-remove-if (function listp) (mapcar (function cadr) (ssnamex ss)))) (setq CountField (ClearField Obj CountField)) ) (princ "\nConverting Field in ")(princ CountField) (princ " text's") ) ) (vla-endundomark Doc) (command "_.Regenall") ) (defun ClearField ( Obj CountField / txtstr att ) (cond ((and (vlax-write-enabled-p Obj) (= (vla-get-ObjectName obj) "AcDbBlockReference") (= (vla-get-HasAttributes obj) :vlax-true) ) ;_ end of and (foreach att (append (vlax-invoke obj 'Getattributes) (vlax-invoke obj 'Getconstantattributes) ) (setq txtstr (vla-get-Textstring att)) (vla-put-Textstring att "") (vla-put-Textstring att txtstr) (setq CountField (1+ CountField)) ) ;_ end of foreach ) ((and (vlax-write-enabled-p Obj) (vlax-property-available-p Obj 'TextString) ) ;_ end of and (setq txtstr (vla-get-Textstring Obj)) (vla-put-Textstring Obj "") (vla-put-Textstring Obj txtstr) (setq CountField (1+ CountField)) ) ((and (vlax-write-enabled-p Obj) ;_Table (eq (vla-get-ObjectName Obj) "AcDbTable") ) (and (vlax-property-available-p Obj 'RegenerateTableSuppressed) (vla-put-RegenerateTableSuppressed Obj :vlax-true) ) (VL-CATCH-ALL-APPLY '(lambda (col row / i j) (setq i '-1) (repeat col (setq i (1+ i) j '-1) (repeat row (setq j (1+ j)) (vla-SetText Obj j i (vla-GetText Obj j i)) (setq CountField (1+ CountField)) ) ) ) (list (vla-get-Columns Obj) (vla-get-Rows Obj) ) ) (and (vlax-property-available-p Obj 'RegenerateTableSuppressed) (vla-put-RegenerateTableSuppressed Obj :vlax-false) ) ) (t nil) ) CountField ) (defun ConvField->Text ( Ask / Doc *error* ClearFieldInAllObjects ) ;;; t - Ask user nil - convert ;;; Как все поля чертежа сразу преобразовать в текст? ;;; Convert Field to Text ;;; Posted Vladimir Azarko (VVA) ;;; http://forum.dwg.ru/showthread.php?t=20190&page=2 ;;; http://forum.dwg.ru/showthread.php?t=20190 (vl-load-com) (defun *error* (msg)(princ msg) (mip:layer-status-restore) (vla-endundomark doc)(princ) ) (defun loc:msg-yes-no ( title message / WScript ret) (setq WScript (vlax-get-or-create-object "WScript.Shell")) (setq ret (vlax-invoke-method WScript "Popup" message "0" title (+ 4 48))) (vlax-release-object WScript) (= ret 6) ) (defun ClearFieldInAllObjects (Doc / txtstr tmp txt count CountField) (setq CountField 0) (vlax-for Blk (vla-get-Blocks Doc) (if (equal (vla-get-IsXref Blk) :vlax-false) ;;;kpbIc http://forum.dwg.ru/showpost.php?p=396910&postcount=30 (progn (setq count 0 txt (strcat "Changed " (vla-get-name Blk)) ) (grtext -1 txt) ;;; (terpri)(princ "=================== ")(princ txt) (if (not (wcmatch (vla-get-name Blk) "`*T*")) ;_exclude table (vlax-for Obj Blk (setq count (1+ count)) (if (zerop(rem count 10))(grtext -1 (strcat txt " : " (itoa count)))) (setq CountField (ClearField Obj CountField)) ) ;_ end of vlax-for ) ) ) ;_ end of if ) ;_ end of vlax-for (vl-cmdf "_redrawall") CountField ) (setq Doc (vla-get-activedocument (vlax-get-acad-object))) (mip:layer-status-save)(vla-startundomark Doc) (if (or (not Ask ) (if (= (getvar "DWGCODEPAGE") "ANSI_1251") (loc:msg-yes-no "Внимание" "Все поля будут преобразованы в текст !!!\nПродолжить?" ) (loc:msg-yes-no "Attension" "All fields will be transformed to the text!!!\nto Continue?" ) ) ) (progn (princ "\nConverting Field in ") (princ (ClearFieldInAllObjects Doc)) (princ " text's") ) (princ) ) (mip:layer-status-restore)(vla-endundomark Doc) (command "_.Regenall") (princ) ) (defun mip:layer-status-restore () (foreach item *MIP_LAYER_LST* (if (not (vlax-erased-p (car item))) (vl-catch-all-apply '(lambda () (vla-put-lock (car item) (cdr (assoc "lock" (cdr item)))) (vla-put-freeze (car item) (cdr (assoc "freeze" (cdr item))) ) ;_ end of vla-put-freeze ) ;_ end of lambda ) ;_ end of vl-catch-all-apply ) ;_ end of if ) ;_ end of foreach (setq *MIP_LAYER_LST* nil) ) ;_ end of defun (defun mip:layer-status-save () (setq *MIP_LAYER_LST* nil) (vlax-for item (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)) ) ;_ end of vla-get-layers (setq *MIP_LAYER_LST* (cons (list item (cons "freeze" (vla-get-freeze item)) (cons "lock" (vla-get-lock item)) ) ;_ end of cons *MIP_LAYER_LST* ) ;_ end of cons ) ;_ end of setq (vla-put-lock item :vlax-false) (if (= (vla-get-freeze item) :vlax-true) (vl-catch-all-apply '(lambda () (vla-put-freeze item :vlax-false)) ) ;_ end of vl-catch-all-apply ) ;_ end of if ) ;_ end of vlax-for ) ;_ end of defun The Russian-language forum at Edward spied another idea to transform the field in the text (remove dictionary "ACAD_FIELD"), but has not been able to test it fully in all primitives (vl-load-com) (defun C:field-to-text () (if (and (setq txt-nabor (ssget '((0 . "mtext,insert")))) (setq txt-nabor (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex txt-nabor) ) ) ) ) ) (mapcar '(lambda (x / dict) (cond ( (and (= (vla-get-objectname x) "AcDbMText") (= (vla-get-HasExtensionDictionary x) :vlax-true) ) (vlax-for item (setq dict (vla-GetExtensionDictionary x)) (if (= (vla-get-name item) "ACAD_FIELD") (progn (vla-remove dict "ACAD_FIELD") (vla-put-textstring x (vl-string-trim "%<>" (vla-get-textstring x)) ) ) ) ) ) ( (= (vla-get-objectname x) "AcDbBlockReference") (vlax-for item2 (vla-item (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object) ) ) (vla-get-name x) ) (if (and (= (vla-get-objectname item2) "AcDbMText") (= (vla-get-HasExtensionDictionary item2) :vlax-true) ) (vlax-for item3 (setq dict (vla-GetExtensionDictionary item2)) (if (= (vla-get-name item3) "ACAD_FIELD") (progn (vla-remove dict "ACAD_FIELD") (vla-put-textstring item2 (vl-string-trim "%<>" (vla-get-textstring item2) ) ) ) ) ) ) ) ) ) ) txt-nabor ) ) (princ) )1 point
-
1 point