Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.
Darkforce_the_ilogic_guy
465 Views, 5 Replies

Selece before running the rule and not after ?

I have this ilogic code 

 

 

I force me to select an part in an assembly... but is it possible to select first and then run the code

 

my code now is this ... I want it to do the same ... but add the information for the part that are already select 

 

 

Dim oPart As ComponentOccurrence = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyLeafOccurrenceFilter, "Select FG component")

 

Try this code

 

Dim asm As AssemblyDocument = ThisDoc.Document

Dim occ As ComponentOccurrence = Nothing

For Each selectedItem In asm.SelectSet
	Dim selectedOccurrence As ComponentOccurrence
	Try
		selectedOccurrence = selectedItem
		occ = selectedOccurrence
		Exit For
	Catch
		Continue For
	End Try
Next

If occ Is Nothing Then
	occ = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyLeafOccurrenceFilter, "Select FG component")
End If

If occ Is Nothing Then
	'Raise exception or return
	Return
End If

'...
MsgBox(occ.Name)

@Michael.Navara Instead of trying to assign the selected item to a predefined object type and see if an error occurs (try-catch), why don't you simply check the .type of the selected item?


@Darkforce_the_ilogic_guy Please find below the first section of code used in my macros which support selecting an object before running. As in your case, the selected object should be an occurrence. In my case, the user is only allowed to select one item.

Specific checks on the occurrence (is it visible, suppressed or else) are placed after this section. It's VBA, but it should be easily converted into iLogic.

'Declarations
Dim oSourceOcc As ComponentOccurrence

'Get the selected occurrence
If ThisApplication.ActiveDocument.SelectSet.Count = 0 Then

  'Let user select a component
  Set oSourceOcc = ThisApplication.CommandManager.Pick(kAssemblyLeafOccurrenceFilter, "Select a component (or press ESC to quit)")

  'Quit if user pressed ESC
  If oSourceOcc Is Nothing Then
    End
  Else
    Call ThisApplication.ActiveDocument.SelectSet.Select(oSourceOcc)
  End If

ElseIf ThisApplication.ActiveDocument.SelectSet.Count > 1 Then

  'Inform user about too much selection
  MsgBox "Please select only one component at a time.", vbCritical + vbOKOnly, "<Macro Name>"
  End

Else

  'Check if selected item is an occurrence
  If Not ThisApplication.ActiveDocument.SelectSet(1).Type = kComponentOccurrenceObject And Not ThisApplication.ActiveDocument.SelectSet(1).Type = kComponentOccurrenceProxyObject Then

    'Inform user about incompatible selection
    MsgBox "Can't use this type of object." & vbCrLf & vbCrLf & "Please select a part or sub assembly and try again", vbCritical + vbOKOnly, "<Function Name>"
    End
  Else

    'Set source occurrence
    Set oSourceOcc = ThisApplication.ActiveDocument.SelectSet(1)
  End If
End If

 

@_dscholtes_  I use Try-Catch beacuse this has better performance in usual way and this is well known construct. When you use .Type check, VB.NET (iLogic) compiler creates late binding construct in background and this has worse performance. See https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/early-late-... for more information.

The best solution is use of TryCast. This has the same performance in usual way as Try-Catch and much better in unusual way.

 

And also I use C# fo common work and there is not possible to use .Type check directly.

 

Bellow  is benchmark code sample. Try run this code in part sketch environment and in model environment.

 

Expected results

In PlanarSketch [ms]

DEBUG|Try-Catch: 0,9974
DEBUG|Late binding: 25,932
DEBUG|TryCast: 0,9942

 

In Model [ms]

DEBUG|Try-Catch: 370,0105
DEBUG|Late binding: 19,9461
DEBUG|TryCast: 3,9891

 

 

Dim oSketch As PlanarSketch
Dim start As DateTime
Dim span As TimeSpan
Dim count = 10000
Dim activeEditObject = ThisApplication.ActiveEditObject

'Try-Catch
start = DateTime.Now
For i = 1 To count
	Try
		oSketch = activeEditObject
	Catch
		Continue For
	End Try
Next
span = DateTime.Now - start
Logger.Debug("Try-Catch: " & span.TotalMilliseconds)

'Late binding
start = DateTime.Now
For i = 1 To count
	If (activeEditObject.Type = ObjectTypeEnum.kPlanarSketchesObject) Then
		oSketch = ThisApplication.ActiveEditObject
	Else
		Continue For
	End If
Next
span = DateTime.Now - start
Logger.Debug("Late binding: " & span.TotalMilliseconds)

'TryCast
start = DateTime.Now
For i = 1 To count
	oSketch = TryCast(activeEditObject, PlanarSketch)
	If oSketch Is Nothing Then Continue For
Next
span = DateTime.Now - start
Logger.Debug("TryCast: " & span.TotalMilliseconds)

 

 

@Michael.Navara I can't run the code. It gives an error on the line starting with Logger. I don't think it's supported in Inventor 2018.

 

I have read various comments on StackOverflow saying that using try-catch has a performance impact (same for using the VBA equivalent of 'on error'). That is clearly shown in the 'In model' numbers you have provided, which I think come closest to the user case of bt. (I don't think he will be selecting 1000 objects, though).

TryCast is the overall winner. I didn't know about this operator (and it's even available in VBA). I'm sure to check it out, thanks.



@Darkforce_the_ilogic_guy,

 

After selection of part, selected part can be obtained from below code.

 

Dim oDoc As AssemblyDocument
oDoc = ThisApplication.ActiveDocument

Dim obj As Object
obj = oDoc.SelectSet.Item(1)

 


 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network