Delete all components from assembly fast

Delete all components from assembly fast

RolfEven
Enthusiast Enthusiast
2,047 Views
15 Replies
Message 1 of 16

Delete all components from assembly fast

RolfEven
Enthusiast
Enthusiast

Hi,

I have been puzzling over something that I think I'm just doing wrong. What I want to do is simply delete all components in an assembly as fast as possible. The code below does work, but it is painfully slow on larger assemblies, as it deletes occurence one by one. I have not found a code solution to delete everything in one go. If anybody could help me with the lines, I would highly appreciate that.

 

Dim activeDoc As AssemblyDocument
activeDoc = ThisApplication.ActiveDocument

Dim assemblyDef As AssemblyComponentDefinition
assemblyDef = activeDoc.ComponentDefinition

' Disable graphics update to speed up the deletion process
ThisApplication.SilentOperation = True

' Iterate through all component occurrences and delete them
For Each compOcc As ComponentOccurrence In assemblyDef.Occurrences
    compOcc.Delete
Next

' Enable graphics update after deletion
ThisApplication.SilentOperation = False

MsgBox("All components deleted successfully.", vbInformation, "iLogic")

 


Thanks,
/Rolf Even

0 Likes
Accepted solutions (1)
2,048 Views
15 Replies
Replies (15)
Message 2 of 16

Frederick_Law
Mentor
Mentor

Doesn't delete all component in assembly equal to a new empty assembly?

 

Maybe put them all in selection list and delete?

https://help.autodesk.com/view/INVNTOR/2023/ENU/?guid=GUID-9A2B712A-A08C-4C1D-B3D8-8BE5B3A013C0

0 Likes
Message 3 of 16

RolfEven
Enthusiast
Enthusiast

Understandable question regarding New assembly, but I want to keep the current assembly, with it's Vault versions, iProperty values etc. I want to get rid off current assembly content and afterwards bring in different content.

 

If I do this by hand, select all components and press Delete, it takes Inventor some time to select all components, but the delete is fast. This feels like something that is easy, but I have not found a way to write this correctly in iLogic.

 

Thank you for the link, I'll see if I can figure out a solution.

 

0 Likes
Message 4 of 16

Frederick_Law
Mentor
Mentor

You can overwrite old file with new one using same name.

Add iProperties value and other info you need with iLogic.

 

I do that all the time manually and with iLogic.  Vault won't complain.  As long as Revision is set.

Currently using iLogic to update Modelstate drawings.

Instead of edit and modify drawing, Save as from a "Template" and overwrite old one.

Because view and a few things were changed and there are 200 drawings.

Vault will keep the old versions.

0 Likes
Message 5 of 16

RolfEven
Enthusiast
Enthusiast

I think I understand your sugested workflow, I just need to re-think the process at my end a bit.

Appreciate the help so far, and I will explore that link you shared.

0 Likes
Message 6 of 16

A.Acheson
Mentor
Mentor

Hi @RolfEven 

 

Maybe starting a transaction is key here. All deleted parts will be under one instead of under one per occurrence. See help page here.

In my opinion it isn't possible to delete all in one go as you still need to grab the occurrence object and call the delete function. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 7 of 16

J-Camper
Advisor
Advisor
Accepted solution

@RolfEven,

 

I thank you for asking the question.  Before looking into this, I never realized you could cast an enumerator into an object collection while creating it.

 

This should be fast:

 

 

If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub
Dim ss As SelectSet = ThisDoc.Document.SelectSet
ss.Clear()
'Delete Patterns until there are no more
Dim oc As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection(ThisDoc.Document.ComponentDefinition.OccurrencePatterns)
While oc.Count > 0
	ss.SelectMultiple(oc)
	ss.Delete()
	oc = ThisApplication.TransientObjects.CreateObjectCollection(ThisDoc.Document.ComponentDefinition.OccurrencePatterns)
End While
'Delete All Occurrences
Dim oc2 As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection(ThisDoc.Document.ComponentDefinition.Occurrences)
ss.SelectMultiple(oc2)
ss.Delete()

 

 

The slowest part is the SelectMultiple Method which takes about 10 sec for an assembly with 500 occurrences.

 

Message 8 of 16

A.Acheson
Mentor
Mentor

Hi @J-Camper 

Certainty a fast method nice thanks for sharing, 700 occurrences in 1.53 sec vs 11 sec one by one. The power of the select set I guess. 

I can confirm the transaction has no bearing on the time in this case. 

 

Here is a  timer I found on here a while ago, handy when testing. 

Dim stopWatch As New Stopwatch()
stopWatch.Start()

'enter your code to run here 


stopWatch.Stop()	

'Get the elapsed time as a TimeSpan value.
Dim ts As TimeSpan = stopWatch.Elapsed

'Format and display the TimeSpan value.
Dim elapsedTime As String = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10)

MsgBox("RunTime " & elapsedTime)

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 9 of 16

RolfEven
Enthusiast
Enthusiast

Hi @A.Acheson & @J-Camper,

 

Thank you both for helping me, highly appreciated. I have run the two different delete codes in this post together with the Stopwatch-code. For an assembly with 1711 Total Occurrences in Active document and 750 Documents open in session, I got these performances:

 

Code in post 1: Runtime 00:02:45:33 | CPU one core varies @3,40-4,25 GHz.

Code in post 7: Runtime 00:00:06:14 | CPU one core stable @5,25 GHz.

 

A huge difference between the two different codes.

 

Out of curiosity; All assembly components are on assembly first level, and all of them are inside browser folders. I'm not sure if it possible to exploit that in order to speed up delete even further. For instance, "Delete components in Browser folder named Container, then Container2, then..."?

0 Likes
Message 10 of 16

Frederick_Law
Mentor
Mentor

@J-Camper wrote:

 

I thank you for asking the question.  Before looking into this, I never realized you could cast an enumerator into an object collection while creating it.

This?

For Each compOcc As ComponentOccurrence In assemblyDef.Occurrences
    compOcc.Delete
Next

 

The power and curse of VB Dim everywhere and late casting.

Don't get used to it.  Other langrage won't allow it.

Late casting run slower also.

0 Likes
Message 11 of 16

J-Camper
Advisor
Advisor

@Frederick_Law,

No I meant this:

Dim oc As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection(ThisDoc.Document.ComponentDefinition.Occurrences)

The object collection is nearly instantly filled with the all elements of the enumerator.  Object collections are used for a lot of inputs so I was happy to find that i could essentially covert an enumerator into an object collection without looping through the enumerator to add each element to the collection.

Message 12 of 16

Frederick_Law
Mentor
Mentor

It's using late binding:

VB-01.jpg

 

Intellisense doesn't work with late binding.

Sometime late binding give different object type than what I thought.  Difficult to debug.

Also I'm trying to use C# for addin.

0 Likes
Message 13 of 16

charles4L34S
Contributor
Contributor

Just used this replace a For/Each in a cleanup rule (the assembly is build using a configurator)

 

Huge improvement, and my max part count is as low as 6.

 

Thanks for sharing.

0 Likes
Message 14 of 16

RolfEven
Enthusiast
Enthusiast

-

0 Likes
Message 15 of 16

RolfEven
Enthusiast
Enthusiast

This is what I really like about this forum. Skillful people reply in no time and produces solutions to other people's challenges. Possibly discovering something useful elsewhere along the way. Then somebody else uses the provided code for similar/different things.

Brilliant, and thank you all for helping me 🙂

/Rolf Even

0 Likes
Message 16 of 16

A.Acheson
Mentor
Mentor

I don't think working through the browser nodes would be faster. If you manually select a folder only the folder gets selected. You would need to loop through the folder browser nodes one by one and select then find it's native object the occurrence and then delete. Effectively the same as what the code does currently but in a different method. Here is an an example of browser node/ interaction.

 

An alternative to this is to select the browser folder and run the command select folder contents and delete. I am not sure there is a usable workflow in this, just some thoughts to think over. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes