Because I have been doing a lot of work on some heavy duty rules as of late, I decided that maybe it was time to stop using so much copy / paste, and set some often used functions up in my external rules. Our company does this for a few mathematical functions that require a number of Double inputs and spits out the resulting sum (as double), so I figured it wouldn't be so bad to just tack it onto the end of said existing external rule.
The problem that I run into is that Inventor fails to recognize any of the calls to the Inventor Object Library!
As of right now, I'm not importing anything into the rule, and I know for a fact that the rule is set up as VBOnly (as it's nested inside of a module with no sub main()). Is there something that I need to do, or some way that I need to make a call so that I can use these functions from anywhere in my internal / standard rules?
The code that I would like to get working is as follows...
Public Function GetPartGroup(docAP As Inventor.Document) As String
Dim PartLocation As String
PartLocation = "Nothing"
Dim RefFile As Inventor.FileDescriptor
If docAP.File.ReferencedFileDescriptors.Count > 0 Then
RefFile = docAP.File.ReferencedFileDescriptors.Item(1)
Select Case RefFile.LocationType
Case Inventor.LocationTypeEnum.kLibraryLocation
PartLocation = "Library Part"
Case Inventor.LocationTypeEnum.kWorkspaceLocation
PartLocation = "Local Part"
Case Inventor.LocationTypeEnum.kWorkgroupLocation
PartLocation = "Remote Part"
Case Inventor.LocationTypeEnum.kUnknownLocation
PartLocation = "Unknown Location"
End Select
Return PartLocation
End If
End Function
Btw, this will take a document and tell me if it's a library / standard / or some other variant type part.
Thanks for any help.
Solved! Go to Solution.
Solved by MjDeck. Go to Solution.
Because I made this post right before I left work, I rushed a little and didn’t get the best information possible.
I have several external rules that work perfectly using the Inventor API. The thing that I am curious about at the moment is if you can have a function in an external rule that not only access the API but also returns a value to an internal rule.
Thanks for any help that you can provide on this subject.
I have started to work my way through this problem but I would love some feedback from Autodesk / Anyone In the Know - on a strange issue that I'm encountering.
First thing first, I have attached two files. One is called CustomFunctions.iLogicVb which is my external rule file, and the other .txt is the rule file that I will be using internally in Inventor. You can use the internal Rule file anywhere as it's not making any environmentally dependent calls.
Basically, if I have a rule file that has a call for AddVbFile "YourFileNameHere.iLogicVB" but do NOT make any calls to the Inventor API (Application) from within that rule, it will not invoke the Inventor application for use inside of the external rule!
This basically means that this fails with errors for any line containing an API call in the external rule ->> :
AddVbFile "CustomFunctions.iLogicVb"
Dim ThisApp As Object
Dim Num1, Num2 As Integer
Num1 = 12
Num2 = 10
If Num1 > Num2 Then
MessageBox.Show("Num1 is larger!")
Else
MessageBox.Show("Num2 is larger!")
End If
'''''''''ThisApp = ThisApplication <-- Totally commented out!
While this succeeds... :
AddVbFile "CustomFunctions.iLogicVb"
Dim ThisApp As Object
Dim Num1, Num2 As Integer
Num1 = 12
Num2 = 10
If Num1 > Num2 Then
MessageBox.Show("Num1 is larger!")
Else
MessageBox.Show("Num2 is larger!")
End If
ThisApp = ThisApplication ' <-- Totally not commented out!'
The external rule that I am currently using :
' <IsStraightVb>True</IsStraightVb>
Public Module CustomFunctions Public Function ReturnString(OutPut As String) As String If OutPut = "" Then OutPut = "Nothing here" End If Return OutPut End Function Public Function ReturnDouble(OutPut As Double) As Double If OutPut = 0 Then OutPut = 1 End If Return OutPut End Function Public Function GetPartGroup(docAP As Inventor.Document) As String Dim PartLocation As String PartLocation = "Nothing" Dim RefFile As Inventor.FileDescriptor If docAP.File.ReferencedFileDescriptors.Count > 0 Then RefFile = docAP.File.ReferencedFileDescriptors.Item(1) Select Case RefFile.LocationType Case Inventor.LocationTypeEnum.kLibraryLocation PartLocation = "Library Part" Case Inventor.LocationTypeEnum.kWorkspaceLocation PartLocation = "Local Part" Case Inventor.LocationTypeEnum.kWorkgroupLocation PartLocation = "Remote Part" Case Inventor.LocationTypeEnum.kUnknownLocation PartLocation = "Unknown Location" End Select 'MsgBox("test" & PartLocation,vbOKOnly ) Return PartLocation End If End Function End Module
Is this intended behavior? Is there a to invoke the Inventor Application from the declaration section of the external rule, or must I make an arbitrary call inside of any internal rule that might want to use a function from my iLogicVb file?
It's strange to me that so long as I invoke it somewhere in my internal rule, it will work, even if it's at the very very very end of the file. Being that I assume iLogic is compiled line by line (like anything else) it makes me curious as to why it would be alright with having the Application assigned to something AFTER the calls to the external rule, rather than before.
I hope that someone can help me with this problem.
Thank you for your time.
Hi MegaJerk,
Just giving this a bump. I'm interested in using this strategy also.
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
MegaJerk,
You have found the solution. To provide maximum flexibility in the rule code and to gain a bit of performance, the Inventor API is not referenced unless you explicitly ask for it. And when you add an external rule with AddVbFile (or an internal one with AddVbRule), the API reference has to be in the main rule. Often you would use the API in the main rule to get an object to send to the added rule.
Rules are compiled completely before they are run. They are run line-by-line, but not interpreted line-by-line. So a call to the Inventor API anywhere in the main rule will cause the API to be loaded, and it will be available to the added rule..
Alrighty! So for anyone else that has this question, I suppose it could be summarized by saying that:
1: Using an external rule (module / function / StraightVB combo) to return normal VB datatypes (integers, strings, longs, etc. etc.) is fine, no matter what your internal rule is doing, so long as the function arguments are also of the normal VB datatypes.
EX: Internal Rule -
AddVbFile "MathMagic.iLogicVb" Dim Num1, Num2, Num3 As Integer Num1 = 12 Num2 = 10 Num3 = LargestNumber(Num1, Num2) Msgbox(Num3)
External Rule (Set to StraightVB Only in options) :
Public Module MathMagic Public Function LargestNumber(Num1 As Integer, Num2 As Integer) As Integer If Num1 >= Num2 Then Return Num1 Else Return Num2 End If End Function End Module
Results in a message box that reads : 12
2: Using an external rule (same as above) to return normal VB datatypes, but that require Inventor API specific data types, or that use Inventor API specific objects inside of their block, must be initialized first by making a call to the Inventor API inside of the internal rule that you want the values to be returned to.
EX: Internal Rule -
AddVbFile "MathMagic.iLogicVb" Dim oDoc As Inventor.Document '<- Inventor API call Dim oFileName As String oDoc = ThisApplication.ActiveDocument oFileName = MyFileName(oDoc) Msgbox(oFileName)
External Rule (Set to StraightVB Only in options) :
Public Module MathMagic Public Function MyFileName(SentDoc As Inventor.Document)As String Return SentDoc.FullFileName End Function End Module
Results in a message box that reads : "DriveLetter:\Path\FileName.ipt"
3: Mixing and matching your VB datatype functions with Inventor API based functions will result in bad things happening because occasionally you will need to make a call in a rule that doesn't need to access the API to a function that doesn't use the API. At that point you will receive the problems that I did above, and no one wants you to go through all of that.
EX: Internal Rule -
AddVbFile "MathMagic.iLogicVb" Dim Num1, Num2, Num3 As Integer Num1 = 12 Num2 = 10 Num3 = LargestNumber(Num1, Num2) Msgbox(Num3)
External Rule : (Note the mixing of both types of our previous external rules example)
Public Module MathMagic Public Function LargestNumber(Num1 As Integer, Num2 As Integer) As Integer If Num1 >= Num2 Then Return Num1 Else Return Num2 End If End Function Public Function MyFileName(SentDoc As Inventor.Document)As String Return SentDoc.FullFileName End Function End Module
Results in errors! Because the API was not initialized in the internal rule like it was in Example 2. Even though you don't need it, the external rule does need it despite the fact that you're not even calling on the functions that require it.
Biggest lesson learned? Keep your fancy pants functions that use the API in a separate file than the your mundane typical functions that you'll be using for regular work.
Thanks a lot : to Curtis W for the inital help, and MjDeck who confirmed all things questionable!
I see this is still the case. Thanks for this explanation. You just rescued me after two days of trying to figure out why some code would only work in a few rules. Until your explanation it looked complete random as to when it would and wouldn't work.
I’m glad that this topic was able to help you sort out your problem. Recently I found myself running into this issue again, and was forced to find some sort of workaround. I’m not certain that it’s the most elegant way of achieving the results that I want, but it does what it should do, so it’s a start.
Feel free to give me any feedback on this method.
Here’s an example of a little External Rule that contains two subs, one of which will access the Inventor Application, and one that does only math.
Imports System.Windows.Forms
Imports Inventor
Public Module inventorApp
Public Dim ThisApplication As Object
Sub New ()
Try
ThisApplication = GetObject(, "Inventor.Application")
Catch ex As Exception
MessageBox.Show("Inventor isn't running!?", "Well this is confusing...")
End Try
End Sub
End Module
Public Module myModule
Public Sub testApplicationSub ()
MessageBox.Show(ThisApplication.Documents.Count,"testApplicationSub")
End Sub
Public Function testNumberSub(x As Double, y As Double)
MessageBox.Show(x + y, "testNumberSub")
End Function
End Module
In your main rule, you can call one or the other now without throwing an error because the Application is loaded via the External Rule’s public module.
AddVbFile "inventorApp.iLogicVb" Call testNumberSub(100,0) 'Call testApplicationSub()