Jump to content
MastroLube

xrecord in dictionary management

Recommended Posts

MastroLube

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

 

 

Share this post


Link to post
Share on other sites
BIGAL
Posted (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 by BIGAL

Share this post


Link to post
Share on other sites
Roy_043
Posted (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 by Roy_043

Share this post


Link to post
Share on other sites
MastroLube

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

 

Share this post


Link to post
Share on other sites
MastroLube
Posted (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 by MastroLube

Share this post


Link to post
Share on other sites
MastroLube

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!

Share this post


Link to post
Share on other sites
BIGAL

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.

Share this post


Link to post
Share on other sites
MastroLube

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"



 

Share this post


Link to post
Share on other sites
BIGAL

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 by BIGAL

Share this post


Link to post
Share on other sites
MastroLube

93720307_2019-09-0413_32_42-Plan.png.538af75019f041b4068ee97dd6875e11.png

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.

Share this post


Link to post
Share on other sites
Grrr

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)))

 

  • Thanks 1

Share this post


Link to post
Share on other sites
MastroLube

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) ...))

Share this post


Link to post
Share on other sites
BIGAL

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 by BIGAL
  • Like 1

Share this post


Link to post
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...