MastroLube Posted April 24, 2019 Posted April 24, 2019 Hello guys, I'm about to update my code in order to make it more efficient. A long time ago I wrote this function to save my custom values in an XRECORD inside a dictionary. Is it possible to have the number of parameters (300-301-302- and so on) depending on the length of the list? (DEFUN CP:salva_dati (name nomedizionario lst / dict_name anXrec) (SETQ dict_name (CP:get-or-create-Dict "C_plan")) ;(CDR (ASSOC -1 (DICTSEARCH (NAMEDOBJDICT) nomedizionario)))) (SETQ anXrec (ENTMAKEX (LIST '(0 . "XRECORD") '(100 . "AcDbXrecord") (CONS 300 (nth 0 lst)) ;percorso (CONS 301 (nth 1 lst)) ;unità (CONS 302 (nth 2 lst)) ;scala (CONS 303 (nth 3 lst)) ;scala colore (cons 304 (nth 4 lst)) ;moltiplicatore (cons 305 (nth 5 lst)) ;ang_rot ) ) ) (DICTADD dict_name name anXrec) ) (defun CP:get-or-create-Dict ( nome / adict) (if (not (setq adict (dictsearch (namedobjdict) nome))) (progn (setq adict (entmakex '((0 . "DICTIONARY")(100 . "AcDbDictionary")))) (if adict (setq adict (dictadd (namedobjdict) nome adict))) ) (setq adict (cdr (assoc -1 adict))) ) ) In this case, I can save 6 values. I want to use this function to save even only one value or 10 values without creating other dedicated functions. Is it possible? Any suggestion to accomplish that? Another question: to edit these xrecord I usually get values that don't modify and createa list of them plus values that I want to change. (setq lst (list (CP:leggi_dati "Costanti" "C_plan" 300) "M" "1" "1000" "0.01" (CP:leggi_dati "Costanti" "C_plan" 305) ) ) (dictremove (cdr (assoc -1 (dictsearch (namedobjdict) "C_plan"))) "Costanti") (CP:salva_dati "Costanti" "C_plan" lst) (DEFUN CP:leggi_dati (name nomedizionario valore / dict_name) (SETQ dict_name (CDR (ASSOC -1 (DICTSEARCH (NAMEDOBJDICT) nomedizionario)))) (CDR (ASSOC valore (DICTSEARCH dict_name name))) ) There is a better method? (modify only the element I want without collect the others) Thanks for your help! Dennis Quote
BIGAL Posted April 27, 2019 Posted April 27, 2019 (edited) It should work but you should be able to do a repeat for the 300's section (setq x 301 y 0) (list '(0 . "Xrecord ............... (repeat howmany (cons x (nth y lst)) (setq x (+ x 1)) (setq y (+ y 1)) ) ) Edited April 29, 2019 by BIGAL Quote
Roy_043 Posted April 27, 2019 Posted April 27, 2019 (edited) First of all I think it is strange to store numbers as strings. Second: you can use group codes 300-309 for strings. But not 310-319. Third: consider formatting your data. Example: (... (1 . "MyString") (2 . "ABC") (1 . "MyReal") (40 . 1.23) (1 . "MyOtherReal") (40 . 4.56) (1 . "MyInt") (90 . 1)) Edited April 27, 2019 by Roy_043 Quote
MastroLube Posted May 16, 2019 Author Posted May 16, 2019 Sorry for reply only now, I've been busy with work and had to stop to develop my lisps Thank you both for the answers!! On 4/27/2019 at 10:04 AM, Roy_043 said: First of all I think it is strange to store numbers as strings. Second: you can use group codes 300-309 for strings. But not 310-319. Third: consider formatting your data. Example: (... (1 . "MyString") (2 . "ABC") (1 . "MyReal") (40 . 1.23) (1 . "MyOtherReal") (40 . 4.56) (1 . "MyInt") (90 . 1)) 1 Can you please tell me how I can accomplish that? I mean formatting my data in a clever way. I think my code will improve so much if I understand how to do that instead of doing all in a raw way Just a little example using my code (or a part of it) so I can start learning something.. Thank you very very much! Dennis Quote
MastroLube Posted August 19, 2019 Author Posted August 19, 2019 (edited) (defun CP:crea_xrecord (nome /) (setq dict_name (cdr (assoc -1 (dictsearch (namedobjdict) "Solaio Atlax")))) (setq anXrec (entmakex (list '(0 . "XRECORD") '(100 . "AcDbXrecord") (cons 1 "MyString") (cons 2 "ABC") (cons 1 "MyReal") (cons 40 1.23) ) ) ) (dictadd dict_name nome anXrec) ) Maybe in this way? How do I read that? ((-1 . <Entity name: 15667ad30b0>) (0 . "XRECORD") (5 . "253") (102 . "{ACAD_REACTORS") (330 . <Entity name: 15667ad3090>) (102 . "}") (330 . <Entity name: 15667ad3090>) (100 . "AcDbXrecord") (280 . 1) (1 . "MyString") (2 . "ABC") (1 . "MyReal") (40 . 1.23)) I have to look for "MyString" but how to extract the value at right? thanks Edited August 19, 2019 by MastroLube Quote
MastroLube Posted September 4, 2019 Author Posted September 4, 2019 Sorry for keeping asking but I don't know how to improve my code.. Hope someone can help me this time This is how I store variables in my program. (defun CP:crea_xrecord (nome /) (setq dict_name (cdr (assoc -1 (dictsearch (namedobjdict) "Solaio Pipp")))) (setq anXrec (entmakex (list '(0 . "XRECORD") '(100 . "AcDbXrecord") (cons 300 (dcl-Control-GetText Pipp/Main/h)) ;altezza soletta (cons 301 (dcl-Control-GetText Pipp/Main/tipo_alleggerimento)) ;alleggerimento (cons 302 (dcl-Control-GetText Pipp/Main/c)) ;copriferro inf (cons 303 (dcl-Control-GetText Pipp/Main/c1)) ;copriferro sup (cons 304 (dcl-Control-GetText Pipp/Main/R_fuoco)) ;resistenza al fuoco (cons 305 (dcl-Control-GetText Pipp/Main/phi_base)) ;armatura sup di base (cons 306 (dcl-Control-GetText Pipp/Main/passo_base)) ;passo armatura sup di base (cons 307 (dcl-Control-GetText Pipp/Main/classe_cls)) ;classe del cls (cons 308 (dcl-Control-GetText Pipp/Main/classe_acciaio)) ;classe acciao (cons 309 (dcl-Control-GetText Pipp/Main/superficie)) ;superficie di getto (cons 91 (atoi (AX:getvars_single "Alleggerimenti" "def_all" 305))) ;altezza gabbia (cons 92 (atoi (AX:getvars_single "Alleggerimenti" "def_all" 301))) ;riduzione peso (cons 93 (atoi (rtos (* (atof (AX:getvars_single "Alleggerimenti" "def_all" 302)) 10000) 2 0))) ;volume vuoti (cons 94 (atoi (AX:getvars_single "Alleggerimenti" "def_all" 303))) ;passo alleggerimenti (cons 95 (atoi (rtos (* (atof (AX:getvars_single "Alleggerimenti" "def_all" 304)) 100) 2 0))) ;pezzi a mq (cons 96 (atoi (AX:getvars_single "Alleggerimenti" "def_all" 306))) ;lunghezza gabbia ;(cons 97 (atoi (rtos (* (atof (dcl-Control-GetText Pipp/Main/superficie)) 100) 2 0))) ;diametro ferri sup (cons 281 (atoi (dcl-Control-GetText Pipp/Main/phi_sup1))) (cons 282 (atoi (dcl-Control-GetText Pipp/Main/phi_sup2))) ;diametro ferri inf (cons 283 (atoi (dcl-Control-GetText Pipp/Main/phi_inf1))) (cons 284 (atoi (dcl-Control-GetText Pipp/Main/phi_inf2))) ;classi di esposizione (cons 285 (dcl-ComboBox-GetCurSel Pipp/Main/esposizione_top)) (cons 286 (dcl-ComboBox-GetCurSel Pipp/Main/esposizione_down)) ;;; (cons 287 (dcl-ComboBox-GetItemData Pipp/Main/colore_alleggerimenti (dcl-ComboBox-GetCurSel Pipp/Main/colore_alleggerimenti))) (cons 97 (fix (* (atof (vl-string-subst "." "," (dcl-Control-GetText Pipp/Main/inerzia_eq))) 1000))) ) ) ) (dictadd dict_name nome anXrec) ) As you can see it a stupid way to accomplish that. An user in this post suggested me how to store variables in a clever way but I don't know how to implement that. (how to store and how to get values) Can someone, please, give me an example ? Thanks! Quote
BIGAL Posted September 4, 2019 Posted September 4, 2019 Are you running dcl-Control-GetText every time in the entmake ? if so look at my Multi getvals.lsp Using the loop as I previously posted will do any length list. Quote
MastroLube Posted September 4, 2019 Author Posted September 4, 2019 Hello Bigal, nice to hear you again! You lisp is very usefull! Anyway this dcl-control-gettext is linked to OPENDCL. I've an interface always on with these values and when i press "SAVE" I store them in an xrecord with the name of the slab inside a dictionary. Another way to accomplish my tast is to use that lisp with custom entities (defun CP:crea_xrecord (nome /) (setq dict_name (cdr (assoc -1 (dictsearch (namedobjdict) "Solaio")))) (setq anXrec (entmakex (list '(0 . "XRECORD") '(100 . "AcDbXrecord") (cons 1 "MyString") (cons 2 "TEST1") (cons 1 "MyString2") (cons 2 "TEST2") (cons 1 "MyString4") (cons 2 "TEST4") (cons 1 "MyReal1") (cons 40 1.23) (cons 1 "MyReal2") (cons 40 2.43) ) ) ) (dictadd dict_name nome anXrec) ) BUT I don't know how to get values back. For example how can i get the value of "Mystring2? My getvals uses the code 300-309 91-97 and so on which are univoque. With this metod I've, in this example, three dxf code 2, two dxf code 40 and five dxf code 1. I'm looking for something like this: (GETVAL "Solaio" "Mystring2") RETURN >> "TEST2" Quote
BIGAL Posted September 4, 2019 Posted September 4, 2019 (edited) Can you post a screen image of what the (dcl-Control-GetText Pipp/Main/h) looks like had a quick look at opendcl and understand its 3 parts. Edited September 4, 2019 by BIGAL Quote
MastroLube Posted September 4, 2019 Author Posted September 4, 2019 I get "21" from textbox in my interface It' the high of my slab. When I press to "SALVA SOLAIO" I save all these values in my dictionary. Quote
Grrr Posted September 4, 2019 Posted September 4, 2019 Perhaps try something like: (defun CP:crea_xrecord (nome / dict_name anXrec) (if (setq dict_name (cdr (assoc -1 (dictsearch (namedobjdict) "Solaio Pipp")))) (progn (setq anXrec (entmakex (append '((0 . "XRECORD")(100 . "AcDbXrecord")) (apply 'append (mapcar '(lambda (x / v) (if (setq v (eval (cadr x))) (mapcar 'cons (list 1 (nth (vl-position (type v) '(INT REAL LIST STR)) '(70 40 10 1))) (list (car x) v)))) '( ; list <key> <val> ("altezza soletta" (dcl-Control-GetText Pipp/Main/h)) ("alleggerimento" (dcl-Control-GetText Pipp/Main/tipo_alleggerimento)) ("copriferro inf" (dcl-Control-GetText Pipp/Main/c)) ; ... ("altezza gabbia" (atoi (AX:getvars_single "Alleggerimenti" "def_all" 305))) ("riduzione peso" (atoi (AX:getvars_single "Alleggerimenti" "def_all" 301))) ; ... ) ) ) ) ) ) (dictadd dict_name nome anXrec) ) ) ) And to obtain the value use something like: (cdadr (member '(1 . "altezza gabbia") (entget xrec))) 1 Quote
MastroLube Posted September 5, 2019 Author Posted September 5, 2019 Thank you Mr. Grrr, you have improved my coding Just need to understand how the part "lamba ..." works and then I'm ready! Another little question: in your opinion is it possible to store variable number of data? I mean having a general funcion for storing 3, 5, n variables? Maybe passing them as a list? (store_variables '((key1 . val1) (key2 . val2) ...)) Quote
BIGAL Posted September 6, 2019 Posted September 6, 2019 (edited) As I have said before and Grr is doing also he is using a list to make the entries if you pull all the (dcl-Control-GetText Pipp/Main/ outside of the dictionary part make a list of all the 300's 98's 280's then process the list so it does not matter how many in a list. something like (setq lst (cons (300 "altezza soletta" (dcl-Control-GetText Pipp/Main/h)) lst)) (setq lst (cons (301 "alleggerimento" (dcl-Control-GetText Pipp/Main/tipo_alleggerimento)) lst)) (setq lst (cons (302 "copriferro inf" (dcl-Control-GetText Pipp/Main/c)) lst)) Edited September 6, 2019 by BIGAL 1 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.