Copy & Paste published elements in context
Copy & Paste published elements in context
(OP)
I have one level assembly with multiple parts and their instances on different positions. Parts already have published elements (lines and axis systems) that are needed to be copied in (empty) part called "Positions" which is in the in same assembly, so the position of copied elements doesn't change, and also their name should be same as in source part.
I have very very basic skills on programming, so I searched for a similar macro, but couldn't find it ... does anyone have something similar that I could use for a start?
I have very very basic skills on programming, so I searched for a similar macro, but couldn't find it ... does anyone have something similar that I could use for a start?





RE: Copy & Paste published elements in context
first make a script to identify the 'active document' and make sure it s a product, if not message the user and exit
Second script would be to add an new part in your product with the proper name.
Third script would be to find the first part in your assembly and identify (select) the element to copy.
Fourth would be the copy / paste.
Fifth would be the keep the name requirement.
Finally modify your script to navigate the assembly for the source part.
show us your progress and tell us the challenge you have, you'll find many people ready to help.
Many user could learn from this, so don't be shy to share.
before you do that, go check the v5automation.chm file on your catia install folder (and read as many script as you can) and the catia portable script center (and read more script) ...
Waiting for your code of step 1 and 2, this should not be too long.
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") End SubNow I'm a bit confused how to properly set search parameters, so it would find and select only published elements in parts
RE: Copy & Paste published elements in context
Before you get to the publication, you should get the first part.
check in your rootProduct.Products
Once you have the proper object, you'll find the publications
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
Additional question at this point is, if I can limit parts used in FOR loop to only visible parts?
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions5") Dim subProduct As Product For i = 1 To rootProduct.Products.Count Set subProduct = rootProduct.Products.Item(i) Debug.Print rootProduct.Products.Item(i).Name Next End SubRE: Copy & Paste published elements in context
What you can do is check if rootProduct.Products.Item(i) is visible or not
the visibility is given by selection.VisProperties
CATIA.ActiveDocument.Selection is the selection, once you define the selection object you can add, remove, copy, paste...
Can you debug.Print only visible instances?
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim subProduct As Product For i = 1 To rootProduct.Products.Count Set subProduct = rootProduct.Products.Item(i) If subProduct.VisProperties = True Then Debug.Print subProduct.Name & " IS visible!" Else Debug.Print subProduct.Name & " is NOT visible!" End If Next End SubRE: Copy & Paste published elements in context
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE --> CATVBA
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim oSel As Selection Dim vp As VisPropertySet For i = 1 To rootProduct.Products.Count Set Instance = rootProduct.Products.Item(i) If isVisible(Instance) Then Debug.Print (Instance.Name & " is visible") Else Debug.Print (Instance.Name & " is NOT visible") End If Next End Sub Function isVisible(ByRef object As Variant) As Boolean CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End FunctionI create a function that return true or false is the element I give to the function is visible.
so first step I loop the product for subproduct (instances)
I get the instance object and give it to the function
the function clear the selection, then add the instance to the selection, then check its visibility and finally return the Boolean
Ok now you have to select the element you want to copy.
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
Manually, if the "blue level" is the root product you cannot copy geometry elements but only product elements (instances...)
you have to make the part (not the instance) the "blue level" in order to do the copy/paste.
Well in VBA you do the copy paste with the root product as "blue level"
that's the ay it is.
Waiting for your code...
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim subProduct As Product Dim oSel As Selection Set oSel = CATIA.ActiveDocument.Selection oSel.Clear For i = 1 To rootProduct.Products.Count Set subProduct = rootProduct.Products.Item(i) oSel.Add rootProduct.Products.Item(i) Dim showstate As CatVisPropertyShow Set visProperties1 = CATIA.ActiveDocument.Selection.VisProperties visProperties1.GetShow showstate If showstate < 1 Then Debug.Print subProduct.Name & " IS visible!" Else Debug.Print subProduct.Name & " is NOT visible!" End If oSel.Clear Next End SubRE: Copy & Paste published elements in context
RE: Copy & Paste published elements in context
yep you need selection for copy / paste but it's not incompatible.
did you notice that your positions.1 instance is in the loop? how can you solve that?
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim oSel As Selection Dim vp As VisPropertySet For i = 1 To rootProduct.Products.Count Set instance = rootProduct.Products.Item(i) If isVisible(instance) Then If instance.Name = newPart.Name Then Debug.Print (instance.Name & " This is Positions part!") Else Debug.Print (instance.Name & " IS visible") End If Else Debug.Print (instance.Name & " is NOT visible") End If Next End Sub Function isVisible(ByRef object As Variant) As Boolean CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End FunctionRE: Copy & Paste published elements in context
I would have made the count of product before adding the position part like :
CODE --> CATVBA
Can you post a picture of the tree structure showing the publication and eventually the geometry to be copied?
Did you manage to select your geometry? is you geometry always the same name in the same geometricalset? or the only way to find the geometry is from the publication?
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim PsrtsCount As Integer PartsCount = rootProduct.Products.Count Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim oSel As Selection Dim vp As VisPropertySet For i = 1 To PartsCount Set instance = rootProduct.Products.Item(i) If isVisible(instance) Then If instance.Name = newPart.Name Then Debug.Print (instance.Name & " This is Positions part!") Else Debug.Print (instance.Name & " IS visible") End If Else Debug.Print (instance.Name & " is NOT visible") End If Next End Sub Function isVisible(ByRef object As Variant) As Boolean CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End FunctionHere is Tree structure of my parts, and all parts are created from template part (new from), and in this case it already has published elements like axis system and line. It is important that copied axis system has same name as source part.
RE: Copy & Paste published elements in context
your code still don't do the selection of the element for copy...it should not be that hard...
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim PartsCount As Integer PartsCount = rootProduct.Products.Count Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim vp As VisPropertySet For i = 1 To PartsCount Set instance = rootProduct.Products.Item(i) If isVisible(instance) Then Debug.Print (instance.Name & " IS visible") Dim publCount As Integer publCount = rootProduct.Products.Item(i).Publications.Count Dim selectedEL As Selection Set selectedEL = CATIA.ActiveDocument.Selection selectedEL.Clear For j = 1 To publCount Set publishedEL = rootProduct.Products.Item(i).Publications.Item(j) selectedEL.Add publishedEL Debug.Print (rootProduct.Products.Item(i).Publications.Item(j).Name & " published element is added to selection") Next Else Debug.Print (instance.Name & " is NOT visible") End If Next End Sub Function isVisible(ByRef object As Variant) As Boolean CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End FunctionRE: Copy & Paste published elements in context
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then Debug.Print rootProduct.Name & " Is NOT Product!" Exit Sub End If Debug.Print rootProduct.Name & " Is Product!" Dim PartsCount As Integer PartsCount = rootProduct.Products.Count Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") Dim vp As VisPropertySet For i = 1 To PartsCount Set instance = rootProduct.Products.Item(i) If isVisible(instance) Then Debug.Print (instance.Name & " IS visible") Dim publCount As Integer publCount = rootProduct.Products.Item(i).Publications.Count Dim selectedEL As Selection Set selectedEL = CATIA.ActiveDocument.Selection selectedEL.Clear For j = 1 To publCount Set publishedEL = rootProduct.Products.Item(i).Publications.Item(j) selectedEL.Add publishedEL Debug.Print (rootProduct.Products.Item(i).Publications.Item(j).Name & " published element is added to selection") 'Debug.Print newPart.Name selectedEL.Copy selectedEL.Clear selectedEL.Add newPart selectedEL.PasteSpecial ("CATPrtResultWithOutLink") selectedEL.Clear Next Else Debug.Print (instance.Name & " is NOT visible") End If Next End Sub Function isVisible(ByRef object As Variant) As Boolean CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End FunctionRE: Copy & Paste published elements in context
newPart is the instance (Product)
newPart.ReferenceProduct is the reference product of the instance (Product)
newPart.ReferenceProduct.Parent is the document supporting the reference product (PartDocument)
newPart.ReferenceProduct.Parent.Part is the part of the document (Part)
inside this part you can create a geometricalSet if you want:
CODE --> CATVBA
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
Special thanks to itsmyjob for guidance&help!
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then 'product/part check MsgBox rootProduct.Name & " Is NOT Assembly!" Exit Sub End If 'Debug.Print rootProduct.Name & " Is Product!" Dim PartsCount As Integer PartsCount = rootProduct.Products.Count 'count of parts and instances to use Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", "Positions") 'create part paste in it Dim targetPart As Part Set targetPart = newPart.ReferenceProduct.Parent.Part Dim geomSetTarget As HybridBody Set geomSetTarget = targetPart.HybridBodies.Add geomSetTarget.Name = "CopyOfReferences" Dim vp As VisPropertySet For i = 1 To PartsCount Set instance = rootProduct.Products.Item(i) If isVisible(instance) Then 'hide/show check to copy only visible parts Dim publCount As Integer publCount = rootProduct.Products.Item(i).Publications.Count Dim selectedEL As Selection Set selectedEL = CATIA.ActiveDocument.Selection selectedEL.Clear For j = 1 To publCount Set publishedEL = rootProduct.Products.Item(i).Publications.Item(j) selectedEL.Add publishedEL 'Debug.Print (rootProduct.Products.Item(i).Publications.Item(j).Name & " published element is added to selection") 'Debug.Print newPart.Name selectedEL.Copy selectedEL.Clear selectedEL.Add targetPart 'selectedEL.PasteSpecial ("CATPrtResultWithOutLink") 'paste as result WITHOUT link selectedEL.PasteSpecial ("CATPrtResult") 'paste as result WITH link selectedEL.Clear Next Else 'Debug.Print (instance.Name & " is NOT visible") End If Next newPart.Update End Sub Function isVisible(ByRef object As Variant) As Boolean 'function for cecking hide/show of part CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End FunctionRE: Copy & Paste published elements in context
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
But I'm glad you stayed here with me and learned & share your result.
Just few more things:
you did comment your code, but not enough... please give more info while commenting. Check CATScript in v5automation.chm
if you want to work with multi level product you need to learn about Recursion.
indocti discant et ament meminisse periti
RE: Copy & Paste published elements in context
Here is my code:
CODE -->
Sub CATMain() Dim rootProduct As Product Set rootProduct = CATIA.ActiveDocument.Product 'first check if document is part or product If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then MsgBox rootProduct.Name & " Is NOT Assembly!" Exit Sub End If Dim PartsCount As Integer PartsCount = rootProduct.Products.Count 'count of parts and instances to use 'Enter name od new Part Dim newPartName As String newPartName = InputBox("Please enter new Part name.") Dim newPart As Product Set newPart = rootProduct.Products.AddNewComponent("Part", newPartName) 'create part paste in it Dim targetPart As Part Set targetPart = newPart.ReferenceProduct.Parent.Part 'create Geometical set in new part 'Dim geomSetTarget As HybridBody 'Set geomSetTarget = targetPart.HybridBodies.Add 'geomSetTarget.Name = "CopyOfReferences" Dim vp As VisPropertySet 'loop trough parts For i = 1 To PartsCount Set instance = rootProduct.Products.Item(i) 'check if part is visible, so it takes only visible parts If isVisible(instance) Then 'count published elements which will be copied Dim publCount As Integer publCount = rootProduct.Products.Item(i).Publications.Count Dim selectedEL As Selection Set selectedEL = CATIA.ActiveDocument.Selection selectedEL.Clear 'loop trough published elements in every part For j = 1 To publCount Set publishedEL = rootProduct.Products.Item(i).Publications.Item(j) selectedEL.Add publishedEL selectedEL.Copy selectedEL.Clear selectedEL.Add targetPart 'uncomment if paste WITHOUT link 'selectedEL.PasteSpecial ("CATPrtResultWithOutLink") 'paste elements WITH link selectedEL.PasteSpecial ("CATPrtResult") selectedEL.Clear Next Else 'Debug.Print (instance.Name & " is NOT visible") End If Next newPart.Update '-------------------------------------------------------------------------------------- 'Section for retreiving positions and rotation angle fo elements Dim axisCount As Integer Dim LinesCount As Integer Dim Xaxis1 As Double Dim Xaxis2 As Double LinesCount = targetPart.HybridBodies.HybridBody.Item(1).GeometricElements.Count Debug.Print LinesCount 'counting axissystems in new part axisCount = targetPart.AxisSystems.Count 'Loop trough axissystems to retreive components For i = 1 To axisCount Set ASys = targetPart.AxisSystems.Item(i) Set Oref = targetPart.CreateReferenceFromObject(ASys) Set TheSPAWorkbench = CATIA.ActiveDocument.GetWorkbench("SPAWorkbench") Set TheMeasurable = TheSPAWorkbench.GetMeasurable(Oref) Dim Components(11) TheMeasurable.GetAxisSystem Components Components(0) = Round(Components(0), 3) Components(1) = Round(Components(1), 3) Components(2) = Round(Components(2), 3) Components(3) = Round(Components(3), 4) Components(6) = Round(Components(6), 4) Debug.Print targetPart.AxisSystems.Item(i).Name & " x "; Components(0) & " y "; Components(1) & " z"; Components(2) Xaxis1 = Components(3) Xaxis2 = Components(6) If (Xaxis1 = 1) And (Xaxis2 = 0) Then 'Parallel to X Debug.Print "Parallel to X" ElseIf (Xaxis1 = -1) And (Xaxis2 = 0) Then 'Parallel to X 180° rotated Debug.Print "Parallel to X 180° rotated" ElseIf (Xaxis1 = 0) And (Xaxis2 = -1) Then '+90° rotarted Debug.Print "+90° rotarted" ElseIf (Xaxis1 = 0) And (Xaxis2 = 1) Then '-90° rotarted Debug.Print "-90° rotarted" ElseIf (Xaxis1 > 0) And (Xaxis2 < 0) Then 'First quadrant Debug.Print "First quadrant" ElseIf (Xaxis1 < 0) And (Xaxis2 < 0) Then 'Second quadrant Debug.Print "Second quadrant" ElseIf (Xaxis1 < 0) And (Xaxis2 > 0) Then 'Third quadrant Debug.Print "Third quadrant" ElseIf (Xaxis1 > 0) And (Xaxis2 > 0) Then 'Fourth quadrant Debug.Print "Fourth quadrant" End If Next End Sub Function isVisible(ByRef object As Variant) As Boolean 'function for cecking hide/show of part CATIA.ActiveDocument.Selection.Clear CATIA.ActiveDocument.Selection.Add object Dim vp As VisPropertySet Dim showstate As CatVisPropertyStatus Set vp = CATIA.ActiveDocument.Selection.VisProperties vp.GetShow showstate result = True If showstate = catVisPropertyNoShowAttr Then result = False CATIA.ActiveDocument.Selection.Clear isVisible = result End Function