- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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")
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
@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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
@_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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
@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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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
