| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| Request a special discount on NVIDIA RTX 5000 Ada Generation GPU !, eine Pressemitteilung
|
Autor
|
Thema: Nur im Debug-Modus korrekte Ergebnisse (1339 mal gelesen)
|
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005 Windows 10 Autocad 2015 - 2018 Athena 2015 - 2017 Aufsatz
|
erstellt am: 11. Feb. 2013 17:24 <-- editieren / zitieren --> Unities abgeben:
Hallo mal wieder, mir is grad etwas die Kinnlade heruntergefallen als ich meine ersten Codezeilen meines Programms, um aus einem bestimmten Block die Texte aller enthaltenen Mtexte zu erhalten, testen wollte. Im Debug-Modus (von .Net Express aus gestartet) erhalte ich alle 5 im testblock enthaltenen Texte. Starte ich AutoCAD jedoch normal und lade die DLL, gibt er mir nur zwei oder gar auch nur einen aus. Ich ahne hier einen grundlegenden Fehler meinerseits und den möchte ich nicht in andere Programme einschleppen. Kann mir jemand erklären warum, und was ich ändern muss? Der Code ist recht simpel:
Code: <CommandMethod("MyCommand", CommandFlags.Modal)> _ Public Sub MyCommand() ' This method can have any name Dim db As New Database(True, False) db.ReadDwgFile("C:\testdwg.dwg", FileOpenMode.OpenForReadAndAllShare, True, Nothing) Using actrans As Transaction = db.TransactionManager.StartTransaction Dim acBlkTbl As BlockTable = CType(actrans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) For Each blotbl As ObjectId In acBlkTbl 'Alle Objekte des Modellbereichs durchlaufen If TypeOf (blotbl.GetObject(OpenMode.ForRead)) Is BlockTableRecord Then 'Prüfen ob es ein Block ist Dim blorec As BlockTableRecord = CType(blotbl.GetObject(OpenMode.ForRead), BlockTableRecord) 'erhalten und merken If blorec.Name = "testblock" Then 'Name prüfen Dim textlst As New List(Of MText) 'Leere Liste vorbereiten For Each objid As ObjectId In blorec 'Alle Objekte im Block durchlaufen If TypeOf (objid.GetObject(OpenMode.ForRead)) Is MText Then 'Prüfen ob es ein Mtext ist Dim txt As MText = CType(objid.GetObject(OpenMode.ForRead), MText) 'erhalten und merken textlst.Add(txt) 'In der Liste anfügen MsgBox(txt.Text) 'Textinhalt ausgeben End If Next MsgBox(textlst.Count) 'Summe ausgeben End If End If Next End Using End Sub
Dwg ist angehängt (Bitte direkt auf C: platzieren oder Pfad ändern) ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
bccad Mitglied
Beiträge: 57 Registriert: 02.11.2009
|
erstellt am: 11. Feb. 2013 23:57 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
Hallo Andreas, Ich seh auf den ersten Blick auch nicht was hier falsch ist. Allerdings würde ich den Scan nach dem Block anders machen. Die ganze Zeichnung zu scannen kann bei großen Zeichnungen und langsamen Rechnern kritisch werden. Ich hab dir mal aufgeschrieben wie ich es machen würde. (Aber nur freihändig , schon zu spät zum Testen) Im ersten for-each wird in den Blockdefinitionen nach dem Testblock gesucht und mit einem Schwung alle IDs der in der Zeichnung enthaltenen Referenzen in eine Liste geladen. (oic) Im zweiten for-each scannst du dann nur noch in deinen Testblöcken. Der Rest ist wieder aus deinem Code. Ich hoffe das hielt dir irgendwie weiter. Mfg. Bernd
Code:
<CommandMethod("test")> Public Shared Sub test() Dim db As New Database(True, False) db.ReadDwgFile("c:\testdwg.dwg", FileOpenMode.OpenForReadAndAllShare, True, Nothing) Using tr As Transaction = db.TransactionManager.StartTransaction() Try Dim oic As ObjectIdCollection = Nothing Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead, False), BlockTable) For Each oid As ObjectId In bt If (oid.IsValid) AndAlso (Not oid.IsErased) Then Dim btr As BlockTableRecord = DirectCast(tr.GetObject(oid, OpenMode.ForWrite, False), BlockTableRecord) If UCase(btr.Name) = "TESTBLOCK" Then oic = btr.GetBlockReferenceIds(False, True) Exit For End If End If Next If (oic IsNot Nothing) AndAlso (oic.Count > 0) Then Dim textlst As New List(Of MText) 'Leere Liste vorbereiten For Each oid As ObjectId In oic If TypeOf (oid.GetObject(OpenMode.ForRead)) Is MText Then 'Prüfen ob es ein Mtext ist Dim txt As MText = CType(oid.GetObject(OpenMode.ForRead), MText) 'erhalten und merken textlst.Add(txt) 'In der Liste anfügen MsgBox(txt.Text) 'Textinhalt ausgeben End If Next MsgBox(textlst.Count) 'Summe ausgeben End If Catch MsgBox("Fehler beim Einlesen der Punkte") End Try End Using End Sub
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005 Windows 10 Autocad 2015 - 2018 Athena 2015 - 2017 Aufsatz
|
erstellt am: 12. Feb. 2013 08:42 <-- editieren / zitieren --> Unities abgeben:
Hallo Bernd, klar, nur die Blockdefinitionen statt aller Zeichnungsobjekte zu durchlaufen klingt plausibel. Allerdings dachte ich dass ich nur Blockdefinitionen erhalte wenn ich einen Blocktable durchlaufe. Aber man lernt ja nie aus ^^ Ich werd deinen Vorschlag gleich testen. ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005
|
erstellt am: 12. Feb. 2013 09:37 <-- editieren / zitieren --> Unities abgeben:
Hallo Bernd, habe deinen Code getestet. Du hast mich leider falsch verstanden. Dein Code über die ObjectIDCollection liefert mir alle Platzierungen des Blocks "Testblock" und nicht dessen Inhalt. Wieviele Platzierungen von dem Block in der Zeichnung sind ist mir egal, ich möchte nur wissen wieviele und welche MTexte in dessen Blockdefinition enthalten sind. Warum ich im Normalbetrieb ein falsches Ergebnis erhalte, im Debugmodus jedoch alles stimmt ist mir leider auch dadurch nicht klar geworden. ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005 Windows 10 Autocad 2015 - 2018 Athena 2015 - 2017 Aufsatz
|
erstellt am: 12. Feb. 2013 17:01 <-- editieren / zitieren --> Unities abgeben:
Hallo, auf Bernds Anregung hing konnte habe ich meinen Code bezüglich dem Blockzugriff optimiert (geht ja wunderbar über eine Zeile). Nach wie vor aber gibt mir das Programm im nicht-Debug-Modus falsche Anzahlen der im Block enthaltenen Texte aus. Das geht sogar soweit dass es bei mehrfachem Ausführen unterschiedliche Ergebnisse liefert. Ich bitte weiterhin um Hilfe! Code: <CommandMethod("MyCommand", CommandFlags.Modal)> _ Public Sub MyCommand() ' This method can have any name Dim db As New Database(True, False) db.ReadDwgFile("C:\testdwg.dwg", FileOpenMode.OpenForReadAndAllShare, True, Nothing) Using actrans As Transaction = db.TransactionManager.StartTransaction Dim acBlkTbl As BlockTable = CType(actrans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) Dim blorec As BlockTableRecord = CType(acBlkTbl.Item("testblock").GetObject(OpenMode.ForRead), BlockTableRecord) 'erhalten und merken Dim textlst As New List(Of MText) 'Leere Liste vorbereiten For Each objid As ObjectId In blorec 'Alle Objekte im Block durchlaufen If TypeOf (objid.GetObject(OpenMode.ForRead)) Is MText Then 'Prüfen ob es ein Mtext ist Dim txt As MText = CType(objid.GetObject(OpenMode.ForRead), MText) 'erhalten und merken textlst.Add(txt) 'In der Liste anfügen MsgBox(txt.Text) 'Textinhalt ausgeben End If Next MsgBox(textlst.Count) 'Summe ausgeben End Using End Sub
------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005
|
erstellt am: 12. Feb. 2013 17:34 <-- editieren / zitieren --> Unities abgeben:
OK, Leute, ich hab die Lösung!!!!!!!! Es war die Messagebox!! Ich habe Sie durch Editor.WriteMessage ersetzt und siehe da, die Anzahlen stimmen jedesmal!!! Hat dafür jemand ne Erklärung??? Und jetzt sind glaub ich die Philosophen dran Der neue Code:
Code: <CommandMethod("MyCommand", CommandFlags.Modal)> _ Public Sub MyCommand() ' This method can have any name Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor 'Für die Meldungsausgabe Dim db As New Database(True, False) db.ReadDwgFile("C:\testdwg.dwg", FileOpenMode.OpenForReadAndAllShare, True, "") Using actrans As Transaction = db.TransactionManager.StartTransaction Dim acBlkTbl As BlockTable = CType(actrans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) Dim textlst As New List(Of MText) 'Leere Liste vorbereiten Try Dim blorec As BlockTableRecord = CType(acBlkTbl.Item("testblock").GetObject(OpenMode.ForRead), BlockTableRecord) 'erhalten und merken For Each objid As ObjectId In blorec 'Alle Objekte im Block durchlaufen ed.WriteMessage("Prüfe Object") If TypeOf (objid.GetObject(OpenMode.ForRead)) Is MText Then 'Prüfen ob es ein Mtext ist Dim txt As MText = CType(objid.GetObject(OpenMode.ForRead), MText) 'erhalten und merken textlst.Add(txt) 'In der Liste anfügen ed.WriteMessage(" => Text: " & txt.Text) 'Textinhalt ausgeben End If ed.WriteMessage(Environment.NewLine) Next
ed.WriteMessage("Anzahl Texte: " & textlst.Count) 'Summe ausgeben Catch ed.WriteMessage("Block ""Testblock"" nicht vorhanden.") End Try End Using End Sub
------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
bccad Mitglied
Beiträge: 57 Registriert: 02.11.2009
|
erstellt am: 12. Feb. 2013 21:58 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
|
oscarr Mitglied CAD-Manager
Beiträge: 198 Registriert: 02.10.2007 ACA 2012 - English Win 7/x64
|
erstellt am: 13. Feb. 2013 16:38 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
Hm, das ist ja spannend. Versuch mal: Code:
System.Windows.Forms.MessageBox.Show(txt.Text)
die msgbox ist eine function aus dem Microsoft.VisualBasic.Interaction Namespace. Die steht der nur im debug modus zur verfügung (via vshost.exe). LG Holger
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005
|
erstellt am: 14. Feb. 2013 08:40 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger, interessanter Ansatz, aber
Code: System.Windows.MessageBox.Show(txt.text)
hat leider den selben (schlechten) Effekt. ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
bccad Mitglied
Beiträge: 57 Registriert: 02.11.2009
|
erstellt am: 14. Feb. 2013 11:31 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
Hi Andreas, >> hat leider den selben (schlechten) Effekt. << Ist das in allen ACAD-Versionen so oder nur in der aktuellen ?? Gib mal die Daten, statt in der MessageBox, in eine Datei aus und guck mal was da tatsächlich drinsteht. Bernd Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005 Windows 10 Autocad 2015 - 2018 Athena 2015 - 2017 Aufsatz
|
erstellt am: 14. Feb. 2013 11:38 <-- editieren / zitieren --> Unities abgeben:
Getestet hab ich's nur in der 2013er AcadVersion. Von anderen weis nicht wie sie sich verhalten. Die Dateiausgabe kann ich abkürzen, wie oben beschrieben hab ich die Meldungen mal alle in Prompts in die Befehlszeile umgeleitet => Ergebnis, alles I.O., alle Mtexte werden aufgelistet. Sprich: Benutze Messageboxen: "Gefundene Mtexte:" zwischen 1 und 3 Stück Benutze Befehlszeilenmeldung: "Gefundene Mtexte: 5" <= korrektes Ergebnis ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
oscarr Mitglied CAD-Manager
Beiträge: 198 Registriert: 02.10.2007 ACA 2012 - English Win 7/x64
|
erstellt am: 14. Feb. 2013 15:04 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
Das ja totaler Bullshit was ich da geschrieben habe. Sorry. Vielleicht ist es eher ein trigger Problem, AutoCAD rennt schneller durch die schleife als es die msgbox generieren kann. Ich habe jetzt mal ein paar Compileroptionen durchgespielt (denn dort liegen ja die Unterschiede zwischen DEBUG und RELEASE). [EDIT]
mit eingeschalteten TRACE und ohne Optimierung scheint es immer zu funktionieren. Sicher bin ich da aber nicht. Egal welche compiler option, debugt man es mit VisuaöStudio dann geht es sonst nicht [/EDIT] LG Holger [Diese Nachricht wurde von oscarr am 14. Feb. 2013 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |