| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | | | PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
|
Autor
|
Thema: Linientypfaktor in Blockreferenz ändern (2500 mal gelesen)
|
Boehri Mitglied
Beiträge: 80 Registriert: 07.04.2008
|
erstellt am: 14. Dez. 2010 09:07 <-- editieren / zitieren --> Unities abgeben:
Hallo zusammen, ich möchte in der Zeichnung für alle Linien den Linientypfaktor auf 1 stellen. Dies habe ich auch mit folgtendem Code hinbekommen.
Code:
<CommandMethod("ltf1")> _ Public Sub SetLinentypfaktor21() '' Get the current document and database, and start a transaction Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = acDoc.Database Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() '' Open the Block table record for read Dim acBlkTbl As BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, _ OpenMode.ForRead) '' Open the Block table record Model space for read Dim acBlkTblRec As BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _ OpenMode.ForRead) Dim nCnt As Integer = 0 acDoc.Editor.WriteMessage(vbLf & "Model space objects: ") '' Step through each object in Model space and '' display the type of object found For Each acObjId As ObjectId In acBlkTblRec Dim ent As Entity = CType(acTrans.GetObject(acObjId, OpenMode.ForWrite), Entity) If ent.GetType.ToString Like "*.Line" Then ent.LinetypeScale = 1 End If nCnt = nCnt + 1 Next
'' If no objects are found then display the following message If nCnt = 0 Then acDoc.Editor.WriteMessage(vbLf & " No objects found") End If '' Dispose of the transaction acTrans.Commit() End Using End Sub
Nur ein Problem bleibt bestehen. Der Linientypfaktor in Blockreferenzen wird damit nicht geändert. Wie komme ich da dran, bzw. wie kann ich da vorgehen. Vielen Dank! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 14. Dez. 2010 10:25 <-- editieren / zitieren -->
Hi, hast Du eine Zeichnung vor und eine nach Deiner Konvertierung für uns? Bitte diese beiden ZIPpen und hier uploaden. - alfred - ------------------ www.hollaus.at |
Boehri Mitglied
Beiträge: 80 Registriert: 07.04.2008
|
erstellt am: 14. Dez. 2010 11:25 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied
|
erstellt am: 14. Dez. 2010 21:50 <-- editieren / zitieren -->
Hi, ich glaube, Du musst erst durch die AutoCAD-Objektstruktur durch, insbesondere wie ein Block in AutoCAD funktioniert. Mach Dich mal schlau, was eine BlockReference ist und was ein Block (Blockdefinition) ist. Hier der Code, den Du gewünscht hast ==> allen Blockreferenzen wird Linientypfaktor 1 zugewiesen:
Code: Using acTrans As DatabaseServices.Transaction = acCurDb.TransactionManager.StartTransaction() '' Open the Block table record for read Dim acBlkTbl As BlockTable = CType(acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead), BlockTable) '' Open the Block table record Model space for read Dim acBlkTblRec As BlockTableRecord = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord) Dim nCnt As Integer = 0 acDoc.Editor.WriteMessage(vbLf & "Model space objects: ") '' Step through each object in Model space and '' display the type of object found For Each acObjId As ObjectId In acBlkTblRec if (acObjId.isValid) andalso (not acObjId.isErased) then Dim ent As Entity = CType(acTrans.GetObject(acObjId, OpenMode.ForRead), Entity) If ent.LinetypeScale <> 1 Then CType(acTrans.GetObject(acObjId, OpenMode.ForWrite), Entity).LinetypeScale = 1 End If nCnt = nCnt + 1 end if Next '' If no objects are found then display the following message If nCnt = 0 Then acDoc.Editor.WriteMessage(vbLf & " No objects found") else acTrans.Commit() 'commit TransAction End If End Using
Beachte bei diesem Code folgende Änderungen verglichen zu Deinem:
a) Du hast ein IF dringehabt, das auf *LINE* geprüft hat ==> damit konnten keine Blockreferenzen modifiziert werden b) Mit For Each acObjId ... hast Du jede ObjectID behandelt ohne zu wissen, ob da nicht eventuell ein gelöschtes Element dahintersteht c) Du öffnest jedes Element mit Schreibrecht, damit wird intern das Element gelockt ==> kostet Zeit d) Du weist jedem Element den Linientypskalierfaktor 1 zu, auch wenn der schon auf 1 steht ==> kostet Zeit, da AutoCAD die Eigenschaft des Elements trotzdem ändert und das Element in die REGEN-Warteschlange stellen muss e) solltest Du mit Try-Catch-End Try arbeiten, es könnte ja z.B. sein, dass ein Element ev. auf einem gesperrten Layer liegt, dann wird Dir der Versuch, dem Objekt Änderungen beizubringen mit einer System Exception beantwortet ==> wichtig, das soll nicht als Kritik wirken, sonderen ist zum Lernen gedacht! ---------------------------------------- So und jetzt zum eigentlichen Thema: Läßt Du meinen Code laufen, dann erkennst Du (am besten mittels _QSELECT und nach Elementen suchen, deren Linientypskalierfaktor <> 1 ist), dass es keine Elemente mehr gibt, sprich allen Elementen ist der Linientypfaktor 1 zugewiesen, damit auch den BlockReferenzen. Und das Handicap dabei bleibt bestehen ==> die Linien in der Blockdefinition haben schon einen Linientyp <> 1 ==> und das kannst Du nur ändern, indem Du die Elemente innerhalb des Blocks (der Blockdefinition) durchscannst und bei bedarf korrigierst (hatten wir das nicht schon in einem Thread hier? ). HTH, alfred - ------------------ www.hollaus.at |
Boehri Mitglied
Beiträge: 80 Registriert: 07.04.2008
|
erstellt am: 15. Dez. 2010 13:27 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, erst mal recht herzlichen Dank für die ausführliche Kommentierung und die Zeit die es gekostet hat. Zitat: ==> wichtig, das soll nicht als Kritik wirken, sonderen ist zum Lernen gedacht!
Dafür auch vielen Dank, wie gesagt ich bin noch am Anfang und versuche mich hier etwas einzuarbeiten. Die Anmerkungen a - e sind mir jetzt klar.
Zitat: Und das Handicap dabei bleibt bestehen ==> die Linien in der Blockdefinition haben schon einen Linientyp <> 1 ==> und das kannst Du nur ändern, indem Du die Elemente innerhalb des Blocks (der Blockdefinition) durchscannst und bei bedarf korrigierst (hatten wir das nicht schon in einem Thread hier? ).
Aber wie du schon sagtest, das eigentliche Problem besteht für mich die Elemente der Blockdefintion durchzuscannen. Wie mache ich das? Ich steh hier voll auf dem Schlauch.
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 15. Dez. 2010 13:34 <-- editieren / zitieren -->
Hi, >> das eigentliche Problem besteht für mich die Elemente der Blockdefintion durchzuscannen. Wie mache ich das? Erinnere Dich an: - LinetypeTable & LinetypeTableRecords - LayerTable & LayerTableRecords Und jetzt setze das um auf - BlockTable & BlockTableRecords Scanne die BlockTable durch, dann bekommst Du alle Blockdefinitionen (BlockTableRecord) zur Bearbeitung. Eine kleine Prüfung, ob diese Blockdefinition geändert werden darf (z.B. dass es kein XRef-Objekt ist), ist diese änderbar, dann hinein in die Blockdefinition und die Elemente darin durchgehen und Linientypfaktor (bei bedarf) auf 1 setzen. Eigentlich hast Du mit obigem Beispiel das schon gemacht, aber eben nur für die Blockdefinition 'Modellbereich'. Erweitere es auf eben alle (modifizierbaren) Blockdefinitionen. - alfred - ------------------ www.hollaus.at |
Boehri Mitglied
Beiträge: 80 Registriert: 07.04.2008
|
erstellt am: 16. Dez. 2010 10:55 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, nach langem probieren habe ich einen lauffähigen Code erstellt. Code: <CommandMethod("bltf1")> _ Public Sub SetBlockLinentypfaktor21() '' Get the current document and database, and start a transaction Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = acDoc.Database Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() Try '' Open the Block table for read Dim acBlkTbl As BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) Dim nCnt As Integer = 0 Dim nCnt1 As Integer = 0 For Each acobjectID As ObjectId In acBlkTbl Dim acBlkTblRec As BlockTableRecord = acTrans.GetObject(acobjectID, OpenMode.ForRead) '' Step through each object in Model space and '' display the type of object found For Each acObjId As ObjectId In acBlkTblRec If acBlkTblRec.XrefStatus = XrefStatus.NotAnXref Then If (acObjId.IsValid) AndAlso (Not acObjId.IsErased) Then Dim ent As Entity = CType(acTrans.GetObject(acObjId, OpenMode.ForRead), Entity) If ent.LinetypeScale <> 1 Then CType(acTrans.GetObject(acObjId, OpenMode.ForWrite), Entity).LinetypeScale = 1 End If nCnt = nCnt + 1 End If End If nCnt1 = nCnt1 + 1 Next Next acDoc.Editor.WriteMessage(vbLf & nCnt1 & " Objekte gefunden") acDoc.Editor.WriteMessage(vbLf & nCnt & " Objekte geändert")
'Falls keine Objekte gefunden If nCnt = 0 Then acDoc.Editor.WriteMessage(vbLf & " Keine Objekte gefunden") Else acTrans.Commit() 'commit TransAction End If 'Zeichnung Regenerieren acDoc.SendStringToExecute("._REGEN ", True, False, False) Catch ex As Autodesk.AutoCAD.Runtime.Exception acDoc.Editor.WriteMessage(ex.Message) End Try End Using End Sub
ist bestimmt nicht schön aber er funktioniert. Vielen Dank für deine Hilfe.
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 16. Dez. 2010 11:02 <-- editieren / zitieren -->
Hi, ist ja super! Das REGEN wäre noch anders gegangen und die Zeile: CType(acTrans.GetObject(acObjId, OpenMode.ForWrite), Entity).LinetypeScale = 1 hätte ich jetzt noch in ein Try-Catch-End Try eingepackt. Hut ab, schnell gelernt! - alfred - ------------------ www.hollaus.at |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|