3
$\begingroup$

I'm writing a script to extract all the dimensions from a 2D drawing in NX. In doing so, I have been able to get the dimensions and tolerances on all sheets, along with the zone numbers. This has been fairly easy. However, I'm running into a brick wall when it comes to the other "dimensions" or drawing specifications. I don't know how to loop through the properties of the Surface Finish or the parallelism annotations.

Here's my code currently.

' VBA Script to extract all the dimensions in an NX part file to an MS Excel Spreadsheet. ' The details extracted are:

' Sheet No. | Zone | Balloon No. | Description\Measurement Direction | Nominal Value | ' Tolerance Type | Upper Tolerance | Lower Tolerance | Maximum Value | Minimum Value

Option Strict Off Imports System Imports System.IO Imports NXOpen Imports NXOpen.UF Imports NXOpen.UI Imports NXOpen.Annotations

Module ExportDimensionsAndAnnotations 'Declare global variables Dim theSession as Session = Session.GetSession() Dim theUfSession As UFSession = UFSession.GetUFSession

Sub Main()
    ' First read the active part file from NX.
    ' Then, loop through the sheets.
    ' Then, loop through the dimensions in the sheet
    ' Grab the zone, text, tolerance type, tolerance and the measurement direction for each.
    ' Grab the nearest annotation in that zone.
    ' Build an array or a dictionary (similar to JSON or Python's Dictionary class)
    ' Then, loop through the text in the document, and do the same steps, except for those that are inapplicable, of course.
    ' Ask for a savefile location.
    ' Create an Excel file in that location
    ' Open the Excel file.
    ' Write array to the excel file.

    If IsNothing(theSession.Parts.Work) Then 'Error handling
        MsgBox("This code requires an active part. Please open a drawing first and then try again.")
        Exit Sub
    End If 
    Dim workPart as Part
    workPart = theSession.Parts.Work

    Dim theUISession as UI = UI.getUI
    Dim saveFileName as String
    Dim saveDialog as New System.Windows.Forms.SaveFileDialog
    Dim objExcel as Object
    Dim objWorkbook as Object
    Dim excelFileExists as Boolean = False
    Dim objWorksheet as Object
    Dim colSheetNumber as Integer = 1
    Dim colZone as Integer = 2
    Dim colBalloon as Integer = 3
    Dim colDescrMatlDir as Integer = 4
    Dim colNomValue as Integer = 5
    Dim colTolerType as Integer = 6
    Dim colTolerUpper as Integer = 7
    Dim colTolerLower as Integer = 8
    Dim colMaxValue as Integer = 9
    Dim colMinValue as Integer = 10
    Dim colComment as Integer = 11

    Dim valueSheetNumber as String
    Dim valueZone as String
    Dim valueBalloon as String
    Dim valueDescrMatlDir as String
    Dim valueNomValue as String
    Dim valueTolerType as String
    Dim valueTolerUpper as String
    Dim valueTolerLower as String
    Dim valueMaxValue as String
    Dim valueMinValue as String
    Dim valueComment as String

    Dim rowNumber as Integer = 1

    With saveDialog
        .DefaultExt = "xlsx"
        .FileName = "Exported Data"
        .Filter = "MS Excel Spreadsheets (*.xlsx)|*.xlsx|All Files (*.*)|*.*"
        .FilterIndex = 1
        .OverwritePrompt = True
        .Title = "Select a file where you'd like to save the exported data."
    End With
    saveDialog.ShowDialog()
    saveFileName = saveDialog.FileName
    If saveFileName ="Exported Data" Then
        MsgBox("You failed to select a save file. Exitting the macro.")
        Exit Sub
    End If
    objExcel = CreateObject("Excel.Application")
    if objExcel is Nothing Then
        theUISession.NXMessageBox.Show("Error", theUISession.NXMessageBox.DialogType.Error, "Could not start Excel, journal exiting")
        Exit Sub
    End If
    If File.Exists(saveFileName) Then
        excelFileExists = True
        objWorkbook = objExcel.Workbooks.Open(saveFileName)
        objWorksheet = objWorkbook.Sheets.Add
    Else
        objWorkbook = objExcel.Workbooks.Add
        objWorkbook.saveAs(saveFileName)
        objWorksheet = objWorkbook.Sheets(1)
    End If

    objWorksheet.cells(rowNumber, colSheetNumber).Value = "Sheet Number"
    objWorksheet.cells(rowNumber, colZone).Value = "Drawing Zone"
    objWorksheet.cells(rowNumber, colBalloon).Value = "Balloon Number"
    objWorksheet.cells(rowNumber, colDescrMatlDir).Value = "Description Text \ Measurement Direction"
    objWorksheet.cells(rowNumber, colNomValue).Value = "Nominal Value"
    objWorksheet.cells(rowNumber, colTolerType).Value = "Tolerance Type"
    objWorksheet.cells(rowNumber, colTolerUpper).Value = "Upper Tolerance"
    objWorksheet.cells(rowNumber, colTolerLower).Value = "Lower Tolerance"
    objWorksheet.cells(rowNumber, colMaxValue).Value = "Maximum Value"
    objWorksheet.cells(rowNumber, colMinValue).Value = "Minimum Value"

    For Each tempDim as Annotations.Dimension in workPart.Dimensions
        rowNumber = rowNumber + 1

        Dim theSheet as Drawings.DrawingSheet = AskDrawingSheet(tempDim)
        valueSheetNumber = getSheetNumber(theSheet).ToString
        valueZone = getZone(theSheet, tempDim)
        valueBalloon = ""
        valueNomValue = tempDim.ComputedSize

        valueDescrMatlDir = tempDim.GetType.ToString
        ' Clean up the material direction.
        valueDescrMatlDir = Replace(valueDescrMatlDir, "NXOpen.Annotations.","")

        Select Case valueDescrMatlDir
            Case "DiameterDimension"
                valueDescrMatlDir = "ø"
            Case "CylindricalDimension"
                valueDescrMatlDir = "ø"
            Case "MinorAngularDimension"
                valueDescrMatlDir = "∠"
            Case "HorizontalDimension"
                valueDescrMatlDir = "Length"
        End Select

        valueTolerLower = "-"
        valueTolerUpper = "-"
        valueMaxValue = "-"
        valueMinValue = "-"
        valueComment = "-"

        valueTolerType = tempDim.ToleranceType.ToString
        Select Case valueTolerType
            Case Is = "UnilateralBelow"
                valueTolerLower = tempDim.LowerMetricToleranceValue.ToString
                valueMaxValue = tempDim.ComputedSize
                valueMinValue = tempDim.ComputedSize + tempDim.LowerMetricToleranceValue
            Case Is = "UnilateralAbove"
                valueTolerUpper = tempDim.UpperMetricToleranceValue.ToString
                valueMaxValue = tempDim.ComputedSize + tempDim.UpperMetricToleranceValue
                valueMinValue = tempDim.ComputedSize
            Case Is = "LimitsAndFits"
                valueTolerLower = tempDim.LimitFitDeviation
                valueTolerUpper = tempDim.LimitFitGrade
                valueMaxValue = "As per standards"
                valueMinValue = "As per standards"
            Case Is = "BilateralOneLine"
                valueTolerUpper = tempDim.UpperMetricToleranceValue.ToString
                valueTolerLower = (-1*tempDim.UpperMetricToleranceValue).ToString
                valueMaxValue = tempDim.ComputedSize + tempDim.UpperMetricToleranceValue
                valueMinValue = tempDim.ComputedSize - tempDim.UpperMetricToleranceValue
            Case Is = "BilateralTwoLines"
                valueTolerLower = tempDim.LowerMetricToleranceValue.ToString
                valueTolerUpper = tempDim.UpperMetricToleranceValue.ToString
                valueMaxValue = tempDim.ComputedSize + tempDim.UpperMetricToleranceValue
                valueMinValue = tempDim.ComputedSize + tempDim.LowerMetricToleranceValue
            Case Is = "None"
                valueTolerUpper = "NA"
                valueTolerLower = "NA"
                valueMaxValue = tempDim.ComputedSize
                valueMinValue = tempDim.ComputedSize
            Case Is = "Basic"
                valueTolerUpper = "NA"
                valueTolerLower = "NA"
                valueMaxValue = tempDim.ComputedSize
                valueMinValue = tempDim.ComputedSize
            Case Is = "LimitOneLine"
                valueTolerUpper = tempDim.UpperMetricToleranceValue.ToString
                valueTolerLower = tempDim.LowerMetricToleranceValue.ToString
                valueMaxValue = tempDim.ComputedSize + tempDim.UpperMetricToleranceValue
                valueMinValue = tempDim.ComputedSize + tempDim.LowerMetricToleranceValue
            Case Else
                valueComment = "Error, " & valueTolerType & " is a tolerance type that hasn't been accounted for in the code. Please modify the script."
        End Select


        objWorksheet.cells(rowNumber, colSheetNumber).Value = valueSheetNumber
        objWorksheet.cells(rowNumber, colZone).Value = valueZone
        objWorksheet.cells(rowNumber, colBalloon).Value = valueBalloon
        objWorksheet.cells(rowNumber, colDescrMatlDir).Value = valueDescrMatlDir
        objWorksheet.cells(rowNumber, colNomValue).Value = valueNomValue
        objWorksheet.cells(rowNumber, colTolerType).Value = valueTolerType
        objWorksheet.cells(rowNumber, colTolerUpper).Value = valueTolerUpper
        objWorksheet.cells(rowNumber, colTolerLower).Value = valueTolerLower
        objWorksheet.cells(rowNumber, colMaxValue).Value = valueMaxValue
        objWorksheet.cells(rowNumber, colMinValue).Value = valueMinValue
        objWorksheet.cells(rowNumber, colComment).Value = valueComment
    Next

    for each annote as Annotation in workPart.Annotations

    Next

    objWorkbook.save()
    objWorkbook.close()
    objExcel.Quit()
    objWorksheet = Nothing
    objWorkbook = Nothing
    objExcel = Nothing
    MsgBox("Completed the extraction successfully! Check " & saveFileName & " for the data.")

End Sub

Function getSheetNumber(ByVal theSheet as Drawings.DrawingSheet) As String
    ' This function returns the number of a sheet given the DrawingSheet object.
    Dim sheetNum as Integer
    Dim theSheetBuilder as Drawings.DrawingSheetBuilder
    theSheetBuilder = theSession.Parts.Work.DrawingSheets.DrawingSheetBuilder(theSheet)
    sheetNum = theSheetBuilder.Number
    theSheetBuilder.Destroy()
    Return sheetNum.ToString
End Function


Function AskDrawingSheet(ByVal theObject As TaggedObject) As Drawings.DrawingSheet

    Dim theView As View = TryCast(theObject, View)
    If Not theView Is Nothing Then
        Dim sheetTag As Tag = Nothing
        Try
            theUfSession.Draw.AskDrawingOfView(theView.Tag, sheetTag)
            Return Utilities.NXObjectManager.Get(sheetTag) ' the drawing it is on
        Catch ex As NXException
            Return Nothing  ' it is a model view
        End Try
    End If

    Dim viewName As String = Nothing
    Dim status As Integer = Nothing
    Try
        theUfSession.View.AskViewDependentStatus(theObject.Tag, status, viewName)
    Catch ex As NXException
        Return Nothing
    End Try
    If status = 0 Then Return Nothing ' it is a model mode object

    Dim viewTag As Tag = Nothing
    theUfSession.View.AskTagOfViewName(viewName, viewTag)
    Dim viewType As Integer = Nothing
    Dim viewSubtype As Integer = Nothing
    theUfSession.View.AskType(viewTag, viewType, viewSubtype)
    If viewType = 0 Then Return Nothing ' it is view dependent in a modeling view

    Dim drawingTag As Tag = Nothing
    theUfSession.Draw.AskDrawingOfView(viewTag, drawingTag)
    Return Utilities.NXObjectManager.Get(drawingTag)  ' the drawing it is on!

End Function

Function getZone(ByVal theSheet As Drawings.DrawingSheet, ByVal theDimension As Annotations.Dimension) As String
    Dim borderBuilder As Drawings.BordersAndZonesBuilder
    borderBuilder = theSession.Parts.Work.Drafting.BordersAndZonesObjects.CreateBordersAndZonesBuilder(theSheet.BordersAndZones)

    Dim numHorizontalZones As Integer = (theSheet.Length - borderBuilder.LeftMargin - borderBuilder.RightMargin) / borderBuilder.HorizontalSize
    Dim numVerticalZones As Integer = (theSheet.Height - borderBuilder.BottomMargin - borderBuilder.TopMargin) / borderBuilder.VerticalSize

    'calculate zone wrt bottom left of drawing (ZoneOrigin.BottomLeft)
    Dim Hcell As Double = (theDimension.AnnotationOrigin.X - borderBuilder.LeftMargin) / borderBuilder.HorizontalSize
    Dim Vcell As Double = (theDimension.AnnotationOrigin.Y - borderBuilder.BottomMargin) / borderBuilder.VerticalSize

    Hcell = Math.Ceiling(Hcell)
    Vcell = Math.Ceiling(Vcell)

    Dim theZoneOrigin As Drawings.BordersAndZonesBuilder.ZoneOrigin = borderBuilder.Origin
    borderBuilder.Destroy()

    Dim verticalLetterNum As Integer
    Dim verticalLetter As Char

    Dim horizontalNum As Integer

    If theZoneOrigin = Drawings.BordersAndZonesBuilder.ZoneOrigin.BottomLeft Or theZoneOrigin = Drawings.BordersAndZonesBuilder.ZoneOrigin.TopLeft Then
        horizontalNum = Hcell
    Else
        'origin on right side
        horizontalNum = numHorizontalZones - Hcell + 1
    End If

    If theZoneOrigin = Drawings.BordersAndZonesBuilder.ZoneOrigin.BottomLeft Or theZoneOrigin = Drawings.BordersAndZonesBuilder.ZoneOrigin.BottomRight Then
        verticalLetterNum = Asc("A") + Vcell - 1
        verticalLetter = Chr(verticalLetterNum)

    Else
        'origin on the top
        verticalLetterNum = Asc("A") + numVerticalZones - Vcell
        verticalLetter = Chr(verticalLetterNum)

    End If
    Return verticalLetter & horizontalNum.ToString
End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer 
    'Unloads the image immediately after execution within NX
    GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
    '-------------------------------
End Function

End Module

Could someone help me out here?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.