Showing results for 
Search instead for 
Do you mean 
Reply
Solved! Go to solution

Text Encoding question ...

[ Edited ]

I am on the design side of things at our company - so am not very familiar with NX from the manufacturing side of things.

 

Our CNC folks run this journal which creates an output file. I am a bit fuzzy on the next part... I believe that they then run a TCL-enabled routine which reads this text file and imports the strings to use in the HTM/HTML-based setup sheets as well as in the CNC G-Code file. (UPDATE: I've pasted-in the TCL-Enabled code that our MFG folks use to read the output file from the journal [below the journal code in this posting])

 

They have a problem in that there are some odd characters (as shown in the attached image file) precede the part number. If I open the file output by the journal in MS-Notepad the file looks fine. If I switch the text-encoding in MS-Word to "Western European (Windows)" encoding then I see the same odd characters that they end up with after the TCL-enabled tools have imported the text file (the same garbage characters are displayed by choosing Unicode UTF-7 or Latin 9 (ISO) encoding when reading the file).

 

 

I used the .Net My.Computer.FileSystem.WrireAllText method (as shown in the in-line code below). This is an overloaded method and I am using the three-argument method. In the 4-argument method the 4th argument is System.Text.Encoding. The default encoding is UTF-8.

 

' outputMFGAttributes.vb
' 01/21/14
' S. Applegate
'
' ========================================================================================
' Given a CNC-Programming NX file - which has a design-engineering part as a child,
' this journal will write the ITEM_NUMBER, DESCRIPTION, REVISION and MATERIAL attributes
' of the design-engineering child part to the text file pointed to by the outputFileName
' variable.
'
' ----------------------------------------------------------------------------------------
'
' If the part file that the journal is being run in has no children -
' a message is displayed stating such and no text file will be written.
'
' If the part file that the journal is being run in has only one child -
' the text file will be written.
'
' If the part file that the journal is being run in has more than one child (clamps
' and/or fixtures for example) - the list of all children will be displayed - with a
' corresponding I.D. number for each child. The user will be prompted for the I.D. number
' of the child model-file whose attributes they want to be written to the text file.
' The text file will then be written.
'
' =======================================================================================

Option Strict Off

Imports System
Imports NXOpen
Imports NXOpen.Assemblies


Module outputMFGAttributes

   Public theSession As Session = Session.GetSession()

   Sub Main()

     Dim outputFileName As String = "c:\temp\output.txt"

     Dim dispPart As Part = theSession.Parts.Display

     Dim child As Component = Nothing
     Dim root As Component = Nothing
     Dim myChildren As Component() = Nothing

     Dim compAssy As ComponentAssembly = dispPart.ComponentAssembly

     root = compAssy.RootComponent

     if not IsNothing(compAssy.RootComponent) then

        myChildren = root.GetChildren()

        Dim myItemNumber  As String
        Dim myDescription As String
        Dim myRevision    As String
        Dim myMaterial    As String
        
        if myChildren.Length = 1 then

          child = myChildren(0)   
                
          myItemNumber  = child.GetStringAttribute("ITEM_NUMBER")
          myDescription = child.GetStringAttribute("DESCRIPTION")
          myRevision    = child.GetStringAttribute("REVISION")
          myMaterial    = child.GetStringAttribute("MATERIAL")

          My.Computer.FileSystem.WriteAllText(outputFileName, myItemNumber  & ControlChars.NewLine, False)
          My.Computer.FileSystem.WriteAllText(outputFileName, myDescription & ControlChars.NewLine, True)
          My.Computer.FileSystem.WriteAllText(outputFileName, myRevision    & ControlChars.NewLine, True)
          My.Computer.FileSystem.WriteAllText(outputFileName, myMaterial    & ControlChars.NewLine, True)

          MsgBox("Text File Written" & ControlChars.NewLine, vbOKOnly, "Note:")

        else

            Dim myPartsList As String = "ID    Filename" & ControlChars.NewLine & "---|---------------" & ControlChars.NewLine
            Dim myCounter = 0
            Dim myChoice As Integer

            For Each myChild As Component In myChildren

              myCounter += 1         
              myPartsList += myCounter & "    " & myChild.Name & ControlChars.NewLine

            Next

            Dim myInputFlag As Boolean = True

            While myInputFlag

              MsgBox(myPartsList, vbOKOnly, "Multiple Children Found, Enter I.D. of correct Child in Next Dialog Box.")
              myChoice = InputBox("Enter Child File Number:")

              If myChoice <= myChildren.Length And myChoice > 0 Then

                child = myChildren(myChoice - 1)

                myInputFlag = False     

                myItemNumber  = child.GetStringAttribute("ITEM_NUMBER")
                myDescription = child.GetStringAttribute("DESCRIPTION")
                myRevision    = child.GetStringAttribute("REVISION")
                myMaterial    = child.GetStringAttribute("MATERIAL")

                My.Computer.FileSystem.WriteAllText(outputFileName, myItemNumber  & ControlChars.NewLine, False)
                My.Computer.FileSystem.WriteAllText(outputFileName, myDescription & ControlChars.NewLine, True)
                My.Computer.FileSystem.WriteAllText(outputFileName, myRevision    & ControlChars.NewLine, True)
                My.Computer.FileSystem.WriteAllText(outputFileName, myMaterial    & ControlChars.NewLine, True)

                MsgBox("Text File Written", vbOKOnly, "Note:")

              Else

                MsgBox(myChoice, vbOKOnly,  "Incorrect Choice")

              End If

            End While

        end if        

     else

        MsgBox("Part has no children" & ControlChars.NewLine & "No Text File Written", vbOKOnly, "Warning:")

     end if

   End Sub ' Main

End Module ' outputMFGAttributes



 

My questions Are:

 

* Can I supply a 4th argument to the My.Computer.FileSystem.WriteAllText method that will not produce the extra/garbage characters shown in the first image above?

 

* Should I use a different .Net class/method to write this output file?

 

* Is this something that needs addressed on the read side (the TCL-enabled tools that are reading the text file)?

 

-------------

 

One item of note is that this happens on our PCs that have NX8.5.3.3 with no patches on them - but on our one PC with patch 8.5.3.3MP7 the only garbage character preceding the part number is a hash/pound-sign "#".

 

Thanks for any help.

 

Steve A.

 

 

SteveA
DRT Mfg. Co. Inc.
www.drtusa.com
Win7x64 NX8.5.3.3
8 REPLIES

Re: Text Encoding question ...

I'd experiment with some of the different encoding options, starting with Encoding.Default.

Re: Text Encoding question ...

[ Edited ]

I'll give that a try. Somewhat slow to determine success/failure - as I need to have our mfg folks run the journal and then run their TCL-enabled code and check the result.

 

Since my original-post I did have our mfg folks provide me the code that they run - to read the output file created by the above journal. I've pasted that in below:

 

#===============================================================================
# Exported Custom Commands created by rs
# on Tuesday, December 09, 2014 2:14:34 PM Eastern Standard Time
#===============================================================================


#=============================================================
proc PB_CMD_output_part_attributes { } {
#=============================================================

  # Find the attributes in the file of the part being machined

  # Set variables with info retrieved with UFUNC program
  set infile [open c:\\temp\\output.txt r]
  gets $infile part_nbr
  gets $infile part_des
  gets $infile part_rev
  gets $infile part_mat
  close $infile

  MOM_output_literal "( PART NUMBER:  $part_nbr )"
  MOM_output_literal "( DESCRIPTION:  $part_des )"
  MOM_output_literal "( REVISION:  $part_rev )"
  MOM_output_literal "( MATERIAL:  $part_mat )"
}

 

SteveA
DRT Mfg. Co. Inc.
www.drtusa.com
Win7x64 NX8.5.3.3
Solution
Solution
Accepted by topic author SteveA
‎08-26-2015 04:32 AM

Re: Text Encoding question ...

UTF-8 doesn't work, make sure to use ANSI encoding.

 

BTW, why aren't you using a StreamWriter?

Stefan Pendl, Systemmanager CAx, HAIDLMAIR GmbH
Production: NX10.0.3, VERICUT 8.0, FBM, MRL 3.1.4 | TcUA 10.1 MP7 Patch 0 (10.1.7.0) | TcVis 10.1
Development: VB.NET, Tcl/Tk    Testing: NX11.0 EAP, NX12.0 EAP

How to Get the Most from Your Signature in the Community

Re: Text Encoding question ...

I added the last (overloaded) parameter/argument as shown here and the problem went away. The UTF-8 encoding writes a BOM (Byte Order Mark) at the start of a file. Setting the encoding parameter to System.Text.Encoding.ASCII doesn't write the BOM.

 

My.Computer.FileSystem.WriteAllText(outputFileName, myDescription & ControlChars.NewLine,  True, System.Text.Encoding.ASCII)

 

---------

 

Not sure why I used this method over streamWriter. I am a part-time coder - so I am not always familiar with best practices. I've used streamReader quite a bit. I will look into this.

SteveA
DRT Mfg. Co. Inc.
www.drtusa.com
Win7x64 NX8.5.3.3

Re: Text Encoding question ...

Using the My.Computer.FileSystem.WriteAllText() method is simply a convenience provided by VB.net. My guess is that behind the scenes, it is using a streamwriter object then doing the cleanup for you. I don't see anything 'wrong' with using this method nor would switching to a streamwriter immediately solve your problem - you still have to choose the encoding for the streamwriter.

Re: Text Encoding question ...

Sure it is not wrong at all to use this method, but it always opens the file, writes to it and closes it.

 

A streamwriter would open the file once, write all the text to it and closes it.

 

It is just to avoid the multiple open and close actions.

Stefan Pendl, Systemmanager CAx, HAIDLMAIR GmbH
Production: NX10.0.3, VERICUT 8.0, FBM, MRL 3.1.4 | TcUA 10.1 MP7 Patch 0 (10.1.7.0) | TcVis 10.1
Development: VB.NET, Tcl/Tk    Testing: NX11.0 EAP, NX12.0 EAP

How to Get the Most from Your Signature in the Community

Re: Text Encoding question ...

I went MSDN to look at the file-writing options. Interestingly, I saw the following ...

 

 

I certainly think that the stream-based options are best for anything that writes more than just a few lines to a file (due to the opening/closing used).

SteveA
DRT Mfg. Co. Inc.
www.drtusa.com
Win7x64 NX8.5.3.3

Re: Text Encoding question ...

Hi folks!

 

Just in case someone reads this in the future.

Note that there is also a File.WriteAllLines method that takes a string array and writes all its contents as individual lines to the file (only opening it once).

 

// IEnumerable<string> can be used instead of string[]
System.IO.File.WriteAllLines(pathToFile, stringArray, encoding)

If this was really an issue, it could also be beneficial to use a StringBuilder to build all content in memory and only writing it in the end:

 

var sb = new StringBuilder();

// Write everything to the string builder, first
foreach( char character in "Hello World!" )
{
   sb.AppendLine( character.ToString() );
}

// Write to the file only once
System.IO.File.WriteAllText( pathToFile, sb.ToString(), encoding );

For simple purposes, the File.Write* methods (and for that matter File.Read* and File.Append*, too), are a lot more readable and easier to use (especially for beginners) than using StreamWriter and StreamReader. And supposedly a lot less can go wrong when you use these "dumbed-down" methods Smiley Happy

 

Hope this helps!

Marcus