Bonjour,
Je cherche à savoir s'il est possible en VB.NET de faire un filtre de sélection sur un nom de bloc dynamique spécifique.
J'ai essayé de la manière suivante, mais ca n'a pas l'air de fonctionner.
Surement dû au renommage des blocs dynamique en "*U..."
Dim filter() As TypedValue = New TypedValue(1) {}
filter(0) = New TypedValue(0, "INSERT")
filter(1) = New TypedValue(2, "PL")
Par avance merci (à @_gile je suppose)
Yoan
Le titre du sujet a été modifié par un modérateur pour faciliter la recherche. Titre original:
VB.NET Filtre de sélection sur un nom de bloc dynamique spécifique
Yoan AUBRY
Résolu ! Accéder à la solution.
Résolu par _gile. Accéder à la solution.
Résolu par Y.AUBRY. Accéder à la solution.
Résolu par O_Eckmann. Accéder à la solution.
Bonjour @Y.AUBRY
Je n'ai pas accès au logiciel en ce moment pour vérifier, mais je pense qu'il faut se diriger vers la propriété "effectivename".
Amicalement
Didier Aveline
Bonjour,
normalement la sélection du nom de bloc est du type (pas d'AutoCAD sous la main pour vérifier)
"`*U*,PL"
Puis balayer chaque bloc et vérifier son effectivname
Olivier
PS : Code modifié pour ajouter l'astérisque nécessaire.
Olivier Eckmann
Bonjour @O_Eckmann,
J'ai testé mais ca n'a pas l'air de fonctionné non plus.
Je suis en train de lire l'article de Kean qui traite du sujet mais je pensais pouvoir faire cela plus simplement.
Mon code actuel est le suivant et il fonctionne en l'état même si d'autres blocs dynamiques sont pris en compte lors de la sélection. (le nom est ensuite filtré par la suite)
'Selection d'une liste de points levés
Function SELECT_LIST_PL() As List(Of ClPL)
Dim ListPL As New List(Of ClPL)
Dim doc As Document = AcadAp.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Try
Dim filter() As TypedValue = New TypedValue(1) {}
filter(0) = New TypedValue(DxfCode.Start, "INSERT") 'Filtre sur les blocs...
filter(1) = New TypedValue(DxfCode.BlockName, "`*U*,PL") '...uniquement dynamiques
'(le ",PL" sert à ajouter les blocs dynamiques PL qui n'aurait pas été modifié donc n'aurait pas un nommage type *U...)
Dim sf As SelectionFilter = New SelectionFilter(filter)
Dim psr As PromptSelectionResult = ed.GetSelection(sf)
Dim ss As SelectionSet = psr.Value
'Dans la séletion réalisée par l'opérateur, seuls les blocs dynamiques sont selectionnés/surlignés (hightlight)
'Tri dans la sélection
If ss.Count > 0 Then
Using tr As Transaction = doc.Database.TransactionManager.StartTransaction()
For Each id As ObjectId In ss.GetObjectIds()
Dim ent As Entity = TryCast(tr.GetObject(id, OpenMode.ForRead), Entity)
If TypeOf ent Is BlockReference Then
Dim acBlk As BlockReference = CType(ent, BlockReference)
Dim bname As String = ""
'La sélection ne contient que des blocs dynamique
Dim dynId As ObjectId = acBlk.DynamicBlockTableRecord
If dynId.IsNull Or dynId.IsErased Then
Continue For
End If
Dim dynbtr As BlockTableRecord = TryCast(tr.GetObject(dynId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), BlockTableRecord)
If dynbtr IsNot Nothing Then
bname = dynbtr.Name
End If
If bname = "PL" Then
If acBlk.Layer = "PL_TRA_CHGT" Or acBlk.Layer = "PL_TRA" Then
Dim PL As New ClPL
PL.LOAD_VAR_FROM_INFO(acBlk)
ListPL.Add(PL)
End If
End If
End If
Next
End Using
End If
Catch ex As System.Exception
MsgBox(ex.ToString)
End Try
Return ListPL
End Function
Cependant, ma demande de sélection sur un nom de bloc spécifique n'est toujours pas résolu
Merci tout de même
Yoan
Yoan AUBRY
En ajoutant un * après le U la sélection se fait sur tous les blocs (uniquement) dynamiques (on avance)
"`*U*,PL"
Yoan AUBRY
Salut,
Quel que soit l'environnement de programmation (LISP, .NET ou autre), on ne peut pas filtrer directement les blocs dynamiques avec une filtre de sélection.
Il faut donc, comme il a été dit, filtrer avec "`*U*,PL" pour sélectionner tous les blocs anonymes et les blocs "PL" (ceux dont aucune propriété dynamique n'a été modifiée. Ensuite on parcourt le jeu de sélection, pour contrôler que le nom de la définition du bloc source (DynamicBlockTableRecord) soit bien "PL".
foreach (var id in selection.Value.GetObjectIds())
{
var br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
var btr = (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
if (btr.Name == "PL")
{
//...
}
}
Bonjour @_gile ,
Ok, très bien... au moins je ne cherche pas plus loin dans ces cas là.
Je vais mettre la réponse d' @O_Eckmann comme solution car c'est ce qui m'a le plus aider dans mes recherches (mais il faudra qu'il pense à ajouter l' * manquant dans son code, mais merci à tous pour votre investissement.
Bon courage et à bientôt.
Yoan
Yoan AUBRY
Une solution plus élégante pour l'utilisateur qui sélectionne les objets est de gérer l'événement Editor.SelectionAdded pour filtrer les blocs au moment de la sélection (seuls les "bons blocs" sont mis en surbrillance).
void SelectionAdded(object sender, SelectionAddedEventArgs e)
{
var ids = e.AddedObjects.GetObjectIds();
using (var tr = new OpenCloseTransaction())
{
for (int i = 0; i < ids.Length; i++)
{
var br = (BlockReference)tr.GetObject(ids[i], OpenMode.ForRead);
var btr = (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
if (btr.Name != "PL")
{
e.Remove(i);
}
}
}
}
ed.SelectionAdded += SelectionAdded;
var selection = ed.GetSelection(filter);
ed.SelectionAdded -= SelectionAdded;
Vous n'avez pas trouvé ce que vous recherchiez ? Posez une question à la communauté ou partagez vos connaissances.