| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Batchprogramm (1309 mal gelesen)
|
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 21. Jan. 2009 12:58 <-- editieren / zitieren --> Unities abgeben:
Hallo zusammen Ich habe ein Problem mit einem Batchprogramm. Ich öffne alle DXF-Files die ich in einem Verzeichnis finde um diese zu konvertieren. Nun mein Problem: Ist eine DXF-Files kaputt (DXF-Files kommen auch aus Fremdsystemen ) was öfter mal vorkommt, dann bleibt mein Batchprogramm stehen und im Autocad kommt die Meldung Zeichnung kann nicht geöffnet werden. Gibt es eine Möglichkeit, wie ich aus VB vorab prüfen kann ob das DXF-File ok ist oder wie ich auf die Meldung aus dem Autocad reagieren kann damit mein Batchprogramm weiterläuft? Gerhard
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 21. Jan. 2009 13:06 <-- editieren / zitieren -->
Hi Gerhard, zeigst Du mal das Codeschnippsel, in dem Du öffnest und wieder schliesst? Ich hätte (wenn Layouts im DXF nicht vorhanden sind, sondern nur Modellbereich notwendig ist), nicht DXF geöffnet, sondern eine leere Zeichnung gestartet und das DXF mittels insert eingefügt, dann bekomme ich im Falle eines Fehlers einen ganz normalen RunTime-Fehler mit description, das ist mit 'On Error Resume Next' abzufangen. - alfred - ------------------ www.hollaus.at |
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 21. Jan. 2009 13:49 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, ein guter Ansatz, aber ich verwende eine ähnlichen Batch auch für das Plotten von Zeichnungen und da habe ich das selbe Problem wenn eine Zeichnung kaputt ist. Anbei ein Codeauszug aber aus eine DB ist aber egal, Public Sub machBilder() Dim SQL As String Dim z As Integer Dim t1, t2 As String SQL = ("select Dokumentennummer, dateiname from DB where Dokumentennummer = '11111' order by Dokumentennummer;") Set rs = CreateObject("adodb.recordset") Set con = CreateObject("adodb.connection") con.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID......." Set rs = con.Execute(SQL) While Not rs.EOF On Error Resume Next t2 = rs!dateiname 'So öffne ich auch die DXF-Files AutoCAD.Documents.Open t2, True 'Mit diesem Sub erstelle ich PNG-Dateien je Layout 'für unser ERP-System Call pngPlot ThisDrawing.Close False rs.MoveNext Wend con.Close Set con = Nothing Set rs = Nothing End Sub Hoffe du kannst was damit anfangen. Gerhard Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 21. Jan. 2009 13:58 <-- editieren / zitieren -->
Hi Gerhard, Code: On Error Resume Next t2 = rs!dateiname 'So öffne ich auch die DXF-Files AutoCAD.Documents.Open t2, True 'Mit diesem Sub erstelle ich PNG-Dateien je Layout 'für unser ERP-System Call pngPlot ThisDrawing.Close False
wenn ich es (ohne zu probieren) richtig verstehe, dann solltest Du eigentlich folgendes ändern können:
Code: AutoCAD.Documents.Open t2, True if Err.Number = 0 then 'nur plotten, wenn problemlos geöffnet Call pngPlot ThisDrawing.Close False else Err.Clear Call debug.print("Fehler bei Zeichnung " & t2) 'oder wie auch immer Deine Fehlermeldungen geschrieben werden sollen end If
geht das so nicht? - alfred -
------------------ www.hollaus.at |
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 22. Jan. 2009 11:24 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, vorab mal danke für das Beispiel, aber leider ist es nicht so einfach. Damit du mein Problem nachvollziehen kannst: Erstelle von einer einfachen Zeichnung ein DXF-File, editier das File und lösche wahllos einige Zeilen auf den DXF-File und speicher das File danach. Jetzt versuch das DXF-File mit deinem VAB-Code zu öffnen, du wirst sehen, das Autocad wartet auf eine Eingabe und das VBA-Programm wird angehalten bis im Autocad eine Escape oder Enter eingegeben wird. Vielleicht kannst du mir ja noch einen Tipp geben wie ich mit diesem Problem weiterkommen könnte. Lg. Gerhard Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 22. Jan. 2009 11:29 <-- editieren / zitieren -->
Hi, dann mach den anderen Weg, den ich vorgeschlagen habe: - neue Zeichnung erstellen - DXF mit insert einfügen, das sollte keinen Dialog hochbringen. - alfred - ------------------ www.hollaus.at |
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 22. Jan. 2009 11:50 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, ich habe 7 Routinen laufen die auch Zeichnungen plotten (aus Layouts) die kann ich leider nicht mit Insert einfügen. Der Tipp ist bei den DXF-Files schon OK, aber leider nicht überall verwendbar. Wir haben auch hin und wieder das Problem, dass wir von externen Firmen Zeichnungen bekommen die mit einer Schulungsversion erstellt wurden. Dann habe ich ein ähnliches Phänomen, Autocad wartet auf eine Eingabe. Toll wäre es, zB nach 2 Minuten passiert einfach ein Escape ans Autocad zu senden wenn das Programm stoppt. Lg. Gerhard Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 22. Jan. 2009 11:55 <-- editieren / zitieren -->
Hi, Workaround, das mir jetzt einfällt: mach den Schritt mit DXF-Einfügen in neue leere Zeichnung, wenn Du dann eine Exception bekommst (und diese sollte dann nicht den Dialog von AutoCAD unterbrechen), dann weisst Du, dass das DXF nciht zu öffnen ist. Funktioniert es doch, dann kannst Du ja das DXF mit 'Documents.Open' öffnen, dann weisst Du ja schon dass es funkt. Anderes Workaround wäre, dass Du versucht, mit Windows-API's Fenster zu überwachen und dann mit WindowsMessages (so glaube ich, dass der Name ist, stehe damit gerade auf der Leitung) das 'OK' in dem Dialog virtuell drückst. - alfred - ------------------ www.hollaus.at |
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 22. Jan. 2009 12:30 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied
|
erstellt am: 22. Jan. 2009 12:45 <-- editieren / zitieren -->
Hi, noch eine Idee: z.B. Civil3D hat einen Batch-Converter (ähnliche gibt's auch als Freeware in Internet), da könntest Du ja einen Durchlauf loslassen, der Dir mal DXF in DWG konvertiert, dann weisst Du, dass es mal lesbar ist, denn mein Workaround wird bei vielen und großen DXF's wohl ein wenig langsam sein. Die Konverter sollten bei fehlerhaften DXF's nicht 'steckenbleiben'. - alfred - ------------------ www.hollaus.at |
jakob schaaf Mitglied DIpl. Ing.
Beiträge: 49 Registriert: 05.08.2003
|
erstellt am: 28. Jan. 2009 10:24 <-- editieren / zitieren --> Unities abgeben: Nur für gerhard123
Hallo, wir machen das so (entweder die Methode 1 oder 2): 1) vor dem ACAD-Aufruf, eine externe EXE Starten die, nach einer bestimmten Zeit ACAD killt. Ist ACAD vorher fertig, dann den Killer killen. 2) Starten von ACAD mittels Script, und ggf. killen des ACAD nach einer gewissen Zeit. Hier einige Auszüge: ... taskID = ExecuteTask(AUTOCAD & " /b " & pfad & DateiName) --> ACAD starten, mittels script While IsTaskRunning(taskID) If Zeit2 - Zeit1 > Val(TIMEOUT) Then Call KillACAD("AutoCAD - [Zeichng.dwg]") ... Public Function ExecuteTask(Path As String, Optional Parameters As String = "") As Long Dim proc As PROCESS_INFORMATION Dim startup As STARTUPINFO Dim ret As Long Dim cmdline As String cmdline = Path If Trim(Parameters) <> "" Then cmdline = cmdline & Parameters ' Initialize the STARTUPINFO structure: startup.cb = Len(startup) ' Start the application: ret = CreateProcessA(0&, cmdline, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, startup, proc) ExecuteTask = proc.hProcess End Function Public Function IsTaskRunning(taskID As Long) As Boolean 'OK Dim ret As Long If taskID = 0 Then Exit Function ret = WaitForSingleObject(taskID, 0) IsTaskRunning = (ret <> 0) If Not IsTaskRunning Then ret = CloseHandle(taskID): taskID = 0 End Function Private Sub KillACAD(ByVal Zeichnung) Dim strClassName As String Dim strWinTitle As String strClassName = "Afx:400000:8:10011:0:7e4022d" strWinTitle = Zeichnung If Not KillApp(strClassName, strWinTitle) Then Zeichnung = Zeichnung End Sub PS: Die zweite Methode läuft mit ACAD R14 !!! mfg Jakob
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 28. Jan. 2009 11:00 <-- editieren / zitieren --> Unities abgeben:
Hallo Jakob, vorab mal Danke für deinen Tip. Wenn ich zB. mittels Datenbank die Zeichnungen die zu konvertierenten sind (select ..... where... order bei zng) aus der DB ermittle und ich deine Varianten umsetzte, dann würde mir doch jedesmal bei der selben Autocad ZNG das Autocad gekillt und alle Zeichnungen nach der Problemzeichnung würden nicht mehr konvertiert. mfg Gerhard Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
jakob schaaf Mitglied DIpl. Ing.
Beiträge: 49 Registriert: 05.08.2003 ACAD-INV 2010-12 XP + W7
|
erstellt am: 28. Jan. 2009 14:24 <-- editieren / zitieren --> Unities abgeben: Nur für gerhard123
Hallo Gerhard. Es kommt auf die Fehlerhandhabung an. Mit (select ..... where... order bei zng) hast Du, z.B: ein Tabelle, die Du mit einer While Schleife durchläufst. Beim Auftreten eines Fehlers, solltest Du ihn loggen und die Schleife weiter abarbeiten lassen. Du kannst ja, z.B: AutoCAD starten, konvertieren, AutoCAD beenden und dann zum nächsten Datensatz springen. Das Öfnnen und Schliessen von ACAD ist natürlich langsammer, aber mit Der Fehlerhandhabung ist es besser zu händeln. mfg Jakob
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 29. Jan. 2009 07:24 <-- editieren / zitieren --> Unities abgeben:
|
jakob schaaf Mitglied DIpl. Ing.
Beiträge: 49 Registriert: 05.08.2003 ACAD-INV 2010-12 XP + W7
|
erstellt am: 29. Jan. 2009 11:03 <-- editieren / zitieren --> Unities abgeben: Nur für gerhard123
Hallo Gerhard, was dies bedeutet <AutoCAD.Documents.Open t2, True>, das weiss ich nicht, aber hier könntest Du deinen Code erweitern. z.B: Zeit1 = ... taskID = ExecuteTask("C:\programme\AutoCADR14\acad.exe" & " /b " & pfad & DateiName) While IsTaskRunning(taskID) Zeit2 = ... If Zeit2 - Zeit1 > Val(TIMEOUT) Then Call KillACAD("AutoCAD - [Zeichng.dwg]") ... Ich verwende hier einige API funktionen, bitte selbst danach googeln. Hier noch eine Function: Function KillApp(AppClass As String, WinTitle As String) As Boolean Dim hwnd As Long, lRet As Long Dim ProcessId As Long, hProcess As Long Dim ThreadId As Long 'per Class Name: 'hWnd = FindWindow(AppClass, vbNullString) 'per Window Title: hwnd = FindWindow(vbNullString, WinTitle) 'mit beiden: 'hwnd = FindWindow(AppClass, WinTitle) If hwnd <> 0 Then 'existiert ein Fenster? lRet = PostMessage(hwnd, WM_CLOSE, 0, 0) lRet = WaitForSingleObject(hwnd, 100) DoEvents Else 'kein Fenster gefunden KillApp = False Exit Function End If 'Wenn Fenster noch da --> hängenden Process terminieren: If IsWindow(hwnd) Then ThreadId = GetWindowThreadProcessId(hwnd, ProcessId) hProcess = OpenProcess(PROCESS_TERMINATE, 0, ProcessId) lRet = TerminateProcess(hProcess, 0) lRet = CloseHandle(hProcess) End If KillApp = True End Function mfg Jakob
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Konstrukteur (m/w/d) | Die Günther Maschinenbau entwickelt und fertigt mit ihren ca. 75 Mitarbeiter*innen technische Lösungen für die Lebensmittelindustrie und den handwerklichen Sektor. Im Mittelpunkt des Leistungsspektrums stehen Maschinen und Anlagen für das Pökeln, Tumbeln und Coaten. Ob Fleisch, Geflügel, Fisch, Käse, Convenience oder Vegetarisches, wir kennen die speziellen Anforderungen ... | Anzeige ansehen | Konstruktion, Visualisierung |
|
gerhard123 Mitglied techn.Angestellter
Beiträge: 151 Registriert: 29.11.2007
|
erstellt am: 29. Jan. 2009 11:09 <-- editieren / zitieren --> Unities abgeben:
|
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|