BOM balloons without a parts list

Hi,

I am writing a journal to allow users to create a BOM balloon that is automatically populated with the correct find number. I know this functionality exists with parts lists, but we use TeamCenter and do not want parts lists on our drawings (even placing them off the page has been ruled out!).

I can manually create a balloon that is linked to the find number of the component by adding an identification symbol, editing the text and changing the category to 'Relationships' and clicking the 'Insert Object Attribute' button and then selecting my component. This produces text such as <W!47198@CALLOUT>.

My question is: Where does the number 47198 come from in that text? And can I find out that number from within my journal?

Cheers,

Ian

I'd guess that is the ID of the component. Run the following code on a component to see if the ID numbers match (code written by Amy Webster of GTAC).

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
 
Module NXJournal
 
  Dim s As Session = Nothing
  Dim ufs As UFSession = Nothing
  Dim lw As ListingWindow = Nothing
 
  Sub Main
      s = Session.GetSession()
      lw = s.ListingWindow
      ufs = NXOpen.UF.UFSession.GetUFSession()
 
      Dim object1 As NXObject = SelectAnObject("Report Object ID")
      Dim handle As String = Nothing
      Dim fileData As String = Nothing
      Dim ID as UInteger = 0
      Dim version as UInteger = 0
 
      Do While object1 isnot nothing
        handle = ufs.Tag.AskHandleOfTag(object1.Tag)
        ufs.Tag.DecomposeHandle(handle, fileData, ID, version)
        ECHO("ID = " & ID)
 
        object1  = SelectAnObject("Report Object ID")
      Loop
  End Sub
 
  Function SelectAnObject(ByVal prompt As String) As NXObject
 
    Dim selobj As NXObject = Nothing
    Dim theUI As UI = UI.GetUI
    Dim cursor As Point3d
    Dim typeArray() As Selection.SelectionType = _
      {Selection.SelectionType.All, _
      Selection.SelectionType.Faces, _
      Selection.SelectionType.Edges}
 
    Dim resp As Selection.Response = theUI.SelectionManager.SelectObject( _
      prompt, "Select an object", _
      Selection.SelectionScope.AnyInAssembly, _
      False, typeArray, selobj, cursor)
 
    Return selobj
  End Function
 
  Sub Echo(ByVal output As String)
    lw.Open()
    lw.WriteLine(output)
    ufs.UF.PrintSyslog(output & vbCrLf, False)
  End Sub
 
End Module

Oh, and be aware that this all changes in NX 8 or higher.
http://community.plm.automation.siemens.com/t5/NX-Languages/Reading-Text...

Hi,

Thanks for hint about the handles. It wasn't what was needed, but it pointed me in the right direction. The number is actually the component Tag. I've used it in the code below, which allows the user to select an edge, then finds the component or subassembly and correctly populates a callout balloon.

The bit that I'm stuck on is attaching the leader to the geometry on the view. The arrow always ends up in the bottom left of the drawing, not attached to anything. If you have any advice on this front, it would be greatly appreciated.

Cheers,
Ian

' NX 7.5.5.4
' Journal created by Ian Eldred on Mon Feb 16 12:55:59 2015 GMT Standard Time
' Last updated by Ian Eldred on 01/05/2015.
 
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
 
Module AutoBalloon
    Dim theSession As Session = Session.GetSession()
    Dim workPart As Part = theSession.Parts.Work
    Dim displayPart As Part = theSession.Parts.Display
    Dim lw As ListingWindow = theSession.ListingWindow
    Dim ufs As UFSession = UFSession.GetUFSession
    Dim theUI As UI = UI.GetUI
 
    Sub Main()
 
        Dim myEdge As Object
        Dim myPoint As Point3d
        Dim myPointBalloon As Point3d
        Dim type As Integer
        Dim subtype As Integer
        Dim handle As String = Nothing
        Dim fileData As String = Nothing
        Dim ID As UInteger = 0
        Dim version As UInteger = 0
        Dim strCallout As String
        Dim myComponent As Assemblies.Component
 
        ' ----------------------------------------------
        '   Menu: Insert->Annotation->Identification Symbol...
        ' ----------------------------------------------
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Start")
 
        'Select edge
        If UserSelectEdge("Select edge to attach balloon", myEdge, myPoint) = Selection.Response.Cancel Then
            Return
        Else
            'Find out if the selected component is a child of the current assembly or if it is a child of a subassembly.
            myComponent = myEdge.OwningComponent
            Do Until workPart.ComponentAssembly.RootComponent.DisplayName = myComponent.Parent.Parent.DisplayName
                myComponent = myComponent.Parent
            Loop
            strCallout = "<W!" & myComponent.Tag.ToString & "@CALLOUT>"
        End If
 
        Dim nullAnnotations_IdSymbol As Annotations.IdSymbol = Nothing
 
        Dim idSymbolBuilder1 As Annotations.IdSymbolBuilder
        idSymbolBuilder1 = workPart.Annotations.IdSymbols.CreateIdSymbolBuilder(nullAnnotations_IdSymbol)
        idSymbolBuilder1.UpperText = strCallout
        idSymbolBuilder1.Size = 12.0
 
        Dim leaderData1 As Annotations.LeaderData
        leaderData1 = workPart.Annotations.CreateLeaderData()
        leaderData1.Arrowhead = Annotations.LeaderData.ArrowheadType.FilledArrow
        leaderData1.TerminatorType = Annotations.LeaderData.LeaderType.PlainWithoutStub
 
        idSymbolBuilder1.Leader.Leaders.Append(leaderData1)
        idSymbolBuilder1.Origin.SetInferRelativeToGeometry(True)
 
        Dim nullView As View = Nothing
 
        'Arrow location
        'Why 2 identical points?
        Dim coordinates1 As Point3d = New Point3d(myPoint.X, myPoint.Y, 0.0)
        Dim point1 As Point
        point1 = workPart.Points.CreatePoint(coordinates1)
        Dim point2 As Point3d = New Point3d(myPoint.X, myPoint.Y, 0.0)
        leaderData1.Leader.SetValue(point1, workPart.Views.WorkView, point2)
 
        Dim assocOrigin1 As Annotations.Annotation.AssociativeOriginData
        idSymbolBuilder1.Origin.SetAssociativeOrigin(assocOrigin1)
 
        'Balloon location
        Dim response2 As Selection.DialogResponse = UserSelectScreenPos("Place balloon", myPointBalloon)
        If response2 <> Selection.DialogResponse.Pick Then
            Return
        End If
 
        Dim point3 As Point3d = New Point3d(myPointBalloon.X, myPointBalloon.Y, 0.0)
        idSymbolBuilder1.Origin.Origin.SetValue(Nothing, nullView, point3)
 
        Dim nXObject1 As NXObject
        nXObject1 = idSymbolBuilder1.Commit()
 
        idSymbolBuilder1.Destroy()
    End Sub
 
    Function UserSelectEdge(ByVal prompt As String, ByRef selObj As TaggedObject, ByRef selPoint As Point3d) As Selection.Response
 
        'Allow user to interactively select an edge
 
        Dim title As String = "Select an edge"
        Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
        Dim selectionMask_array(6) As Selection.MaskTriple
 
        'Set the selection criteria to any edge
        'TODO: Add point on surface
        selectionMask_array(0).Type = UFConstants.UF_solid_type
        selectionMask_array(0).Subtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
        selectionMask_array(0).SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
 
        selectionMask_array(1).Type = UFConstants.UF_line_type
        selectionMask_array(1).Subtype = UFConstants.UF_all_subtype
 
        selectionMask_array(2).Type = UFConstants.UF_circle_type
        selectionMask_array(2).Subtype = UFConstants.UF_all_subtype
 
        selectionMask_array(3).Type = UFConstants.UF_conic_type
        selectionMask_array(3).Subtype = UFConstants.UF_all_subtype
 
        selectionMask_array(4).Type = UFConstants.UF_spline_type
        selectionMask_array(4).Subtype = UFConstants.UF_all_subtype
 
        selectionMask_array(5).Type = UFConstants.UF_solid_silhouette_type
        selectionMask_array(5).Subtype = UFConstants.UF_all_subtype
 
        selectionMask_array(6).Type = UFConstants.UF_section_edge_type
        selectionMask_array(6).Subtype = UFConstants.UF_all_subtype
 
        'This line allows the user to select from any view:
        ufs.Ui.SetCursorView(0)
 
        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selObj, selPoint)
        If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If
 
    End Function
 
    Function UserSelectScreenPos(ByVal prompt As String, ByRef selPoint As Point3d) As Selection.DialogResponse
        'Allow user to interactively select a screen position
        Dim view As NXOpen.View = Nothing
        Return theUI.SelectionManager.SelectScreenPosition(prompt, view, selPoint)
    End Function
 
End Module

The picked point is reported with respect to 3D model space; the leader point is being specified in terms of the 2D drawing sheet space. You will need to convert from the drawing view coordinates to the drawing sheet coordinates.

You might try the .MapModelToDrawing method.

Also, you might want to look at:
http://nxjournaling.com/content/move-parts-list-callout-leader-location
This journal allows the user to select an edge in the drawing and attach the callout balloon to the selected edge.

Thank you for that. The .MapModelToDrawing method looks like it could work for me. This method requires me to provide a view, so how do I identify the view that the user has clicked on (without asking them to select a view with a separate click)?

In the code linked to above, the .SelectWithSingleDialog method was used, which will return the point and the view selected.

I've just reviewed your parts list leader link above and I think that answers my question using the .SelectWithSingleDialog method. I'll give that a try with the .MapModelToDrawing method and see if I can get it to work. Either way, I'll post back here and let you know. Thanks again!

I now have this working pretty much as intended. See code below, much of the which was taken from: http://nxjournaling.com/content/move-parts-list-callout-leader-location.
As ever, thank you very much for your help!

' NX 7.5.5.4
' Journal created by Ian Eldred on 14/04/2015
' This journal allows a user to select an edge of a component on an assembly drawing, then
' select a location to place the balloon. The callout within the balloon will be associated
' to the callout of the component.
'################################################################################################################
' Version History:
' Version | Date       | Changed by    | Description of change
' --------|------------|---------------|-------------------------------------------------------------------------
' 1.0     | 29/04/2015 | Ian Eldred    | Initial release
'################################################################################################################
 
Option Strict Off
Imports System
Imports System.Windows.Forms
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
 
Module AutoBalloon
    Dim theSession As Session = Session.GetSession()
    Dim workPart As Part = theSession.Parts.Work
    Dim displayPart As Part = theSession.Parts.Display
    Dim lw As ListingWindow = theSession.ListingWindow
    Dim lg As LogFile = theSession.LogFile
    Dim ufs As UFSession = UFSession.GetUFSession
    Dim theUI As UI = UI.GetUI
    Dim dicSectionEdges As New Dictionary(Of Tag, Tag)
    Dim viewList As New List(Of Tag)
 
    Sub Main()
 
        Dim myPointBalloon As Point3d
        Dim strCallout As String
        Dim myComponent As Assemblies.Component
        Dim mySelPoint(2) As Double
        Dim mySelViewTag As Tag = Tag.Null
        Dim mySelEdgeTag As Tag = Nothing
        Dim myEdgeCurve As DisplayableObject
 
        lw.Open()
        lg.WriteLine("~~ Auto balloon without parts list ~~")
        lg.WriteLine("  timestamp: " & Now)
 
        If IsNothing(theSession.Parts.Work) Then
            'active part required
            lg.WriteLine("  no active part, exiting journal")
            Return
        End If
 
        Const undoMarkName As String = "Auto balloon without parts list"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)
 
        Do Until UserSelectEdge("Select edge to attach balloon", mySelPoint, mySelViewTag, mySelEdgeTag) = Selection.Response.Cancel
 
            lg.WriteLine("  User has selected an edge.")
            'return the object from the given tag
            ufs.Disp.SetHighlight(mySelEdgeTag, 0)
            myEdgeCurve = Utilities.NXObjectManager.Get(mySelEdgeTag)
            If IsNothing(myEdgeCurve) Then
                lg.WriteLine("  UserSelectEdge() returned Nothing, skip to next edge selection")
                Continue Do
            End If
 
            lg.WriteLine("  selected object type: " & myEdgeCurve.GetType.ToString)
            Dim selView As NXOpen.View = Utilities.NXObjectManager.Get(mySelViewTag)
            lg.WriteLine("  selected in view: " & selView.Name)
            lg.WriteLine("  View type: " & selView.GetType.ToString)
            lg.WriteLine("  selected point: " & mySelPoint(0) & ", " & mySelPoint(1) & ", " & mySelPoint(2))
 
            If TypeOf (selView) Is Drawings.SectionView Then
                lg.WriteLine("  View is a section view. Building dictionary of sections edges.")
                BuildSectionDictionary(selView)
            End If
 
            lg.WriteLine("  Get the component from the selected edge.")
            myComponent = GetComponentOfEdge(mySelEdgeTag)
            lg.WriteLine("  mySelEdgeTag = " & mySelEdgeTag.ToString)
            If IsNothing(myComponent) Then
                lg.WriteLine("  Could not find component of edge, skip to next edge selection")
                Continue Do
            End If
            lg.WriteLine("  GetComponentOfEdge(mySelEdgeTag) = " & myComponent.DisplayName)
 
            lg.WriteLine("  Find out if the selected component is a child of the current assembly or if it is a child of a subassembly.")
            Do Until workPart.ComponentAssembly.RootComponent.DisplayName = myComponent.Parent.Parent.DisplayName
                lg.WriteLine("  myComponent = " & myComponent.DisplayName & ": No")
                myComponent = myComponent.Parent
            Loop
            strCallout = "<W!" & myComponent.Tag.ToString & "@CALLOUT>"
            lg.WriteLine("  myComponent = " & myComponent.DisplayName & ": Yes")
            lg.WriteLine("  strCallout = " & strCallout)
 
            Dim symPt As Point3d
            symPt.X = mySelPoint(0)
            symPt.Y = mySelPoint(1)
            symPt.Z = mySelPoint(2)
 
            lg.WriteLine("  Building the new ID symbol...")
            Dim nullAnnotations_IdSymbol As Annotations.IdSymbol = Nothing
 
            Dim idSymbolBuilder1 As Annotations.IdSymbolBuilder
            idSymbolBuilder1 = workPart.Annotations.IdSymbols.CreateIdSymbolBuilder(nullAnnotations_IdSymbol)
            idSymbolBuilder1.UpperText = strCallout
            idSymbolBuilder1.Size = 12.0
 
            Dim leaderData1 As Annotations.LeaderData
            leaderData1 = workPart.Annotations.CreateLeaderData()
            leaderData1.Arrowhead = Annotations.LeaderData.ArrowheadType.FilledArrow
            leaderData1.TerminatorType = Annotations.LeaderData.LeaderType.PlainWithoutStub
 
            idSymbolBuilder1.Leader.Leaders.Append(leaderData1)
            idSymbolBuilder1.Origin.SetInferRelativeToGeometry(True)
 
            Dim nullView As NXOpen.View = Nothing
 
            'Arrow location
            lg.WriteLine("  Creating the leader.")
            leaderData1.Leader.SetValue(myEdgeCurve, selView, symPt)
 
            Dim assocOrigin1 As Annotations.Annotation.AssociativeOriginData
            idSymbolBuilder1.Origin.SetAssociativeOrigin(assocOrigin1)
 
            'Balloon location
            lg.WriteLine("  Getting the screen position to place the balloon.")
            Dim response2 As Selection.DialogResponse = UserSelectScreenPos("Place balloon", myPointBalloon)
            If response2 <> Selection.DialogResponse.Pick Then
                Return
            End If
 
            Dim point3 As Point3d = New Point3d(myPointBalloon.X, myPointBalloon.Y, 0.0)
            idSymbolBuilder1.Origin.Origin.SetValue(Nothing, nullView, point3)
 
            lg.WriteLine("  Committing the ID symbol.")
            Dim nXObject1 As NXObject
            nXObject1 = idSymbolBuilder1.Commit()
 
            idSymbolBuilder1.Destroy()
 
        Loop
        lg.WriteLine("~~ End Auto balloon without parts list ~~")
        lw.Close()
 
    End Sub
 
    Function UserSelectEdge(ByVal prompt As String, ByRef theCursor() As Double, ByRef theView As Tag, ByRef theObject As Tag) As Selection.Response
 
        'Allow user to interactively select an edge
        Dim response As Integer = 0
        Dim user_data As System.IntPtr
 
        ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
        Dim curCursorView As Integer
        ufs.Ui.AskCursorView(curCursorView)
 
        Try
            ufs.Ui.SetCursorView(0)
            'SelectWithSingleDialog allows the user to make a single selection and returns the object, the point and the view.
            ufs.Ui.SelectWithSingleDialog("Select component: ", prompt, _
                UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY, AddressOf init_proc_body, _
                user_data, response, theObject, theCursor, theView)
        Finally
            ufs.Ui.SetCursorView(curCursorView)
            ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
        End Try
 
        Select Case response
            Case UFConstants.UF_UI_BACK
                Return Selection.Response.Back
            Case UFConstants.UF_UI_OK
                Return Selection.Response.Ok
            Case UFConstants.UF_UI_OBJECT_SELECTED
                Return Selection.Response.ObjectSelected
            Case UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME
                Return Selection.Response.ObjectSelectedByName
            Case Else
                Return Selection.Response.Cancel
        End Select
    End Function
 
    Public Function init_proc_body(ByVal select_ As IntPtr, _
                              ByVal userdata As IntPtr) As Integer
        'this function must have the same signature as UFUi.SelInitFnT Delegate
 
        'setup mask to filter for edges or curves
        Dim num_triples As Integer = 7
        Dim mask_triples(num_triples - 1) As UFUi.Mask
 
        mask_triples(0).object_type = UFConstants.UF_solid_type
        mask_triples(0).object_subtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
        mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
 
        mask_triples(1).object_type = UFConstants.UF_line_type
        mask_triples(1).object_subtype = UFConstants.UF_all_subtype
 
        mask_triples(2).object_type = UFConstants.UF_circle_type
        mask_triples(2).object_subtype = UFConstants.UF_all_subtype
 
        mask_triples(3).object_type = UFConstants.UF_conic_type
        mask_triples(3).object_subtype = UFConstants.UF_all_subtype
 
        mask_triples(4).object_type = UFConstants.UF_spline_type
        mask_triples(4).object_subtype = UFConstants.UF_all_subtype
 
        mask_triples(5).object_type = UFConstants.UF_solid_silhouette_type
        mask_triples(5).object_subtype = UFConstants.UF_all_subtype
 
        mask_triples(6).object_type = UFConstants.UF_section_edge_type
        mask_triples(6).object_subtype = UFConstants.UF_all_subtype
 
        ufs.Ui.SetSelMask(select_, _
                          UFUi.SelMaskAction.SelMaskClearAndEnableSpecific, _
                          num_triples, mask_triples)
 
        Return UFConstants.UF_UI_SEL_SUCCESS
 
    End Function
 
    Function GetComponentOfEdge(ByVal theEdgeTag As Tag) As Assemblies.Component
        'Find the owning componet of the edge
 
        Dim dwgObj As NXObject
        dwgObj = Utilities.NXObjectManager.Get(theEdgeTag)
 
        If dwgObj.IsOccurrence Then
            'object is owned by a component (edge, face, etc)
 
            Return dwgObj.OwningComponent
        Else
            'object is owned by the drawing (silhouette edge curve, section edge curve, extracted edge curve, etc)
 
            If TypeOf (dwgObj) Is NXOpen.Line Or TypeOf (dwgObj) Is NXOpen.Arc Or _
                TypeOf (dwgObj) Is NXOpen.Spline Or TypeOf (dwgObj) Is NXOpen.Conic Then
 
                Dim groupTag As Tag
                Dim groupType As Integer
                Dim groupSubType As Integer
                'determine if this is a section or silhouette curve
                ufs.Draw.AskGroupOfCurve(dwgObj.Tag, groupTag, groupType, groupSubType)
 
                Select Case groupType
                    Case Is = UFConstants.UF_solid_silhouette_type
                        'silhouette type 201
                        Dim theFaceTag As Tag
                        ufs.Draw.AskFaceOfSil(dwgObj.Tag, theFaceTag)
                        lg.WriteLine("  theFaceTag = " & theFaceTag)
 
                        Dim theFace As NXObject = Utilities.NXObjectManager.Get(theFaceTag)
                        lg.WriteLine("  theFace = " & theFace.ToString)
                        Return theFace.OwningComponent
 
                    Case Is = UFConstants.UF_solid_section_type
                        'section curve type 198
 
                        Dim tempComp As Assemblies.Component
                        tempComp = ComponentOfSectionEdge(dwgObj.Tag)
 
                        Return tempComp
 
                    Case Else
                        Return Nothing
 
                End Select
 
            End If
            'theObject is not a line, arc, conic, or spline
            Return Nothing
        End If
 
    End Function
 
    Sub BuildSectionDictionary(ByVal sectionView As Drawings.SectionView)
 
        'If you have previously built a dictionary for this view, exit sub.
        If viewList.IndexOf(sectionView.Tag) = -1 Then
            viewList.Add(sectionView.Tag)
        Else
            Exit Sub
        End If
 
        Dim sxSolidTags() As Tag
        Dim numSxSolids As Integer
        ufs.Draw.AskSxsolidsOfSxview(sectionView.Tag, Nothing, numSxSolids, sxSolidTags)
 
        For Each sxSolidTag As Tag In sxSolidTags
 
            Dim numSxEdges As Integer
            Dim sxEdgeTags() As Tag
            ufs.Draw.AskSxedgesOfSxsolid(sxSolidTag, numSxEdges, sxEdgeTags)
 
            For Each sxEdgeTag As Tag In sxEdgeTags
 
                dicSectionEdges.Add(sxEdgeTag, sxSolidTag)
 
            Next
 
        Next
 
    End Sub
 
    Function ComponentOfSectionEdge(ByVal sectionEdgeTag As Tag) As Assemblies.Component
 
        Dim tempComp As Assemblies.Component
 
        If dicSectionEdges.ContainsKey(sectionEdgeTag) Then
            Dim sxSolidTag As Tag = dicSectionEdges.Item(sectionEdgeTag)
 
            Dim solidTag As Tag
            ufs.Draw.AskSolidOfSection(sxSolidTag, solidTag)
 
            Dim tempSolid As Body = Utilities.NXObjectManager.Get(solidTag)
            tempComp = tempSolid.OwningComponent
 
            Return tempComp
 
        Else
            Return Nothing
        End If
 
    End Function
 
    Function UserSelectScreenPos(ByVal prompt As String, ByRef selPoint As Point3d) As Selection.DialogResponse
        'Allow user to interactively select a screen position
        Dim view As NXOpen.View = Nothing
        Return theUI.SelectionManager.SelectScreenPosition(prompt, view, selPoint)
    End Function
 
End Module

This is absolutely brilliant. However, with the DraftingCurve introduction in later versions of NX this does not seem to work anymore. The only thing I could get it to work on was pre-nx8 views on the silhouette curves. This would be a god send if it worked for NX8.5+.
The DraftingCurve.OwningPart gives the actual drawing sheet and the OwningComponent gives a null tag.

I only have access to NX7.5 at the moment. We are due to upgrade to NX10 later this year. In the meantime, I'd be happy to work on it with you if you can test it.

Hi guys! Any news about this with nx9 or later?

I now have access to NX10, so I should be able to work on this again. I'll let you know when I make some progress.

Have you been able to update it to make it work in NX10?

thanks!I´ve been looking for this for long. I´m cluless about programming, so I can´t do nothing but ask whoever it takes (because the way it works now is not proficient...).

Hello,
I find this utility very interesting and very useful!

However, I use NX11 and it does not seem to work on this version. That is true ?

Would it be possible to update this code to work with NX11?

Best Regards !

Pat

Hello,

It's possible to create a smart balloon without any part-list. Let me explain, I would like to create a balloon manually attached to a component (edge ​​or surface) and the number displayed in the balloon must match the callout attribute of the coin it is associated with? I wish to be able to insert more than one balloon for the same component if it is found in several copies in an assembly. Unless I'm wrong, it's not possible to do that in NX11 and NX12, you have to manually enter the balloon number if you have more than one balloon with the same number, but I would like do not have to manually enter the number in the ball.

In addition, could the number displayed in the balloon can be automatically updated if Callout changes?

It's possible to do this with the previous examples? If so, how can you help me?

Best!

Pat