Sorry for the long delay on this. My weekend turned out to be full of thrills and chills, leaving little time for Inventor.
No matter, I think that I've cracked. Give the following code a try and tell me if it works correctly for your full assemblies.
I ran a quick test in one of my assemblies and it seems to work perfectly. Thank you so much for your help.
I also looked into using the iTrigger button to fire it, but I can't seem to make it work. As I understand it, you need to put a line of code in the rule that says "trigger = iTrigger0" which I did. When I click the button, it creates a parameter in the assembly and increments it by one, but the rule doesn't fire. What am I doing wrong?
On another note, how on earth did you learn this stuff? I have yet to find a good reference that contains any of the object names and method strategies that you employed here. Everything I can find seems to relate to parameters and part model automation..... I've found very little that contains information about the document structures, getting at components inside an assembly, etc. Any suggestions of where to start climbing the learning curve?
I would suggest that instead of trying to tie this into an iTrigger, you simply set it up on a normal ilogic Rule Event Trigger (perhaps even as an external rule).
Go to the Manage tab, and select Event Triggers (iLogic section above iTrigger). Double click on Before Save Document to open up the Rule Association Browser, and select the iLogic rule that contains my code. After that , just make sure that the top check box “Run these rules when events occur” is checked on the main Rules Triggered by Events box, then hit OK.
As for learning these things, it has been a combination of a few very awesome blogs, this community, and stumbling around the Inventor Object Library in VBA.
After I get out of work, I will gladly compile a list of references and places you can go to get you on track to learning the ins and outs of Inventor API stuffs.
Also, if you are satisfied with the above code for your needs, please accept that post as a solution as it will help others who are looking to do the same thing in the future (Gotta keep the community tidy!).
More posts from me later on.
Peace for now.
Alright so as promised. Here are some of the resources that I use to learn stuffs.
First and foremost, blogs. There are a few really notable ones that exist, and a few of the authors roam these forums, which is even more useful!
For the Tips n' Tricks blogs I would suggest Being Inventive and Curtis's blog, From the Trenches.
For the more code oriented aspect of things, there is Brian Ekins Mod The Machine and the new Inventor Manufacturing Dev Blog. Those are far more VB.Net coded orriented (VBA coding as well) sites, with Mod the Machine acting more as a 'how in the hell do I manage to do this?' guide, and the DevBlog as more of a 'Now why didn't I think of that?' sort of place.
In the end, one of the other best places to get information about things is the VBA help file itself.
While in Inventor press Alt + F11 to open the Microsoft Visual Basic environment. If you navigate to the object browser you can search for Inventor Objects (such as AssemblyDocument), right click, and select help. This should open up the Autodesk Inventor 2012 COM API Reference help file, and inside it contains a whole hell of a lot of information that you can use to help supplement all of our wild code examples (as you can use the API directly from iLogic!). It may not be the most intuitive way of learning, but if you ever run into a wall, you can always post a question on the forums and someone should see it and be able to respond.
Other than that, I suggest using the VBA debugger to help crawl through a program line by line to see what is changing and the general structure of the objects you’re accessing. I’m not the most code savviest person on the face of this planet, so when I figured that out it was like taking the blinders off.
The code below is a little test program you can throw into VBA to get started (add a new module, and paste this code into the new module window (you’ll also need to have an assembly open in Inventor)). All it does is look at each part and determines if it’s a library part, a local part, a remote part, or some other strange sort of part. If you were to go to View à Toolbars and check the Debug bar, a new bar would pop up that will allow you to step through the code line by line. On the debug bar click on the Locals Window button, and the Immediate Window button, then (after clicking back inside of the window with your code (somewhere between the public sub and End sub)), go up and press the Step Into button to begin going through the code. You’ll notice that it will build a list of empty and assigned objects in the Locals Window. You can expand those to see what they are made of, and get a good idea on how to change / call / query those aspects.
I hope that this helps with getting you down the path of Inventor API madness. Also, for kicks you can check out the pinned topic of this forum “Getting Started: My First Pluggin” as it too will help in getting your hands dirty with the API development and access.
If you have any further questions, please ask!
Public Sub LibraryChecker() Dim openDoc As Inventor.Document Dim docFile As Inventor.Document Dim assemblyDoc As AssemblyDocument Dim assemblyDef As AssemblyComponentDefinition Dim partQty As ComponentOccurrencesEnumerator Dim partOcc As ComponentOccurrence Dim RefFile As FileDescriptor Dim PartLocation As String Set openDoc = ThisApplication.ActiveDocument If openDoc.DocumentType = kAssemblyDocumentObject Then Set assemblyDoc = openDoc Set assemblyDef = assemblyDoc.ComponentDefinition For Each docFile In openDoc.AllReferencedDocuments 'If docFile.DocumentType = kPartDocumentObject Then Set partQty = assemblyDef.Occurrences.AllReferencedOccurrences(d
ocFile) If IsNumeric(partQty.Count) = True Then Set partOcc = partQty.Item(1) Set RefFile = partOcc.ReferencedDocumentDescriptor.ReferencedFil eDescriptor Select Case RefFile.LocationType Case Is = kLibraryLocation PartLocation = "Library Part" Case Is = kWorkspaceLocation PartLocation = "Local Part" Case Is = kWorkgroupLocation PartLocation = "Remote Part" Case Is = kUnknownLocation PartLocation = "Unknown Location" End Select Debug.Print (partOcc.Name & " --- " & PartLocation) Else Debug.Print (docFile.DisplayName & " --- Is Not Active.") End If 'End If Next End If End Sub
Wow that's very helpful and very thorough. I guess that was one of my most basic questions...... What is the connection between the iLogic langauge and VBA? The code that you sent me wouldn't compile when I tried to step through it in the VBA browser. If I recall, it was mostly method issues when calling out a messagebox or something like that. After seeing that, I assumed that they were two different langauges with no connection.
But it seems that some objects and methods are common then?
I've been doing advanced VBA stuff in Excel for years and I love it. I've done a little bit in other office programs, but never with any AutoDesk products. VBA is so application-specific that when you start doing it in a new application, it's like learning a new language altogether because so many things are different from program to program.
I've seen some of the individual posts on both of those blogs I think when Google searches picked them up for me. I'll get them added into my RSS feed.
Thanks again for all your help! If you should ever need Excel VBA help, look me up!
Well it should be stated that an iLogic rule can contain VB.net code (or just regular ol' VBA), and not have any 'iLogic' code in it. In a nut shell, iLogic is an exclusive collection of methods that are only recognized when used in the context of an iLogic rule inside of Inventor. For instance the command :
Component.IsActive("ComponentName : #") = True / False
This will change the suppression state of the component named, and is an ilogic statement. Becasue of this you may notice that you don't have to declare just where that component exists, as it tries to derive the context from the place you are running the actual rule from. That is, if you run that command in a rule that is in the main assembly and your componet named exists inside the first level of that assembly, it will have its state changed. However, if you attempt to run that from a part file it will simply error out as it can not grasp the correct context from the environment.
So when you start to mash the two together inside of a rule, you can get the full power of the API plus the additional ease of having some of the methods automatically applied within the correct context.
Using the sollution code I will provide an example of a mashup
There is a line :
iProperties.Value(docFName, "Project", "Authority")
That bit of code would not work inside of VBA or VB.net, but iLogic (please refere to your iLogic snippets specifically for this line of code) is able to handle and point to iproperties that I would otherwise have to map out, making life easier.
Normally I would have to work my way through the PropertySets of an object, but this way I can simply declare the name of the document I would like to interact with, the iproperty tab, and the iproperty itself, and it does the rest.
It should also be said that most things you write in VBA can work in the iLogic rule editor so long as you remove the ‘Set’ and ‘Let’ keywords. You can also get a lot of ilogic code working inside of VBA if you include the Set keyword when setting the value of an object. Of course, no matter what you will not be able to use the iLogic only keywords inside of anything other than iLogic.
I hope that this helps!
We've been looking for something like this for some time, so I tried your code and it works great. The problem is, is that we need to show total quantities for library parts too, which of course it can't do, since it would require updating those.
Is there a way that it could create an external Excel file, with the same path & file name as the top-level assembly, to store this information? Then when placing a parts list on the drawing, it could look up the total quantity from this Excel file? We do the "one" model per drawing, so it could use the model name as its look up value.
The program would have to update the Excel file if it already existed.
Thanks in advance.
Are you using just a default Parts List with no custom properties added? I don't know if this is important, but I suppose it's worth asking ahead of time, just in case.
The parts list would include:
- ITEM No.
- TOTAL QTY
- PART No.
Thanks for looking into this.
This is a great peice of code!
Can I ask how you would make it only go through items in the top-level assembly it is being run from and not to go through any assemblies within the top-level?