Including sub-totals with CVTDBFXL

Quite a common question to the helpdesk is ‘How can I include sub-totals in the excel spreadsheet?’

The CVTDBFXL command does not include functionality to calculate any form of totals.

CVTDBFXL with QUERY/400

One approach is to base your CVTDBFXL statement on a QUERY/400 query, which can include both detail and summary rows in the output. This is probably the simplest approach.

This example demonstrates how to use QUERY/400 to extract data from a database file with CVTDBFXL. It uses a query named SUBTOTAL. We are not explaining how to create a query here.

CVTDBFXL FROMFILE(*QRYDFN)

                TOSTMF(/SUBTOTALS.XLSX)

                STMFOPT(*REPLACE)

                QRYDFN(*LIBL/SUBTOTAL *NO *MIXED *SUBTOTAL)

                INCLFLD(STATE LSTNAM INIT CUSNUM BALDUE)

                HEADER(*AVAIL 2 *NO ‘Report with Sub-Totals’)

                EXCEL(*XLSX)

 

CVTDBFXL with SQL

Another approach would be to include totalling rows in the output using a SQL select statement. The example is using UNIONs to join the data rows to additional total rows.

I am using the Client Access sample database file QCUSTCDT in the QIWS library.

Personally, I always define SQL using a SQL source file, it gives you the ability to change the SQL without the need to re-compile any programs.

SQL source

Create a SQL source member called SUBTOTAL in QSQLSRC file.

SELECT STATE as SEQ, 0 as LVL, STATE, LSTNAM, INIT, CUSNUM, BALDUE

  FROM QIWS/QCUSTCDT        

UNION

SELECT STATE as SEQ, 1 as LVL, STATE, 'SUB-TOTAL' as LSTNAM, ' ' as INIT,         

       0 as CUSNUM, SUM(BALDUE)          

FROM QIWS/QCUSTCDT        

  GROUP BY STATE            

UNION

SELECT 'ZZ' as SEQ,  2 as LVL, '**' as STATE, 'GRAND TOTAL' as LSTNAM,                                    

       ' ' as INIT, 0 as CUSNUM,  SUM(BALDUE)          

FROM QIWS/QCUSTCDT        

  ORDER BY SEQ, LVL, CUSNUM     

 

In addition to the fields from QCUSTCDT two additional columns are created by the SQL, SEQ and LVL. SEQ is used to ensure the sub-totals are included with the relevant group of data records and LVL used to position them at the end of the group.

 

Convert DBF to excel command

The CVTDBFXL statement.

CVTDBFXL FROMFILE(*SQLSRC)                                 

         TOSTMF('/subtotals.xlsx')            

         STMFOPT(*REPLACE)                                 

         SQLSRC(*LIBL/QSQLSRC SUBTOTAL *SYS)      

         EXCLFLD(SEQ LVL)                                  

         DFNSTYLES((NOZERO *NO *NO *GENERAL *NONE *BOTTOM *DFT

                   *NO *AUTOFIT *ARIAL 10 *NO *NO *NO *AUTO

                   *NONE *AUTO *NONE *NONE *AUTO *FIXED *FIELD

                   *FMT *FMT *FMT *NO)

     (AMOUNT *NO *NO *GENERAL *NONE *BOTTOM *DFT

                    *NO *AUTOFIT *ARIAL 10 *NO *NO *NO *AUTO *NONE

                    *AUTO *NONE *NONE *AUTO *FIXED 2 *NO *NONE *FMT))

APYSTYLES((*FLDNAM CUSNUM NOZERO) (*FLDNAM BALDUE AMOUNT))                                           

EXCEL(*XLSX)

 

Notes:

1.       The two additional fields SEQ and LVL are excluded from the resulting excel spreadsheet.

2.       Style NOZERO is used to remove zeros from the CUSNUM column on the total rows.

3.       Style AMOUNT is used to format the values on the BALDUE column.

The generated excel

Report with Sub-Totals

STATE

LSTNAM

INIT

CUSNUM

BALDUE

CA

Doe

J W

475938

250.00

CA

SUB-TOTAL

 

 

250.00

CO

Stevens

K L

389572

58.75

CO

SUB-TOTAL

 

 

58.75

GA

Johnson

J A

938485

-3987.50

GA

SUB-TOTAL

 

 

-3987.50

MN

Abraham

M T

583990

500.00

MN

Alison

J S

846283

10.00

MN

SUB-TOTAL

 

 

510.00

NY

Lee

F L

192837

489.50

NY

Tyron

W E

397267

0.00

NY

Jones

B D

839283

100.00

NY

SUB-TOTAL

 

 

589.50

TX

Williams

E D

593029

25.00

TX

 Henning

G K

938472

37.00

TX

SUB-TOTAL

 

 

62.00

VT

Vine

S S

392859

439.00

VT

SUB-TOTAL

 

 

439.00

WY

Thomas

A N

693829

0.00

WY

SUB-TOTAL

 

 

0.00

**

GRAND TOTAL

 

 

-2078.25