Write to a text file

Write to a text file



Thanks to functionality in NXOpen and .NET, writing to a text file is not much more difficult than reading from a text file. The NXOpen API provides the ListingWindow class that is often used to show the user relevant information. The NX UI and help files refer to this window, appropriately enough, as the "information window". To see it in action, run practically any command from the Information menu. Of course, the .NET framework also provides tools for creating files and writing information to them. Either approach used gives you an easy way to generate a report, log the actions the journal performed, log any errors the journal encountered, or write out any other information you have need of.

ListingWindow Overview



Message boxes work well for showing short informational messages, warnings or errors, but are not well suited for large amounts of information. The ListingWindow (information window) is a better choice, and it gives the user the ability to cut and paste information or save the information to a text file (you may never have noticed, but the information window has a File menu that allows you to save the current contents). NXOpen also allows us to specify a file to save the contents of the listing window. You can write to the screen, a file, or both at the same time.

The basic steps to use the ListingWindow is as follows:

  1. declare a variable of type listing window
  2. obtain a reference to the listing window of the current session
  3. set the output device desired
  4. open a stream to the device
  5. write to the device
  6. close the stream to the listing window
  7. if writing to a file, flush the buffer

Steps one and two are usually combined into one line of code; if you only want to write to the screen, you can skip step three because the screen is the default device; and step seven only applies if you are writing to a file. According to the NXOpen help file: to properly flush the buffer, we'll need to change the output device after we have written the desired information.


The following journal uses the ListingWindow class to write some information about the current file name to both the window and a file (located in your "My Documents" folder). The journal deletes this file and creates a new file on each run. If you desire to append the information of each run to the existing file, comment out (or delete) the indicated section of code.


[vbnet]
'NXJournaling.com
'NXOpen ListingWindow
'write to text file example

Option Strict Off
Imports System
Imports NXOpen

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
Dim myDocs As String
myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim outputFile As String = IO.Path.Combine(myDocs, "test.log")

'get information about current work part
Dim fileName As String = IO.Path.GetFileName(workPart.FullPath)
Dim fileNameNoExt As String = IO.Path.GetFileNameWithoutExtension(workPart.FullPath)
Dim parentFolder As String = IO.Path.GetDirectoryName(workPart.FullPath)
Dim root As String = IO.Path.GetPathRoot(workPart.FullPath)

'***** comment out this section to append to existing file *****
'does file already exist? if so, delete it
If IO.File.Exists(outputFile) Then
Try
IO.File.Delete(outputFile)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error deleting file:")
End Try
End If
'***** end of section *****

'use listing window to write to file and window
lw.SelectDevice(ListingWindow.DeviceType.FileAndWindow, outputFile)
lw.Open()

'write information to listing window
lw.WriteLine("full path: " & workPart.FullPath)
lw.WriteLine(New String("-", ("full path: " & workPart.FullPath).Length))
lw.WriteLine("file name: " & fileName)
lw.WriteLine("file name w/o extension: " & fileNameNoExt)
lw.WriteLine("parent folder: " & parentFolder)
lw.WriteLine("root folder: " & root)
lw.WriteLine("")

lw.Close()
'flush file buffer by changing listing window device
lw.SelectDevice(ListingWindow.DeviceType.Window, "")

End Sub

End Module
[/vbnet]

Journal Notes



After running the journal, use the file explorer to find the file and open it in notepad (or other text editor) to verify the contents.


The options for the ListingWindow output device are:

  • File
  • Window
  • FileAndWindow
  • None

The options are self-explanatory, though you may be wondering why anyone would use the "None" option. Imagine a large, complicated program with many calls to the ListingWindow's WriteLine method scattered throughout the code. You may want to give the user the option to write the output to file, window, or suppress it completely. Rather than wrapping each WriteLine call in an If statement, you can simply toggle the output device to None if the user decides they don't want the output. No other changes to your code are necessary, all the calls to the WriteLine method still happen, just all the output gets thrown into the void.


If you use an option that writes to a file, you will want to pass in the full name of the file you want to write to. If an empty string is passed in, a generically named file will be created in your NX install directory (usually the UGII folder). If you are switching to the window output option (or the none option), the second parameter (file name) is still required by the method, but you can pass in an empty string.


The WriteLine method takes the input, writes it to the current line, and starts a new line (it appends a newline character to the end of your input).

The .NET StreamWriter



The counterpart to the StreamReader is the StreamWriter. As the name suggests, this object will allow us to write information to a stream, which in our case will be a buffer written to a file. The StreamWriter class lives in the System.IO namespace. This article will only touch on a few properties and methods of the StreamWriter as needed; if you want more in-depth coverage, the MSDN page is a good place to start.

The StreamWriter has many overloaded constructors to cover various needs, the one we are using takes the form:

StreamWriter(outputFile as String, appendMode as Boolean)

The outputFile is a string variable/literal that represents the full path of the file that you want to write to. The appendMode parameter can be either True or False.

  • True = append to the specified file if it exists
  • False = overwrite the specified file if it exists

If the specified file does not exist, a new file is created and the appendMode parameter is ignored since it no longer applies.



[vbnet]
'NXJournaling.com
'.NET StreamWriter
'write to text file example

Option Strict Off
Imports System
Imports NXOpen

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim myDocs As String
myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim outputFile As String = IO.Path.Combine(myDocs, "test.log")

'get information about current work part
Dim fileName As String = IO.Path.GetFileName(workPart.FullPath)
Dim fileNameNoExt As String = IO.Path.GetFileNameWithoutExtension(workPart.FullPath)
Dim parentFolder As String = IO.Path.GetDirectoryName(workPart.FullPath)
Dim root As String = IO.Path.GetPathRoot(workPart.FullPath)

'pass False to overwrite existing file, True to append existing file
'if file does not exist, a new file will be created and the True/False value will be ignored
Using myWriter As New IO.StreamWriter(outputFile, False)

'write information to the stream writer
'*** these statements will all be written to the same line
myWriter.Write("In the month of ")
myWriter.Write(Today.ToString("MMMM"))
myWriter.Write(" of the year: ")
myWriter.WriteLine(Today.ToString("yyyy"))
'*** the above 4 statements will all be written on the same line

myWriter.WriteLine("full path: " & workPart.FullPath)
myWriter.WriteLine(New String("-", ("full path: " & workPart.FullPath).Length))
myWriter.WriteLine("file name: " & fileName)
myWriter.WriteLine("file name w/o extension: " & fileNameNoExt)
myWriter.WriteLine("parent folder: " & parentFolder)
myWriter.WriteLine("root folder: " & root)
myWriter.WriteLine("")

End Using

End Sub

End Module
[/vbnet]

Journal Notes



After running the journal, use the file explorer to find the file and open it in notepad (or other text editor) to verify the contents.


The .NET StreamWriter has a WriteLine method that works similarly to the ListingWindow's WriteLine method. In addition, the .NET StreamWriter also offers a Write method; which will not start a new line in the file. When the Write method is called, the output is written to the current line of the file, but no new line is created (no newline character is added). Subsequent calls to the Write or WriteLine method are appended to the current line. You can see this in action in the first few calls to the StreamWriter object.

Conclusion



A word a warning: several things can go wrong when writing to a file, such as:

  • the specified directory does not exist
  • the current user does not have permission to write to the specified directory
  • the disk is full
  • the specified path is longer than the system allowed limit
  • the specified path is nothing, only white space, or contains invalid characters

The journal code is a bad example in that it does no exception handling. Make your code robust by adding Try blocks as necessary.


Reading and writing text files are important programming skills that will add a lot of flexibility to your journal input/output.

Comments

how can I find the class library?

Which class library are you looking for?

I am trying to replicate a .csv file output but it seems that once I hit a certain number of characters, it bumps me to the next row in Excel(when I look at the .csv). Has anyone else had this problem, and if so, any ideas how to make everything appear on the first row?

DHuskic
Nx 9 VB

What is the size of your rows?

Is your csv file in ASCII format? Excel may have problems with unicode.

I am getting 132 characters per line in the listing window, anything in excess goes to the next line. I have the output file labeled as a .csv, and my work station automatically opens that with excel. I am currently using ASCII.

DHuskic
Nx 9 VB

I believe that is a limitation of the listing window object. You will need to use the .net stream writer to get what you want.