dr.loveless Posté(e) le 8 octobre 2004 Posté(e) le 8 octobre 2004 Salut à tous, Y a un truc que je comprends pas sur le BASIC ci dessous que je suis en train de réaliser. Il s'agit d'une application qui doit se dérouler comme suit: - Liste tous les objets du ModelSpace - Si c'est un bloc, poursuit le programme, sinon quitte l'application - Liste tous les objets contenu dans le bloc - Si un de ces objets est une ligne, en extrait les coordonnées - S'il y a au moins 2 lignes dans ce bloc, me relie d'un trait le milieu de ces deux lignes - Passe au bloc suivant Le code ci-dessous contient les 2 solutions que j'ai trouver, mais aucune ne fonctionne qomme je voudrais. Dans le premier cas, je me sers du nom du bloc. Ca fonctionne quand il n'y a qu'un bloc du même nom, si'il y en a deux, çà me relie bien les milieus des lignes, mais toujours pour le premier bloc (donc fonctionne doublement pour le premier bloc, et çà ne fonctionne pas pour le second). Il existe une solution qui ne me convient pas et qui consiste à ajouter la ligne au bloc, ainsi tous les blocs du même noms auront la fameuse ligne, mais le probleme c que cette ligne doit être dessinnée en fonction de l'attribut du bloc, et deux de même nom peuvent tres bien avoir des attributs différents. La seconde solution envisagée consiste à trouver l'ID du bloc, mais en faisant le set du bloc la boucle recherchant les ligne du bloc ne fonctionne pas!! Un casse tête quoi !! 'Boucle sur tous les objets du dessinFor Each ObjElem In ThisDrawing.ModelSpace 'Vérifie si l'objet est un bloc If ObjElem.EntityType = acBlockReference Then 'Attribue le numéro ObjectID du bloc NomID = ObjElem.ObjectID 'affiche le numéro ID MsgBox NomID ' Test avec le nom du bloc Set ObjBlock = ThisDrawing.Blocks(ObjElem.Name) 'Test avec le numéro ID du bloc Set ObjBlock = ThisDrawing.ObjectIdToObject(NomID) 'Pour chaque element consaituan le bloc For Each objent In ObjBlock 'Vérifie si l'objet du bloc est une ligne If objent.ObjectName = "AcDbLine" Then If A = 0 Then Pt1L1 = objent.StartPoint Pt2L1 = objent.EndPoint End If If A = 1 Then Pt1L2 = objent.StartPoint Pt2L2 = objent.EndPoint PtDepart(0) = (Pt1L1(0) + Pt2L1(0)) / 2 PtDepart(1) = (Pt1L1(1) + Pt2L1(1)) / 2 PtDepart(2) = 0 PtFin(0) = (Pt1L2(0) + Pt2L2(0)) / 2 PtFin(1) = (Pt1L2(1) + Pt2L2(1)) / 2 PtFin(2) = 0 'dessinne une ligne entre le milieu des 2 lignes d'un bloc Set L1 = ThisDrawing.ModelSpace.AddLine(PtDepart, PtFin) End If A = 1 + A End If Next objent End If Next Cpt1 End If A = 0 Next ObjElem Unload Me End Sub [Edité le 8/10/2004 par dr.loveless] [Edité le 8/10/2004 par dr.loveless] Le DOC
dr.loveless Posté(e) le 8 octobre 2004 Auteur Posté(e) le 8 octobre 2004 Comprends pas pourquoi je peux pas joindre l'image ?? Le DOC
Bacon Posté(e) le 8 octobre 2004 Posté(e) le 8 octobre 2004 Bonjour docteur, c'est sans rdv ? Blague à part, j'ai fait un peu de VB sous AutoCAD mais il ne me reste que de très vagues souvenirs. Aujourd'hui, je bosse sous MicroStation. Si je dis ça, c'est qu'à mon avis, tu récupères l'ID de la définition du bloc et non celle de chaque instance du bloc (premier bloc de ce nom placé dans le dessin). Donc lui il doit pointer sur la définition ou sur le première instance. Tu ne dois pas utiliser la bonne méthode de l'objet. Mais tout ceci n'est que supposition, mais si je te parlais de Usta, c'est que ça marche comme ça dans les grandes lignes... Bon courage en espérant que ceci soit une piste de recherche. Mais je suis pas sûr en fait... Bacon Seuls les fous savent qu'ils ne sont pas fous...
dr.loveless Posté(e) le 8 octobre 2004 Auteur Posté(e) le 8 octobre 2004 J'ai pas compris, j'y connais rien en ID! Le DOC
Bacon Posté(e) le 8 octobre 2004 Posté(e) le 8 octobre 2004 Les ID : Tout produit graphique, ou du moins la plupart, travaillent en interne avec des identifiants (des numéros) pour pointer vers des éléments graphiques. Dans AutoCAD, tu peux très bien avoir un bloc en définition mais qui n'est pas encore placé dans le dessin. Cette définition a un identifiant (un ID), donc un numéro. Si tu places ce bloc dans le dessin, l'élément graphique "bloc" placé dans le dessin aura très certainement un autre numéro. Je pense même qu'il y en aura deux : un pour pointer vers la définition, l'autre pour l'élément graphique placé dans le dessin lui-même. Ainsi, je pense que ton scan se passe bien mais que l'ID que tu récupères est celui de la définition du bloc. If faudrait que tu utilises la complétion de code pour lister toutes les méthodes de ton objet VB et ainsi trouver celle qui pointe sur l'ID de ton instance. Exemple : Bloc "toto", ID de la définition : 12 Instances placées : nombre : 3 ID respectifs : 56, 73, 136 Tu récupères 12 et non chacun des ID de tes instances, soit 56, 73 et 136 Est-ce plus clair ? Bacon PS : Je ne suis quand même pas sûr que ce soit ça, mais la manière dont tu évoques ton problème me laisse penser qu'il s'agit de ça. Pour en être plus sûr, essaie de récupérer les coordonnées de l'origine de tes blocs. Si pour plusieurs instances tu as les mêmes origines, c'est que tu pointes vers ta définition... Seuls les fous savent qu'ils ne sont pas fous...
dr.loveless Posté(e) le 8 octobre 2004 Auteur Posté(e) le 8 octobre 2004 OK, j'ai pigé mais d'apres ce que tu dit, si j'ai X fois un bloc du même nom, je devrais avoir X ID différentes c'est bien çà? parceque quand je fais ma boucle et qu'il me repère un bloc, j'ai integrer un MSGBOX qui m'affcihe le numéro d'ID qu'il retourne. Et bien que soit ce 3 blocs du même nom, il me retourne 3 ID différentes, donc si j'ai bien compris le probleme que tu évoques est finalement celui que j'avais au début en effectuant une recherche par nom (et là effectivement il me faisait apparaitre 3 fois de suite le même nom). En revanche il existe aussi le handle, j'ai essayer avec mais çà n'a rien donné! [Edité le 8/10/2004 par dr.loveless] Le DOC
Bacon Posté(e) le 8 octobre 2004 Posté(e) le 8 octobre 2004 Bien, au moins un problème de bien localisé. Ce qu'il faut se dire, c'est que le seul moyen serait alors de passer par les ID qui eux sont bien différents et pointent donc bien vers tes différentes instances de blocs. Maintenant, il faudrait regarder dans l'aide VBA pour AutoCAD la méthode ThisDrawing. ObjectIdToObject(NomID) Il y a sans doute une conversion nécessaire de l'ID à faire pour obtenir autre chose et ce autre chose doit permettre de faire le Set ObjBlock = ... Car en fait, il faut aussi voir quel type d'élément retourne la fonction ThisDrawing.ObjectIdToObject. Retourne-t-elle vraiment un bloc ? Donc retourne-t-elle la même chose que la fonction ThisDrawing.Blocks ? Bacon Seuls les fous savent qu'ils ne sont pas fous...
dr.loveless Posté(e) le 8 octobre 2004 Auteur Posté(e) le 8 octobre 2004 Merci, en effet je pense également que le soluce passe par ObjectIDToObject, je me acharn depuis au moins 1 heure, mais rien n'y fais, je crois bien que je vais laisser, tombre, çà commence à me chauffer les oreilles! Merci encore ET pis non, j'vais insister , dois bien y avoir un moyen c dingue tout de même Le DOC
dr.loveless Posté(e) le 8 octobre 2004 Auteur Posté(e) le 8 octobre 2004 Le probleme est vraiment là : Set ObjBlock = ThisDrawing.Blocks(ObjElem.Name) Il faut que je trouve le moyen de faire le set objblock sans passer par Objelem.name car cell-ci me renvoi le nom du bloc de base!! [Edité le 8/10/2004 par dr.loveless] Le DOC
didier Posté(e) le 9 octobre 2004 Posté(e) le 9 octobre 2004 helloLeDocSansAmour nous a encore pondu un message ?*µ$£!§@"#~é&çu,mais comme on est des teigneux, on s'accroche et on s'y colle. Première questionNe serait-il pas intéressant de filtrer la sélectionen effet, des centaines de blocs différents peuvent contenir deux lignes,et ne sont sans doute pas concernés par ta requête.Et je ne te parle pas des blocs qui contiennent plus de deux lignes !!!! Deuxième questionSi, seulement un type de bloc est concerné par ton traitement,il est facile de connaître le milieu des deux lignes concernées,en rapport avec le point d'insertion de ce bloc et son angle de rotation,c'est une constanten'est ce pas ? faisons simple, et les entités seront bien gardéesen tenant compte de ces remarques,il va devenir aisé de traiter ton fichier.si je suis hors sujet, n'hésite pas à me le faire savoir.si ce n'est pas le cas, je veux bien t'aider...amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
dr.loveless Posté(e) le 11 octobre 2004 Auteur Posté(e) le 11 octobre 2004 Ben en fait il s'agit de plan dejà "nettoyer", donc les seuls blocs quils restent sont ceux qui m'interresse, donc pas de filtre, le seul filtre à effectuer est par rapport à l'attribut (le "remplissage" du bloc ce fait en fonction de celui-ci). Le probleme c'est que même si l'attribut est différent, le nom du bloc peut etre le même, donc quand je cherche le milieu des deux lignes il me retourne systématiquement le milieu des deux lignes du bloc de base ( le premier crée avec le nom concerné). Par exemple : J'ai 7 blocs du même nom, mais il y en a deux dont l'attribut n'est pas celui qui m'interresse. Il me dessinera alors que 5 lignes (çà j'y arrive), mais le probleme c'est qu'il me dessinne les lignes les unes sur les autres, tjs en reliant les milieu des lignes du premiers bloc!!! Sinon, je pensais, on doit pouvoir éviter le probleme en renommant chaque bloc du plan avec un nom propre à lieu (1 bloc = 1 nom), mais alors la taille de mon dessin va considérablement augmenter non?? [Edité le 11/10/2004 par dr.loveless] Le DOC
dr.loveless Posté(e) le 11 octobre 2004 Auteur Posté(e) le 11 octobre 2004 Voilà le programme apres rectification, He ben j'ai rarement autant galéré, pourtant çà parait tellement clair, en fait j'étais parti sur de mauvaises bases. Merci à tous Private Sub CommandButton1_Click() Dim ObjElem As ObjectDim ObjBlock As Object Dim A As Integer Dim Pt1L1 As VariantDim Pt2L1 As VariantDim Pt1L2 As VariantDim Pt2L2 As Variant Dim NomBlocAncien As String Dim PtDepart(0 To 2) As DoubleDim PtFin(0 To 2) As DoubleDim L1 As ObjectDim ModRemp As String Dim tablAttrib As Variant MoRemp = TxtRemp.TextB = 0Test = 0C = 0 For Each ObjElem In ThisDrawing.Blocks nbrebloc = ObjElem.Count For B = 0 To nbrebloc - 1 NomBloc = ObjElem.Item(B).NamePtInsertBloc = ObjElem.Item(B).InsertionPoint Set ObjBlock = ThisDrawing.Blocks(NomBloc) tablAttrib = ObjElem.Item(B).GetAttributes For Cptpm70 = LBound(tablAttrib) To UBound(tablAttrib) ' si vous préférez avoir la liste des étiquettes au lieu ' de leur valeur, remplacez TextString par TagString If tablAttrib(Cptpm70).TagString = "TYPE" Then TypeMod = tablAttrib(Cptpm70).TextString End If Next If TypeMod = MoRemp Then For Each objent In ObjBlock If objent.ObjectName = "AcDbLine" Then If A = 0 Then Pt1L1 = objent.StartPoint Pt1L1(0) = Pt1L1(0) + PtInsertBloc(0) Pt1L1(1) = Pt1L1(1) + PtInsertBloc(1) Pt2L1 = objent.EndPoint Pt2L1(0) = Pt2L1(0) + PtInsertBloc(0) Pt2L1(1) = Pt2L1(1) + PtInsertBloc(1) End If If A = 1 Then Pt1L2 = objent.StartPoint Pt1L2(0) = Pt1L2(0) + PtInsertBloc(0) Pt1L2(1) = Pt1L2(1) + PtInsertBloc(1) Pt2L2 = objent.EndPoint Pt2L2(0) = Pt2L2(0) + PtInsertBloc(0) Pt2L2(1) = Pt2L2(1) + PtInsertBloc(1) PtDepart(0) = (Pt1L1(0) + Pt2L1(0)) / 2 PtDepart(1) = (Pt1L1(1) + Pt2L1(1)) / 2 PtDepart(2) = 0 PtFin(0) = (Pt1L2(0) + Pt2L2(0)) / 2 PtFin(1) = (Pt1L2(1) + Pt2L2(1)) / 2 PtFin(2) = 0 Set L1 = ThisDrawing.ModelSpace.AddLine(PtDepart, PtFin) End If A = 1 + A End If Next End IfA = 0Next B Exit ForNext ObjElem Unload Me End Sub Le DOC
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