Objects in this document may appear out of sequence if not viewed with Internet Explorer

ORMSware NMOD Primer: Chapter 16


Using Microsoft Excel for inputs

ODBC interface using f90SQL from Canaima Software is planned for ORMSware to facilitate both reading from and writing to Excel workbooks and Access databases directly from models. In the mean time, NMOD has a limited facility (GetTable) to read tables from Excel worksheets.


Figure 14

 
Note: Limitations listed below have no relevance to the spreadsheet-to-NMOD transformation process described in Chapter 6 of the Hands-on Tutorial. What is described here is just a temporary method for using Excel as an input device to your models.

The limitations are as follows:

  • There should be only one worksheet in any Excel workbook used for storing input tables of NMOD models. If you want to use data from a workbook you already have with multiple sheets, this limitation can be circumvented by creating and intermediate workbook with just one sheet and pulling into it the desired data from the multiple-sheet workbook.

  • Workbooks containing input tables must be saved in html format.

  • A table should be delineated with Table object tags in column A (first column) as in Figure 14. Table labels (names) should be fully visible, since NMOD only reads the displays in spreadsheet cells. They should be no longer than 25 characters. However, characters in the tag are not counted for compliance by GetTable, which means that NETrans will not catch it if you violate this requirement.

  • Every blank cell in a table should be indicated so with a dash in it. You will see examples of this in Chapter 20 (Reinforcing concepts through PrimerSubNet's feedback file).

  • Columns in table spaces should not be hidden.

  • The top delineator should be followed in the same row in column B by the number of rows used for row titles, and in column C by the number of columns used for column titles. In the CostPerPieceInputs table in Figure 14, 0 rows are used for row titles and 1 column is used for column titles. In the LaborCosts table, 2 rows are used for row titles and 1 column is used for column titles (though there are no entries in the title column in this case).

  • Every table must have at least 1 title column. Please remember that number of title columns are defined in column C of every table's tag row. It is a common mistake to enter it in column B and to enter the number of title rows in column C. In other words, the order is row-column, not column-row.

  • To let NMOD deduce the number of rows and columns of data in the table, there should be no row entries to the right of the last column of a given table. In this case, there should be no entries in columns C and higher in the rows containing CostPerPieceInputs table values, and there should be no entries in columns D and higher in the rows containing LaborCosts table values.

  • Tables should be of character (string) type, or real/floating point type of the dbl KIND. If the LaborCosts table above were of character type (say) of 100-character string elements, it's name would be {Table.100}LaborCosts.
Tables may contain formulas. GetTable reads the results of the formula, if any, in each cell, as it is displayed. Please remember that GetTable reads only what is displayed; i.e. it is what-you-see-is-all-you-get technology!

How tables are automatically stored in NMOD

Two-dimensional arrays for storing tables from Excel will be automatically named in the DefNet.F95 file generated for the model by NETrans.EXE (network translator). For example, two-dimensional arrays for the above tables in Figure 14 will be automatically named and declared as

REAL(KIND=dbl), DIMENSION(:,:), POINTER::  dblCostPerPieceInputs
REAL(KIND=dbl), DIMENSION(:,:), POINTER::  dblLaborCosts

The two colons in the DIMENSION attributes of dblCostPerPieceInputs and dblLaborCosts indicate that they are two-dimensional arrays (i.e. the rank of both arrays is 2), and that the shape definition of the arrays (i.e. the extent along each of the two dimensions) is deferred. When NMOD fetches the tables during model run, it will deduce the shapes of the tables from the html code and allocate memory for table arrays accordingly.

Click here to open a separate (PrimerSigDefNetF95.TXT) window to view the DefNet.F95 file generated by NETrans.EXE for the current version of our example model.

Glance down for the section comment Table declaration(s) deduced by... Notice the array declarations for LaborCosts and CostPerPieceInputs tables.

Close PrimerSig's DefNet.F95 window.

At run time, NMOD will deduce from html file containing the worksheet that dblCostPerPieceInputs table has 3 rows and 1 column and dblLaborCosts table has 4 rows and 2 columns. It will allocate memory for both tables accordingly when the analyst uses NMOD's GetTable procedure to load the table from Excel.

Notes

We will explain how to use GetTable below and and go through a feedback file a little later to illustrate how NMOD loads tables.

If the LaborCosts table were of 100-character string type (i.e. {Table.100}LaborCosts), it would have been automatically declared as

    CHARACTER(len=100), DIMENSION(:,:), POINTER::  strLaborCosts

Loading tables from Excel files

To get data from Excel tables, the analyst should open the file containing the table (we recommend that you use NMOD's OpenTableFile procedure) and use NMOD's GetTable procedure to load tables. Click here to see how this is done in PrimerSig.NET, the NET file of the latest version of our model diagram displayed in Figure 13/PrimerSig.VSD window (click here if it is not open). Page down in PrimerSigNET.TXT window, or search, to find {Object.6}.

Under [6]'s Trans property procedure notice the statement for opening the PrimerSigTables.HTM file. This is the file containing the two tables used in this model. Though we used the PrimerSig name, however, name of a file containing tables for a model need not resemble the model name in any fashion. A model can use tables from as many files as necessary. 

Alert: Notice that the file handle number is 21. User-defined file handles in NMOD models must have a number > 20, because NMOD uses various file handles with numbers <= 20 during model execution. We have plans to remove this restriction so that users will not have to  be concerned with file handle numbers in the future.

The next two lines under the OpenTableFile statement call the GetTable procedure to load CostPerPieceInputs and LaborCosts tables into the model. Once tables are loaded, there is no need to keep PrimerSigTables.HTM open. Hence, the CLOSE statement below the GetTable calls.

Accessing individual elements of a table

Scanning down to the section below GetTable instructions (between dashed delineating records in PrimerSigNET.TXT window), notice the notation {t.D}. This notation refers to an element from a table of real/floating point numbers of the dbl KIND. The table's name is CostPerPieceInputs and the entries in this table are shown in Figure 15.

Figure 15

Numbers in parenthesis at the end of the table's name (in the statements with {t.D} notation) refers to the row and column positions of the element in the table. Notice that this table has only one column of data.

Note: 0 and 1 in the first record (same row in the spreadsheet showing a table tag) are indicators of row and column title sizes. They are not elements of the table.

In the three statements in this section, elements of the table are being assigned to various surrogate and global properties in the model. Notice that though the table array is a column vector, we have to use both row and column subscripts to retrieve values from the table. Since there is only one column in the array, all elements in the array have 1 for their column subscripts.

Note: If a model is set up such that its input need to be directly entered in its nodes and arcs, one has to navigate to and/or click open several objects to enter data. Further, the model will have to be translated, compiled and linked to create a new EXE file each time there is a change in any of the inputs. Therefore, it is always a good idea to use Excel tables or ASCII text files as sources of input to a model, and use NMOD's GetTable procedure and just plain READs to feed data as needed to network objects in the model. Then, model can be rerun after changing data in Excel tables, without having to recompile and renew the model's EXE file.

Using reference values to look up a table element

NMOD's LookUp function is similar to those found in spreadsheets:

  • NMOD provides vertical lookup function (no horizontal lookup for now).

  • LookUp function is (data) type-specific. A table can contain only one of two types of entries; the dbl KIND or string entries. If one needs to have a table with mixed entries, the analyst can accomplish that by using NMOD's VarLookUp procedure to read user-defined variables/properties, and numeral scalar or array values from a table of strings holding numerical values.

    Note: User-defined variables are explained in the next chapter.

     

  • NMOD searches for the lookup value from the highest row of the table down to the lowest row. It stops the search when the value in the the first column of a row is less than the search value. If the search value is less than the first element of a table (i.e. row 1, column 1), NMOD considers the first row of the table to be the answer row.

  • LookUp returns other values in addition to the value in the desired column of the answer row. It returns a binary value that indicates whether the search value matched a row value in the first column or just the inequality part of the test was satisfied. It also returns the number of the answer row.

Find {Object.4} in the PrimerSigNET.TXT window to see an example of how LookUp is used. We had to use &D.Temp as the lookup variable, because LaborCosts is a table of the dbl KIND. The lookup value we are using is {cp.B}PiecesPerHour (i.e. big KIND customer property PiecesPerHour).

Look at the table in Figure 14. If the value of {cp.B}PiecesPerHour is 40 or above, NMOD will set the value of #S.LaborCostPerHour to 35.00; if the value of {cp.B}PiecesPerHour is 30 or above, but less than 40, NMOD will set the value of #S.LaborCostPerHour to 30.00; and so on. If the value of {cp.B}PiecesPerHour is <= 0, NMOD will set the value of #S.LaborCostPerHour to 20.00.  

Notes:

If the analyst wanted to know whether there was an exact match of the search value in the first column of the table (using, say, user-defined customer property #L.Match), the statement would have been
  #S.LaborCostPerHour = LookUp( {t.D}LaborCosts, &D.Temp, 1, logEqual = #L.Match )

If the analyst wanted to know the answer row number (using, say, user-defined customer property #B.AnswerRow), the statement would have been
  #S.LaborCostPerHour = LookUp( {t.D}LaborCosts, &D.Temp, 1, bigRow = #B.AnswerRow )

If the analyst wanted to know the answer row number and whether there was an exact match of the search value in the first column of the table, the statement would have been
  #S.LaborCostPerHour = LookUp( {t.D}LaborCosts, &D.Temp, 1, logEqual = #L.Match, bigRow = #B.AnswerRow )
or
  #S.LaborCostPerHour = LookUp( {t.D}LaborCosts, &D.Temp, 1, bigRow = #B.AnswerRow, logEqual = #L.Match )

The number 1 in the function calls above can be replaced with any expression that evaluates to a scalar integer of the int KIND to identify the desired offset from column 1 for the result column (in this case, 2) of  the [LaborCosts] table.

 

Click to go to Chapter 15: AND-arc Multiplier property (an Arc flow vector element)

Click to go to Chapter 17: User-defined scalars, arrays, derived types and procedures

Click to go to Introduction: NMOD Primer