I've been struggling with iLogic in Inventor 2011. It seems there are problems with RunExternalRule(...) and the GoExcel spreadsheet functions. Both seem to behave erratically. Sometime the code works, sometimes is doesn't.
I'm trying to do a simple spreadsheet operation. I want to create a simple external rule that uses a spread sheet to do a simple code conversion. I'm using TEXT parameters in the document containing the calling code to pass arguments to the routine.
The calling code is as follows:
codeTablePath = "C:/codetables/"
codeTable = "species"
codeFrontier = iProperties.Value("Custom", "DRSPC")
iLogicVb.RunExternalRule("translateCode")
iProperties.Value("Custom", "DRSPC") = codeModel
The called code .... translateCode.iLogicVb:
codeFrontier = Parameter("codeFrontier")
table = Parameter("codeTablePath") & Parameter("codeTable") & ".xlsx"
GoExcel.Open(table, "Sheet1")
i = GoExcel.FindRow(table, "Sheet1", "codeFrontier", "=",codeFrontier)
If i = -1
Parameter("codeModel") = codeFrontier
Else
Parameter("codeModel") = GoExcel.CurrentRowValue("codeModel")
End If
GoExcel.Close
I had put some messageboxes into both the calling and called code to determine what was going on, and I discovered that sometimes the RunExternalRule(...) doesn't execute the rule, and when the rule is executed, sometimes the GoExcel.FindRow() and/or the GoExcep.CurrentRowValue(...) gets the wrong row (usually retrieves row 1).
It seemed like a simple thing to do, but I've been struggling with it all day.
Can someone tell what I'm doing wrong, or if there are known bugs in this area.
Thanks
Mike G
Solved! Go to Solution.
Solved by MikeGillam5072. Go to Solution.
You have to use the function RuleParametersOutput() to send the parameter values that you changed in the rule to Inventor. Put that in before running the external rule:
' ...
codeFrontier = iProperties.Value("Custom","DRSPC")
RuleParametersOutput()
iLogicVb.RunExternalRule("translateCode")
iProperties.Value("Custom", "DRSPC") = Parameter("codeModel")
Note that you have to use Parameter("codeModel") (instead of just codeModel) after running the external rule.
This is required because the parameter names that are used as variables in the rules aren't live links. They are assigned from the model when the rule starts and assigned back to the model when the rule ends. In between, changes to their value is only local within the rule. Unlike the parameter variables, the Parameter function connects directly to the model every time you use it.
Thank you.
That explains a lot.
Some related questions ...
Does the RunExternalRule() function support a Map parameter like the the RunRule() does?
Is there a way to implement a function in iLogic (like in VB) that allows you to pass in parameters and return a value? If yes, can you point me to example code?
thanks
Mike G
Yes, you can use RunExternalRule with arguments. Here's an example that sends some input to the rule, and gets a return value:
Dim args As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
args.Add("arg0", "Sample String Value")
args.Add("ReturnValue", 0)
iLogicVb.RunExternalRule( "ArgumentsTest.iLogicVb", args)
MessageBox.Show("Return Value = " & args.Value("ReturnValue"), "iLogic")
Here's the external rule:
app = ThisApplication
if (Not RuleArguments.Exists("arg0")) Then
MessageBox.Show("Argument arg0 was not provided", "iLogic")
Else
MessageBox.Show(RuleArguments("arg0"), "iLogic")
End If
RuleArguments.Arguments.Value("ReturnValue") = 128
The line
app = ThisApplication
is required to create a reference to the Inventor API in the external rule (so it knows about the NameValueMap). The RuleArguments.Arguments is required to assign a return value back to one of the arguments.
> Is there a way to implement a function in iLogic (like in VB) that allows you to pass in parameters and return a value? If yes, can you point me to example code?
Yes, you can put a function directly in a rule. But based on your original question, you probably want to put it in an external file, right? I'll post an example based on your original rule/external rule combination.
Here's a rule that uses a class defined in an external rule and calls a function on it:
AddVbFile "ExcelCode.vb"
codeTablePath = "C:/codetables/"
codeTable = "species"
codeFrontier = iProperties.Value("Custom", "DRSPC")
Dim ec as New ExcelCode(GoExcel, Parameter)
codeModel = ec.TranslateCode(codeTablePath, codeTable, codeFrontier)
iProperties.Value("Custom", "DRSPC") = codeModel
Here's the external rule, in a file named ExcelCode.vb. This should be stored in the same folder as your model. or in the workspace folder, or in one of the folders listed under External Rule Directories in Tools -> iLogic Configuration.
Class ExcelCode
Private GoExcel as IGoExcel
Private Parameter as iParamDynamic
Sub New(GoExcel As IGoExcel, Parameter As IParamDynamic)
Me.GoExcel = GoExcel
Me.Parameter = Parameter
End Sub
Function TranslateCode(codeTablePath As String, codeTable As String, codeFrontier As String) As String
Dim codeModel As String
table = codeTablePath & codeTable & ".xlsx"
GoExcel.Open(table, "Sheet1")
i = GoExcel.FindRow(table, "Sheet1", "codeFrontier", "=", codeFrontier)
If i = -1
codeModel = codeFrontier
Else
codeModel = GoExcel.CurrentRowValue("codeModel")
End If
GoExcel.Close
Return codeModel
End Function
End Class
This external rule must be marked as Straight VB Code. This is on the Options tab in the Rule Editor.
Note that the GoExcel and Parameter objects are not predefined in Straight VB rules, so they have to be supplied from the calling rule. The Parameter object is not actually used in this sample, but I left it in to show how it would be passed in from the calling rule.
This is terrific! Thank you very much.
I can do a lot of things taking this approach.
I knew you could write rules in straight VB, but help text doesn't explain how. Next release you should add some example code to the doc.
thanks again
Mike G