Note Replacement Error

Hello all, I have used this site before wit great success. For reference I am using NX7.5 and trying to utilize the journal below

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.Utilities
Imports NXOpen.Annotations

Module ChangeNoteWord
Sub Main()
Dim s As Session = Session.GetSession()
Dim dp As Part = s.Parts.Display
Dim nc As NoteCollection = dp.Notes
Dim notetext1 As String = "CURRENT WORD"
notetext1 = NXInputBox.GetInputString("Change Note", "Note word to be changed", notetext1)
Dim notetext2 As String = "REPLACEMENT WORD"
notetext2 = NXInputBox.GetInputString("Change Note", "New note word", notetext2)
Dim notestring() As String
Dim nolines As Integer = 0
Dim found1 As Boolean = False
Dim m1 As Session.UndoMarkId = s.SetUndoMark(Session.MarkVisibility.Visible, "M1")
For Each a_note As SimpleDraftingAid In nc
notestring = a_note.GetText()
nolines = notestring.Length
For i As Integer = 0 To nolines - 1
found1 = notestring(i).Contains(notetext1)
If found1 = True Then
notestring(i) = notestring(i).Replace(notetext1, notetext2)
End If
Next
a_note.SetText(notestring)
Next
s.UpdateManager.DoUpdate(m1)
End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function
End Module

However, I receive this error

Runtime error:
NXOpen.NXException: Invalid text
at NXOpen.Annotations.SimpleDraftingAid.SetText(String[] lines)
at ChangeNoteWord.Main() in C:\Users\bbowley\AppData\Local\Temp\NXJournals7004\journal.vb:line 31

Any thoughts?

The error message states "invalid text"; what text are you searching for and what are you trying to replace it with?
Also, what region/language setting is your computer currently using?

Region:USA - English

Some text is XX and needs to be replaced with nothing so I blank the input line, however, with testing I tried replacing XX with AA being the new text and I receive the same message.

I'm able to reproduce your error if I try to replace text that shows up in a reference.

For instance: I have a view on the drawing with the label displayed (VIEW A). However, the "A" is reference text driven from an attribute. If I edit the annotation text of the label, it looks like this: "VIEW ". If I try to replace text that shows up in the reference, such as "VW", "TT", or "839", I get an invalid text error because the reference to the driving attribute is no longer valid. So even though "TT" doesn't show up on my drawing, it does exist as text in one of the notes/labels.

Check that the text you are trying to replace isn't driven by an expression or attribute value...

They are not driven by expression or attribute value. I am dealing with exported data and changing the sheet format, when I replace the format via importing a prt file with the new dwg format, the journal functions; I find this odd.

Can you email me a sample file where this error is occurring?
info@nxjournaling.com

Unfortunately due to the nature of the components, I cannot. I wish I could

If you copy the file and delete out the components, do you get the same error?

Yes.

I would like to change this journal to run only on note text items that I select, is that possible?

Is it possible?
Absolutely!
I suggest you start here:
http://nxjournaling.com/content/using-mask-triples-selectobject-routine

The function for selecting note objects (NX 7.5) will look something like this:

Function SelectObjects(ByVal prompt As String, ByRef selObj() as NXObject) As Selection.Response

Dim theUI as UI = UI.GetUI
Dim title As String = "Select notes"
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.WorkPart
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_drafting_entity_type
.Subtype = UFConstants.UF_draft_note_subtype
End With

Dim resp as Selection.Response = theUI.SelectionManager.SelectObjects(prompt, _
title, scope, selAction, _
includeFeatures, keepHighlighted, selectionMask_array, _
selobj)
If resp = Selection.Response.Ok Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

The overall strategy is:

  • prompt user to select one or more note objects
  • loop through selected note objects
  • search and replace text

If you run into trouble, post back with specific questions.

after reading it seems that I am appending this block of code to the end, something like this perhaps?

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.Utilities
Imports NXOpen.Annotations

Module ChangeNoteWord
Sub Main()

Dim s As Session = Session.GetSession()
Dim dp As Part = s.Parts.Display
Dim nc As NoteCollection = dp.Notes
Dim notetext1 As String = "CURRENT WORD"
notetext1 = NXInputBox.GetInputString("Change Note", "Note word to be changed", notetext1)
Dim notetext2 As String = "REPLACEMENT WORD"
notetext2 = NXInputBox.GetInputString("Change Note", "New note word", notetext2)
Dim notestring() As String
Dim nolines As Integer = 0
Dim found1 As Boolean = False
Dim m1 As Session.UndoMarkId = s.SetUndoMark(Session.MarkVisibility.Visible, "M1")
For Each a_note As SimpleDraftingAid In nc
notestring = a_note.GetText()
nolines = notestring.Length
For i As Integer = 0 To nolines - 1
found1 = notestring(i).Contains(notetext1)
If found1 = True Then
notestring(i) = notestring(i).Replace(notetext1, notetext2)
End If
Next
a_note.SetText(notestring)
Next
s.UpdateManager.DoUpdate(m1)
End Sub
Function SelectObjects(ByVal prompt As String, ByRef selObj() As NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim title As String = "Select notes"
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.WorkPart
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_drafting_entity_type
.Subtype = UFConstants.UF_draft_note_subtype
End With

Dim resp As Selection.Response = theUI.SelectionManager.SelectObjects(prompt, _
title, scope, selAction, _
includeFeatures, keepHighlighted, selectionMask_array, _
selobj)
If resp = Selection.Response.Ok Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function
End Module

I feel this is not correct.

Congratulations!
Step 1 is to add the function to the module, which you have done correctly. You will now be able to call the newly added function from any code within the module (such as Sub Main).

Step 2 is: we need to modify the existing code in Sub Main to make use of the new function.
About 1/2 through the Main subroutine (Sub Main), you will see the line:

For Each a_note As SimpleDraftingAid In nc

We need to understand what this line is doing so that we can modify it.
"For Each" - this starts a loop construct; we are going to perform some action on every item in a given collection. We don't need to know beforehand how many items are in the collection, the For Each loop will stop when the collection runs out of items.

"a_note As SimpleDraftingAid" - this part is a variable declaration. We are creating a variable named "a_note" and declaring it to be of type "SimpleDraftingAid". A "SimpleDraftingAid" is an object type defined by the NXOpen API; to see more details about this type of object, open the NXOpen .NET reference document (the compiled help file), activate the "index" tab and type in the keyword "SimpleDraftingAid". Selecting the resulting "SimpleDraftingAid class" link will open a page that lists all the available properties and methods that this object gives us access to (we'll be using the .GetText and .SetText methods).

"In nc" - this specifies what collection we want to work with. "nc" is the name of a variable; if we look at the variable declarations near the beginning of the code, we see it refers to the currently displayed part's note collection.

So, the programmer of this particular journal is going to process every note object in the currently displayed part without the user's intervention. We want to change that to only process the note objects that the user selects. We won't need the "nc" variable since we won't be using the part's note collection. However, we can modify it to our needs. Change this line of code:

Dim nc As NoteCollection = dp.Notes

to this:

Dim nc() As NXObject

The selection function is going to return an array of objects of type "NXObject", so we have modified "nc" to be an array of NXObject (the parentheses behind "nc" designate it as being an array).

Almost there!
Finally, we need to add the code that will call our selection function, allowing the user to select the note objects. Just before the "For Each" loop in the journal, add the following code:

If SelectObjects("Select objects", nc) = Selection.Response.Cancel Then
Exit Sub
End if

When the selection function is called, the familiar NX selection dialog will pop up. At this point the user can select one or more objects and press "OK", or they can press "Cancel". If the response = "Cancel" then we exit the subroutine (the Main subroutine), which in our particular case will end the journal with no questions asked. If the response is anything other than "Cancel" ("OK" is the only other option in this case), the journal will continue executing.

Try it out!

That was really helpful. I use it for Labels too, it works the same way.

I tyed to implement this for dimensions, particularly for after text. I can select the after text and print it in a listing window with .GetAppendedText.GetAfterText but i don't know how to change it. I have tried using SetAfterText instead of SetText but it didn't work.

I am new to this and i really don't know how to get it to work.

After you edit and set the appended text, you will need to perform an update to apply the changes, see example code below:

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
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.Invisible, "Start")

Dim myDim As Annotations.Dimension
If SelectDimension("Select a dimension", myDim) = Selection.Response.Back Then
Exit Sub
End If

Dim myAppendedText As Annotations.AppendedText = myDim.GetAppendedText

Dim newAfterText(0) As String
newAfterText(0) = "NEW APPENDED TEXT"
myAppendedText.SetAfterText(newAfterText)

myDim.SetAppendedText(myAppendedText)

'update dimension display
myAppendedText.Dispose()
Dim nErrs1 As Integer
nErrs1 = theSession.UpdateManager.DoUpdate(markId1)

End Sub

Function SelectDimension(ByVal prompt As String, ByRef selDim As Annotations.Dimension) As Selection.Response

Dim selObj As TaggedObject
Dim theUI As UI = UI.GetUI
Dim title As String = "Select a dimension"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
Dim cursor As Point3d
Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_dimension_type
.Subtype = UFConstants.UF_all_subtype
End With

Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
title, scope, selAction, _
includeFeatures, keepHighlighted, selectionMask_array, _
selobj, cursor)
If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
selDim = selObj
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

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

Hi,

I have used above journal to find and replace a text in a note.
But I need to get text after a string. i.e., If RGB393 or RGB465 is there in a note, I have to get both specifications separately by searching RGB.
Can you please help me to extract text or numbers after a string in a note.

Thanks,
Muthu

Regular expressions is one way to handle this situation. The code below extracts any numbers that follow the string "RGB". The code illustrates the technique on a string variable, but you can use the text from a note or other NX object that returns text.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Imports NXOpen

Module Module2

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

Sub Main()

If IsNothing(theSession.Parts.BaseWork) Then
'active part required
Return
End If

lw.Open()

Const undoMarkName As String = "regex replace"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim myRGBnums As New List(Of String)

Dim myString As String = "A STRING RGB12 OTHER STUFF RGB987 AND ANOTHER RGB123456"
myRGBnums = RGBNum(myString)

If myRGBnums.Count > 0 Then
lw.WriteLine("-------------------------")
End If

For Each temp As String In myRGBnums
lw.WriteLine(temp)
Next

lw.Close()

End Sub

Function RGBNum(ByVal inputString As String) As List(Of String)

Dim theMatches As New List(Of String)

'change search string as needed
Dim strRegex As String = "RGB(?\d+)"
Dim myRegex As New Regex(strRegex, RegexOptions.IgnoreCase Or RegexOptions.Multiline)

Dim myMatches As MatchCollection = myRegex.Matches(inputString)

lw.WriteLine(myMatches.Count.ToString & " matches found")

For Each match As Match In myMatches
Dim groups As GroupCollection = match.Groups
'lw.WriteLine("match: " & groups.Item(0).Value)
'lw.WriteLine("numbers found: " & groups.Item(1).Value)
theMatches.Add(groups.Item(1).Value)
Next

Return theMatches

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

That works fantastic. I really appreciate your help. On top of trying to learn VB.NET (as I know python and matlab really well) I do not have access to the help files for this project as they are on a different part of our network. Do you have any suggestions on how to utilize an access database with this Journal so that Col A has the value that is in the "current word" and Col B has the "replacement word"

I think that I need to add this code so far:

Imports System.Data.OleDb

and

Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader

and

Sub SpecCon
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\XXXX\.accdb" ' Change it to your Access Database location
connString = provider & dataFile
myConnection.ConnectionString = connString
End Sub

If you are using 32 bit NX with 32 bit Office or 64 bit NX with 64 bit Office, it will probably work fine. However, if you are using 64 bit NX with 32 bit Office, you will probably run into a database driver issue. If this is the case, do some web searching - MS has a driver that allows a 64 bit application to talk to a 32 bit access database. Some claim that it "works like a charm"; others (myself included) had considerably less luck with it.

Sorry for bringing up this old Topic, could you Point me in the right direction where I can find this miraculous Driver that supposedly works for 64 to 32 Bit Communication? I am trying to do a macro that utilizes communication between NX and Access and I get Errors due to the 64/32 Bit Problem.
Thanks for your Help!