iPart table update of specific cells only works one column at the time

iPart table update of specific cells only works one column at the time

alexander.hendrix
Contributor Contributor
416 Views
5 Replies
Message 1 of 6

iPart table update of specific cells only works one column at the time

alexander.hendrix
Contributor
Contributor

Hi all,

 

First post after a year of delving into the deep crevasses of this forum. Normally I have been able to find the code I needed directly or tweak it a bit, but now I am at a loss. I use the following iLogic code to update some of the iProperties  in the iPart Factory table (these change based on size of the iPart). For each row the iProperties are calculated and then written to the iPart Factory table. What happens, is that the first iProperty, ArealSkilling, is written to the table after I run the rule, but not the other two. When I run the rule once more, iProperty, Kvantum, is updated in the table and I have to run a third time to get iProperty, LakkVektkg, to be updated in the table. Can someone explain why it doesn't work as I expected? The code that works half of the time is: 

 

 

 

			oRow.Item(iArealSkillingColumnIndex).Value = iProperties.Value("Custom", "ArealSkilling")
			oRow.Item(iKvantumColumnIndex).Value = iProperties.Value("Custom", "Kvantum")
			oRow.Item(iLakkVektkgColumnIndex).Value = iProperties.Value("Custom", "LakkVektkg")

 

 

 

I attached one of the factory parts for reference. And here you can find the 2 external rules in full:

 

 

' K:\ACAD\InventorAdmin\2021\Ilogic Rules\DXF&IGSCreation.iLogicVb
Sub Main()
	Dim oDoc As PartDocument = ThisDoc.Document
	If (oDoc.ComponentDefinition.IsiPartFactory = False) Then
		SharedVariable("LagDXFIGS") = MessageBox.Show("Vil du lagre DXF eller IGS nå?", "Title", MessageBoxButtons.YesNo)
    	iLogicVb.RunExternalRule("DXF&IGSCreationCore")
	Else
		SharedVariable("LagDXFIGS") = MessageBox.Show("Vil du lagre DXF eller IGS for alle iParts?", "Title", MessageBoxButtons.YesNo)
		Dim oFact As iPartFactory = oDoc.ComponentDefinition.iPartFactory
		Dim oRowDefault As iPartTableRow = oFact.DefaultRow
		For Each oRow As iPartTableRow In oFact.TableRows
			oFact.DefaultRow = oRow
			oDoc.Update()
			oDoc.Update2(False)
			iLogicVb.RunExternalRule("DXF&IGSCreationCore")
			
			'Find column in iPart table that is called ArealSkilling
		    Dim iArealSkillingColumnIndex As Long = GetColumnIndex(oFact, "ArealSkilling")
		    If iArealSkillingColumnIndex = -1 Then
		        ShowMessageBox("ArealSkilling")
		        Exit Sub
		    End If
			Dim iKvantumColumnIndex As Long = GetColumnIndex(oFact, "Kvantum")
		    If iKvantumColumnIndex = -1 Then
		        ShowMessageBox("Kvantum")
		        Exit Sub
		    End If
			Dim iLakkVektkgColumnIndex As Long = GetColumnIndex(oFact, "LakkVektkg")
		    If iLakkVektkgColumnIndex = -1 Then
		        ShowMessageBox("LakkVektkg")
		        Exit Sub
		    End If
			oRow.Item(iArealSkillingColumnIndex).Value = iProperties.Value("Custom", "ArealSkilling")
			oRow.Item(iKvantumColumnIndex).Value = iProperties.Value("Custom", "Kvantum")
			oRow.Item(iLakkVektkgColumnIndex).Value = iProperties.Value("Custom", "LakkVektkg")
			iPart.ChangeRow("", oRow.Index)
		Next
		iPart.ChangeRow("", oRowDefault.Index)
	End If
	iLogicVb.UpdateWhenDone = True
End Sub

' Function that given a factory And the name Or a column will Return
' the index number Of the column, If it's found In the factory's
' table.  If the column Is Not found it returns –1.  The comparison
' Of the name Is done In a Case insensitive way.
Private Function GetColumnIndex(ByVal Factory As iPartFactory, ByVal ColumnName As String) As Long
    ' Iterate through all Of the columns looking For a match To the input name.
    Dim i As Long
    For i = 1 To Factory.TableColumns.Count
        Dim oColumn As iPartTableColumn
        oColumn = Factory.TableColumns.Item(i)

        ' Compare this Column With the Input name.
        If LCase(oColumn.DisplayHeading) = LCase(ColumnName) Then
            ' A matching column was found so exit.
            GetColumnIndex = i
            Exit Function
        End If
    Next

    ' The column wasn't found so return -1.
    GetColumnIndex = -1
End Function

Private Sub ShowMessageBox(ByVal iPropertyName As String)
		MessageBox.Show("Kolonne med iProperty " & iPropertyName & " må legges til i iPart tabellen! Kjør iLogic rule på nytt etter kolonnen er lagt til.")
End Sub
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' K:\ACAD\InventorAdmin\2021\Ilogic Rules\DXF&IGSCreationCore.iLogicVb
Imports SysIO = System.IO
Sub Main()
	Dim oWorkspacepath As String = ThisDoc.WorkspacePath()
	Dim oWorkspacePathLength As Integer = Len (oWorkspacepath)
	Dim oPathonly As String = ThisDoc.Path
	Dim oDirectorypath As String
	If oPathonly.Length < oWorkspacepath.Length Then
		oDirectorypath = oPathonly
	Else
		oDirectorypath = Strings.Right(oPathonly, oPathonly.Length - oWorkspacePathLength)
	End If
	Dim oFolder As String
	If Left(oPathonly, 1) = "K" Or ThisDoc.FileName(False) = "Standard" Then
		oFolder = oPathonly
	Else
		oFolder = "K:" & oDirectorypath
	End If
	
	Dim oDoc As PartDocument = ThisDoc.Document
	Dim oType As String = oDoc.DocumentSubType.DocumentSubTypeID
	If oType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then
		Dim oCompDef As SheetMetalComponentDefinition
		oCompDef = oDoc.ComponentDefinition
		iProperties.Value("Custom", "ArealSkilling") = Round(SheetMetal.FlatExtentsLength * SheetMetal.FlatExtentsWidth,0)
		iProperties.Value("Custom", "Kvantum") = Round(SheetMetal.FlatExtentsLength * SheetMetal.FlatExtentsWidth / (1500 * 3000), 3)
		iProperties.Value("Custom", "KnekkAntall") = oCompDef.Bends.Count
		iProperties.Value("Custom", "Platemateriale") = oCompDef.ActiveSheetMetalStyle.Name()
		iLogicVb.RunExternalRule("Overflate")
		Dim sFname As String
		Dim oPartNumber As String
		Try
			oPartNumber = iProperties.Value("Custom", "DXF")
			sFname = oFolder & "\" & oPartNumber & ".dxf"
		Catch
			Try
				oPartNumber = iProperties.Value("Custom", "Art.Nr. Skilling")
			Catch
				oPartNumber = iProperties.Value("Project", "Part Number")
			End Try
			If iProperties.Value("Summary", "Title") <> "" Then
				sFname = oFolder & "\" & oPartNumber & " " & iProperties.Value("Summary", "Title") & ".dxf"
			Else
				sFname = oFolder & "\" & oPartNumber & ".dxf"
			End If
		End Try
		If oPartNumber <> "" And SharedVariable("LagDXFIGS") = vbYes Then
			questionDXF = MessageBox.Show("Vil du lagre DXF'en til "& sFname &  "?", "iLogic spørsmål",MessageBoxButtons.YesNo,MessageBoxIcon.Question)
			If questionDXF = vbYes Then
				If SysIO.Directory.Exists(oFolder) = False Then
					SysIO.Directory.CreateDirectory(oFolder)
				End If
				If oCompDef.HasFlatPattern = False Then
					oCompDef.Unfold
				Else
					oCompDef.FlatPattern.Edit
				End If
	
				'DXF Settings
				Dim sOut As String
				Dim sPATH As String
			        sOut = "FLAT PATTERN DXF?AcadVersion=2013&InvisibleLayers=IV_TANGENT;IV_BEND;IV_Bend_Down;IV_Bend?_Up"
	
				'Export the DXF and fold the model back up
				oCompDef.DataIO.WriteDataToFile( sOut, sFname)
				Dim oSMDef As SheetMetalComponentDefinition
				oSMDef = oDoc.ComponentDefinition
				oSMDef.FlatPattern.ExitEdit
	'			MessageBox.Show("DXF saved to: "& sFname, "Success!")
			End If
		Else
		End If
	End If
	
	Dim oRørlaser As String
	Try
		oRørlaser = iProperties.Value("Custom", "Rørlaser")
	Catch
		oRørlaser = ""
	End Try
	If oRørlaser <> "" And SharedVariable("LagDXFIGS") = vbYes Then
		' Get the IGES translator Add-In.
		Dim oIGESTranslator As TranslatorAddIn
		oIGESTranslator = ThisApplication.ApplicationAddIns.ItemById("{90AF7F44-0C01-11D5-8E83-0010B541CD80}")
		Dim oContext As TranslationContext
		oContext = ThisApplication.TransientObjects.CreateTranslationContext
		Dim oOptions As NameValueMap
		oOptions = ThisApplication.TransientObjects.CreateNameValueMap
		If oIGESTranslator.HasSaveCopyAsOptions(ThisApplication.ActiveDocument, oContext, oOptions) Then
		   ' Set geometry type for wireframe.
		   ' 0 = Surfaces, 1 = Solids, 2 = Wireframe
			oOptions.Value("GeometryType") = 1
		   ' To set other translator values:
		   ' oOptions.Value("SolidFaceType") = n
		   ' 0 = NURBS, 1 = Analytic
		   ' oOptions.Value("SurfaceType") = n
		   ' 0 = 143(Bounded), 1 = 144(Trimmed)
			oContext.Type = IOMechanismEnum.kFileBrowseIOMechanism
			Dim oData As DataMedium
			oData = ThisApplication.TransientObjects.CreateDataMedium


			Dim oPartNumberRør As String
			oPartNumberRør = iProperties.Value("Project", "Part Number")

			Try
				oProdukt = iProperties.Value("Custom", "Produkt")
				If oProdukt <> "" Then
					oProdukt = " " & oProdukt
				End If
			Catch
				oProdukt = ""
			End Try
			If iProperties.Value("Summary", "Title") <> "" Then
				oTitle = " " & iProperties.Value("Summary", "Title")
			End If
			oData.FileName = oFolder & "\" & oPartNumberRør & oProdukt & oTitle &".igs"
			questionIGS = MessageBox.Show("Vil du lagre IGS'en til " & oData.FileName & "?", "iLogic spørsmål", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
			If questionIGS = vbYes Then
				If SysIO.Directory.Exists(oFolder) = False Then
					SysIO.Directory.CreateDirectory(oFolder)
				End If
				oIGESTranslator.SaveCopyAs(ThisApplication.ActiveDocument, oContext, oOptions, oData)
				MessageBox.Show("IGS saved to: "& oData.FileName, "Success!")
			End If
		End If
	End If
End Sub

 

 

 

 

 

0 Likes
417 Views
5 Replies
Replies (5)
Message 2 of 6

alexander.hendrix
Contributor
Contributor
I understand from reading more on the forum, that trying to update iProperties 'through' the iPart factory table is maybe not the way to go. Anyone has any suggestions on how to update iProperties for each member of an iPart? If these are not in the table, these are not shown correctly in for example the BOM view.
0 Likes
Message 3 of 6

A.Acheson
Mentor
Mentor

Selecting each member by code and updating the iproperties should have the same effect as going into the table itself. As long as the iproperties columns are in the table.

 

Here is a code I have successfully used but have not tested in your example. 

The key thing is selecting each member and forcing the update of the table before you move to the next member. I have used it with an external rule to import iproperties from an excel file so multiple iproperties. All iproperties are written to the table when cycling through each members. Unfortunately I could not eliminate the update message box that is system generated to say the ipart value is different than the table. 

 

Hopefully that helps you in your search for an answer. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 4 of 6

alexander.hendrix
Contributor
Contributor

Hi Alan,

thanks For you suggestion.I have altered your code To fit my needs, but somehow it does Not trigger the "Do you want to change table contents accept yes to allow parameters to be saved to ipart member row." at all.Only after the rule Is done And I manually go To edit table In the browser, I Do Get the popup And When I accept, the current Row Is updated, but none Of the others.

 

Sub Main
SharedVariable("LagDXFIGS") = MessageBox.Show("Loop through iPart factory and populated members, This will take a while. Are you sure?" _
, "Ilogic Instructions", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
If  SharedVariable("LagDXFIGS") = vbYes Then 
 	
	Dim oDoc As Document = ThisDoc.Document
	
    'Check if ODoc is a Part Document
	If oDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject  Then
	   'MessageBox.Show("This is a part file.", "iLogic")
		      
		'Set a reference to the component definition
		oDef = ThisApplication.ActiveEditDocument.ComponentDefinition

		'Make sure we have an iPart factory.
	    If oDef.IsiPartFactory  = False Then
	        MsgBox ("Chosen document is not a factory.", vbExclamation)
	        Exit Sub
	    End If
			
		' Set a reference to the factory.
		Dim oFactory As iPartFactory
		oFactory = oDef.iPartFactory

		'Get the number of rows in the factory.
		Dim iNumRows As Integer
		iNumRows = oFactory.TableRows.Count 
		 
		Dim iRow As Integer

		Try
			For iRow = 1 To iNumRows 'oStart To oEnd
'				'Use if this main rule is external

				'Change ipart Row
				iPart.ChangeRow("", iRow)

				'---Call external "function" or rule or do something---]
				iLogicVb.RunExternalRule("DXF&IGSCreationCore")

				'[Select by UI the node of current member in order to bring up the message ipart has change contents,
				'If this is not used parameters will only apply to last member active
				'https://forums.autodesk.com/t5/inventor-customization/possible-to-check-all-members-of-factory-for-errors-using-ilogic/td-p/3863094]
				']
				Dim oErrorManager As ErrorManager
				   oErrorManager = ThisApplication.ErrorManager
				 
				Dim oTop As BrowserNode
				     oTop = oDoc.BrowserPanes("Model").TopNode
				   
'				Dim bHasErrorOrWarning As Boolean
				'To skip without messages, this will not work for change of parameter
				'ThisApplication.SilentOperation = False
				   
			    ' Highlight the iPart table row 
			    oTop.BrowserNodes("Table").BrowserNodes.Item(iRow).DoSelect

			    ' Activate the iPart table row, this will trigger the "Do you want to change table contents accept yes to allow parameters to be saved to ipart member row. 
			    Dim oCommand As ControlDefinition
			    oCommand = ThisApplication.CommandManager.ControlDefinitions("PartComputeiPartRowCtxCmd")
			    oCommand.Execute
			    If oErrorManager.HasErrors Or oErrorManager.HasWarnings Then
				        MsgBox (oErrorManager.LastMessage, vbOKCancel)
				 End If
			Next
	
			Catch
			MessageBox.Show("Error Exiting", "iLogic")	
			End Try
			iLogicVb.UpdateWhenDone = True
		Else
		End If
	Else
	End If
End Sub
0 Likes
Message 5 of 6

A.Acheson
Mentor
Mentor

I think I found the issue, it took a while. But the issue here is the number of keys you have for the ipart. The rule as is will only work for  1 key in the ipart table.  What the node selection is doing is just mimicking the user selecting the single key node in the browser, this will then activate the updating. If you have more than one key the sequence is lost and you get updating occurring on just one or two members. 

AAcheson_0-1645646047826.png

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 6 of 6

alexander.hendrix
Contributor
Contributor
I do not have any keys in the table at all. Can that also be an issue? I'll try setting one of the other parameters as key 1.
0 Likes