New Functions in XLPARSER4

Article ID: 57503

Q: I've been trying your XLPARSER4 utility to read Excel spreadsheets, but I have a problem. My subprocedures don't get called when a cell is empty. Since some empty cells occur at the end of a row, how can I tell when a row is complete?

A: XLPARSER4 skips empty cells because they don't exist in the Excel file. Excel keeps the size of the XLS file to a minimum by not storing empty cells on disk. You're right that this behavior makes it challenging to keep track of when a new row begins or ends, because it's possible that the last cell in a row will be empty and therefore you can't use the last cell in the row to indicate that the entire row has been read.

I've had that problem myself, so I decided to add some new functions to XLPARSER4 to help you detect when an entire row is complete.

If you've been using my XLPARSER4 utility to read a spreadsheet, you know that you provide it with three subprocedures, one to be called when it finds a cell containing character data, one to be called when it finds a cell containing numeric data, and one to be called when it finds a cell with a formula in it. If you haven't used the tool previously or would like to refresh your memory, please read the most recent article about XLPARSER4.

In this new update to XLPARSER4, you can provide two additional subprocedures to XLPARSER4. The XLPARSER4 service program calls these routines when a new row begins or ends, respectively.

For example, your program might start like this:

      xlparse_notify(  %paddr(clear_struct)
                    :  %paddr(print_struct) );

      xlparse_workbook( '/tmp/november_sales.xls'
                      : %paddr(Numeric) 
                      : %paddr(Character)
                      : %paddr(Formula) );

The xlparse_notify() subprocedure is the one I added for this article. It accepts two parameters: a subprocedure to call before each row begins, and a subprocedure to call when each row is complete.

In the above example, the clear_struct() subprocedure is called when a row begins. That procedure clears the contents of a data structure that will eventually contain one row-full of data from the spreadsheet. Because this data structure will be cleared before every row, any empty cells will be empty in the data structure. Clear_struct() will be called only for rows that have data in the spreadsheet.

The print_struct() subprocedure will be called when all the cells have been loaded for a particular row. It will be called only for rows that have data in the spreadsheet. In this example, print_struct() will be used to print the contents of the data structure that contains one row.

The Numeric, Character, and Formula subprocedures will be called when cells that contain Numeric, Character, and Formula data, respectively, are found. They will be called repeatedly in a loop for every cell found in the spreadsheet file. In the sample program, they're used to load data into the data structure that will eventually be printed by the print_struct() routine.

You can download the updated copy of XLPARSER4 as well as the sample program described in this article and all the sample programs from the previous articles from the following link:
http://www.pentontech.com/IBMContent/Documents/article/57503_795_XlParse.zip

@PANUSER: You need to ensure that you are running version 1.4 or higher of Java in order to avoid that java/util/regex/Pattern error. If you have multiple versions of Java on your system, you can control which one is invoked by setting the QIBM_RPG_JAVA_PROPERTIES environment variable to -Djava.version=1.4; (The variable name and it's value are case-sensitive.)

If you're still having trouble, it would be much easier to discuss this in the System iNetwork forums. http://forums.systeminetwork.com (use the RPG forum for this question)

@PANUSER: This message (which is standard in any ILE RPG program that uses subprocedures) tells you which subprocedure an error occurred in. That's all it tells you. Since it doesn't say what the error was, it's not very useful in determining the problem. The actual error will be a previous message in the job log. So, as the error message text says, "Check the job log for more information"
OOPS !! See the word java and panic set in, you are so right and I have now done the obvious, however the rror is Java exception "java.lang.NoClassDefFoundError: java/util/regex/Pattern" when calling method "setCellFormula" with signature "(Ljava.lang.String;)V" in class "org.apache.poi.hssf.usermodel.HSSFCell". covery . . . : Contact the person responsible for program maintenance to Now I have been looking and it appears that this was a problem earlier on, is there something I am missing on my system and where would I get it. Thanks very much for the assistance. I have downloaded the latest version and it works with an empty DIVSALES file but as soon as I add data to this file the process crashes with the following: Additional Message Information Message ID . . . . . . : RNQ0202 Date sent . . . . . . : 09/02/09 Time sent . . . . . . : 09:05:06 Message . . . . : The call to ADDMONTH ended in error (C G D F). Cause . . . . . : RPG procedure HDRDEMO in program QGPL/HDRDEMO at statement 006400 called program or procedure ADDMONTH, which ended in error. If the name is *N, the call was a bound call by procedure pointer. Recovery . . . : Check the job log for more information on the cause of the error and contact the person responsible for program maintenance. Possible choices for replying to message . . . . . . . . . . . . . . . : D -- Obtain RPG formatted dump. S -- Obtain system dump. G -- Continue processing at *GETIN. C -- Cancel. F -- Obtain full formatted dump. Bottom Press Enter to continue. F1=Help F3=Exit F6=Print F9=Display message details F10=Display messages in job log F12=Cancel F21=Select assistance level

ProVIP Sponsors

ProVIP Sponsors