PhilOctet Posté(e) le 19 février 2010 Posté(e) le 19 février 2010 Bonsoir à tous, Mon p'tit programme de traitement de mes fichiers dessin AutoCAD tourne. Je passe dans une phase de test avec l'environnement. Notamment, je détourne les sauvegardes afin d'y appliquer une partie de ces traitements. Bref, dans la série des 'QSave', il y a la commande 'eTransmit' qui déclenche une sauvegarde. La variable 'cmdnames' nous donne la commande en cours. Mais lorsque j'arrive sur l'évênement 'BeginSave', ce n'est pas la commande 'eTransmit' qui est donné par la variable mais la commande 'QSave'.Comment puis-récupérer la "vraie" commande déclenchée à savoir' eTransmit' ? Ce que voudrait faire : L'opérateur lance la commande eTransmit qui déclenche un QSave. le programme prendre en charge la sauvegarde et relance l'eTransmit et crée enfin le zip. Je pensais aussi utiliser la variable 'DBMod' mais je ne vois pas comment l'intégrer dans ma routine. A moins que quelqu'un ai une meilleur idée ! merci et à bientôt
(gile) Posté(e) le 19 février 2010 Posté(e) le 19 février 2010 Salut, Quel type d'évènement utilises tu ? Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 Bonjour, Mes collègues font souvent des sauvegardes de leur dessin. Ce qui est une bonne chose. Je déclenche un traitement à chaque sauvegarde. En voici le code. Module Module1 ' récupère le chemin du dessins courant Public DWGPath As String Public DWGName As String Public DWG As String '' Executer à chaque ouverture d'un dessin (nouveau ou existant)Public Sub OnDocumentCreated(ByVal sender As Object, ByVal e As DocumentCollectionEventArgs) Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument AddHandler acDoc.BeginDocumentClose, AddressOf docBeginDocClose Dim acDb As AcBdd.Database = acDoc.Database AddHandler acDb.BeginSave, AddressOf docBeginSave End Sub '' Executer à chaque fermeture de fenetre de dessinPublic Sub docBeginSave() Dim CmdNames As String = Application.GetSystemVariable("cmdnames") Dim DBMod As Integer = Application.GetSystemVariable("dbmod") Debug.Print (CmdNames & " / " & DBMod) Dim acDoc As Document = AcApp.DocumentManager.MdiActiveDocument ' récupère le chemin du dessin courant DWGPath = Application.GetSystemVariable("DwgPrefix") DWGName = Application.GetSystemVariable("DwgName") DWG = AF_ScanLAN.strLanPath(DWGPath & DWGName) Call Traitements() End Sub Il y a surement d'autres façons de faire. Et tout aussi surement plus classe. Avez-vous une idée à me proposer ? Merci de votre soutient et au plaisir de vous lire.
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 Salut, Je ne comprends pas la demande.Je t'avais donné un exemple ici pour garantir que tous les documents ouverts au chargement de l'application et tous ceux qui seront ouverts par la suite seront abonnés à l'évènement. D'autre part, j'ai du mal à lire le VB d'autant plus qu'il est présenté dans le corps du message, sans identations.S'il te plait utilise les balises bbcode : [surligneur][[/surligneur][surligneur]code[/surligneur][surligneur]][/surligneur] ici le code [surligneur][[/surligneur][surligneur]/code[/surligneur][surligneur]][/surligneur] donne : ici le code Accessibles avec l'icône # : http://img94.imageshack.us/img94/8380/bbcode.png Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 De ce que j'arrive à voir, tu n'utilises pas ce qui existe déjà... Tu devrais pouvoir remplacer :Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument AddHandler acDoc.BeginDocumentClose, AddressOf docBeginDocClose Dim acDb As AcBdd.Database = acDoc.Database AddHandler acDb.BeginSave, AddressOf docBeginSavepar :AddHandler e.Document.Database.BeginSave, AddressOf docBeginSavepuis que tu ne semble pas utiliser docBeginDocClose. Et, de même :DWGPath = Application.GetSystemVariable("DwgPrefix") DWGName = Application.GetSystemVariable("DwgName") DWG = AF_ScanLAN.strLanPath(DWGPath & DWGName)par :DWG = AF_ScanLAN.strLanPath(e.FileName) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 Les procédures de traitement avec BeginSave se déclenchent lorsque qu'il le faut, même pendant l'eTransmit.Il m'avait sembler avoir considéré tes conseils du message dans la réponse n°3 de http://cadxp.cadmag.info/XForum+viewthread-fid-42-tid-26409-page-2.html Toutefois, le tout fonctionne bien. Cela pourrait être mieux soit, mais ca roule !Aussi j'ai d'autres traitements pour la fermeture du dessin sans sauvegarde. Mais dans mon cas de figure, ce n'est pas 'eTransmit' qui effectue la sauvegarde. La commande repose la question de sauvegarde sans fin jusqu'à la pression de la touche annuler. Donc la sauvegarde n'est pas effectuée par 'eTransmit' et la commande est interrompue. Donc je ne peux plus genérer de 'eTransmit'. Ce qui est un drame pour mon outil. Comment faire ?
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 Si tu as une instruction SaveAs dans ton traitement, elle déclenchera indéfiniment l'évènement BeginSave (boucle sans fin).Soit tu supprimes cette instruction du traitement, soit tu désabonnes docBeginSave de l'évènement BeginSave avant l'instruction SaveAs et tu le réabonnes ensuite. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 C'est ce je cherche à faire. Mais, pour l'instant, que lors de l'appel à la fonction 'eTransmit'. Non, je ne fais pas de sauvegarde dans mes traitements puisque c'est AutoCAD que s'en charge. Je pensais pouvoir récupérer le nom de la commande 'eTransmit' dans la variable 'cmdnames'. Ce que je récupère est en fait 'QSave' puisque 'eTransmit' lance la commande 'QSave'. Comment ne pas effectuer les traitements liés aux sauvegardes lors de l'appel de 'eTransmit' ? Merci [Edité le 20/2/2010 par PhilOctet]
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 Non, je ne fais pas de sauvegarde dans mes traitements C'est curieux que tu rentres dans une boucle sans fin alors :casstet: Essaye ca, le traitement se limite à ouvrir une boite d'alerte signifiant que l'évènement est déclenché la boite de dialogue s'affiche et le Etransmit s'effectue ensuite sans problème :Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Runtime Namespace EventTest Public Class MyPlugin Implements IExtensionApplication Private docMan As DocumentCollection = Application.DocumentManager Public Sub Initialize() AddHandler docMan.DocumentCreated, AddressOf docMan_DocumentCreated For Each doc As Document In docMan AddHandler doc.Database.BeginSave, AddressOf Database_BeginSave Next End Sub Public Sub Terminate() End Sub Private Sub docMan_DocumentCreated(ByVal sender As Object, ByVal e As DocumentCollectionEventArgs) AddHandler e.Document.Database.BeginSave, AddressOf Database_BeginSave End Sub Private Sub Database_BeginSave(ByVal sender As Object, ByVal e As DatabaseIOEventArgs) Application.ShowAlertDialog("BeginSave") End Sub End Class End Namespace Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 Effectivement, cela va mieux. Donc le problème ne vient pas de "mes évênements". Et traçant le code, j'ai découvert que AutoCAD me reposait la question en boucle à cause la ligne : app.ActiveDocument.SendCommand("_.-xref _reload * " & vbLf) Et si je met cette ligne en remarque, 'eTransmit' ne me repose plus la question. Le code est celui que tu m'as généreusement offert. je ne l'ai que très peu défiguré. '' Modifie le chemin des XRefs (Dwg) en chemin relatif Public Sub Abs2RelXRefs() Dim doc As Document = AcApp.DocumentManager.MdiActiveDocument Dim db As AcBdd.Database = doc.Database Dim ed As Editor = doc.Editor ' récupère le chemin du dessin courant DWGPath = Application.GetSystemVariable("DwgPrefix") DWGName = Application.GetSystemVariable("DwgName") DWG = AF_ScanLAN.strLanPath(DWGPath & DWGName) DWGPath = DWGPath.Trim(New Char() {"\"c}) Using tr As AcBdd.Transaction = db.TransactionManager.StartTransaction() ' Traitement des xrefs Dim xrg As AcBdd.XrefGraph = db.GetHostDwgXrefGraph(True) Dim gnc As New AcBdd.GraphNodeCollection() Dim i As Integer = 0 While i < xrg.NumNodes gnc.Add(xrg.GetXrefNode(i)) i += 1 'System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1) End While Dim LstUnloadXRefs As New ArrayList Dim app As AcadApplication = Application.AcadApplication Try Dim j As Integer = 1 While j < xrg.NumNodes Dim xrgn As AcBdd.XrefGraphNode = xrg.GetXrefNode(j) If (Not xrgn.IsNested) AndAlso (xrgn.XrefStatus <> AcBdd.XrefStatus.FileNotFound) Then Call SetXrefRelativePath(xrgn, xrg, gnc, tr, DWG, LstUnloadXRefs) End If j += 1 'System.Math.Max(System.Threading.Interlocked.Increment(j), j - 1) End While Catch ex As System.Exception ed.WriteMessage(vbLf & "Erreur: " + ex.Message) End Try app.ActiveDocument.SendCommand("_.-xref _reload * " & vbLf) If LstUnloadXRefs.Count > 0 Then Dim AllUnlXRefs As String = LstUnloadXRefs(0) For Idx As Int16 = 1 To LstUnloadXRefs.Count - 1 AllUnlXRefs = AllUnlXRefs & "," & LstUnloadXRefs(Idx) Next app.ActiveDocument.SendCommand("_.-xref _unload " & AllUnlXRefs & vbLf) End If tr.Commit() End Using End Sub J'ai mis cette ligne parce que j'avais besoin de régénérer mes XRefs en relatif dans le gestionaire d'XRefs. Et je ne peux les recharger systématiquement parce que, quelques fois, les utilisateurs déchargent leurs XRefs. Il faut que nous trouvions une autre solution pour modifier visuellement cette ligne dans le gesttionnaire. As-tu une idée ? merci
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 Regarde si, suivant la version d'AutoCAD que tu utilises, tu as les méthodes Database.UnloadXrefs() et Database.ReloadXrefs() (elles existent en 2010 mais pas en 2007). Si tu les as, il suffit de faire 2 ObjectIdCollection un avec toutes les xrefs traitées et un autre avec celles qui sont traitées et déchargées.Une fois les xrefs traitées tu les recharges toutes avec ReloadXrefs() puis tu décharges celles qui étaient déchargées. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 J'ai trouvé une solution sans les méthodes Database.UnloadXrefs() et Database.ReloadXrefs() avec COM. XrefGraph xrg = db.GetHostDwgXrefGraph(true); [surligneur]List xrefs = new List(); List unloaded = new List();[/surligneur] for (int i = 1; i { XrefGraphNode xrgn = xrg.GetXrefNode(i); if ((!xrgn.IsNested) && (xrgn.XrefStatus != XrefStatus.FileNotFound)) { try { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(xrgn.BlockTableRecordId, OpenMode.ForWrite); [surligneur]xrefs.Add((AcadBlock)btr.AcadObject);[/surligneur] [surligneur]if (xrgn.XrefStatus == XrefStatus.Unloaded)[/surligneur] [surligneur]unloaded.Add((AcadBlock)btr.AcadObject);[/surligneur] btr.PathName = GetRelativePath(folder, btr.PathName); } catch (System.Exception ex) { ed.WriteMessage("\nErreur: " + ex.Message); } } } [surligneur]foreach (AcadBlock xr in xrefs) {[/surligneur] [surligneur] xr.Reload();[/surligneur] [surligneur]} foreach (AcadBlock xr in unloaded) {[/surligneur] [surligneur] xr.Unload(); }[/surligneur] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 Cela fonctionne "génial". Je t'en remercie. Questions Bonus : - Comment trouves-tu les infos ? - Sur quelles documentations t'appuies-tu ? A bientôt ...
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 - Comment trouves-tu les infos ?- Sur quelles documentations t'appuies-tu ? En ce qui concerne les APIs DotNET, il y a de la doc dans ObjectARX2010 (.\Docs\acad_mgd.chm) et j'utilise aussi arxref(.net) pour 2007.Et l'Intellisense de Visual Studio qui te propose une liste déroulante des méthodes propriétés et évènements des objets En ce qui concerne les APIs COM il y l'Aide aux développeurs d'AutoCAD : ActiveX and VBA Reference. Quelle méthode as tu essayé et sur quelle version ? Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 J'ai essayé la première méthode. Mais j'ai pour projet d'essayer la deuxième et ce rapidement. En ce qui concerne la doc, tu as la capacité de trouver vite ce je cherche longtemps. Peut-être parce que je ne sais pas ce que cherche ? Il y a un ouvrage VB.Net pour AutoCAD 2010 sur amazone.com http:// http://www.amazon.com/s/ref=nb_sb_ss_i_7_7?url=search-alias%3Daps&field-keywords=vb.net+for+autocad&sprefix=vb.net+ Mais en ce moment il est en rupture de stock.
PhilOctet Posté(e) le 20 février 2010 Auteur Posté(e) le 20 février 2010 J'ai oublié de te répondre à une question Quelle méthode as tu essayé et sur quelle version ? J'ai intégré la 1ère méthode et je vais essayé la 2ème. J'ai la version 2010 et j'ai la chance de pouvoir des essais sur la version 2011. Mais j'ai hatte de trouver un RealDWG SDK pour faire qlq dev sur des fichiers .dwg sans AutoCAD.
(gile) Posté(e) le 20 février 2010 Posté(e) le 20 février 2010 Attention avec l'interface COM, il y a des incompatibilités entre les versions.Si tu compiles en ayant référencé les librairies 2010, ça ne marchera pas sur une version 2007 et inversement. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 17 mars 2010 Auteur Posté(e) le 17 mars 2010 Bonjour, Mes routines ont été déployés sur une dizaine de postes de mon entreprise qui comporte 130 AutoCAD 200x que je compte migrer en v2011. Il en ressort que le traitement systématique à chaque sauvegarde pause plus de problème que cela en résoud. J'utilisai un évênement BeginSave. Mais voilà, cet évenement est appelé dans de nombreuses commandes AutoCAD : eTransmit (Pb que ensemble avons résolu), Publier (commande souvent utilisée). Je ne voudrais pas faire un bouton qui déclenche le traitement à la demande. Donc existe-t-il un moyen qui me permettrait de lancer mon traitement à l'apel de la commande QSave ? Soit par Ctrl+S, fermer la fenêtre puis sauvegarde. 1er élément de réponse : Je sais qu'en AutoLisp, il est possible d'encapsuler une commande AutoCAD dans une commande personnalisée qui prend la place de la dite commande AutoCAD par l'intermédiaire d'un "undefine". Je ne sais pas le faire en VB.Net. Qu'elle est l'instruction qui me le permettrait ? 2ème élément de réponse : Existe-t-il un moyen de savoir qu'elle est(sont) la commande(s) en cours avec les lesquels je pourrais combiner via un "Select Case" afin de déclencher mon traitement. Si je suis dans ce forum, c'est aussi pour entendre (lire) d'autres suggestions.
(gile) Posté(e) le 17 mars 2010 Posté(e) le 17 mars 2010 Salut, Tu peux utilise l'évènement Document.CommandWillSart() public class CommandEventPlugin : IExtensionApplication { private DocumentCollection docMan = Application.DocumentManager; // Abonnement du DocumentManager à l'évènement "DocumentCreated" // Abonnement de tous les documents déjà ouverts à l'évènement "CommandWillStart" void IExtensionApplication.Initialize() { docMan.DocumentCreated += new DocumentCollectionEventHandler(OnDocumentCreated); foreach (Document doc in docMan) { doc.CommandWillStart += new CommandEventHandler(doc_CommandWillStart); } } void IExtensionApplication.Terminate() { } // Réaction à l'ouverture d'un document => abonnement à l'évènement "CommandWillStart" private void OnDocumentCreated(object sender, DocumentCollectionEventArgs e) { e.Document.CommandWillStart += new CommandEventHandler(doc_CommandWillStart); } // Réaction à l'évènement "CommandWillStart" void doc_CommandWillStart(object sender, CommandEventArgs e) { if (e.GlobalCommandName == "QSAVE") Application.ShowAlertDialog("Sauvegarde lancée"); } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant