Professional Documents
Culture Documents
■ Introduction
There are many situations where it is useful to exchange information (in either direction) between NX and Excel.
For example, you might want to export an NX bill-of-material or other report to Excel. Alternatively, you might want
to import data from an Excel spreadsheet and use this to assign values to attributes in NX. There are two somewhat
separate steps in the data exchange process: getting data into and out of NX, and getting data into and out of Excel.
These two steps are both discussed in this chapter, even though the second one is not really related to NX.
There are (at least) three different ways to programmatically “push” data to Excel:
The Automation Approach: use the Excel API to write data into an Excel document.
The CSV Approach: write a csv file that can then be imported into Excel.
The XML Approach: write an XML file that can then be imported into Excel
These are discussed in the sections below. However, note that the first and second of these are somewhat related,
so you should read about automation even if you’re primarily interested in csv files.
The final section in this chapter discusses importing data from Excel.
Many of the code examples given below are just fragments, as usual. The complete code is provided in four folders
in C:\Program Files\Siemens\NX 8.5\UGOPEN\SNAP\Examples\More Examples. The four folders are called
Excel Automation, Excel Write CSV, Excel Write XML, and Excel Read.
Here is some code that creates the three spheres and assigns the attributes:
Getting Started with SNAP Chapter xx: Communicating with Excel Page 1
This CreateParts function will be called in each of the examples below, to provide us with some sample data that we
can then transfer to Excel.
Excel Macros
The functions in the Excel API (whether wrapped or not) correspond very closely with the functions of interactive
Excel. As with NX, you can understand this correspondence by recording macros in Excel and examining their
contents. For example, if you record the actions of typing “xyz” into cell C3, and making it bold, your macro will
contain the following code:
Range("C3").Select
ActiveCell.FormulaR1C1 = "xyz"
Selection.Font.Bold = True
This code uses the VBA language (Visual Basic for Applications), but translating it into VB.NET or other languages
is typically straightforward. NX has a nice advantage in this area, of course —it can record and play back macro
code in several languages, not just one.
Required References
The approach here is to call Excel API functions to write the attribute data into the cells of a newly-created
worksheet. To gain access to these functions, our code will need a reference to Microsoft.Office.Interop.Excel. As its
name suggests, this is the interoperability assembly for Excel, and you can find it on the .NET tab of the Add
Reference dialog in Visual Studio, as shown below:
On the COM tab, you can find another Excel library, called Microsoft Excel 14.0 Object Library. This will work, too,
but the one on the .NET tab is preferable.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 2
Example Code
The code to write the data is as follows:
Most of the code is straightforward, and should be easy to understand. One thing to note is that cell numbering in
Excel starts at 1, not at 0. So, cell “C2” is Cells(2,3), for example.
As you can see, the code saves the Excel file into a folder called C:\public. You can use a different folder, instead, of
course, as long as it’s one for which you have write access.
The only real mystery in the code is the last step, where we “clean up COM objects”. This step is necessary because
the Excel API we’re using is, at its core, a COM API. When our VB code defines objects like the Excel application, the
workbook, and the worksheet, hidden COM objects are created, and the normal .NET garbage collection is unable to
handle these. So, when we are finished with these objects, we have to take care of destroying them and free-ing
their memory.
Note that cleaning up the COM objects always has to be done in the reverse order from their creation. So, in this
case, the order had to be cells, sheet, workBook, app.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 3
Some code to do this cleanup is shown below. Don’t worry if you don’t understand it — many experienced
programmers don’t understand it very well, either. Just place this code inside your AutomateExcel class, accept that
it’s necessary, and try not to worry about it too much.
If you really want to know more about COM object cleanup, you can start by reading this discussion. But note that
that most of the suggestions essentially say “I tried this, and it seems like it worked, maybe, but I don’t know why”.
Running the code should produce an Excel spreadsheet that looks something like this:
cells = sheet.Columns(1)
cells.NumberFormat = "@" ' Format column #1 as text
If you rebuild and run the modified code, the result will be this spreadsheet:
Since we are no longer providing any help, Excel tries to make a guess about the items in column #1, and it guesses
that they should be numbers, and stores them internally as numbers. But, Excel numbers only have around 15
digits of precision, so, as the display in the formula bar shows, the last 3 digits of each part number have been lost.
Clearly, text formatting (and text storage) is the right choice, here.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 4
Writing a CSV File
Using the same fabricated data as before, the code to write a csv file is as follows:
Class WriteCsv
End Sub
End Class
As you can see, the file we created is arguably not a “csv” file. It actually uses semicolons as delimiters, not commas,
and it has the file extension “txt”, rather than “csv”. But, anyway, it’s a text file with fields separated by delimiters,
which is all that really matters. Note how we have used the ToString function to format the weight and purchase
date attributes appropriately.
The user could just manually import this file into Excel, of course, so we could stop at this point. But importing text
files into Excel requires a bit of expertise, so, to avoid inconsistencies and mistakes, it’s better if we can automate it.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 5
Space Object True to have the space character be a field delimiter.
(Boolean) The default value is False.
Other Object True to have the character specified by the OtherChar argument be a
(Boolean) field delimiter. The default value is False.
OtherChar Object (required if Other is True). Specifies the delimiter character when
(String) Other is True. If more than one character is specified, only the first
character of the string is used.
FieldInfo Object(2, n) A two-dimensional array containing parse information for individual
columns of data. See below for further details.
TextVisualLayout XlTextVisualLayoutType The visual layout (direction) of the text. The default is the system
setting (I think) which will usually be xlTextVisualLTR (left-to-right),
unless you are using a language like Hebrew.
DecimalSeparator Object The decimal separator that Microsoft Excel uses when recognizing
(String) numbers. The default setting is the system setting.
ThousandsSeparator Object The thousands separator that Excel uses when recognizing numbers.
(String) The default setting is the system setting.
TrailingMinusNumbers Object Specify True if numbers with a minus character at the end should be
(Boolean) treated as negative numbers. If False or omitted, numbers with a
minus character at the end are treated as text.
Local Object Specify True if regional settings of the machine should be used for
(Boolean) separators, numbers and data formatting.
The arguments correspond closely to those available in the Excel “Text Import Wizard” that is invoked when you
open a text file interactively from within Excel:
So, you can get a better understanding of the arguments by recording a macro while you import a text file. Some of
the more puzzling ones are described in detail in the paragraphs below.
Origin: This can be one of the following XlPlatform constants: xlMacintosh, xlWindows, or xlMSDOS.
Alternatively, it can be an integer indicating the number of the desired code page. The allowable integer values are
shown in the “File origin” menu in the Text Import Wizard:
One of the most useful values is 65001, which corresponds to Unicode text in UTF-8 encoding. If this argument is
omitted, the method uses the current setting from the Text Import Wizard.
TextQualifier: This is a character that can be used to enclose a sequence of characters, thereby forcing them to
become one cell, even if they include a delimiter character. For example, suppose that commas are being used as
delimiters. Then the string 1,260 would be split into two cells, even though the intention is probably to create a
single cell containing the number 1260. Similarly, we would probably want to force the string “Monday, July 4th” to
be a single cell. Of course, if you choose delimiter characters that don’t appear within the data itself, then there is
no need for a TextQualifier. That’s why our examples use a semi-colon as the delimiter.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 6
There is widespread confusion about the TextQualifier argument, possibly as a result of its poorly chosen name.
Many people think that using this argument will force Excel to format the enclosed strings as text (rather than as
numbers). This is not correct. To force Excel to format data as text, you must use the “FieldInfo” parameter.
FieldInfo: This is a two-dimensional array indicating how various columns of data should be parsed and formatted
during import. It is easiest to think of it as a list of pairs of the form (columnNumber, dataType), where
columnNumber indicates which column is under consideration, and dataType is one of the enumerated values from
Excel.XlColumnDataType. The most interesting values of this enum are:
The first two lines just define variables with short names, for convenience. Then the third line says that
Columns #1 and #4 (the “A” column and the “D” column) should be formatted as text,
Column #3 (the “C” column) should be formatted as dates
All other columns should be parsed and formatted as “general”.
The order of the pairs doesn’t matter. The code
gives the same result as the code above. If there's no column specifier for a particular column of input data, the
column is parsed with the General setting, which means that Excel will try to guess the correct format. If the
column contains strings that Excel can recognizes as dates, for example, then this column will be formatted as dates
even though you specified a “general” format or no format at all.
If you specify that a column is to be skipped, you must explicitly state the type for all the other columns, or the data
will not parse correctly.
The xlDMYFormat date format seems to have some bugs, but the xlMDYFormat one works fine. Having spaces at the
beginning of a date field will confuse the parsing, just as it does when typing into Excel.
workbooks.OpenText(
pathName, origin, startRow,
dataType, textQualifier, consecutiveDelimiter,
useTab, useSemicolon, useComma, useSpace, useOther, otherChar,
myFormat,
textVisualLayout,
decimalSeparator, thousandsSeparator, trailingMinusNumbers, local)
Getting Started with SNAP Chapter xx: Communicating with Excel Page 7
But we can take advantage of Visual Basic’s ability to omit optional arguments, and write this, instead:
workbooks.OpenText(
pathName,
Semicolon := True,
DataType := Excel.XlTextParsingType.xlDelimited,
FieldInfo := myFormat)
The “:=” syntax is used to give values to optional named arguments. Some people use sequences of commas when
omitting arguments, or they use System.Type.Missing as a placeholder, but the approach shown above seems
easier to read and less error-prone.
A Simple Example
The code given earlier creates a simple text file called data.txt, with the following contents:
123456123456123456;14.75;1995;02/03/2012
234567234567234567;2.75;675;06/11/2012
345678345678345678;0.25;69;12/17/2011
The code to import this file would be as follows. Again, note that you’ll need a a reference to the
Microsoft.Office.Interop.Excel assembly to use this code
Class OpenTextExample
' Import the data file, which will add a new item to the Workbooks collection
Dim workBooks As Excel.Workbooks = app.Workbooks
workBooks.OpenText(path, DataType:=myType, Semicolon:=True, FieldInfo:= myFormat)
End Sub
End Class
Getting Started with SNAP Chapter xx: Communicating with Excel Page 8
Specifying the DataType as XlDelimited is necessary, or else Excel will interpret the file as having fixed-width
fields. As you can see, we have asked for the first column to be parsed and formatted as text. Without this request,
the part numbers would be interpreted and stored as numbers, which would cause problems, as we saw earlier.
Also, we need to specify the “general” format for the second column, or else Excel will mysteriously interpret the
2.75 in cell B2 as a date (February 1st 1975). Since we’re calling Excel API functions, some COM object cleanup is
needed, again.
Further Formatting
With the approach outlined above, the only formatting controls available to us are the rudimentary ones provided
by the OpenText function. But, once we have imported the data, we can use other Excel API functions to format it
further, as we saw earlier in this chapter. The code to do this is as follows:
cells = workSheet.Columns(1)
cells.Font.Bold = True ' Make column #1 bold
cells.ColumnWidth = 22 ' Adjust its width
cells = workSheet.Columns(2)
cells.NumberFormat = "0.00" ' Format column #2 with 2 decimal places
cells = workSheet.Columns(3)
cells.NumberFormat = "$#,##0" ' Format column #3 as currency
cells = workSheet.Columns(4)
cells.NumberFormat = "dd-mmm-yyy" ' Change the date format in column #4
You can insert this code after the call to OpenText and before the save/close/quit steps. Note that this code
introduces two new COM objects (workSheet and cells), which we will need to clean up. So, our call to the
Cleanup function must be modified to read as follows:
Note the little green triangles in the “A” column. Excel is telling us that the items in this column look like numbers,
but we have formatted them as text, which might be a mistake. As we know, it’s not a mistake, in this case, but Excel
gives us the helpful hint, anyway.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 9
This is the same problem we saw earlier — Excel has stored the part numbers as numbers, rather than text, so we
have lost the last three digits, and no subsequent reformatting operation will be able to recover them.
Getting Started with SNAP Chapter xx: Communicating with Excel Page 10
Note that we didn’t need to do any of the usual COM object cleanup. We called ClosedXML functions, not the Excel
COM API, so no COM objects were created, and there’s nothing to clean up.
You can accomplish the same thing using the plain Open XML API, or you can even write the XML yourself, if you
have the patience and expertise. To find out how to do this, you could start with this tutorial. If you really want to
understand the details, you will find the Open XML SDK “Productivity Tool” to be very useful. This is a “document
reflector” that can show the XML structure of any Office document, plus the Open XML code needed to create it:
Getting Started with SNAP Chapter xx: Communicating with Excel Page 11
Using Edit Properties within NX, you can see that the attributes of the first sphere body have been set like this:
Getting Started with SNAP Chapter xx: Communicating with Excel Page 12