Aller au contenu

Incompatibilité vlisp/autolisp


Patrick_35

Messages recommandés

Bonjour

 

Je regarde comment faire un dictionnaire en vlisp et je me suis aperçu d'une chose

Quand je créé un dictionnaire avec un enregistrement en vlisp, et bien je suis incapable de récupérer l'enregistrement en autolisp.

 

Voici un exemple fournit dans l'aide

(vl-load-com)
(defun c:Example_SetXRecordData()
   ;; This example creates a new XRecord if one doesn't exist,
   ;; appends data to the XRecord, and then reads it back.  To see data being added,
   ;; run the example more than once.
   (setq acadObj (vlax-get-acad-object))
   (setq doc (vla-get-ActiveDocument acadObj))
   
   ;; Unique identifiers to distinguish this XRecordData from other XRecordData
   (setq TYPE_STRING 1
         TAG_DICTIONARY_NAME "ObjectTrackerDictionary"
         TAG_XRECORD_NAME "ObjectTrackerXRecord")

   ;; Connect to the dictionary in which to store the XRecord
   (setq dictionaries (vla-get-Dictionaries doc))
   (setq TrackingDictionary (vl-catch-all-apply 'vla-Item (list dictionaries TAG_DICTIONARY_NAME)))

   ;; (= (vl-catch-all-error-message TrackingDictionary) "Automation Error. Key not found")
 
   (if (= (type TrackingDictionary) 'VLA-OBJECT)
       (setq TrackingXRecord (vla-GetObject TrackingDictionary TAG_XRECORD_NAME))
       (progn
           ;; Create the objects that hold this XRecordData
           (setq TrackingDictionary (vla-Add dictionaries TAG_DICTIONARY_NAME))
           (setq TrackingXRecord  (vla-AddXRecord TrackingDictionary TAG_XRECORD_NAME))
)
   )

   ;; Get current XRecordData
   (vla-GetXRecordData TrackingXRecord 'temp-XRecordDataType 'temp-XRecordData)
   
   ;; If there is no array yet then create one
   (setq ArraySize 0)
   (if (/= temp-XRecordDataType nil)
       (progn
    (setq ArraySize (vlax-safearray-get-u-bound temp-XRecordDataType 1))
           (setq XRecordDataType (vlax-make-safearray vlax-vbInteger (cons 0 (1+ ArraySize))))
           (setq XRecordData (vlax-make-safearray vlax-vbVariant (cons 0 (1+ ArraySize))))

           (setq iCount 0)
           (while (>= ArraySize iCount)
               ;; Get information for this element
               (setq DataType (vlax-safearray-get-element temp-XRecordDataType iCount))
               (setq Data (vlax-variant-value (vlax-safearray-get-element temp-XRecordData iCount)))

               (vlax-safearray-put-element XRecordDataType iCount DataType)
               (vlax-safearray-put-element XRecordData iCount Data)
      
               (setq iCount (1+ iCount))
           )
)
       (progn
           (setq XRecordDataType (vlax-make-safearray vlax-vbInteger '(0 . 0)))
           (setq XRecordData (vlax-make-safearray vlax-vbVariant '(0 . 0)))
)
   )
   
   ;; Append new XRecord Data
   ;;
   ;; For this sample we only append the current time to the XRecord
   (vlax-safearray-put-element XRecordDataType ArraySize TYPE_STRING)
   (setq cdate (rtos (vlax-variant-value (vla-GetVariable doc "CDATE")) 2 6))
   (vlax-safearray-put-element XRecordData ArraySize (strcat (substr cdate 5 2) "/"
						      (substr cdate 7 2) "/"
						      (substr cdate 1 4) "-"
						      (substr cdate 10 2) ":"
						      (substr cdate 12 2) ":"
						      (substr cdate 14)))
   (vla-SetXRecordData TrackingXRecord XRecordDataType XRecordData)
   
   ;; Read back all XRecordData entries
   (vla-GetXRecordData TrackingXRecord XRecordDataType XRecordData)
   (setq ArraySize (vlax-safearray-get-u-bound XRecordDataType 1))
   
   ;; Retrieve and display stored XRecordData
   (setq iCount 0
  msg "")
   (while (>= ArraySize iCount)
       ;; Get information for this element
       (setq DataType (vlax-safearray-get-element XRecordDataType iCount))
       (setq Data (vlax-variant-value (vlax-safearray-get-element XRecordData iCount)))

       (if (= DataType TYPE_STRING)
           (setq msg (strcat msg Data "\n"))
       )
     
       (setq iCount (1+ iCount))
   )
   
   (alert (strcat "The data in the XRecord is: \n\n" msg))
)

Tout fonctionne.

 

Maintenant, je regarde pour récuperer les info en autolisp

(setq dict (dictsearch (namedobjdict) "ObjectTrackerDictionary"))
(dictnext dict t)

Et bien, j'ai l'erreur

; erreur: type d'argument incorrect: lentityp ((-1 . <Nom d'entité: 7e708800>) (0 . "DICTIONARY") (5 . "18290") (102 . "{ACAD_REACTORS") (330 . <Nom d'entité: 7e7c7c60>) (102 . "}") (330 . <Nom d'entité: 7e7c7c60>) (100 . "AcDbDictionary") (280 . 0) (281 . 1) (3 . "ObjectTrackerXRecord") (350 . <Nom d'entité: 7e708808>))

 

Alors incompatible ?

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Non, tout à fait compatible.

 

Patrick, regarde le message d'erreur, dictnext requiert un argument de type ename et dictsearch retourne une liste DXF.

 

essaye :

(setq dictEname (cdr (assoc -1 (dictsearch (namedobjdict) "ObjectTrackerDictionary"))))
(setq xrecList (dictsearch dictEname "ObjectTrackerXRecord"))
(setq dataList (cdr (member (assoc 280 xrec) xrecList)))
(alert (strcat "The data in the XRecord is: \n\n" (cdar dataList)))

 

ou encore, avec les routines données ici :

(alert
 (strcat "The data in the XRecord is: \n\n"
  (cdar
    (gc:GetXrecData
      (gc:GetNamedDict (namedobjdict) "ObjectTrackerDictionary")
      "ObjectTrackerXRecord"
    )
  )
 )
)

 

J'ai toujours pensé qu'il était plus pratique d'accéder aux dictionnaires/xrecords en AutoLISP qu'avec vlisp.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Merci pour ta réponse (gile)

 

Une chose que je ne comprends pas.

 

Quand je fais

(setq xname (entmakex  '((0 . "DICTIONARY") (100 . "AcDbDictionary"))))
(setq dict (dictadd (namedobjdict) "Mon_Dict" xname))
(setq xrecord (entmakex '((0 . "XRECORD") (100 . "AcDbXrecord") (1 . "Test"))))
(dictadd dict "Rec_01" xrecord)

Tout fonctionne et avec

(dictnext dict t)

Je retrouve bien mon enregistrement, ou je m'y prend mal ?

 

Si vraiment tu préfères vlisp, j'avais fait quelques routines pour faciliter la lecture ou l'écriture des xrecords avec les listes de pairs pointées ici (gc:GetXrecordData et gc:SetXrecordData)

Pas spécialement, mais c'est pour utiliser l'un ou l'autre en fonction du lisp et des mes variables.

Merci pour le lien.

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

dictnext retourne l'entrée suivante dans le dictionnaire, si tu n'as qu'une entrée, pas de problème, mais il peut y en avoir plusieurs : des dictionnaires, des enregistrements ou d'autres objets comme les LAYOUT dans "ACAD_LAYOUT".

 

Les dictionnaires (en général) sont des collections de paires clé/objet, il est en général plus facile (et plus performant) d'y accéder par la clé plutôt qu'en les parcourant.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Oui, tu as raison, comme je n'ai qu'une entrée, j'ai fait au plus simple

(dictsearch dict "Rec_01") revient à faire (dictnext dict T)

 

Pout tout te dire, voila le bout de code sur lequel je travaille

(setq doc (vla-get-activedocument (vlax-get-acad-object))
     dic (vla-get-dictionaries doc)
)

(setq new (vla-add dic "Mon_Dict"))

(and (ssget)
 (progn
   (vlax-for ent (setq sel (vla-get-activeselectionset doc))
     (setq lst (cons (vlax-make-variant (vla-get-handle ent)) lst)
    dxf (cons 5 dxf)
     )
   )
   (vla-delete sel)
 )
)

(setq xre (vla-Addxrecord new "Rec_01")
     xrt (vlax-make-safearray vlax-vbInteger (cons 0 (1- (length dxf))))
     xrd (vlax-make-safearray vlax-vbVariant (cons 0 (1- (length lst))))
)

(vlax-safearray-fill xrt dxf)
(vlax-safearray-fill xrd lst)

(vla-setxrecorddata xre xrt xrd)

Et je voulais faire comme précedement avec la recherche simplifié.

Il faut mettre un ename et non une liste, même si ça fonctionne en pur autolisp

 

Merci pour tout

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité