By Adam Nagy
I've seen a few posts on the forum about trying to use iLogic code inside iAssembly and iPart factories to customize the created member file to change e.g. some of its iProperties.
So I thought it could be useful to talk about the internal process of member creation.
This is quite straight-forward. In this case when an iAssembly instance's row is changed in the containing assembly document then Inventor checks if the appropriate member file already exists. If it does, there is nothing to do. If it does not, then:
1) it copies the iAssembly factory file and names it according to the member name
2) updates the properties in the member file based on the iAssembly table row info
3) saves and closes the member file
So in this case if the iAssembly factory has a rule that fires on "Before Save Document" which modifies the document, then it basically modified the created member file - which is what you probably want.
This is more complicated. When an iPart instance's row is changed in the containing assembly document then Inventor checks if the appropriate member file already exists. If it does, there is nothing to do. If it does not, then:
1) it creates a new part file based on the active part file template and names it according to the member name
2) in the factory file it starts a transaction which will be aborted later, so that the factory file does not get modified in the end
3) inside the transaction it changes the iPart row to the required one
4) stores all the info it will need later on for the member file: the generated geometry, iProperties, Parameters, etc
5) aborts the transaction
6) copies the previously stored info into the member file
7) saves and closes the member file
So in this case if the iPart factory has a rule that fires on "Before Save Document" which modifies the document, then it has no effect on the created member file because the event is not firing inside the member file, but inside the factory. Also, inside member files most iLogic functionality, along with lots of other features as well, is disabled so it could not fire an event anyway (you could run a rule explicitly though).
Unfortunately, there are no events specific to member file generation steps that would fire e.g. before the information from the factory file gets saved.
We only have the ModelingEvents.OnGenerateMember (the closest to it in iLogic is "iPart or iAssembly Change Component" but that also fires if the member is already available) but that fires inside the assembly that contains the iPart/iAssembly member instance, not inside the member or the factory.
Hooking into other events could achieve some results, but it might not be very robust.
E.g. if you have a rule in the iPart factory that is set to fire on "Part Geometry Change" to modify some geometry and in it you also synchronously update the document to reflect the changes immediately (using Document.Update2()), then it can modify the geometry that gets copied into the created member file.
But e.g. if you try to modify there an iProperty (like Project >> Description) that will be too late. It seems by the time "Part Geometry Change" is fired those already got stored. Also, that seems to be the only event firing during member creation.
Note: the workaround in the following article only works when you modify the iPart table row explicitly when the factory file is open. It does not work if the row is changed as a result of a row change on a member instance inside an assembly: http://adndevblog.typepad.com/manufacturing/2015/12/no-iproperty-change-event-fired-for-ipart-row-change.html
Best thing is to keep everything you want to drive inside the member files in the iPart/iAssembly table: the Parameters, the iProperties, etc.
So if you want to drive e.g. the Project >> Description property, add that to the table:
Since iParts and iAssemblies are driven by an Excel table, you can also use Excel functions to calculate things and set up relationships between cells: