Aller au contenu

Pb Set avec ObjectID !!


Messages recommandés

Posté(e)

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 dessin

For 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

Posté(e)

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

 

Posté(e)

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

 

Posté(e)

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

Posté(e)

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

 

Posté(e)

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

Posté(e)

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

Posté(e)

hello

LeDocSansAmour nous a encore pondu un message ?*µ$£!§@"#~é&çu,

mais comme on est des teigneux, on s'accroche et on s'y colle.

 

Première question

Ne serait-il pas intéressant de filtrer la sélection

en 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 question

Si, 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 constante

n'est ce pas ?

 

faisons simple, et les entités seront bien gardées

en 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

Posté(e)

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

Posté(e)

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 Object

Dim ObjBlock As Object

 

Dim A As Integer

 

Dim Pt1L1 As Variant

Dim Pt2L1 As Variant

Dim Pt1L2 As Variant

Dim Pt2L2 As Variant

 

Dim NomBlocAncien As String

 

 

Dim PtDepart(0 To 2) As Double

Dim PtFin(0 To 2) As Double

Dim L1 As Object

Dim ModRemp As String

 

Dim tablAttrib As Variant

 

 

MoRemp = TxtRemp.Text

B = 0

Test = 0

C = 0

 

For Each ObjElem In ThisDrawing.Blocks

 

nbrebloc = ObjElem.Count

 

For B = 0 To nbrebloc - 1

 

NomBloc = ObjElem.Item(B).Name

PtInsertBloc = 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 If

A = 0

Next B

 

 

Exit For

Next ObjElem

 

Unload Me

 

End Sub

 

Le DOC

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é