If I can add my $0.02 to this thread:
I too recently figured out how to use RuleArguments to pass values from one rule to another in order to allow creation of "cascading multi-value lists" i.e. lists whose participants change based on the values in other "parent" lists.
Returning values from iLogic rules ought to be possible, but without testing it, the only way I can think of achieving this would be to leverage the IiLogicAutomation Interface described here: http://help.autodesk.com/view/INVNTOR/2019/ENU/?guid=__iLogic_API_html_8db501bb_0b0d_acaf_e151_dca66...
This would (I think) require the calling rule to actually create an iLogicRule object with which you should in theory be able to pass properties to/from.
After further reading, I don't think this is possible since the RunExternalRule method returns 0 if the resultant rule ran successfully. Attached is a file I created a week or so ago to demonstrate the cascading list principal to a colleague and here are the rules it uses:
(this first external rule populates a series of multivalue list objects in the parent assembly)
Option Explicit On
Imports System.Linq
''' This rule is designed to populate a series of supplied column parameters, creating them as required.
Sub Main()
'Dim trans As Transaction = ThisApplication.TransactionManager.StartTransaction(ThisApplication.ActiveDocument, "Populate Multivalue Lists")
Dim columns As String = "E,G,I,L,N,O,R" 'this could be automated by adding an "isKey" at the top of each column!?
'Try
Call SetMatchingParameterNames(columns, cDefaultMultivaluePrefix, cDefaultMultivalueSuffix)
Call SetMatchingParameterNames(columns, cDefaultMultivaluePrefix)
Call PopulateColumnDefaults(columns, cDefaultMultivaluePrefix, cDefaultMultivalueSuffix)
Call PopulateColumnDefaults(columns, cDefaultMultivaluePrefix)
'trans.End()
' Catch ex As Exception
' Logger.Error("The error was: " & ex.Message)
' trans.Abort()
' End Try
End Sub
Public Const cStartRow As Integer = 7
Public Const cEndRow As Integer = 50
Public Const cDefaultMultivaluePrefix As String = "column"
Public Const cDefaultMultivalueSuffix As String = "defaults"
Public ColumnAList As New List(Of Object)
Public ColumnBList As New List(Of Object)
Public ColumnCList As New List(Of Object)
Public ColumnDList As New List(Of Object)
Public ColumnEList As New List(Of Object)
Public ColumnGList As New List(Of Object)
Public ColumnIList As New List(Of Object)
Public ColumnLList As New List(Of Object)
Public ColumnNList As New List(Of Object)
Public ColumnOList As New List(Of Object)
Public ColumnRList As New List(Of Object)
Sub SetMatchingParameterNames(ByVal columnlist As String, ByVal columnPrefix As String, Optional columnSuffix As String = "")
Dim Doc As AssemblyDocument = ThisApplication.ActiveDocument
Dim columns As List(Of String) = columnlist.Split(",").ToList()
For Each col As String In columns
Dim thisParam As Inventor.Parameter = (From param As Inventor.Parameter In Doc.ComponentDefinition.Parameters
Where param.Name = columnPrefix & col & columnSuffix
Select param).FirstOrDefault()
If thisParam Is Nothing Then
Logger.Debug(columnPrefix & col & columnSuffix & " does not exist in " & Doc.FullFileName)
Doc.ComponentDefinition.Parameters.UserParameters.AddByValue(columnPrefix & col & columnSuffix, "", UnitsTypeEnum.kTextUnits)
Else
Logger.Debug(thisParam.Name & " already exists")
End If
Next
End Sub
Sub PopulateColumnDefaults(ByVal columnlist As String, ByVal columnPrefix As String, Optional columnSuffix As String = "")
Dim newFilesArray As New ArrayList
newFilesArray = GoExcel.CellValues("path\to\spreadsheet.xlsx", "sheet1", "a1", "a2")
Dim columns As List(Of String) = columnlist.Split(",").ToList()
Logger.Debug(columns.ToString())
Dim TempList As New List(Of Object)
For Each col As String In columns
Logger.Debug("columnname: "& col)
For MyRow As Integer = cStartRow To cEndRow
If Not CStr(GoExcel.CellValue(col & MyRow)) = "" Then
If isParamText(columnPrefix & col & columnSuffix) And Not TypeOf GoExcel.CellValue(col & MyRow) Is String Then
TempList.Add(GoExcel.CellValue(col & MyRow).ToString())
Else
TempList.Add(GoExcel.CellValue(col & MyRow))
End If
End If
Next
TempList.Sort()
TempList = TempList.Distinct().ToList()
Logger.Debug("Column" & col & "list.Count: " & TempList.Count)
Dim tmpArrayList As ArrayList = New ArrayList(TempList)
MultiValue.List(columnPrefix & col & columnSuffix) = tmpArrayList
TempList.Clear()
Next
' break
End Sub
Function isParamText(ByVal paramName As String) As Boolean
Logger.Debug("Parameter is: " & paramName)
Dim p As Parameter = Parameter.Param(paramName)
If p.Units = "Text" Or p.units = "Boolean" Then
Return True
Else
Return False
End If
End Function
Sub SetArrayListDefaults(col As String, tmplist As List(Of Object))
Select col
Case "E"
ColumnEList.addrange(tmplist)
Case "G"
ColumnGList.addrange(tmplist)
Case "I"
ColumnIList.addrange(tmplist)
Case "L"
ColumnLList.addrange(tmplist)
Case "N"
ColumnNList.addrange(tmplist)
Case "O"
ColumnOList.addrange(tmplist)
Case "R"
ColumnRList.addrange(tmplist)
Case Else
'do nothing
End Select
End Sub
Inside the assembly file itself we need a series of rules which reference the newly created multivalue parameters by name so taking column L as an example we have:
'columnL Rule
s = columnL
'Logger.Debug("columnL updated to: " & Parameter("columnL"))
Dim RuleArguments As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
RuleArguments.Value("ParameterName") = "columnL"
iLogicVb.RunExternalRule("UpdateMultivalueLists", RuleArguments)
This rule will fire every time the columnL parameter is updated. Which in turn activates this rule:
' UpdateMultiValueLists Rule
Option Explicit On
Sub Main()
If Not RuleArguments.Exists("ParameterName") Then 'not fired from relevant rule
MessageBox.Show("This rule only works from the context-sensitive files we need!")
Exit Sub
Else
Dim paramName As String = RuleArguments.Value("ParameterName")
Dim p As Parameter = Parameter.Param(paramName)
Logger.Debug(paramName & " updated value = " & p.Value)
Dim FilterArguments As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
FilterArguments.Value("ParameterValue") = p.Value
iLogicVb.RunExternalRule("Filter" & paramName, FilterArguments)
End If
End Sub
Which in turn fires the next rule in the sequence In this case "FilterColumnL":
'FilterColumnL Rule
Option Explicit On
Sub main()
If Not RuleArguments.Exists("ParameterValue") Then
MessageBox.Show("How did we get here?")
Else
'Column L
Dim paramValue As String = RuleArguments.Value("ParameterValue")
Dim FilterArguments As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
'this needs to be a list of values to remove/add from the next column along.
Dim filterList As List(Of String) = New List(Of String)
Select paramValue
Case "L"
filterList.Add("C")
filterList.Add("K")
filterList.Add("S")
Case "R"
filterList.Add("F")
filterList.Add("K")
filterList.Add("M")
filterList.Add("S")
filterList.Add("T")
Case Else
End Select
FilterArguments.Value("UniqueValues") = filterList
FilterArguments.Value("ColumnToFilter") = cNextColumn
iLogicVb.RunExternalRule("FilterColumnRule", FilterArguments)
End If
End Sub
Public Const cNextColumn As String = "N"
The final rule in the sequence takes us back to editing the multivalue list:
Option Explicit On
'FilterColumn Rule
Sub Main()
If Not RuleArguments.Exists("UniqueValues") And Not RuleArguments.Exists("ColumnToFilter")Then
MessageBox.Show("How did we get here?")
Else
Dim Doc As AssemblyDocument = ThisApplication.ActiveDocument
Dim columnToEdit As Inventor.Parameter = (From param As Inventor.Parameter In Doc.ComponentDefinition.Parameters
Where param.Name = "column" & RuleArguments.Value("ColumnToFilter")
Select param).FirstOrDefault()
' Dim columnToEdit As Inventor.Parameter = Parameter.Param("column" & RuleArguments.Value("ColumnToFilter"))
Dim listofUniqueValues As List(Of String) = RuleArguments.Value("UniqueValues")
Logger.Debug(columnToEdit.Name)
Logger.Debug(debugListValues(listofUniqueValues))
If Not listofUniqueValues Is Nothing And Not columnToEdit Is Nothing Then
listofUniqueValues.Sort()
Dim tmpArraylist As ArrayList = New ArrayList(listofUniqueValues)
MultiValue.List(columnToEdit.Name) = tmpArraylist
End If
End If
End Sub
Function debugListValues(ByVal listofValues As List(Of String)) As String
For Each Val As String In listofValues
debugListValues = Val & "," & debugListValues
Next
End Function
If you store the last two rules externally, and open the attached assembly file you'll see there's an iLogic form included in the assembly that will update the values of column 'N' when you change the selection in column L.
I'm not sure how much of this helps what you were trying to accomplish, but hopefully it will present some ideas not seen or considered before.
Cheers,
Alex.