Tolerance and dimensions input from XLS

Hello,

Right now I am exporting all the dimensions and tol into a spreadsheet that we use for stacks.
I'm curios how do I revert that, if I make some tol tweaks I would like to bring the data from the XLS to the drawing back.
This is the code I use to get from drawing to XLS:

Option Strict Off
Imports System
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.IO
Imports NXOpen
Imports NXOpenUI
Imports NXOpen.Annotations
Imports NXOpen.UF

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
Dim theUISession As UI = UI.GetUI
Dim workPart As Part = theSession.Parts.Work

Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "journal")

Dim row As Long = 1
Dim column As Long = 1

'create Excel object
Dim objExcel as Object
Try
objExcel = Marshal.GetActiveObject("Excel.Application")
Catch
objExcel = CreateObject("Excel.Application")
End Try

If objExcel Is Nothing Then
theUISession.NXMessageBox.Show("Error", NXMessageBox.DialogType.Error, "Could not start Excel, journal exiting")
theSession.UndoToMark(markId1, "journal")
Exit Sub
End If

' open a blank Excel file to output dimensions into
Dim objWorkbook = objExcel.Workbooks.Add()
If objWorkbook Is Nothing Then
theUISession.NXMessageBox.Show("Error", NXMessageBox.DialogType.Error, "Could not open Excel file")
theSession.UndoToMark(markId1, "journal")
Exit Sub
End If

objExcel.visible = True

objExcel.Cells(row, 1) = workPart.FullPath

Dim objects1(0) As NXOpen.DisplayableObject
Dim myDimText() As String
Dim myDimDualText() As String
Dim draftingFeatureControlFrameBuilder1
For Each myDimension As Annotations.Dimension In workPart.Dimensions
row += 1

' (1) get the current value and put that into a cell
myDimension.GetDimensionText(myDimText, myDimDualText)
objExcel.Cells(row, column) = myDimText(0)

' (1) get the current value and put that into a cell
myDimension.GetDimensionText(myDimText, myDimDualText)
objExcel.Cells(row, column + 1) = myDimText(0)
objExcel.Cells(row, column+2) = myDimension.UpperToleranceValue
objExcel.Cells(row, column+0) = myDimension.GetAppendedText().GetAfterText()
objExcel.Cells(row, column+3) = myDimension.GetAppendedText().GetBeforeText()
'objExcel.Cells(row, column+4) = myDimension.GetAppendedText().GetBelowText()

' (2) force the dimension back to a numerical value
objects1(0) = myDimension
Dim editSettingsBuilder1 As NXOpen.Annotations.EditSettingsBuilder = Nothing
editSettingsBuilder1 = workPart.SettingsManager.CreateAnnotationEditSettingsBuilder(objects1)

Dim editsettingsbuilders1(0) As NXOpen.Drafting.BaseEditSettingsBuilder
editsettingsbuilders1(0) = editSettingsBuilder1
workPart.SettingsManager.ProcessForMultipleObjectsSettings(editsettingsbuilders1)
editSettingsBuilder1.AnnotationStyle.DimensionStyle.OverrideDimensionText = False

Dim nXObject1 As NXOpen.NXObject = Nothing
nXObject1 = editSettingsBuilder1.Commit()
editSettingsBuilder1.Destroy()

' (3) put the new value into Excel
myDimension.GetDimensionText(myDimText, myDimDualText)
objExcel.Cells(row, column+1) = myDimText(0)
objExcel.Cells(row, column+2) = myDimension.UpperToleranceValue

Next

For Each temp As Gdt In workPart.Gdts

row += 1

If Not TypeOf (temp) Is Annotations.DraftingFcf Then
Continue For
End If

Dim fcfBuilder As Annotations.DraftingFeatureControlFrameBuilder
fcfBuilder = workPart.Annotations.CreateDraftingFeatureControlFrameBuilder(temp)

Dim featureControlFrameDataBuilder1 As Annotations.FeatureControlFrameDataBuilder = fcfBuilder.FeatureControlFrameDataList.FindItem(0)

objExcel.Cells(row, column+2) = featureControlFrameDataBuilder1.ToleranceValue / 2.0
objExcel.Cells(row, column) = featureControlFrameDataBuilder1.PrimaryDatumExtendedText
objExcel.Cells(row, column + 1) = 0.0
'objExcel.Cells(row, column+2) = fcfBuilder.Characteristic.ToString
'objExcel.Cells(row, column) = featureControlFrameDataBuilder1.ZoneShape.ToString

'objExcel.Cells(row, column+5) = featureControlFrameDataBuilder1.PrimaryDatumReference.MaterialCondition

fcfBuilder.Destroy()

Next

' get a reference to the stack data work book
Dim OpenFileDialog1 as New OpenFileDialog()
Dim strFilePath as String

Dim result As DialogResult = OpenFileDialog1.ShowDialog()
' Test result.
If result = DialogResult.OK Then
' Do something.
strFilePath = OpenFileDialog1.FileName
End If

Dim wkbkStackData
Dim wkbkOpen as Object
For Each wkbkOpen in objExcel.Workbooks
Dim nameOnly = Path.GetFileName(strFilePath)
If wkbkOpen.Name = nameOnly Then
wkbkStackData = objExcel.Workbooks(nameOnly)
End if
Next

If wkbkStackData Is Nothing Then
wkbkStackData = objExcel.Workbooks.Open(strFilePath)
End If

' prompt for a file - if name is already open, prompt if that workbook should be used

' clear out the changes worksheet (or create if not there)
Dim doesSheetExist as Boolean
Dim shtTest as Object
For Each shtTest In wkbkStackData.Sheets
If shtTest.Name = "Changes"
doesSheetExist = True
End If
Next

If Not doesSheetExist Then
wkbkStackData.Sheets.Add( After:=wkbkStackData.Sheets("Stack_Data"))
wkbkStackData.Sheets(wkbkStackData.Sheets.Count).Name = "Changes"
End If

wkbkStackData.Sheets("Changes").UsedRange.Clear()
wkbkStackData.Sheets("Changes").Cells(1,1).Value = "Cleared"

Dim index as Integer
index = 1

Dim sht as Object
sht = objWorkbook.Sheets("Sheet1")

Dim rngAllData as Object
rngAllData = sht.UsedRange

Dim rngRows as Object
rngRows = rngAllData.Rows()

' run through each row, check if valid stack label
Dim rngRow as Object
For Each rngRow In rngRows
wkbkStackData.Sheets("Changes").Cells(1, 1) = index
Dim possibleRange = rngRow.Cells(1,1).Value

Dim isValidRange = False
Dim rng as Object

Try
rng = wkbkStackData.Sheets("Stack_Data").Range(possibleRange)
isValidRange = True
Catch

End Try

' if valid label, go ahead check against excisting info
If isValidRange Then

Try

wkbkStackData.Sheets("Changes").Cells(index, 2) = possibleRange

' if anythign changed, add to the changes worksheet

Dim curDim = rng.Value
Dim curTol = rng.Offset(0,1).Value

If curDim is Nothing Then
curDim = 0.0
End If

If curTol is Nothing Then
curTol = 0.0
End if

Dim didDimChange as Boolean
didDimChange = rng.Value <> rngRow.Cells(1,2).Value
Dim didTolChange as Boolean
didTolChange = rng.Offset(0,1).Value <> rngRow.Cells(1,3).Value

rng.Value = rngRow.Cells(1,2).Value
rng.Offset(0,1).Value = rngRow.Cells(1,3).Value

If didDimChange
wkbkStackData.Sheets("Changes").Cells(index, 3) = possibleRange + "Dimension changed" + curDim.ToString() + "--->" + rng.Value.ToString()
rng.Style="Bad"
End If

If didTolChange
wkbkStackData.Sheets("Changes").Cells(index, 4) = possibleRange + "Tolerance changed" + curTol.ToString() + "--->" + rng.Offset(0,1).Value.ToString()
rng.Offset(0,1).Style="Bad"
End If

Catch ex as Exception
wkbkStackData.Sheets("Changes").Cells(index, 4) = ex.ToString()

End Try
index = index + 1

End If

Next

wkbkStackData.Sheets("Changes").Columns().AutoFit()

' comment this line out if you want to leave the intermediate sheet open
objWorkbook.Close(False)

objWorkbook = Nothing
objExcel = Nothing

lw.Close()

' ----------------------------------------------
' Menu: Edit->Undo
' ----------------------------------------------
Dim marksRecycled1 As Boolean = Nothing
Dim undoUnavailable1 As Boolean = Nothing
theSession.UndoLastNVisibleMarks(1, marksRecycled1, undoUnavailable1)

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination

'----Other unload options-------
'Unloads the image immediately after execution within NX
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

'Unloads the image explicitly, via an unload dialog
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Explicitly
'-------------------------------

End Function

End Module

The main issue that I see is: How do you relate the NX dimension object to the XLS info? One possible solution would be to assign a unique ID number to each NX dimension (via an attribute) and record that ID in the XLS file along with the dimension value. If/when you change the tolerance info in the XLS file, your code could look at the ID in the XLS file, then find and edit the appropriate dimension in the NX part file.

You correct, I forgot to mention that. I have a code i.e A1, A4, B4 that we tie down the dimension a tolerance to that. When I export from NX to XLS I use that code to place the dim and tol in the spreadsheet using offset.
Knowing that now, I only need the tolerance back to NX from the xls.
DO you happen to know how to do that?

I'd suggest starting by recording a journal.

Open a file with some dimensions, record a journal while you edit the value of the tolerance; stop recording. The generated code will show you the calls necessary to change the dimension tolerance; it also often adds code that you don't need for your particular process. Eliminate the code you don't need, remove selection stickiness, and (optionally) turn it into a sub or function that you can reuse later.

Below is a quick journal that I recorded while changing a dimension's tolerance value (I edited out some unnecessary code - mostly undo marks).

Option Strict Off
Imports System
Imports NXOpen

Module NXJournal
Sub Main (ByVal args() As String)

Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workPart As NXOpen.Part = theSession.Parts.Work

Dim displayPart As NXOpen.Part = theSession.Parts.Display

' ----------------------------------------------
' Menu: Edit->Settings...
' ----------------------------------------------
Dim markId1 As NXOpen.Session.UndoMarkId
markId1 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Settings")

Dim objects1(0) As NXOpen.DisplayableObject
Dim horizontalDimension1 As NXOpen.Annotations.HorizontalDimension = CType(workPart.FindObject("ENTITY 26 1 1"), NXOpen.Annotations.HorizontalDimension)

objects1(0) = horizontalDimension1
Dim editSettingsBuilder1 As NXOpen.Annotations.EditSettingsBuilder
editSettingsBuilder1 = workPart.SettingsManager.CreateAnnotationEditSettingsBuilder(objects1)

Dim editsettingsbuilders1(0) As NXOpen.Drafting.BaseEditSettingsBuilder
editsettingsbuilders1(0) = editSettingsBuilder1
workPart.SettingsManager.ProcessForMultipleObjectsSettings(editsettingsbuilders1)

editSettingsBuilder1.AnnotationStyle.DimensionStyle.UpperToleranceEnglish = 0.005

Dim nXObject1 As NXOpen.NXObject
nXObject1 = editSettingsBuilder1.Commit()

editSettingsBuilder1.Destroy()

' ----------------------------------------------
' Menu: Tools->Journal->Stop Recording
' ----------------------------------------------

End Sub
End Module

We can see that it uses a ".FindObject" call to get the particular dimension that I selected during the recording process. Your code will need to find the dimension based on your ID and use it instead. Also, we can see that an "edit settings builder" object was used to edit the dimension style settings. How to create and use the edit settings builder is the main take away from this exercise.

In my case, I had an inch dimension that used an equal bilateral tolerance; we can see from the recorded code that the .UpperToleranceEnglish value was changed. If you use various dimension styles, you may need to query the dimension for the units and type to see what properties you need to change.