Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Use VBA to Add Qty Req'd to Custom Properties for Components from the ****'y?

24 REPLIES 24
SOLVED
Reply
Message 1 of 25
tdswanson
2236 Views, 24 Replies

Use VBA to Add Qty Req'd to Custom Properties for Components from the ****'y?

Hello:

 

I'd like to create a macro that I can run from within an assembly that will loop through each BOM item and add the quantity req'd to a custom property within the component.  I'm very familiar with VBA from Office, but I'm new to it with respect to Inventor so I'm pretty fuzzy with object titles and options.  Can someone assist with the coding?

 

Here's an outline of what I'd like to do:

 

Execute Macro from within Assembly file

 

For Each BOM Item to # of BOM Items

 

  If Vendor = "Make" then

    Set Component Custom Property "Qty_Reqd" = Total Qty from BOM

  Endif

 

Next BOM Item

 


Can someone help and/or Is there an easier way?

 

Thanks!!

24 REPLIES 24
Message 2 of 25
MegaJerk
in reply to: tdswanson

The below example is code that I use to look at each part in an assembly, tally up how many of each is being used, and throw that total into the Authority iProperty of each part. The only reason that I used a stock (vanilla) iProperty as the value holder is so I can more easily access it from the drawing where I need to display totals next to things like flat patterns, etc. etc.

However, if you don’t need to show these values on the drawings, then we’ll go with a custom iprop. Right now I’m just going to post the code that I have as I am at work. I also would like a little more information from you before I customize this to match your needs better. As it is, the code now looks for all parts that are able to be modified (IE: non-suppressed parts / non-library content center files), but you mention that you may have something in place that determines which parts you’ll be using (Vendor?). So are you using another iProperty, or are you too also just using what hasn’t been suppressed by a Level of Detail to determine which parts will actually be manufactured?

Once you provide that info I will be able to customize this for you, or you can set off to customizing it on your own. I know that a few posts back I helped someone with something similar, so if you click on my user name and look for my posts you might be able to find some other interesting information back there.

------------

 

Dim openDoc As Document
openDoc = ThisDoc.Document
Dim docFile As Document
If openDoc.DocumentType = 12291 Then    
For Each docFile In openDoc.AllReferencedDocuments
If docFile.IsModifiable = True Then
If docFile.DocumentType = 12290 Then
Dim assemblyDoc As AssemblyDocument
assemblyDoc = openDoc
Dim assemblyDef As AssemblyComponentDefinition
assemblyDef = assemblyDoc.ComponentDefinition
Dim partDoc As PartDocument
partDoc = ThisApplication.Documents.Open(docFile.FullFileName, False)
Dim partQty As ComponentOccurrencesEnumerator
partQty = assemblyDef.Occurrences.AllReferencedOccurrences(partDoc)
'MessageBox.Show(partQty.Count, "")
If IsNumeric(partQty.Count) = True Then
If CDblAny(partQty.Count) <>  CDblAny(iProperties.Value(docFile.DisplayName, "Project", "Authority")) Then
iProperties.Value(docFile.DisplayName, "Project", "Authority") = partQty.Count
partDoc.Close
Else 
partDoc.Close
End If 
End If 
Else 
Dim docDisplayName As String	
If docFile.LevelOfDetailName <> "Master" Then 
docDisplayName = (Left(docFile.DisplayName, Len(docFile.DisplayName) - Len(docFile.LevelOfDetailName) - 3))
'MessageBox.Show( (Left(docFile.DisplayName, Len(docFile.DisplayName) - Len(docFile.LevelOfDetailName) - 3)) ,"")
Else
docDisplayName = docFile.DisplayName
'MessageBox.Show(docFile.DisplayName,"")
End If 
If iProperties.Value(docDisplayname, "Project", "Authority") <> "Assembly" Then 
iProperties.Value( docDisplayName, "Project", "Authority") = "Assembly"
End If 
End If 
End If
Next
Else
MessageBox.Show("You must have a valid Assembly document open before using this code!", "File Type Mismatch!",MessageBoxButtons.OK,MessageBoxIcon.Exclamation)
End If 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 3 of 25
tdswanson
in reply to: MegaJerk

Thanks MegaJerk, your assertions are right on target. 

 

The end goal is to place "Quantity Req'd: X" on the print for the component without me having to manually do it.  I don't use the "Authority" field, so I guess I really don't care much about which particular field that we use to populate the data.

 

And yes, for custom components, I typically enter the word "Make" in the vendor field for the component model.  This will then differentiate the custom components in the parts lists on my assembly prints.

 

So I planned on using the Vendor field as a trigger point for the modification.  But your way looks to be more sophisticated, so that will probably work too.

 

Thanks very much for your help!  I'll paste your code in and run some tests and see how it goes.

Message 4 of 25
tdswanson
in reply to: MegaJerk

Wait, is this VBA or iLogic?

 

It won't run in VBA.  I get errors in the first couple lines, the MessageBox command at the bottom is bad, and I need to change most of the variable setting steps to utilize the "Set" method. 

 

Am I missing something?

Message 5 of 25
MegaJerk
in reply to: tdswanson

iLogic



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 6 of 25
tdswanson
in reply to: MegaJerk

Ahhh, well that explains it....  I'm even less experienced with this.  So I create a rule with this pasted in, right?  How do you trigger it?

Message 7 of 25
tdswanson
in reply to: tdswanson

OK, so I've got that stuff figured out and I've got a rule created.  However, in my test assembly, it's getting hung up on a phantom sub-assembly created by the bolted joint wizard.

 

The error is:

 

*** iProperties: The component named "Bolted Connection" was not found.***

 

Can we filter out components that are phantom?

 

Thx

Message 8 of 25
MegaJerk
in reply to: MegaJerk

Ah! I’ve never messed with virtual components. If you’re using Inventor 2012 and happen to be able to post a small assembly that has everything needed, do so. Otherwise, when I get home I will mess around with recreating (and fixing) said error.

Darn! 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 9 of 25
tdswanson
in reply to: MegaJerk

Well I'm messing around a little myself with the iLogic code (my first time) and it looks pretty handy......

 

However, it looks like most of the fields that I would use to differentiate "make" parts for this code are unavailable to iLogic.  It doesn't look like I can choose the "BOM Structure" field or the "Vendor" field.  Am I wrong?

 

I'm using IV2012, but I really can't post my assembly because it's got customer proprietary stuff in it.  I'll see if I can get around to making up a test one with just some plates and a bolted joiint in it.

 

Thx!

Message 10 of 25
tdswanson
in reply to: tdswanson

OK:

 

Here's a simple assembly with two flat plates and a bolted joint holding them together.  Same issue is present with the iLogic rule.  I'll be messing around a bit too over the weekend.

 

Thanks again for your help!

Message 11 of 25
MegaJerk
in reply to: tdswanson

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. 




If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 12 of 25
tdswanson
in reply to: MegaJerk

Hey Magejerk:

 

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?

 

Thanks again!

Message 13 of 25
MegaJerk
in reply to: MegaJerk

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. 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 14 of 25
MegaJerk
in reply to: MegaJerk

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(docFile)
            
            If IsNumeric(partQty.Count) = True Then
                Set partOcc = partQty.Item(1)
                Set RefFile = partOcc.ReferencedDocumentDescriptor.ReferencedFileDescriptor
                
                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

 

 

 

 

 

 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 15 of 25
tdswanson
in reply to: MegaJerk

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!

Message 16 of 25
MegaJerk
in reply to: tdswanson

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! 

 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 17 of 25
Greatwhitenorth
in reply to: MegaJerk

Hi MegaJerk,

 

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.

 

Bob

____________________________________________________
Product Design & Manufacturing Collection 2021 | Vault Professional 2021
Dell Precision 7670 | Intel i7-12850HX - 2100 Mhz - 64GB
nVIDIA RTX A3000 12GB | Windows 10/64 Pro
Message 18 of 25
MegaJerk
in reply to: MegaJerk

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. 




If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 19 of 25
Greatwhitenorth
in reply to: MegaJerk

The parts list would include:

 

- ITEM No.

- QTY

- TOTAL QTY

- DESCRIPTION

- PART No.

 

Thanks for looking into this.

 

Bob

____________________________________________________
Product Design & Manufacturing Collection 2021 | Vault Professional 2021
Dell Precision 7670 | Intel i7-12850HX - 2100 Mhz - 64GB
nVIDIA RTX A3000 12GB | Windows 10/64 Pro
Message 20 of 25
Nsteel
in reply to: MegaJerk

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?

 

Thanks,

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report