Macro alle Teile & Unterbraugruppen umbenennen / SolidWorks
Captain Feature 07. Apr. 2021, 08:58

Moin 

ich bin gerade auf der Suche, möglichst flott alle Teile/Unterbaugruppen einer Baugruppe umzubenennen.
Hintergrund ist, dass wir zukünftig alle unsere Anlagen anderen Abteilungen zur Verfügung stellen müssen. Zusätzlich habe ich die Auflage, alle Teilenamen "dumm" zu machen (da im Dateinamen teilweise vertrauliche Informationen stecken).

Da dieser Vorgang für sämtliche Anlagen und bei jeder Revision erneut passieren muss, fällt mir eigentlich nur ein, das Ganze per Macro zu machen.

Ich habe ein Macro gefunden, was in einer geöffneten Baugruppe die ausgewählte Unterkomponente automatisch umbenennt.
Leider bin ich nicht besonders fit in VBA, daher wäre es genial, wenn mir jemand helfen könnte, das Macro folgendermaßen abzuändern:
- Es soll nicht nur das ausgewählte Teil/Baugruppe umbenannt werden, sondern sämtliche Teile/Unterbaugruppen und deren Teile (also alles)
- Der Dateiname soll nicht erweitert werden, sondern komplett umbenannt werden (Egal in was...z.B. Teil1, Teil2 etc.)

Code:
Const SUFFIX As String = "_Renamed"

Dim swApp As SldWorks.SldWorks

Sub main()
   
    Set swApp = Application.SldWorks
   
    Dim swModel As SldWorks.ModelDoc2
    Dim swSelMgr As SldWorks.SelectionMgr

    Set swModel = swApp.ActiveDoc
   
    If Not swModel Is Nothing Then
   
        Set swSelMgr = swModel.SelectionManager
       
        Dim swComp As SldWorks.Component2
       
        Set swComp = swSelMgr.GetSelectedObject6(1, -1)
       
        If Not swComp Is Nothing Then
       
            Dim compName As String
           
            compName = swComp.Name2
           
            If Not swComp.GetParent() Is Nothing Then
                'if not root remove the sub-assemblies name
                compName = Right(compName, Len(compName) - InStrRev(compName, "/"))
            End If
           
            If swComp.IsVirtual() Then
                'if virtual remove the context assembly name
                compName = Left(compName, InStr(compName, "^") - 1)
            Else
                'remove the index name
                compName = Left(compName, InStrRev(compName, "-") - 1)
            End If
           
            Dim newCompName As String
            newCompName = compName & SUFFIX
           
            swComp.Name2 = newCompName
           
        Else
            MsgBox "Please select component to rename"
        End If
   
    Else
        MsgBox "Please open assembly document"
    End If
   
End Sub


Christoph Weise 07. Apr. 2021, 22:13

Hallo,

hast du es schonmal mit der funktion Pack and Go von SWX versucht?

Hier kann man alle Bauteile umbenennen bzw. auch mit Suchen/Ersetzten umbennennen lassen.

Du musst nur aufpassen das die Dateinamen eindeutig bleiben:
Also "Projekt_XY_Teil_1"
Ansonsten könnte es vorkommen das 2 Bauteile gleich heißen-> dann weiß SWX nichtmehr welches Bauteil gemeint ist.

Eine andere Möglichkeit wäre die Baugruppe zuerst als Part abzuspeichern. Anschließend diese Datei (enthält ja noch die Dateinamen) als Parasolid exportieren und wieder importieren.
Übrig bleibt ein Teil, in dem alle anderen Teile als einzelene Volumenkörper abgebildet sind. Benannt sind diese anschließend mit Importiert1 /Importiert2 / Importiert3.

Allerdings ist dies je nach Größe der Baugruppe bzw. der komplexität dann nicht mehr sinnvoll für die "anderen Abteilungen"

Captain Feature 08. Apr. 2021, 06:23

Moin,

danke für die Tipps 

An Pack & Go habe ich auch schon gedacht, leider ist das ziemlich aufwändig, da unsere Anlagen teilweise aus mehreren hundert Bauteilen bestehen. Diese Anlagen haben noch bis zu 20 Variationen, die über Konfigurationen realisiert wurden...müssten dann also 20x exportiert werden. Und das jedes mal, wenn die Anlage revidiert wird.

Das mit Baugruppe->Teil->Parasolid ist bisher auch meine einzige Lösung. Die verschlingt aber auch viel Zeit, da alleine das Speichern einer großen Baugruppe als Teil bei uns schon ~40min. dauert (von SSD auf SSD). Bedeutet, dass man tagelang vorm Rechner sitzt um zu öffnen/speichern.
Zusätzlich wäre es super, wenn die Baugruppen weiterhin flexibel bleiben, damit man z.B. einen darin enthaltenen Kompressor auch mal bei Bedarf verschieben kann (z.B. wenn das Modell beim Kunden dazu benutzt wird, um den Betriebsraum zu planen). Über Umwege geht das bestimmt auch mit dem Einzelteil aber eleganter wäre es mit einer Baugruppe.

Wenn ich ein Macro hätte, was mit einem Klick alle Bauteile umbenennt (meinetwegen auch vorher alle Bauteile virtuell macht), würde der Export nur einen Bruchteil der Zeit kosten.
Ich google heute noch weiter und hoffe, dass ich mir doch irgendwie selbst ein Macro zusammenbasteln kann.
Nur als VBA Laie ist das manchmal nicht so einfach 

Also wenn jemand doch noch ein Tipp für das Macro hätte, wäre ich mega dankbar 

Ralf Tide 08. Apr. 2021, 09:14

Hallo Captain 

schau Dir doch mal das Beispiel von Stefan an: http://solidworks.cad.de/mm_36.htm
Speziell den Teil: Private Function TraverseComponent(Level As Integer, Component As Object) ' rekursive Routine, die alle Komponenten durchläuft

HTH
Ralf

Captain Feature 08. Apr. 2021, 12:06

Super Hinweis Ralf!
Genau das ist für mich immer eine Schwierigkeit (Schleifen in VBA einbauen)
Gucke ich mir gleich mal an 

Captain Feature 13. Apr. 2021, 13:10

So, ich bin schon ein wenig weiter:
Das Macro funktioniert schon fast.
Es durchläuft alle Komponenten, macht alle virtuell, die noch nicht virtuell sind und benennt sie dann um.

Code:
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Dim swComp As SldWorks.Component2
Dim swCompModel As SldWorks.ModelDoc2
Dim i As Integer
Dim vComps As Variant
   
Sub main()
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    Set swAssy = swModel
   
    vComps = swAssy.GetComponents(False)
   
    If IsEmpty(vComps) Then Exit Sub
   
    For i = 0 To UBound(vComps)
        Set swComp = vComps(i)
        Set swCompModel = swComp.GetModelDoc2
            'RUN YOUR CODE HERE
            Dim compName As String
          
            compName = swComp.Name2
          
            If Not swComp.GetParent() Is Nothing Then
                'if not root remove the sub-assemblies name
                compName = Right(compName, Len(compName) - InStrRev(compName, "/"))
            End If
          
            If swComp.IsVirtual() Then
                'if virtual remove the context assembly name
                compName = Left(compName, InStr(compName, "^") - 1)
            Else
                'if not virtual make component virtual & remove the context assembly name
            boolstatus = swComp.MakeVirtual()
            compName = swComp.Name2
            compName = Left(compName, InStr(compName, "^") - 1)
            End If
          
            Dim newCompName As String
            newCompName = "Komponente" & i + 1
          
            swComp.Name2 = newCompName
            '====================================================
    Next i
End Sub

Ein Problem habe ich aber noch:
Das Macro ändert nicht die Bauteile von Unterbaugruppen.
Hat jemand eine Idee, woran das liegen kann?

[Diese Nachricht wurde von Captain Feature am 13. Apr. 2021 editiert.]

EIBe 3D 13. Apr. 2021, 13:47

Code:
... Hat jemand eine Idee, woran das liegen kann?

Ja. 

Schrieb oben schon Ralf.

Du traversierst nicht. Schau dir das Beispiel oben an. In deine Sub Main gehört im Prinzip nur der Aufruf mit Übergabe der OBG als Parameter deiner rekursiven Methode (die du ja schon hast) welche all die Arbeit erledigt. Diese muss sich, wenn sie eine UBG erkennt wiederum selbst aufrufen mit Übergabe der UBG als Parameter.


Grüße

EIBe 3D

Captain Feature 13. Apr. 2021, 14:13

Zitat:
Original erstellt von EIBe 3D:
Code:
... Hat jemand eine Idee, woran das liegen kann?

Ja.  

Schrieb oben schon Ralf.

Du traversierst nicht. Schau dir das Beispiel oben an. In deine Sub Main gehört im Prinzip nur der Aufruf mit Übergabe der OBG als Parameter deiner rekursiven Methode (die du ja schon hast) welche all die Arbeit erledigt. Diese muss sich, wenn sie eine UBG erkennt wiederum selbst aufrufen mit Übergabe der UBG als Parameter.


Grüße

EIBe 3D


Oh Gott...ich merke immer öfter, was ich für ein blutiger Anfänger in VBA bin 

Ich glaube zwar, dass ich deinen Hinweis so halbwegs verstehe, aber hab wiedermal 0 Ahnung, wie ich das in VBA umsetzen soll 


Ich gucke mir das Beispiel-Macro von Ralf/Stefan noch mal an...vllt werde ich doch noch schlau daraus 

Ralf Tide 13. Apr. 2021, 18:57


033379_CaptainFeature.mp4

 
Hallo Captain,

die Codezeilen von Stefan und Deine drei Befehle hab ich mal Q&D zusammengefasst...

Code:
Dim i As Integer        ' Zähler der Komponente

Sub main()
    ' wesentliche Teile von Stefan Berlitz http://solidworks.cad.de/mm_36.htm
    Dim swApp As Object
    Dim AssemblyDoc As Object
    Dim Configuration As Object
    Dim RootComponent As Object
    ' an SolidWorks anklinken und aktives Assembly holen
    Set swApp = Application.SldWorks
    Set AssemblyDoc = swApp.ActiveDoc
    ' Root-Komponente des Assemblies als Ausgangspunkt festmachen
    Set Configuration = AssemblyDoc.GetActiveConfiguration()
    Set RootComponent = Configuration.GetRootComponent()

    swApp.CommandInProgress = True
    ' und jetzt rekursiv durch alle Ebenen
    i = 0
    If Not RootComponent Is Nothing Then
        TraverseComponent 1, RootComponent
    End If
    swApp.CommandInProgress = False

End Sub

Private Function TraverseComponent(Level As Integer, swComp As Object)
    ' rekursive Routine, die alle Komponenten durchläuft

    Dim Children As Variant
    Dim Child As Object
    Dim ChildCount As Integer
    Dim Feature As Object
    Dim FeatureCreatedBy As String
    Dim ret As Boolean
    If Not (swComp.IsVirtual()) Then
        ret = swComp.MakeVirtual2(True)
    End If
    swComp.Name2 = "TIDE" & i
    i = i + 1
    ' schauen, ob's ein Subassy ist und ggf. über die Kinder rüberschauen
    Children = swComp.GetChildren
    ChildCount = UBound(Children) + 1
    For j = 0 To (ChildCount - 1)
        Set Child = Children(j)
        TraverseComponent Level + 1, Child
    Next j
End Function


Ist nicht so ganz sauber, da die erste Komponente (die BG in der das Makro gestartet wurde) nicht virtuell gespeichert werden kann...
Ist aber auch nur ein Gerüst 

HTH
Ralf

Captain Feature 14. Apr. 2021, 06:22

Ganz ehrlich Ralf? Du bist der Knaller!     

Genau so hatte ich mir das gedacht. Funktioniert einwandfrei.

Jetzt gucke ich mir erst mal den Code an und versuche zu verstehen, was mir gefehlt hat (wenn man vorher noch nie mit Rekursion, traversieren etc. zu tun hatte, ist das alles nicht so aus dem Ärmel geschüttelt  )

CAD-Maler 14. Apr. 2021, 08:00

Bitte teste das Ganze seeehr gründlich!

Ich habe mir vor einigen Jahren selbst ein ähnliches Makro zur Aufbereitung großer Zukauf-Baugruppen aus den gleichen Bausteinen zusammengestellt, das Komponenten und Unterbaugruppen virtuell macht, das Material ändert und auch Alles umbenennt.

Ich habe das hier nicht gepostet, weil:

Wenn ich das Makro im Einzelschritt laufen lasse, tut es.
Wenn ich das Makro auf kleinere Baugruppen mit wenigen Unterbaugruppen loslasse, tut es.
Wenn ich das Makro auf große Baugruppen mit einigen Unterbaugruppen loslasse, tut es MEISTENS.

An einem bestimmten Punkt scheint entweder mein Makro oder SolidWorks selbst durcheinanderzukommen und vergibt den gleichen Dateinamen mehrmals. Selbstverständlich an nicht-identische Teile/Baugruppen. Da es das Ganze auch speichert hat man beim nächsten Laden auf einmal einige Teile doppelt und andere fehlen. Da virtuelle Teile i.d.R. nirgends anders gespeichert werden, sind die dann pfutsch.

Ich will nicht ausschließen, dass irgendwo in meinem Makro ein Bug rumkrabbelt, dann wäre es aber ein sehr gerissener kleiner Käfer.


Gruß, Jens 

Ralf Tide 14. Apr. 2021, 09:42

Hallo Captain,

der Hinweis von Jens  ist dringend zu beachten!
Ich zitier mich ja gerne selbst 

Zitat:
Original erstellt von Ralf Tide:
...nur ein Gerüst
Ein paar Anregungen/Fragen, die mir zum Thema einfallen:
  • Was passiert mit Konfigurationen?
  • Was passiert mit unterdrückten Teilen?
  • Was passiert mit mehrfach verwendeten Teilen?
    - Vielleicht eine Abfrage ob das Teil schon "TIDE"  heißt.
  • Ich würde unbedingt eine Protokolldatei anlegen mit mindestens folgenden Informationen:
    - Name der Komponente,
    - ob die Komponente virtualisiert wurde,
    - ob die Namensgebung funktioniert hat,
    - wie sie neu heißt.
  • Immer nur mit Pack & Go Sicherungen lokal auf einem separaten Rechner arbeiten.
  • Nach jeder größeren Baugruppe SolidWorks herunterfahren und neu starten.
  • ...
Da können außer Jens und mir auch einige andere hier sicher noch Erfahrungen mit einbringen 

HTH
Ralf

Captain Feature 14. Apr. 2021, 10:00

Ok, gut zu wissen, dass ich da ein wenig aufpassen muss.
Bisher habe ich das Macro immer nur mit einer kleinen Testbaugruppe getestet.
Ich mache nachher mal ein paar Testdurchläufe mit unseren echten Baugruppen.

Viel kaputt machen kann ich zum Glück nicht...ist immer ne lokale Kopie aus dem PDM.
Aber mit der doppelt Benennung von Teilen ist natürlich gefährlich. Da werde ich besonders drauf achten.

Ich halte euch auf dem Laufenden 

Ralf Tide 17. Apr. 2021, 10:16

Zitat:
Original erstellt von Captain Feature:
Ich mache nachher mal ein paar Testdurchläufe mit unseren echten Baugruppen.
Mir ist was eingefallen: Wenn eine Unterbaugruppe mehrfach vorkommt, dann wird die erste Instanz beim Durchlauf virtualisiert und umbenannt. Wenn nun die darin enthaltenen Teiele auch virtualisiert und umbenannt werden, passiert dies nicht mit den Teilen der zweiten und weiteren Instanzen dieser Unterbaugruppe. Du würdest auf alle Fälle viel mehr veschiedene Komponenten erhalten als es eigentlich sind.
Abhilfe würden zwei Durchläufe bringen. Im ersten Durchlauf nur Teile virtualisieren und umbenennen und im zweiten Durchlauf in der untersten Unterbaugruppe anfangen (da wäre es hilfreich den größten Wert für Level festzuhalten) und dann nach oben durcharbeiten. Wenn da jetzt mal kein Fehler in meiner Logik ist... 

HTH
Ralf

Andi Beck 17. Apr. 2021, 11:57

Zitat:
Original erstellt von Ralf Tide:
Du würdest auf alle Fälle viel mehr veschiedene Komponenten erhalten als es eigentlich sind.



Hallo,
ich würde beim abarbeiten ein Protokoll (Array) mitschreiben, und mir den vorherigen und neuen Namen merken.
Bei jeder neuen Komponente dann dieses Array durchforsten und schauen, ob der Name schonmal dran war. Entsprechend kann man dann die neue Namensgebung abgleichen.

So etwas ähnliches habe ich ja in meinem Makro Assembly-Print-Drawings gemacht, um die Doubletten rauszufiltern.

Grüße, und schönes WE, Andi

riesi 19. Apr. 2021, 10:21

Wenn zufällig PDM bei euch im Einsatz ist, würde ich es damit machen. (Struktur verschieben, umbenennen mit Seriennummer) Dann braucht nichts programmiert werden.

Wenn alle Dateien in einem Verzeichnis abgelegt sind, würde ich dieses komplett in eine Tabelle einlesen, eine neue Spalte mit den neuen Namen dazu schreiben und mit der Document-Manager-API die Referenzen nach Tabelle austauschen.

Captain Feature 20. Apr. 2021, 08:21

Moin   

ich habe es endlich geschafft, das Macro mal auf eine unserer großen Baugruppen loszulassen.

Die Warnung von CAD-Maler trifft leider auch bei diesem Macro zu:
Bei kleinen Baugruppen funktioniert alles, bei großen Baugruppen fangen komische Probleme an...teilweise wurden einige Komponenten komplett ausgelassen, andere werden zwar virtuell gemacht aber nicht umbenannt, andere werden zwar umbenannt aber in der Benennung steckt noch der alte original-Baugruppenname (nach dem ^) und 1x hat sich das Macro mit einem Fehler beendet (leider habe ich das Macro gleich noch mal gestartet, ohne nachzugucken, an welchem Teil es gelegen hat).

Ich versuche mal die Tipps von Andi und Ralf umzusetzen ("erst Teile, dann Baugruppen" & "Protokoll erstellen")

(Leider haben wir hier immer noch PDM-Workgroup(    ) laufen, daher fällt die PDM-Lösung von riesi für uns flach)

[Diese Nachricht wurde von Captain Feature am 20. Apr. 2021 editiert.]

Ralf Tide 20. Apr. 2021, 09:05

Zitat:
Original erstellt von Captain Feature:
(Leider haben wir hier immer noch PDM-Workgroup(      ) laufen, daher fällt die PDM-Lösung von riesi für uns flach)
Immerhin hat WorkgroupPDM eine API  
...und ein Forum: https://ww3.cad.de/cgi-bin/ubb/forumdisplay.cgi?action=topics&forum=SolidWorks+Workgroup+PDM&number=233