Communauté
AutoCAD – tous produits - Français
Bienvenue sur les forums AutoCAD d’Autodesk. Partagez vos connaissances, posez des questions, et explorez les sujets AutoCAD populaires.
annuler
Affichage des résultats de 
Afficher  uniquement  | Rechercher plutôt 
Vouliez-vous dire : 

AutoCAD : Garder le lien vers un Xref même si le nom de ce dernier change

17 RÉPONSES 17
RÉSOLU
Répondre
Message 1 sur 18
martin.cappe
526 Visites, 17 Réponses

AutoCAD : Garder le lien vers un Xref même si le nom de ce dernier change

Bonjour

 

J'ai un dessin contenant un Xref. Ce dernier a pour particularité qu'il change de nom assez souvent.

Ma question est la suivante : comment faire pour garder le lien entre les 2, sans tenir compte du nom ?

Pour être honnête, je ne sais même pas si cela est possible mais on sait jamais.

 

Cordialement,

CM


Le titre du sujet a été modifié par un modérateur pour faciliter la recherche. Titre original:
Garder le lien vers un Xref même si le nom de ce dernier change

17 RÉPONSES 17
Message 2 sur 18
tramber
en réponse à: martin.cappe

Une programmation lisp est toujours imaginable du genre : "trouve-moi le seul dwg contenu dans ce dossier" pour en faire une xref à chaque appui ou lancement d'une instruction au clavier (voire à l'ouverture de chaque dessin) sur un bouton est possible.

MAis as-tu déjà utilisé la rubrique détails de la palette des xrefs pour repointer manuellement ? Je suppose que oui 🙂

Message 3 sur 18
martin.cappe
en réponse à: tramber

Bonjour, merci pour votre réponse

 

Oui j'ai déjà essayé mais le problème est que je n'ai pas qu'un seul fichier..j'en ai au moins une centaine. Donc un automatisme serait pas de refus. Je ne connais pas le Lisp hélas...

Message 4 sur 18
Y.AUBRY
en réponse à: martin.cappe

Bonjour @martin.cappe,

 

Lorsque tu dis que ton XREF change de nom assez souvent c'est un changement de date (voir exemple ci-dessous) ou c'est un changement complet de nommage?

Ex : NOM_FICHIER_20220502.dwg --> NOM_FICHIER_20221027.dwg

 

Si c'est une changement de date, c'est surement possible via programmation, sinon je ne vois pas comment AutoCAD pourrait savoir qu'un XREF a changé de nom.

 

A+ Yoan

Yoan AUBRY

EESignature

Message 5 sur 18
martin.cappe
en réponse à: Y.AUBRY

Bonjour,

 

C'est un changement de "numéro" par exemple : "40-xxxx.dwg" => "45-xxxx.dwg"

Message 6 sur 18
Y.AUBRY
en réponse à: martin.cappe

Du coup, le XXXX reste toujours identique?

Le séparateur entre ton numéro et le XXXX est toujours un "-"?

Les fichiers renommés restent dans le même dossier? (Le chemin du dossier présent dans l'ancien XREF reste inchangé)

Sinon, tu travailles sur un AutoCAD complet ou une version LT (Si c'est LT je ne pourrai rien te faire) ?

Quelle est ta version d'AutoCAD (pour la génération de DLL, la version de Framework change en fonction de la version d'AutoCAD)

 

A+ Yoan

Yoan AUBRY

EESignature

Message 7 sur 18
martin.cappe
en réponse à: Y.AUBRY

Re-bonjour

 

Le séparateur est et sera toujours un "-". Je travaille avec la version complète d'AutoCAD 2021 et 2022.

 

EDIT : Oui le dossier est le même que le fichier de base

 

Cordialement,

CM

Message 8 sur 18
Y.AUBRY
en réponse à: martin.cappe

OK, dans ces cas-là je vais pouvoir te faire quelque-chose.

A+ Yoan

Yoan AUBRY

EESignature

Message 9 sur 18
Y.AUBRY
en réponse à: martin.cappe

Je viens de finir le code, peux-tu me faire un e-transmit d'un plan pour les tests (ici ou en MP)

Yoan

Yoan AUBRY

EESignature

Message 10 sur 18
martin.cappe
en réponse à: Y.AUBRY

Re-bonjour,

 

Voici des fichiers afin de tester la macro. Merci d'avance.

 

Cordialement,

 

CM

Message 11 sur 18
Y.AUBRY
en réponse à: martin.cappe

Tu ne m'as envoyé qu'un zip de plusieurs fichiers d'un dossier en non des e-transmits (je n'ai pas les XREF du coup)

Yoan AUBRY

EESignature

Message 12 sur 18
Y.AUBRY
en réponse à: martin.cappe

Du coup tu trouveras dans le zip ci-joint une DLL nommée RELOAD_XREF.dll.

 

Il se peut que tu ais besoin de la débloquer car transmise par internet.

Pour le savoir faire un clic-droit dessus, puis propriétés, s'il y a le bouton "Débloquer" (ou case à cocher selon la version de Windows)

 

Exemple :

YAUBRY_0-1666866092340.png

 

Une fois débloquer, elle se charge dans AutoCAD via la commande NETLOAD

Tu auras ensuite accès à la commande RELOAD_XREF

 

Je te conseille de créer un dossier dans lequel tu mets cette DLL et d'ajouter ce dossier dans les "Chemins de recherche des fichiers de support de travail" ainsi que dans les "Emplacements approuvés" (Outils\Options onglet fichier)

 

Nota , les fichiers envoyés n'étaient pas des e-transmit et donc ne permettaient pas de faire des tests car je n'avais pas les XREF associés.

 

Ci-dessous le code :

 

Option Compare Text

Imports System.IO
Imports System.Linq

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime

Public Class CmdXREF

	<CommandMethod("RELOAD_XREF")>
	Public Sub RELOAD_XREF()

		Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
		Dim db As Database = doc.Database
		Dim ed As Editor = doc.Editor

		Dim FpDWG As String = doc.Name
		Dim FnDWG As String = FpDWG.Split("\").Last
		Dim FpDoss As String = Microsoft.VisualBasic.Left(FpDWG, Len(FpDWG) - Len(FnDWG))

		Dim TMP() As String
		TMP = FpDWG.Split("\")
		Dim TMP_X() As String

		Dim collection As ObjectIdCollection = New ObjectIdCollection()

		Using tr As Transaction = db.TransactionManager.StartTransaction()

			Dim bt As BlockTable = TryCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)

			For Each btrId As ObjectId In bt

				Dim btr As BlockTableRecord = TryCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)

				If btr.IsFromExternalReference Then

					btr.UpgradeOpen()

					Dim oldPath As String = btr.PathName
					Dim oldFN As String = oldPath.Split("\").Last
					Dim FpDossXREF As String = ""

					If oldPath Like "..\*" Then
						TMP_X = oldPath.Split("\")
						Dim NbRetour As Integer = 0
						For i As Integer = 0 To UBound(TMP_X)
							If TMP_X(i) = ".." Then NbRetour += 1
						Next
						Dim TmpPath As String = ""
						For i As Integer = 0 To UBound(TMP) - (NbRetour + 1)
							If TmpPath = "" Then
								TmpPath = TMP(i)
							Else
								TmpPath = TmpPath & "\" & TMP(i)
							End If
						Next
						For i As Integer = 0 To UBound(TMP_X) - 1
							If TMP_X(i) <> ".." Then
								TmpPath = TmpPath & "\" & TMP_X(i)
							End If
						Next

						FpDossXREF = TmpPath & "\"
					ElseIf oldPath Like ".\*" Then
						FpDossXREF = FpDoss & Microsoft.VisualBasic.Right(oldPath, Len(oldPath) - 2)
						FpDossXREF = Microsoft.VisualBasic.Left(FpDossXREF, Len(FpDossXREF) - Len(oldFN))
					Else
						FpDossXREF = Microsoft.VisualBasic.Left(oldPath, Len(oldPath) - Len(oldFN))
					End If

					If Not Directory.Exists(FpDossXREF) Then
						MsgBox("Le dossier " & FpDossXREF & " n'a pas été trouvé", MsgBoxStyle.Exclamation, "Annulation")
						Exit Sub
					End If

					Dim newFN As String = ""
					Dim newPath As String = ""

					Dim Texte_a_trouver = Microsoft.VisualBasic.Right(oldFN, Len(oldFN) - Len(oldFN.Split("-").First))

					Dim di As System.IO.DirectoryInfo = New System.IO.DirectoryInfo(FpDossXREF)

					For Each fi As System.IO.FileInfo In di.GetFiles
						If fi.Name Like "*" & Texte_a_trouver Then
							newFN = fi.Name
							Exit For
						End If
					Next

					If newFN <> "" Then
						newPath = oldPath.Replace(oldFN, newFN)
						btr.PathName = newPath
						btr.Name = Microsoft.VisualBasic.Left(newFN, Len(newFN) - 4) ' -4 pour ".dwg"
						collection.Add(btrId)
						ed.WriteMessage(String.Format("{0}Ancien chemin : {1} Nouveau Chemin : {2}", Environment.NewLine, oldPath, newPath))
					End If

				End If
			Next

			tr.Commit()
		End Using

		If collection.Count > 0 Then
			db.ReloadXrefs(collection)
		End If

		db.SaveAs(db.OriginalFileName, True, db.OriginalFileVersion, db.SecurityParameters)

	End Sub

End Class

 

 

 

A+ Yoan

Yoan AUBRY

EESignature

Message 13 sur 18
martin.cappe
en réponse à: Y.AUBRY

Désolé je ne suis pas très à l'aise avec les e-transmits, il faudrait que je  trouve un  tutoriel pour ça.

 

Je test le code et je vous tiens au courant 🙂

 

Merci,

CM

Message 14 sur 18
martin.cappe
en réponse à: Y.AUBRY

J'ai testé et cela marche parfaitement à 1 détail près. Si mon Xref contient des calques gelés, après avoir utilisé la commande, tous les calques reviennent.

 

Est-il possible de garder les calques gelés même après le changement ?

 

Question au passage : Est-il possible de faire des "commandes" en un autre langage que le Lisp ?

 

Cordialement, 

 

CM

Message 15 sur 18
Y.AUBRY
en réponse à: martin.cappe

Re-bonjour,

 

Je vais regarder si c'est possible pour les histoires de calques gelés (mais étant donné que l'on change le nom de l'XREF c'est normal qu'actuellement tous reviennent à l'état non gelé).

 

Sinon oui, c'est possible de faire des commande avec d'autres langages : J'ai utilisé le VB.NET pour cette commande mais c'est également possible de C#. Il est également possible de créer une interaction entre Excel et AutoCAD via  programmation VBA, mais cela ne permet pas de faire uniquement du traitement, pas de création de commande.

 

Pour VB.NET et C#, il faut installer Visual Studio (je te conseille la version Community qui est gratuite)

Ensuite tu as pas mal de forums dédiés et de posts dédiés au développement .NET et C# pour AutoCAD

 

Il est également possible (généralement) de convertir des morceaux de codes C# en .NET (et vice-versa) via des pages comme https://converter.telerik.com/

 

Ci-dessous des exemples de pages dédiés à l'interaction Visual Basic / AutoCAD: 

https://gilecad.azurewebsites.net/Resources/Template_Csharp.pdf

https://knowledge.autodesk.com/support/autocad/learn-explore/caas/simplecontent/content/my-first-aut...

http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer%27s%20Guide/index.html

https://www.keanw.com/autocad_net/

 

Je me suis auto-formé sur le sujet et j'avoue que ca a complètement changé ma manière de voir les traitements réalisables sur un dwg. En tout cas bon courage si tu te lance la dedans.

 

A+ Yoan

Yoan AUBRY

EESignature

Message 16 sur 18
Y.AUBRY
en réponse à: martin.cappe

Ci-joint la DLL mise à jour.

 

...et le code associé

Option Compare Text

Imports System.IO
Imports System.Linq

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime

Public Class CmdXREF

	Public Class ClCalque
		Public LayerName As String
		Public _IsOff As Boolean
		Public _IsFrozen As Boolean
		Public _IsLocked As Boolean
		Public _Plottable As Boolean
	End Class

	Public Class ClXREF_MAJ
		Public OldPath As String
		Public NewPath As String
		Public OldFN As String
		Public NewFN As String
	End Class


	<CommandMethod("RELOAD_XREF")>
	Public Sub RELOAD_XREF()

		Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
		Dim db As Database = doc.Database
		Dim ed As Editor = doc.Editor

		Dim LstCalque As New List(Of ClCalque)
		Dim LstXREF As New List(Of ClXREF_MAJ)

		Dim FpDWG As String = doc.Name
		Dim FnDWG As String = FpDWG.Split("\").Last
		Dim FpDoss As String = Microsoft.VisualBasic.Left(FpDWG, Len(FpDWG) - Len(FnDWG))

		Dim TMP() As String
		TMP = FpDWG.Split("\")
		Dim TMP_X() As String

		Dim collection As ObjectIdCollection = New ObjectIdCollection()


		Dim newFN As String = ""
		Dim newPath As String = ""

		Using tr As Transaction = db.TransactionManager.StartTransaction()

			Dim idLay As ObjectId = db.LayerTableId
			Dim lt As LayerTable = tr.GetObject(idLay, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)

			For Each id As ObjectId In lt

				Dim ltr As LayerTableRecord = DirectCast(tr.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), LayerTableRecord)

				Dim Calque As New ClCalque With {
					.LayerName = ltr.Name,
					._IsOff = ltr.IsOff,
					._IsFrozen = ltr.IsFrozen,
					._IsLocked = ltr.IsLocked,
					._Plottable = ltr.IsPlottable
					}

				LstCalque.Add(Calque)

			Next


			Dim bt As BlockTable = TryCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)

			For Each btrId As ObjectId In bt

				Dim btr As BlockTableRecord = TryCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)

				If btr.IsFromExternalReference Then

					btr.UpgradeOpen()

					Dim oldPath As String = btr.PathName
					Dim oldFN As String = oldPath.Split("\").Last
					Dim FpDossXREF As String = ""

					If oldPath Like "..\*" Then
						TMP_X = oldPath.Split("\")
						Dim NbRetour As Integer = 0
						For i As Integer = 0 To UBound(TMP_X)
							If TMP_X(i) = ".." Then NbRetour += 1
						Next
						Dim TmpPath As String = ""
						For i As Integer = 0 To UBound(TMP) - (NbRetour + 1)
							If TmpPath = "" Then
								TmpPath = TMP(i)
							Else
								TmpPath = TmpPath & "\" & TMP(i)
							End If
						Next
						For i As Integer = 0 To UBound(TMP_X) - 1
							If TMP_X(i) <> ".." Then
								TmpPath = TmpPath & "\" & TMP_X(i)
							End If
						Next

						FpDossXREF = TmpPath & "\"
					ElseIf oldPath Like ".\*" Then
						FpDossXREF = FpDoss & Microsoft.VisualBasic.Right(oldPath, Len(oldPath) - 2)
						FpDossXREF = Microsoft.VisualBasic.Left(FpDossXREF, Len(FpDossXREF) - Len(oldFN))
					Else
						FpDossXREF = Microsoft.VisualBasic.Left(oldPath, Len(oldPath) - Len(oldFN))
					End If

					If Not Directory.Exists(FpDossXREF) Then
						MsgBox("Le dossier " & FpDossXREF & " n'a pas été trouvé", MsgBoxStyle.Exclamation, "Annulation")
						Exit Sub
					End If

					newFN = ""
					newPath = ""

					Dim Texte_a_trouver = Microsoft.VisualBasic.Right(oldFN, Len(oldFN) - Len(oldFN.Split("-").First))

					Dim di As System.IO.DirectoryInfo = New System.IO.DirectoryInfo(FpDossXREF)

					For Each fi As System.IO.FileInfo In di.GetFiles
						If fi.Name Like "*" & Texte_a_trouver Then
							newFN = fi.Name
							Exit For
						End If
					Next

					If newFN <> "" Then
						newPath = oldPath.Replace(oldFN, newFN)
						btr.PathName = newPath
						btr.Name = Microsoft.VisualBasic.Left(newFN, Len(newFN) - 4) ' -4 pour ".dwg"
						collection.Add(btrId)
						ed.WriteMessage(String.Format("{0}Ancien chemin : {1} Nouveau Chemin : {2}", Environment.NewLine, oldPath, newPath))
					End If

					Dim XREF_MAJ As New ClXREF_MAJ With {
						.OldPath = oldPath,
						.OldFN = oldFN,
						.NewFN = newFN,
						.NewPath = newPath
					}

					LstXREF.Add(XREF_MAJ)

				End If
			Next

			tr.Commit()
		End Using

		If collection.Count > 0 Then
			db.ReloadXrefs(collection)
		End If

		db.SaveAs(db.OriginalFileName, True, db.OriginalFileVersion, db.SecurityParameters)


		Using tr As Transaction = db.TransactionManager.StartTransaction()

			Dim idLay As ObjectId = db.LayerTableId
			Dim lt As LayerTable = tr.GetObject(idLay, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)

			For Each id As ObjectId In lt

				Dim ltr As LayerTableRecord = DirectCast(tr.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite), LayerTableRecord)

				If ltr.Name Like "*|*" Then 'Nommage des calques des XREF avec un |

					Dim NomCalque As String = ltr.Name

					Dim NomXREF As String = NomCalque.Split("|").First
					Dim XREF_MAJ As ClXREF_MAJ = LstXREF.Find(Function(f) f.NewFN = NomXREF & ".dwg")

					If Not XREF_MAJ Is Nothing Then
						Dim OldNomXREF As String = Microsoft.VisualBasic.Left(XREF_MAJ.OldFN, Len(XREF_MAJ.OldFN) - 4)
						Dim OldNomCalque As String = NomCalque.Replace(NomXREF, OldNomXREF)
						Dim Calque As ClCalque = LstCalque.Find(Function(f) f.LayerName = OldNomCalque)
						If Not Calque Is Nothing Then
							ltr.IsOff = Calque._IsOff
							ltr.IsFrozen = Calque._IsFrozen
							ltr.IsLocked = Calque._IsLocked
							ltr.IsPlottable = Calque._Plottable
						End If
					End If

				End If

			Next

			tr.Commit()

		End Using

	End Sub

End Class

 

A+ Yoan

Yoan AUBRY

EESignature

Message 17 sur 18
martin.cappe
en réponse à: Y.AUBRY

Merci beaucoup ! Le code fonctionne parfaitement.

 

J'ai des bases de VBA et de C#. Je vais me pencher sur les commandes pour voir ce qu'on peut faire.

 

Merci beaucoup encore une fois.

 

Cordialement,

CM

Message 18 sur 18
Y.AUBRY
en réponse à: martin.cappe

Content d'avoir pu t'aider.

Bon courage pour la suite 😉

 

A+ Yoan

Yoan AUBRY

EESignature

Vous n'avez pas trouvé ce que vous recherchiez ? Posez une question à la communauté ou partagez vos connaissances.

Publier dans les forums  

Autodesk Design & Make Report