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?