| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Plotten von Layouts (2220 mal gelesen)
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 01. Feb. 2011 10:47 <-- editieren / zitieren --> Unities abgeben:
Hallo! Ich bekomme bei nachfolgendem Code wo ich Layouts drucke folgenden Fehler: Der Vorgang ist Aufgrund des aktuellen Zustands des Objekts ungültig wie dass? ich dachte using ist sicher... habe auch schon probiert statt den using in den finally block zu überprüfen ob das Objekt disposed wurde, wenn nicht, dann hätte ich es gemacht, selber Fehler... wahrscheinlich übersehe ich schon die ganze Zeit einen banalen Fehler...
Code:
Dim Doc As Document = Nothing Dim ed As Editor = Nothing Dim db As Database = Nothing Dim tr As Transaction = Nothing Dim pltInfo As PlotInfo = Nothing Dim pltSettings As PlotSettings = Nothing Dim pltSettingsValidator As PlotSettingsValidator = Nothing Dim pltInfoValidator As PlotInfoValidator = Nothing Dim bt As BlockTable = Nothing Dim doclock As DocumentLock = Nothing Dim btr As BlockTableRecord = Nothing Dim lo As Layout = Nothing Dim numSheet As Integer = 1 Try Doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument ed = Doc.Editor db = Doc.Database tr = Doc.TransactionManager.StartTransaction() Using tr bt = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) Using bt pltInfo = New PlotInfo() pltInfoValidator = New PlotInfoValidator() pltInfoValidator.MediaMatchingPolicy = MatchingPolicy.MatchEnabled If PlotFactory.ProcessPlotState = ProcessPlotState.NotPlotting Then Dim pltEngine As PlotEngine = PlotFactory.CreatePublishEngine() Dim layoutstoPlot As New ObjectIdCollection For Each btrId As ObjectId In bt btr = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) Using btr If btr.IsLayout And btr.Name.ToUpper() <> BlockTableRecord.ModelSpace.ToUpper() Then layoutstoPlot.Add(btrId) End If End Using Next 'Create a Progress Dialog to provide info 'and allow thej user to cancel Dim pltProgressDialog As PlotProgressDialog = New PlotProgressDialog(False, layoutstoPlot.Count, True) Using pltProgressDialog For Each btrId As ObjectId In layoutstoPlot btr = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) Using btr lo = CType(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout) Using lo pltSettings = New PlotSettings(lo.ModelType) pltSettings.CopyFrom(lo) pltSettingsValidator = PlotSettingsValidator.Current pltSettingsValidator.SetPlotType(pltSettings, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents) pltSettingsValidator.SetUseStandardScale(pltSettings, True) pltSettingsValidator.SetStdScaleType(pltSettings, StdScaleType.ScaleToFit) pltSettingsValidator.SetPlotCentered(pltSettings, True) pltInfo.Layout = btr.LayoutId Try LayoutManager.Current.CurrentLayout = lo.LayoutName Catch ex As Exception MsgBox(ex.Message & vbNewLine & ex.StackTrace) End Try pltInfo.OverrideSettings = pltSettings pltInfoValidator.Validate(pltInfo) If numSheet = 1 Then pltProgressDialog.PlotMsgString(PlotMessageIndex.DialogTitle) = "Custom Plot Progress" pltProgressDialog.PlotMsgString(PlotMessageIndex.CancelJobButtonMessage) = "Cancel Job" pltProgressDialog.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "Cancel Sheet" pltProgressDialog.PlotMsgString(PlotMessageIndex.SheetSetProgressCaption) = "Sheet Set Progress" pltProgressDialog.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "Sheet Progress" pltProgressDialog.LowerPlotProgressRange = 0 pltProgressDialog.UpperPlotProgressRange = 100 pltProgressDialog.PlotProgressPos = 0 ' Let's start the plot, at last pltProgressDialog.OnBeginPlot() pltProgressDialog.IsVisible = True pltEngine.BeginPlot(pltProgressDialog, Nothing) 'We'll be plotting a single document pltEngine.BeginDocument(pltInfo, Doc.Name, Nothing, 1, True, TargetFile) End If ' Which may contain multiple sheets pltProgressDialog.StatusMsgString = "Plotting " & _ Doc.Name.Substring(Doc.Name.LastIndexOf("\\") + 1) & _ " - sheet " & numSheet.ToString() & _ " of " & layoutstoPlot.Count.ToString() pltProgressDialog.OnBeginSheet() pltProgressDialog.LowerPlotProgressRange = 0 pltProgressDialog.UpperPlotProgressRange = 100 pltProgressDialog.PlotProgressPos = 0 Dim pltPageInfo As PlotPageInfo = New PlotPageInfo() pltEngine.BeginPage(pltPageInfo, pltInfo, numSheet = layoutstoPlot.Count, Nothing) pltEngine.BeginGenerateGraphics(Nothing) pltProgressDialog.SheetProgressPos = 50 pltEngine.EndGenerateGraphics(Nothing) pltEngine.EndPage(Nothing) pltProgressDialog.SheetProgressPos = 100 pltProgressDialog.OnEndSheet() numSheet += 1 End Using End Using Next pltEngine.EndDocument(Nothing) pltProgressDialog.PlotProgressPos = 100 pltProgressDialog.OnEndPlot() pltEngine.EndPlot(Nothing) End Using Else ed.WriteMessage("\nAnother plot is in progress.") End If End Using End Using Catch ex As Exception MsgBox(ex.Message & vbNewLine & ex.StackTrace) Finally End Try Return numSheet
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 01. Feb. 2011 11:43 <-- editieren / zitieren -->
Hi, >> Ich bekomme bei nachfolgendem Code wo ich Layouts drucke folgenden Fehler: Da wäre es hilfreich (vielmehr notwendig ) zu wissen, bei welcher Zeile der Fehler auftritt. Weiters probiere mal sicherheitshalber, ob das nur mit einer bestimmten Zeichnung passiert oder bei beliebigen (auch neuen) Zeichnungen; beim Plotten kann man nie ganz sicher sein (zumindest bin ich nie sicher, darum prüfe ich dieses immer vorher). - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 01. Feb. 2011 12:19 <-- editieren / zitieren --> Unities abgeben:
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Feb. 2011 08:44 <-- editieren / zitieren --> Unities abgeben:
Habe heruasgefunden woran es lag, wenn ich das Using bt weggebe, funktionierts. Verstehe ich nicht, ich dachte, das using kann ich bei allen objekten verwenden die ich disposen soll??? So der Plot läuft jetzt durch, pdf ist auch da, aber ich kann mir den pdf nicht ansehen, da er angeblich ungültig ist. Mein Druckertreiber war PDFCreator. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 02. Feb. 2011 09:24 <-- editieren / zitieren -->
Hi, USING - END USING ist (ich kanns aber nicht erklären) die noch härtere Variante als .DISPOSE, beides bedeutet 'Vernichte das Objekt' ==> Du willst aber in Deiner Zeichnung nur dereferenzieren (also auf Nothing setzen), aber Du willst nicht in Deiner Zeichnung den BlockTable kaputtmachen, oder? Wieso es mit PDFCreator nicht geht oder auch Dein anderer Thread sehe ich mir in der Nacht an, wenn kein anderer inzwischen löst. Krieg ich zeitlich jetzt nicht hin. - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Feb. 2011 09:39 <-- editieren / zitieren --> Unities abgeben:
okay, also eher von der Using - End Using Variante abstand halten und lieber im try - finally Block disposen? der Teil mit den Layouteinstellungen ist jetzt nicht so wichtig, warum der Plot einen fehlerhaften PDF erzeugt hingegen schon, denn das Problem kann ich nicht umgehen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 02. Feb. 2011 09:47 <-- editieren / zitieren -->
Hi, >> und lieber im try - finally Block disposen? ...gar nicht bt.Dispose machen! Ich sagte schon, Du willst die BlockTable Deiner Zeichnung doch nicht vernichten (sonst wäre Deine Zeichnung kaputt!). .Dispose wird nur auf Elemente angewendet, die endgültig vernichtet werden sollen. Deine BlockTable entlässt Du zwar aus Deinem Zugriff, Du vernichtest sie aber nicht. Erzeugst Du eine temporäre Linie um z.B. Schnittpunktberechnungen zu machen, Du fügst diese aber nicht dem Modellbereich hinzu, denn Du brauchst diese Linie nicht mehr nach den Berechnungen ==> dieser Linie weist Du mit .Dispose ihr Lebensdauerende zu, das ist OK. Auch die TransAction, wenn Du mit dem Umsetzen der Arbeit fertig bist, wird mit .Dispose vernichtet. Aber die Zeichnung selbst oder in der Zeichnung bestehende (und bestehend bleibende) Elemente bitte nicht (Auch wenn Autodesk das in den meisten Fällen in Ihrer API schon abfängt, es ist der falsche Ansatz). HTH, - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Feb. 2011 10:03 <-- editieren / zitieren --> Unities abgeben:
okay, danke also Objekte die ich mir hole über objid und nur auf einen Wert abprüfe z.b einen Block, oder ein Layout, sollen diese auch disposed werden oder nicht? ich brauche sie ja in dem sinne nicht mehr, aber bestehen bleiben sie ja noch in der Zeichnung. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 02. Feb. 2011 10:08 <-- editieren / zitieren -->
Hi, wenn Du Objekte aus der Zeichnung über TransAction mit ObjectID öffnet, dann brauchst/solltest Du .Dispose auf diese unterlassen. Eine Grundregel könnte sein (nur kurz darüber gedacht, könnte Ausnahmen geben): Was Du mit ... = New ... erstellst und nicht in die Zeichnung hineinschreibst ==> .Dipose JA - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Feb. 2011 14:17 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied
|
erstellt am: 02. Feb. 2011 14:20 <-- editieren / zitieren -->
Hi, nun wenn es bei Dir an verschachtelten TransActions liegt, dann werd ich mich zum Wolf probieren können und es nicht reproduzieren können. Schliess bitte mal verschachtelte TransActions aus und lass mich wissen, wie's dann geht. - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 02. Feb. 2011 14:54 <-- editieren / zitieren --> Unities abgeben:
ich habe keine verschachtelte transaktion, es laufen alle funktionen hintereinander ab. es gibt zwar in jeder funktion eine Transaktion, diese wird aber wieder beendet und freigegeben. Kannst du bitte diesen Code mal bei dir probieren ob er läuft? Bei mir stürzt er ab beim End Using vom tr, änder ich den Code aber folgendermaßen ab Code: tr = Doc.TransactionManager.TopTransaction()
läuft es ohne probleme durch, den pdf kann ich zwar nicht öffnen(mit PDFCreator erstellt) aber es existiert wenigstens mal einer Code:
<Autodesk.AutoCAD.Runtime.CommandMethod("mplot", CommandFlags.Transparent)> _ Public Sub MultiSheetPlot() Dim Doc As Document = Nothing Dim ed As Editor = Nothing Dim db As Database = Nothing Dim tr As Transaction = Nothing Dim pi As PlotInfo = Nothing Dim ps As PlotSettings = Nothing Dim psv As PlotSettingsValidator = Nothing Dim piv As PlotInfoValidator = Nothing Dim bt As BlockTable = Nothing Dim doclock As DocumentLock = Nothing Dim btr As BlockTableRecord = Nothing Dim lo As Layout = Nothing Dim numSheet As Integer = 1 Try Doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument ed = Doc.Editor db = Doc.Database tr = Doc.TransactionManager.StartTransaction() Using tr bt = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) pi = New PlotInfo() piv = New PlotInfoValidator() piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled If PlotFactory.ProcessPlotState = ProcessPlotState.NotPlotting Then Dim pe As PlotEngine = PlotFactory.CreatePublishEngine() Using pe Dim layoutsToPlot As ObjectIdCollection = New ObjectIdCollection() For Each btrId As ObjectId In bt btr = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) If btr.IsLayout And btr.Name.ToUpper() <> BlockTableRecord.ModelSpace.ToUpper() Then layoutsToPlot.Add(btrId) End If Next Dim ppd As PlotProgressDialog = New PlotProgressDialog(False, layoutsToPlot.Count, True) Using ppd For Each btrId As ObjectId In layoutsToPlot btr = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) lo = CType(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout) ps = New PlotSettings(lo.ModelType) ps.CopyFrom(lo) psv = PlotSettingsValidator.Current psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents) psv.SetUseStandardScale(ps, True) psv.SetStdScaleType(ps, StdScaleType.ScaleToFit) psv.SetPlotCentered(ps, True) psv.SetPlotConfigurationName(ps, lo.PlotConfigurationName, lo.CanonicalMediaName) '.Replace(" ", "_") pi.Layout = btr.LayoutId LayoutManager.Current.CurrentLayout = lo.LayoutName pi.OverrideSettings = ps piv.Validate(pi) If numSheet = 1 Then ppd.PlotMsgString(PlotMessageIndex.DialogTitle) = "Custom Plot Progress" ppd.PlotMsgString(PlotMessageIndex.CancelJobButtonMessage) = "Cancel Job" ppd.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "Cancel Sheet" ppd.PlotMsgString(PlotMessageIndex.SheetSetProgressCaption) = "Sheet Set Progress" ppd.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "Sheet Progress" ppd.LowerPlotProgressRange = 0 ppd.UpperPlotProgressRange = 100 ppd.PlotProgressPos = 0 ppd.OnBeginPlot() ppd.IsVisible = True pe.BeginPlot(ppd, Nothing) pe.BeginDocument(pi, Doc.Name, Nothing, 1, True, "C:\temp\test-" & Now.Day & Now.Month & Now.Year & "_" & Now.Hour & Now.Minute & Now.Second & ".pdf") End If ppd.StatusMsgString = "Plotting " & Doc.Name.Substring(Doc.Name.LastIndexOf("\\") + 1) & " - sheet " & numSheet.ToString() & " of " & layoutsToPlot.Count.ToString() ppd.OnBeginSheet() ppd.LowerSheetProgressRange = 0 ppd.UpperSheetProgressRange = 100 ppd.SheetProgressPos = 0 Dim ppi As PlotPageInfo = New PlotPageInfo() pe.BeginPage(ppi, pi, (numSheet = layoutsToPlot.Count), Nothing) pe.BeginGenerateGraphics(Nothing) ppd.SheetProgressPos = 50 pe.EndGenerateGraphics(Nothing) pe.EndPage(Nothing) ppd.SheetProgressPos = 100 ppd.OnEndSheet() numSheet += 1 Next pe.EndDocument(Nothing) ppd.PlotProgressPos = 100 ppd.OnEndPlot() pe.EndPlot(Nothing) End Using End Using Else ed.WriteMessage("\nAnother plot is in progress.") End If End Using Catch ex As System.Exception MsgBox(ex.Message & vbNewLine & ex.StackTrace) End Try End Sub
[Diese Nachricht wurde von veydan am 02. Feb. 2011 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 03. Feb. 2011 01:19 <-- editieren / zitieren -->
Hi, nur mal als Nachfrage: wieso soll ein Plot-Befehl transparent funktionieren (können)? ... in den CommandFlags hast Du diese Option aktiviert! Weitere Info: bei mir fliegt AutoCAD schon bei dieser Zeile im ersten Durchlauf ab:
Code: pe.EndPlot(Nothing)
Und zwar vollständiger Abflug, kein Debug, kein sonst irgendwas, AutoCAD verabschiedet sich mit einer 'unhandled exception' (und das wird nicht mal mehr angezeigt). Also läuft Dein Code bei mir nicht, ich vermute bestimmten Voraussetzungen sind zu setzen, die ich jetzt erst suchen müsste Hast Du bestimmte Zeichnungen? ...bestimmte Layouteinstellungen? ...bestimmte PC3-Einstellungen? Lass mich das wissen, wenn ich das jetzt suchen muss, wird's noch später. Was ich nicht machen würde (auch wenn es im INet einige solche Beispiele gibt): Eine TransAction offen zu haben, wenn ich den Plot-Befehl starte. Du hast zwar nur Elemente zum Lesen geöffnet, ich hätte trotzdem Sorge, dass der Plot-Durchgang ja auch alle Elemente in Zugriff braucht und da eine Zweigleisigkeit existiert, die ev. nicht gut ist. Damit könnte auch indirekt erklärbar sein, wieso es mit .TopTransAction bei Dir funktioniert.
Und dann wäre noch die Aussage mit .TopTransaction, wenn ich Deinen Code starte, dann sind die Anzahl der aktiven TransActions = 0, damit auch die .TopTransAction = Nothing .... wo kommt Deine .TopTransAction her? Sorry, - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 03. Feb. 2011 08:28 <-- editieren / zitieren --> Unities abgeben:
Hallo! Danke, dass du dir die ganze Mühe machst! Also warum ich Transparent nehme? Ehrlich gesagt, kann ich das nur so erklären, dass ich mal Code gepostet habe wo mit empfohlen wurde Transparent zu nehmen, leider konnte mir keiner erklären was welcher Commandflag bewirkt. Ich habe jetzt nochmal gesucht und für 2011 so eine Seite gefunden wo diese Beschrieben werden. Sollte ich dafür dann wahrscheilnich Session oder/und Modal nehmen? Also bestimmte Einstellungen habe ich nicht, ich habe das Kommando probiert mit eingestelltem Layout und PDFCreator und auch mit falschen Papierformat etc... und immer fiel ich beim End Using raus, allerdings genau so wie du, komplett weg. Oft ist der einzige Strohhalm an den man sich klammern kann ein Beispiel aus dem Internet... Wie würdest du denn das Beispiel gestalten, ohne laufender Transaction? Immer wieder neu aufbauen und bevor die Seite gedruckt wird wieder schließen? Von wo die Transaction herkommt weiß ich nicht, ich habe nur das Projekt debugged netload auf die .dll Zeichnung geöffnet, Befehl aufgerufen und das wars. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 03. Feb. 2011 09:43 <-- editieren / zitieren -->
Hi, >> mit eingestelltem Layout und PDFCreator Lass mir eine solche Zeichnung mal bitte zukommen. BTW: Bist Du noch immer auf 2009? Ich hab zwar zurückgeschaltet, von 2011 auf 2010, für älteres (2009) müsste ich was ausgraben gehen. - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 03. Feb. 2011 10:23 <-- editieren / zitieren --> Unities abgeben:
Hallo! Anbei die Zeichnung. Ich habe jetzt die Command Flags auf Modal gestellt, und die Transaction geöffnet, bevor ich die BT hole, dann geschlossen und bevor ich layout und btr wieder hole, geöffnet, danach gleich wieder geschlossen. Plot läuft durch, pdf kann aber nicht geöffnet werden, ist noch korrupt. Edit: Habe jetzt Acroplot Treiber versucht, da ist zwar der pdf mit 0 KB in dem Verzeichnis dass ich angegeben habe(in der pc3 und in der Programmierung) aber der richtige, wo was drinnen ist, ist im Verzeichnis wo die Zeichnung liegt mit dem Namen der .dwg Also der Plot funktioniert, der Rest dürfte ein Problem des Druckertreibers sein... mfg
[Diese Nachricht wurde von veydan am 03. Feb. 2011 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| |
Ex-Mitglied
|
erstellt am: 03. Feb. 2011 20:22 <-- editieren / zitieren -->
Hi, so, jetzt! Wie hatten schon mal >>>dieses<<< .... das mit Layout-Kopie oder im Layout direkt die Einstellungen, könnte mal ein Grund sein. Zur Beruhigung, ich hab auch mal von wo anders ein Beispiel abgekupfert (Deinem ähnlich, aber nicht gleich) ==> und auch da crasht AutoCAD, bist also nicht alleine. Ich hab Dir ein TXT beigelegt, das macht mal Plot vom aktuellen Layout nach DWF, und .... dieses funkt ohne Absturz, sollte also einmal eine Basis sein, mit der Du starten kannst (hoffe ich), arbeite halt von dieser Basis weiter. Vorsicht, Teile davon (die Zeilen mit tPltProcDlg.PlotMsgString) musst Du auf 2009 zurückbauen, da hat sich API geändert. Hoffe, das ist ein funktionierender Ansatz für Dich, viel Erfolg, - alfred - ------------------ www.hollaus.at |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|