rrobert Posté(e) le 9 juin 2021 Auteur Posté(e) le 9 juin 2021 Merci d'avoir pris le temps du lisp et de me montrer en VBA, c'est très appréciable. Je comprends bien mieux la structure des bloc et blocs dynamiques dans Autocad. Donc si je comprends bien il me suffit d'ajouter autant de codes DXF que je souhaite à FilterType et autant de conditions à FilterData pour complexifier le filtrage si je le souhaite?
(gile) Posté(e) le 9 juin 2021 Posté(e) le 9 juin 2021 Vois cette section de la doc et les sujets relatifs en lien. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
rrobert Posté(e) le 9 juin 2021 Auteur Posté(e) le 9 juin 2021 Merci du lien. J'ajoute aussi que si je veux autant développer en VBA et pas trop en lisp c'est que nous sommes 4 au bureau et que je suis le seul à avoir AutoCAD en full, les autres ayant LT c'est mieux si tout le monde peut en profiter 😉
(gile) Posté(e) le 9 juin 2021 Posté(e) le 9 juin 2021 1 hour ago, rrobert said: J'ajoute aussi que si je veux autant développer en VBA et pas trop en lisp c'est que nous sommes 4 au bureau et que je suis le seul à avoir AutoCAD en full, les autres ayant LT c'est mieux si tout le monde peut en profiter Les versions LT ne supportent aucune programmation. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Luna Posté(e) le 9 juin 2021 Posté(e) le 9 juin 2021 Je n'étais pas sûre donc j'ai préféré ne rien dire plutôt que de dire des bêtises mais c'est bien ce qu'il me semblait...Si tu veux écrire des programmes pour des versions LT, il faudrait se tourner plutôt sur des scripts ou le langage DIESEL (il me semble qu'il est compatible avec les versions LT). En revanche, je ne sais plus si les versions LT possèdent les mêmes commandes qu'une version full ou bien si leur nombre est limité (je confonds sûrement avec les Viewers)... Peut-être essaye de voir avec la commande FILTRE (à vérifier s'il y a moyen de ne pas passer par la Boîte de Dialogue) ou SELECTSIMILAR dans ce cas. Mais en effet c'est bien de s'en rendre compte le plus tôt possible que ton programme doit être compatible avec les versions LT. Bon courage !
rrobert Posté(e) le 9 juin 2021 Auteur Posté(e) le 9 juin 2021 Argh, je n'ai donc plus aucun argument pour développer en lisp 😉 Merci de l'info. Yes il en faut, je vais m'attaquer à un gros truc là, mais grâce à tous vos conseils je vais déjà bien avancer 🙂
Luna Posté(e) le 9 juin 2021 Posté(e) le 9 juin 2021 @rrobert, je ne sais pas si tu as bien compris donc je préfère insister juste au cas où : Les versions LT ne supporte AUCUNE programmation, autrement dit, que se soit en VBA ou en LISP, les versions LT n'y auront pas le droit. La seule solution si tu ne veux pas être le seul à en profiter, c'est de creuser le sujet en passant par un script, ou du DIESEL...(ou bien en achetant des licences full pour tout le monde, mais chat fait cher le programme !) Je préfère insister car ta phrase 11 minutes ago, rrobert said: Argh, je n'ai donc plus aucun argument pour développer en lisp 😉 prête à confusion et semble indiquer que tu comptes programmer en LISP, ce qui ne solutionnera pas le problème. Si tu veux développer un programme pour toi uniquement, libre à toi de choisir le VBA ou le LISP en fonction de tes habitudes (les fonctionnalités sont très similaire, c'est juste le langage qui est différent) mais si ton programme à pour vocation d'être utilisé par tes collègues (donc LT), alors autant faire directement tous tes programmation en script/DIESEL qui fonctionneront aussi bien sur une version LT que full ! Tu risques de perdre du temps à devoir écrire le même programme dans deux langages différents (voir 3 si tu veux revenir en version LISP alors que tu as commencé en VBA). Bisous, Luna
rrobert Posté(e) le 9 juin 2021 Auteur Posté(e) le 9 juin 2021 @Luna j'avais bien compris le problème, pour l'instant je vais faire 2/3 trucs urgents en VBA pour moi, je verrai après si je passe le cap du script et diesel pour les collègues car ça fait déjà pas mal de choses à décortiquer en ce moment 😉
(gile) Posté(e) le 9 juin 2021 Posté(e) le 9 juin 2021 28 minutes ago, rrobert said: Argh, je n'ai donc plus aucun argument pour développer en lisp @rrobert, tu fais comme tu veux, chacun ses préférences. Par contre, l'activité des forums peut te donner une idée de la quantité d'aide et d'exemples que tu trouveras: CADxp : VBA = 4600 messages LISP = 41600 messages Autodesk : VBA = 91526 envois, LISP = 385009 envois TheSwamp : VBA 9168 posts, LISP = 110610 posts @Luna, @rrobert, pour les blocs dynamiques pas de salut hors programmation. La commande FILTRE (_FILTER) offre les mêmes possibilités que les filtres de sélections, et le Diesel n'est pas vraiment un langage de programmation, il permet juste de mettre certaines conditions dans les macros de commandes. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 Merci des infos @gile @didier j'ai vidé un peu l' espace de PJ de mon compte, voici le plan de test en PJ. Test selection etage.dwg
didier Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Bonjour @rrobert Pour le coup, c'est vraiment minimaliste ! Trop d'ailleurs, j'aurais aimé un fichier avec des entités, je vais les rajouter pour tester les filtres... Je vais voir ce que je peux te proposer, mais pas dans les minutes ni dans la journée qui vient, je suis over full sur autre chose. Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 J'ai voulu simplifier au max 😬 Pas de souci, c'est déjà gentil de regarder.
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 EDIT : j'avais initialement dû mal recopier le code de @gile, en prenant "*,>=,*" et non pas ">=" tout fonctionne. Merci. Du coup qu'ajoutent le *, en plus du >= ? Je complète le fichier DWG avec le code actuel inspiré de @gile : Sub test420000() Dim nom_bloc As String nom_bloc = "toto" Dim pointMin(0 To 2) As Double Dim filterType(3) As Integer Dim filterData(3) As Variant pointMin(0) = 50 pointMin(1) = 50 pointMin(2) = 50 'Le code suivant renvoie une erreur de declaration de variable 'Dim filterType(0, 2, -4, 10, -4, 10) As Integer 'Dim filterData("INSERT", nom_bloc & ",`*U*", "*,>=,*", pointMin, "*,<,*", pointMax) As Variant 'Les filtres sont faits pour sélectionner tous les blocs situés au-dessus du pointMin de coordonnées (50,50,50) filterType(0) = 0 filterType(1) = 2 filterType(2) = -4 filterType(3) = 10 filterData(0) = "INSERT" filterData(1) = nom_bloc & ",`*U*" filterData(2) = ">=" filterData(3) = pointMin Dim sset As AcadSelectionSet Set sset = ThisDrawing.SelectionSets.Add("test13") sset.Select acSelectionSetAll, , , filterType, filterData 'sset.SelectOnScreen filterType, filterData MsgBox ("Elements filtrés: " & str(sset.Count)) sset.Highlight True sset.Delete End Sub Ca fonctionne très bien pour la coordonnée X. Mais, suivant ce manuel, si je replace le code DXF "10" par le code DXF "20" afin de filtrer suivant la coordonnée Y, et bien il ne se passe rien, aucune entité n'est sélectionnée alors que ça devrait être le cas !
(gile) Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Je ne peux pas t'aider en ce qui concerne la syntaxe VBA pour la déclaration des variables, mais je suis quasiment certain pour la syntaxe pour les valeurs du filtre (c'est le même principe qu'en LISP et qu'en .NET). filterType(0) = 0 filterData(0) = "INSERT" filterType(1) = 2 filterData(1) = nom_bloc & ",`*U*" filterType(2) = -4 filterData(2) = "*,>=,*" filterType(3) = 10 filterData(3) = pointMin filterType(4) = -4 filterData(4) = "*,<,*" filterType(5) = 10 filterData(5) = pointMax Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 @gile je te confirme la syntaxe. Au début quand j'ai copié ta syntaxe j'ai ajouté une virgule en trop du coup ça me mettait une erreur. J'ai continué avec uniquement ">=" mais du coup ça ne prend en compte que le X. C'est corrigé.
Luna Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Coucou, il y a 53 minutes, rrobert a dit : EDIT : j'avais initialement dû mal recopier le code de @gile, en prenant "*,>=,*" et non pas ">=" tout fonctionne. Merci. Du coup qu'ajoutent le *, en plus du >= ? Alors pour commencer, les codes DXF 20 et 30 (respectivement Y et Z) n'existent pas vraiment dans la liste DXF d'un objet...Pour cela, je te conseil de consulter les objets directement via (entget (car (entsel))) ! En réalité, les codes 20 et 30 sont "contenus" dans le code DXF 10 de manière implicite. Le code DXF 10 se compose ainsi : (10 X Y Z), autrement dit, tu as les 3 axes. Le code -4 avec pour valeur "*,>=,*" permet de définir les valeurs acceptable pour le code DXF 10 suivant. Ainsi cela permet de définir que l'on accepte n'importe quelle valeur pour les coordonnées en X et en Z (la virgule permet de séparer les axes) grâce à * (donc on peut mettre n'importe quelle valeur dans le code DXF 10 suivant pour ces axes, car elles ne comptent pas). Et on n'acceptent ici que les valeurs en Y qui sont supérieures ou égales à la valeur précisée dans le code DXF 10 suivant cette paire pointée. Encore une fois, @(gile) est plus rapide ^^" Pour le coup, l'aide en LISP concernant la fonction (ssget) te donneras toutes les réponses que tu souhaites car c'est le même fonctionnement qu'en LISP. http://www.lee-mac.com/ssget.html Bisous, Luna
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 @Luna mille mercis de m'avoir précisé tout ça, je comprends mieux !
didier Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Bonjour @rrobert C'est OK, le sujet est clos ou faut-il proposer une solution ? Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 Le 09/06/2021 à 13:55, Curlygoth a dit : Pour revenir à l'ajout à une sélection : selection.AddItems objet_new et set objet_new = ton objet 😉 J'ai essayé par tous les moyens mais rien n'y fait, ça ne fonctionne pas... Je suis capable de préfiltrer sans souci, mais en post-filtrage je ne peux supprimer ou ajouter des éléments à mon selectionSet. J'ai crée un selectionset "selection" qui contient tous les éléments de ma présélection. et j'ai créé un autre jeu de selection "selection_finale" à qui je veux ajouter mes objets post-filtrés. Sauf que ça ne marche pas, peu importe le type d'objet que je veux y ajouter... (pour l'instant je ne joue qu'avec des selectionset, je regarderai pas la suite pour les collections) Je me suis aidé de cette page de l'aide Autodesk avec l'exemple qu'ils ont mis. La partie qui beugue est à la fin. Sub selection_etage() 'Cette macro permet de sélectionner un bloc manuellement puis de sélectionner tous les blocs présents sur le même étage ' Elle évoluera dans le temps pour créer un utilitaire de sélection complet permettant de renseigner les calques, noms, visibilité, attributs, dimensions, etc. 'Variables permettant de déterminer les limites d'étages de sélection Dim etage_ref As Integer Dim espacement_etage As Double Dim lim_inf As Double Dim lim_sup As Double 'Variables pour la sélection d'objet Dim selectionref As AcadEntity Dim point_selection_ref As Variant Dim blocref As AcadBlockReference Dim nom_bloc_ref As String Dim selection As AcadSelectionSet Dim selection_finale As AcadSelectionSet Dim objet As AcadObject Dim bloc As AcadBlockReference 'Dim bloc_sel As AcadBlockReference 'Variables pour le filtrage Dim pointMin(2) As Double Dim pointMax(2) As Double Dim filterType(5) As Integer Dim filterData(5) As Variant Dim nom_bloc As String 'on vient récupérer l'écartement entre étages définis par la variable USERI1 espacement_etage = ThisDrawing.GetVariable("useri1") '##############SELECTION DU BLOC DE REFERENCE################ 'L'utilisateur doit sélectionner UN bloc de référence 'Si la sélection comporte une erreur on recommence la phase de sélection On Error Resume Next RETRY: 'Code de sélection du bloc de référence ThisDrawing.Utility.GetEntity selectionref, point_selection_ref, vbCr & "Sélectionnez le bloc de référence" 'verification des erreurs de selection If Err <> 0 Then Err.Clear MsgBox "La sélection est vide ou non valide." GoTo RETRY End If 'On vérifie que l'élément de référence sélectionné est un bloc If TypeOf selectionref Is AcadBlockReference Then Set blocref = selectionref nom_bloc_ref = blocref.EffectiveName 'On détermine le niveau du bloc ainsi que les limites sup et inf du niveau auquel il se trouve 'ATTENTION, ceci ne fonctionne qu'avec les coordonnées du SCG If blocref.InsertionPoint(1) >= 0 Then etage_ref = Fix((blocref.InsertionPoint(1)) / espacement_etage) Else etage_ref = Fix((blocref.InsertionPoint(1)) / espacement_etage) - 1 End If lim_sup = espacement_etage * (etage_ref + 1) lim_inf = espacement_etage * etage_ref 'Les lignes en commentaires suivantes servent, au besoin, à faire un suivi pas à pas des étapes précédentes 'MsgBox "Nom du bloc : " & nom_bloc_ref 'MsgBox "Point d'insertion (1) : " & blocref.InsertionPoint(1) 'MsgBox "Etage ref : " & etage_ref 'MsgBox "Lim inf : " & lim_inf 'MsgBox "Lim sup : " & lim_sup Else MsgBox "L'élément sélectionné n'est pas un bloc." GoTo RETRY End If '##############FIN DE LA SELECTION DU BLOC DE REFERENCE################ '##############CARACTERISATION DU PREFILTRAGE################ 'A l'avenir cette partie du code permettra la caractérisation du pré-filtrage via un userform VBA 'On détermine les coordonnées permettant de filtrer la sélection dans l'espace (X, Y, Z) pointMin(0) = 0 pointMin(1) = lim_inf pointMin(2) = 0 pointMax(0) = 0 pointMax(1) = lim_sup pointMax(2) = 0 'Détermination du filtrage qui sera opéré 'Ici on filtre tous les blocs et blocs dynamiques étant sur le même étage que le bloc de référence précédemment sélectionné filterType(0) = 0 filterType(1) = 2 filterType(2) = -4 filterType(3) = 10 filterType(4) = -4 filterType(5) = 10 filterData(0) = "INSERT" filterData(1) = ",`*U*" '& nom_bloc_ref filterData(2) = "*,>=,*" filterData(3) = pointMin filterData(4) = "*,<,*" filterData(5) = pointMax '##############FIN DE LA CARACTERISATION DU PREFILTRAGE################ 'On sélectionne les éléments souhaités Set selection = ThisDrawing.SelectionSets.Add("selectiondyntest1") Set selection_finale = ThisDrawing.SelectionSets.Add("selectionfindyntest1") selection.Select acSelectionSetAll, , , filterType, filterData ReDim ajout(0 To selection.Count - 1) As AcadEntity Dim i As Integer i = 0 '/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ 'ici on sous-entend que la selection contient uniquement des blocs, à adapter si le préfiltrage doit prendre en compte d'autres objets que les blocs '/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ 'Pour cette partie de code on vient post-filtrer afin de n'avoir que les blocs dont le nom effectif correspond au bloc de référence For i = 0 To selection.Count - 1 Set bloc = selection(i) Set objet = selection(i) If bloc.EffectiveName = nom_bloc_ref Then 'LA LIGNE DE CODE SUIVANTE NE FONCTIONNE PAS Set ajout(i) = objet 'MsgBox (TypeName(bloc)) End If Next i selection_finale.AddItems ajout 'MsgBox (TypeName(ajout)) '/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ 'sset.SelectOnScreen filterType, filterData MsgBox ("Elements filtrés en première sélection : " & str(selection.Count)) MsgBox ("Elements filtrés en sélection finale: " & str(selection_finale.Count)) selection_finale.Highlight True selection.Delete selection_finale.Delete End Sub Pour le fichier de test, voir message plus haut.
didier Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Bonjour @rrobert Je n'ai pas lu ta prose, mais elle me semble quelque peu verbeuse Je te propose ceci : Il va falloir montrer le bloc à sélectionner, puis une sélection de ce bloc va se lancer sur l'emprise de l'étage. C'est améliorable à l'infini, mais je reste simple pour que tu comprennes bien, pas à pas. Amicalement Sub Test_rrobert() Dim ssFiltre As AcadSelectionSet Dim SelRef As AcadEntity Dim FilterType(1) As Integer Dim FilterData(1) As Variant Dim ptSel As Variant Dim Pt1(0 To 2) As Double Dim Pt2(0 To 2) As Double Dim nomBlocDyn As String ThisDrawing.Utility.GetEntity SelRef, ptSel, vbCr & "Sélectionnez le bloc de référence" nomBlocDyn = SelRef.EffectiveName & ",`*U*" Set ssFiltre = ThisDrawing.SelectionSets.Add("SS") FilterType(0) = 0 FilterData(0) = "INSERT" FilterType(1) = 2 FilterData(1) = nomBlocDyn Pt1(0) = 0#: Pt1(1) = 50#: Pt1(2) = 0# Pt2(0) = 99#: Pt2(1) = 99#: Pt2(2) = 0# ssFiltre.Select acSelectionSetWindow, Pt1, Pt2, FilterType, FilterData ssFiltre.Highlight (True) MsgBox ssFiltre.Count & " blocs sélectionnés." ssFiltre.Delete End Sub Éternel débutant... Mon site perso : Programmer dans AutoCAD
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 Jusque là je vous suis @didier. Cela me sélectionne sur un seul étage tous les blocs dont le nom correspond au bloc de référence, ainsi que tous les blocs dynamiques. Si je veux désormais supprimer de ma sélection tous les blocs dont le EffectiveName ne correspond pas au EffectiveName du boc de référence, comment dois-je m'y prendre?
didier Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Bonjour @rrobert Je ne comprends plus les questions, j'ai répondu à la demande : sélectionner les blocs dynamiques dont le nom correspond à celui montré en exemple. Ce que j'ai écrit le fait, pourquoi vouloir en retirer de la sélection ? Elle est filtrée. Sauf erreur (toujours possible le dessin fourni étant tellement simpliste) il me semble que le filtre est efficace. Autre chose : Attention aux unités de dessin et aux blocs insérés en échelles 0.001, ça fait désordre Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
rrobert Posté(e) le 10 juin 2021 Auteur Posté(e) le 10 juin 2021 il y a 11 minutes, didier a dit : Autre chose : Attention aux unités de dessin et aux blocs insérés en échelles 0.001, ça fait désordre Je viens justement de m'attaquer à la mise à jour des échelles des anciens plans de mon entreprise parce que là ce n'est plus possible... Le filtre n'est pas complètement fonctionnel car il sélectionne tous les blocs dont le nom correspond au premier bloc, mais aussi tous les blocs dynamiques, peu importe le nom du bloc sélectionné en amont 😕 C'est pour cela que je souhaite, après premier filtrage, supprimer les blocs dynamiques dont EffectiveName ne correspond pas au bloc de référence. Un exemple en image : j'ai sélectionné un des blocs en bas à gauche comme ref. Le bloc dynamique en haut à droite a un nom différent, mais comme il a un nom en *U, il a également été sélectionné par le code SelRef.EffectiveName & ",`*U*"
Luna Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Coucou, Je ne pourrais pas vraiment t'aider en VBA, mais pourquoi créer un second jeu de sélection pour le remplir si l'élément est bon ? Je pense qu'un simple truc comme chat ferait l'affaire (WARNING : je suis nulle en VBA donc je me contente simplement de copier ce que je comprends, c'est donc potentiellement faux à 90%) If bloc.EffectiveName /= nom_bloc_ref Then selection.RemoveItems bloc End If Bisous, Luna
didier Posté(e) le 10 juin 2021 Posté(e) le 10 juin 2021 Bonjour @rrobert Effectivement je n'ai pas vérifié avec d'autres blocs dynamiques... (en fait ce sont les blocs dynamiques dont on a modifié un paramètre car ils deviennent anonymes à ce moment-là) Je ne vois pas tout de suite comment faire étant sur autre chose, Tu peux te documenter et trouver toi-même la solution d'itérer le jeu de sélection et utiliser (je pense) RemoveItem. Je te réponds dès que je peux m'y mettre À bientôt Éternel débutant... Mon site perso : Programmer dans AutoCAD
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant