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: 

Help to create and return a DataTable with an external rule

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
JBerns
254 Views, 4 Replies

Help to create and return a DataTable with an external rule

Community,

 

I have an assembly design that uses an iLogic Form and multiple Rules to configure the model.

 

I have discovered the value of DataTables to store common info.

 

The challenge - I need multiple rules to have access to these DataTables.

 

Currently, the DataTable is (re)defined in each Rule.

 

I would like to avoid this duplication.

 

I created an external rule to create the DataTable, but after the external rule is run, the assembly does not see the DataTable.

 

I tried running an external rule with arguments, but I could not return the DataTable from the external rule.

 

AddReference "System.Data"
AddReference "System.Xml"
Imports System.Data
Imports System.Xml

Public Class ThisRule
	Sub Main()
		' declare map
		Dim RuleArguments As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
		' set a map
		RuleArguments.Value("SharedVariable") = SharedObjects.AttachmentTable
		' run external rule
		iLogicVb.RunExternalRule("BuildAttachmentTable", RuleArguments)
		' see results
		''
		'' Following are lines I tested to see the returned results
		MsgBox(RuleArguments.Item(0))
		MsgBox(RuleArguments.Item("SharedVariable"))
	End Sub
End Class

Public Class SharedObjects
	Public Shared AttachmentTable As New DataTable("AttachmentTable")
End Class

 

How could I make an external rule create and return a DataTable to share with all rules in an assembly?

 

Thank you for your time and attention. I look forward to your replies.

 


Regards,
Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using Inventor 2022
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
4 REPLIES 4
Message 2 of 5
WCrihfield
in reply to: JBerns

Hi @JBerns.  I do not have much experience with DataTable objects myself, but they seem pretty similar to other non generic collections to me, and I know that I can pass a List(Of String) or an Inventor.Document to another rule using the RuleArguments, so I'm thinking that it may not be working because of the use of that other custom Class being used.  Have you tried creating that DataTable directly within the main routine, then passing it into the RuleArguments, without using the custom Class?  Also, have you tried using a regular iLogic SharedVariable to store it in directly?

Edit:  If you need to use a custom Class, have you considered using a separate external iLogic rule, with the 'Straight VB Code' option turned on, then use the AddVBFile line in the Header of the rule to reference it.  Not sure if that would help any, but that is usually a pretty good option for custom Classes.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 5
WCrihfield
in reply to: JBerns

Hi @JBerns.  This may not be exactly what you were looking for, but it is a step in the right direction at least.  As an example, I created two quick, simple internal iLogic rules.  One for creating a DataTable, and filling in some data, then sending it to the other rule to read.  Then the second rule is set up to receive that DataTable, and read it.  This text example worked for me.

Below is rule 1, named "Create DataTable, Send It":

AddReference "System.Data.dll"
AddReference "System.Data.Common.dll"
AddReference "System.XML"
Imports System.Data
Sub Main
	Dim oDataTable As New DataTable
	Dim oCol1 As DataColumn = oDataTable.Columns.Add("Name")
	oCol1.DataType = System.Type.GetType("System.String")
	Dim oCol2 As DataColumn = oDataTable.Columns.Add("Age")
	oCol2.DataType = System.Type.GetType("System.Int32")
	Dim oRow1 As DataRow = oDataTable.Rows.Add({"Tom", 45 })
	Dim oRow2 As DataRow = oDataTable.Rows.Add({"Bob", 37 })
	Dim oArgs As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	oArgs.Add("DataTable", oDataTable)
	iLogicVb.RunRule("Receive DataTable, Read It", oArgs)
End Sub

...and below is the second rule, named "Receive DataTable, Read It":

AddReference "System.Data.dll"
AddReference "System.Data.Common.dll"
AddReference "System.XML"
Imports System.Data
Sub Main
	Dim oDataTable As DataTable = Nothing
	If RuleArguments.Exists("DataTable") Then
		oDataTable = RuleArguments.Value("DataTable")
	Else
		MsgBox("No DataTable Received!", vbCritical, "Nothing Received")
		Exit Sub
	End If
	If oDataTable Is Nothing Then Exit Sub
	For Each oRow As DataRow In oDataTable.Rows
		Dim sName As String = oRow.Item("Name")
		Dim oAge As Int32 = oRow.Item("Age")
		MsgBox(sName & " is " & oAge.ToString & ".", vbInformation, "DataTable ReadOut")
	Next
End Sub

When I run the first rule, I immediately see the messages pop from the second rule.  So, I know that the second rule has received it, and can read/use the data within it.  That settles whether or not you can send/receive a DataTable using RuleArguments.  By the way, the second rule could edit the DataTable further, then respond back to the first rule, or pass it along to another rule also.  If sent back to the first rule (not using RunRule method, just the RuleArguments object), and there could be more code within the first rule that will kick in and continue from there, after the second rule has finished, and do something further with that DataTable.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 5
JBerns
in reply to: WCrihfield

@WCrihfield,

 

Thanks for the quick reply. 

 

I have been successful at sharing a DataTable across rules within the document using a SharedVariable. Here is my code:

 

'Define DataTable rule

AddReference "System.Data"
AddReference "System.Xml"
Imports System.Data
Imports System.Xml
Public Class ThisRule
	Public Shared oTest1 As DataTable '= New System.Data.DataTable("Test1")
	
	Private Sub ClearColumnsCollection(table As DataTable)
		Dim columns As DataColumnCollection
		' Get the DataColumnCollection from a DataTable
		columns = table.Columns
		columns.Clear()
	End Sub

	Sub Main()
		break
		' Clear the datatable of rows
		SharedObjects.oTest1.Clear
		' Clear the datatable of columns
		ClearColumnsCollection(SharedObjects.oTest1)
		' Report column/row count before add
		MsgBox("oTest1 Column Count before: " & SharedObjects.oTest1.Columns.Count & vbLf & _
			   "oTest1 Row    Count before: " & SharedObjects.oTest1.Rows.Count _
				, , "BEFORE - Inside 'Define'")
		' Add two columns
		SharedObjects.oTest1.Columns.Add("Perimeter", GetType(String))
		SharedObjects.oTest1.Columns.Add("Area", GetType(String))
		' Add two rows
		SharedObjects.oTest1.Rows.Add("100", "200")
		SharedObjects.oTest1.Rows.Add("200", "400")
		' Report column/row count after add
		MsgBox("oTest1 Column Count after: " & SharedObjects.oTest1.Columns.Count & vbLf & _
			   "oTest1 Row    Count after: " & SharedObjects.oTest1.Rows.Count _
				, , "AFTER - Inside 'Define'")
		' Set the shared variable
		SharedVariable("dt") = SharedObjects.oTest1
	End Sub
	
End Class

Public Class SharedObjects
	' Declare the datatable
	Public Shared oTest1 As DataTable = New System.Data.DataTable("oTest1")
End Class

 

' View DataTables rule

AddReference "System.Data"
AddReference "System.Xml"
Imports System.Data
Imports System.Xml
Public Class ThisRule

	Public Shared oTest1 As DataTable

	Sub Main()
		' Define the datatables
		iLogicVb.RunRule("Define DataTables")
		' Report column/row count
		MsgBox("dt Column Count: " & SharedVariable("dt").Columns.Count & vbLf & _
			   "dt Row    Count: " & SharedVariable("dt").Rows.Count _
				, , "Inside 'View DataTables'")
	End Sub

End Class

Public Class SharedObjects
	' Declare the datatable
	Public Shared oTest1 As DataTable '= New System.Data.DataTable("oTest1")
End Class

 

When you run the rule, 'View DataTables', the 'Define DataTables' rule is run which creates the SharedVariable of the datatable object.

 

Granted, the DataTable will contain much more data (5 columns, 500+ rows). And this is just one of about six datatables we may need.

 

I have not been successful at using the RuleArguments.

 

I have not tried AddVBFile. I will try that next.

 

The goal to externalize the datatable is because the common info will be used by various equipment designs (assemblies). I could consider a CSV file and read this file each time, but I think that would impact performance.

 

Thanks again for your feedback. I hope I am not overcomplicating the goal to have a common source of data.

 

Regards,

Jerry

 

-----------------------------------------------------------------------------------------
CAD Administrator
Using Inventor 2022
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
Message 5 of 5
JBerns
in reply to: JBerns

@WCrihfield,

 

Thanks for the RunRule with Arguments code example. This too could be useful.

 

Your suggestion to use AddVbFile I think will have the greatest value. 

 

Wish I had found your forum post earlier.

https://forums.autodesk.com/t5/inventor-ilogic-and-vb-net-forum/add-vbrule-in-ilogic-link-to-another... 

 

I put together example external and internal rules.

 

External rule, BuildCustomerTable :

' <IsStraightVb>True</IsStraightVb>
Imports System.Data
Imports System.Xml
Public Class ThisRule
	
	Public Shared CustomerTable As New DataTable("CustomerTable")

	Private Sub ClearColumnsCollection(table As DataTable)
		Dim columns As DataColumnCollection
		' Get the DataColumnCollection from a DataTable
		columns = table.Columns
		' Erase the columns
		columns.Clear()
	End Sub
	
	Function BuildCustomerTable() As System.Data.DataTable
		' Clear the table of rows
		CustomerTable.Clear

		' Clear the columns
		ClearColumnsCollection(CustomerTable)
		
		' Define columns
		CustomerTable.Columns.Add("Name", GetType(String))
		CustomerTable.Columns.Add("Age", GetType(Integer))
		CustomerTable.Columns.Add("Discount", GetType(Single))

		' Add rows
		CustomerTable.Rows.Add("Tom", 45, 0.05)
		CustomerTable.Rows.Add("Mary", 29, 0.08)
		CustomerTable.Rows.Add("Bob", 37, 0.10)

		Return CustomerTable
	End Function
		
End Class

Above is attached in the ZIP file. Note the use of the 'Straight VB' option.

 

 

And the internal rule, Report Customer Info:

AddReference "System.Data"
AddReference "System.Xml"
Imports System.Data
Imports System.Xml
AddVbFile "[YOUR PATH HERE]\BuildCustomerTable.iLogicVb"

''' Main program
''' 
Sub Main()	
	' Build the datatable with Name, Age, Discount
	BuildCustomerTable
	' Verify the table exists
	If Not IsNothing(CustomerTable) Then
		MsgBox("Found a DataTable.")
	End If
End Sub

 

Be sure to edit the path as needed in the AddVbFile line.

 

I will attach a sample part file that demonstrates searching the datatable.

 

Thanks again, Wes, for all the great info!

 

 

Regards,

Jerry

 

-----------------------------------------------------------------------------------------
CAD Administrator
Using Inventor 2022
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report