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
re: tolerance and dimensions to/from XLS
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
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?
re: tolerance and dimensions to/from XLS
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.