home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
4611
/
fw16d.ins
/
SOURCE
/
CLASSES
/
REPORT.PRG
< prev
next >
Wrap
Text File
|
1994-06-09
|
29KB
|
906 lines
/*
NOTA para Antonio Linares:
De momento dejo comentarios por que soy un forofo de ellos, ya los qui-
tare al final si tu lo deseas.
Lo mismo digo con las variables, ya las agruparé por tipos.
*/
/*
┌─ Programa ───────────────────────────────────────────────────────────────┐
│ Fichero: REPORT.PRG │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 16:18:32 │
│ Copyright: 1994 by Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
#include "FiveWin.ch"
#include "common.ch"
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Generador de listados │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 16:18:37 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
CLASS TReport
DATA nWidth ,; // ancho *
nHeight ,; // alto *
aTitle ,; // matriz de bTitulos *
aHead ,; // matriz de bHeader *
aFoot ,; // matriz de bFoot *
aGroups ,; // matriz de bGroups *
aSummary ,; // matriz de lResumen para aGroups *
aEjects ,; // matriz de Eject para aGroups *
aFont ,; // matriz de oFonts *
aColumns ,; // matriz de oColumns *
aTotals ,; // matriz de totales *
aAt ,; // matriz de columna de impresión *
bFor ,; // Condición bFor *
bWhile ,; // Condición bWhile *
bInit ,; // Block de inicio *
bEnd ,; // Block de fin *
bNewLine ,; // Block de Nueva linea *
bNewPage ,; // Block de nueva pagina *
bNewGroup ,; // Block de Nuevo Grupo *
bSkip ,; // Block para skip *
bEject ,; // Block de eject *
cRptFile ,; // Fichero Data *
cResName ,; // Recursos Data *
lPreview ,; // si .T. preview *
lStable ,; // verdadero si esta estable *
lTotal ,; // hay algun total *
lFinish ,; // el listado esta terminando *
lNewGroup ,; // si se esta generado nuevo grupo *
nMargin ,; // margen izquierdo *
nRow ,; // fila actual del listado *
nPage ,; // nº de pagina *
nSkipRow ,; // nº de lineas a saltar en cada newline *
nMinWidth ,; // Ancho mínimo calculado del listado *
nMaxTitle ,; // máximo número de titulos *
nMaxData ,; // máximo número de datos *
aValGroup ,; // matriz de valores actuales de cada grupo *
nCurrGroup ,; // grupo actual en proceso *
cTotalChr ,; // caracter para linea totales *
cSubTotChr // caracter para linea subtotales *
METHOD New( nWidth, nHeight, aTitle, aHead, ;
aFoot, aFont, cRptFile, cResName) CONSTRUCTOR
//METHOD FromFile() CONSTRUCTOR
//METHOD Resource() CONSTRUCTOR
METHOD AddColumn(oColumn) INLINE Aadd(::aColumns,oColumn) ,;
::lStable := .F.
METHOD DelColumn(nColumn) INLINE Adel(::aColumns,nColumn) ,;
Asize(::aColumns,len(::aColumns)-1) ,;
::lStable := .F.
METHOD InsColumn(oColumn ,;
nColumn) INLINE Ains(::aColumns,nColumn) ,;
::aColumns[nColumn]:= oColumn ,;
::lStable := .F.
METHOD AddGroup(bGroup ,;
lSummary ,;
lEject) INLINE Aadd(::aGroups,bGroup) ,;
Aadd(::aSummary,lSummary) ,;
Aadd(::aEjects,lEject) ,;
::lStable := .F.
METHOD DelGroup(nGroup) INLINE Adel(::aGroups,nGroup) ,;
Adel(::aSummarys,nGroup) ,;
Adel(::aEjects,nGroup) ,;
Asize(::aGroups,len(::aGroups)-1) ,;
Asize(::aSummary,len(::aSummary)-1) ,;
Asize(::aEjects,len(::aEjects)-1) ,;
::lStable := .F.
METHOD InsGroup(bGroup ,;
lSummary ,;
lEject ,;
nGroup) INLINE Ains(::aGroups,nGroup) ,;
Ains(::aSummary,nGroup) ,;
Ains(::aEjects,nGroup) ,;
::aGroups[nGroup] := bGroup ,;
::aSummary[nGroup]:= lSummary ,;
::aEjects[nGroup] := lEject ,;
::lStable := .F.
METHOD Stabilize()
METHOD Skip(n)
METHOD Eject()
METHOD Init()
METHOD End(lAbort)
METHOD Newline()
METHOD Newpage()
METHOD Newgroup()
METHOD NeedNewPage()
METHOD PageTotal()
METHOD GroupTotal()
METHOD Title()
METHOD Header()
METHOD Footer()
METHOD Activate(bFor, bWhile, bInit, bEnd, bNewPage, ;
bNewGroup, bNewLine, lPreview)
ENDCLASS
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Constructor de clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD New( nWidth, nHeight, aTitle, aHead, ;
aFoot, aFont, cRptFile, cResName) CLASS TReport
DEFAULT nWidth := 75 ,;
nHeight := 60 ,;
aTitle := {{|| ""} } ,;
aHead := {{|| ""} } ,;
aFoot := {{|| ""} } ,;
aFont := {""} ,;
cRptFile := "" ,;
cResName := ""
::nWidth = nWidth
::nHeight = nHeight
::aTitle = aTitle
::aHead = ahead
::aFoot = aFoot
::aFont = aFont
::cRptFile = cRptFile
::cResName = cResName
::aGroups = {}
::aSummary = {}
::aEjects = {}
::aColumns = {}
::aAt = {}
::aValGroup = {}
::nRow = 0
::nPage = 1
::nMargin = 0
::nSkipRow = 1
::nMinWidth = 0
::nMaxTitle = 0
::nMaxData = 0
::nCurrGroup = 0
::cTotalChr = "="
::cSubTotChr = "-"
::lStable = .F.
::lPreview = .F.
::lTotal = .F.
::lNewGroup = .F.
::lFinish = .F.
Return NIL
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Estabilizador del listado en clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Stabilize() CLASS TReport
LOCAL nColumns, nGroups, nFor
nColumns := len(::aColumns)
nGroups := len(::aGroups)
IF nColumns == 0
Retu (.F.) // No hay columnas
ENDIF
/*
Inicializa la matriz de subtotales por cada grupo en cada objeto
columna, su dimensión es igual al número de grupos
*/
AEval(::aColumns,{|Val| Val:aSubTotal:= Afill(Array(nGroups),0) })
/*
Cálculo del número maximo de titulos y datos pasados a los objetos
columna
*/
::nMaxTitle := 0
::nMaxData := 0
Aeval(::aColumns, {|Val| ::nMaxTitle := Max(len(Val:aTitle),::nMaxTitle) })
Aeval(::aColumns, {|Val| ::nMaxData := Max(len(Val:aData),::nMaxData) })
/*
Comprobar si hay algun total
*/
::lTotal := .F.
aeval(::aColumns,{|Val| iif(Val:lTotal,::lTotal := .T. ,NIL ) })
/*
Cálculo del ancho del listado
*/
::nMinWidth := 0
aeval(::aColumns,{|Val| ::nMinWidth += Val:nWidth+1 })
::nMinWidth--
aeval(::aTitle,{|Val| ::nMinWidth := max(::nMinWidth,len(eval(Val))+1) })
aeval(::aHead ,{|Val| ::nMinWidth := max(::nMinWidth,len(eval(Val))+1) })
aeval(::aFoot ,{|Val| ::nMinWidth := max(::nMinWidth,len(eval(Val))+1) })
/*
Margen del Listado
*/
::nMargin := max(Int((::nWidth-::nMinWidth)/2),0)
/*
Calculo de las distintas columnas del listado
*/
Asize(::aAt,nColumns)
::aAt[1] := iif(::aColumns[1]:nCol>0, ::aColumns[1]:nCol, ::nMargin)
FOR nFor := 2 TO nColumns
IF ::aColumns[nFor]:nCol>0
::aAt[nFor] := ::aColumns[nFor]:nCol
ELSE
::aAt[nFor] := ::aAt[nFor-1] + ::aColumns[nFor-1]:nWidth + 1
ENDIF
NEXT
/*
Indicar que ya esta estable
*/
::lStable := .T.
Return (.T.)
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Inicialización del listado despues de aTitle de columnas │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Init() CLASS TReport
if ::bInit != nil
Eval( ::bInit )
endif
Return Nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Finalización del listado │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD End(lAbort) CLASS TReport
::lFinish := .T.
if lAbort
Break(NIL)
endif
if ::bEnd != nil
Eval( ::bEnd )
endif
Return Nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Salto de registro o equivalente en clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Skip( n ) CLASS TReport
if ::bSkip != nil
retu Eval( ::bSkip, n )
endif
Return DbSkip( n )
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Salto de página o equivalente en clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Eject() CLASS TReport
if ::bEject != nil
Eval( ::bEject )
else
EJECT
endif
::nRow := 0
Return NIL
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Salto de linea en clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD NewLine() CLASS TReport
if ::bNewLine != nil
Eval( ::bNewLine)
endif
::nRow++
if ::NeedNewPage()
::NewPage()
endif
Return nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Salto de pagina en clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD NewPage() CLASS TReport
if ::bNewPage != nil
Eval( ::bNewPage)
endif
::PageTotal()
::Footer()
::Eject()
if !(::lFinish)
::nPage++
::Header()
::Title()
endif
Return nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Nuevo grupo en clase TReport │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD NewGroup() CLASS TReport
::lNewGroup := .T.
if ::bNewGroup != nil
Eval( ::bNewGroup)
endif
if ::NeedNewPage()
::NewPage()
endif
::GroupTotal()
IF ::aEjects[::nCurrGroup]
::NewPage()
ELSE
::NewLine()
ENDIF
Aeval(::aColumns,{|Val| Val:aSubTotal[::nCurrGroup] := 0 })
::lNewGroup := .F.
Return nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Necesidad de nueva hoja │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD NeedNewPage() CLASS TReport
LOCAL nMaxRow
nMaxRow := ::nHeight -;
(iif(::lTotal,3 ,0 ) +;
iif(::lNewGroup,3 ,0 ) +;
iif(len(::aFoot)>0,len(::aFoot)+1,0) )
Return (::nRow > nMaxRow)
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Activación del listado │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Activate(bFor, bWhile, bInit, bEnd, bNewPage, ;
bNewGroup, bNewLine, lPreview) CLASS TReport
LOCAL aData, aPicture, aValueGroup
LOCAL nColumns, nGroups, nFor1, nFor2, nFor3
LOCAL lGroup, lSummary
DEFAULT bFor := {|| !eof() } ,;
bWhile := {|| .T. } ,;
lPreview := .F.
::bFor = bFor
::bWhile = bWhile
::bInit = bInit
::bNewPage = bNewPage
::bNewGroup = bNewGroup
::bNewLine = bNewLine
::lPreview = lPreview
/*
Si no esta estabilizado salir
*/
if !(::lStable)
Retu NIL
endif
/*
Si es un preview salir
*/
if ::lPreview // OTRA HISTORIA
Retu NIL
endif
nColumns := len(::aColumns)
nGroups := len(::aGroups)
/*
Inicializar variables segun existencia de grupos
*/
if nGroups > 0
aValueGroup := Array(nGroups)
lGroup := .T.
lSummary := ::aSummary[1] // ???
else
lGroup := .F.
lSummary := .F.
endif
/*
Inicializar dos matrices de trabajo aData y aPicture para la impresión
del cuerpo del listado, es más rapido que ir comprobando siempre lo
mismo por cada linea, esto es así ya que una columna puede tener un ele-
mento aData y otra tres, lo cual complica bastante el listado.
Prefiero utilizar dos matrices de trabajo en vez de modificar los obje-
tos oColumn en el proceso de estabilización.
*/
aData := Array(nColumns,::nMaxData)
aPicture := Array(nColumns,::nMaxData)
FOR nFor1 := 1 TO nColumns
FOR nFor2 := 1 TO ::nMaxData
if len(::aColumns[nFor1]:aData) < nFor2
aData[nFor1][nFor2] := {|| "" }
else
aData[nFor1][nFor2] := ::aColumns[nFor1]:aData[nFor2]
endif
if len(::aColumns[nFor1]:aPicture) < nFor2
aPicture[nFor1][nFor2] := ""
else
aPicture[nFor1][nFor2] := ::aColumns[nFor1]:aPicture[nFor2]
endif
NEXT
NEXT
/*
Comienzo de la Impresión
*/
BEGIN SEQUENCE
::Header()
::Title()
::Init()
/*
Bucle de rastreo
*/
DO WHILE eval(::bFor)
/*
Comprobar condición While
*/
IF !eval(::bWhile)
EXIT
ENDIF
/*
Condición de Grupo
*/
IF lGroup
FOR nFor1 := 1 TO nGroups
aValueGroup[nFor1]:= eval(::aGroups[nFor1])
NEXT
ENDIF
/*
Cuerpo del Listado
*/
FOR nFor1 := 1 TO ::nMaxData
FOR nFor2 := 1 TO nColumns
if !lSummary
@ ::nRow ,::aAt[nFor2];
SAY eval(aData[nFor2][nFor1]) ;
PICTURE aPicture[nFor2][nFor1]
endif
/*
Control Sumas
*/
IF ::lTotal .AND. ;
::aColumns[nFor2]:lTotal .AND. ;
valtype(eval(aData[nFor2][nFor1])) == "N" .AND. ;
eval(::aColumns[nFor2]:bTotalExpr)
::aColumns[nFor2]:ntotal += eval(aData[nFor2][nFor1])
if lGroup
FOR nFor3 := 1 TO nGroups
::aColumns[nFor2]:aSubtotal[nFor3] += ;
eval(aData[nFor2][nFor1])
NEXT
endif
ENDIF
NEXT
/*
Si no es resumen nueva linea
*/
IF !lSummary
::NewLine()
ENDIF
NEXT
/*
Proximo registro o equivalente
*/
::Skip(1)
/*
Control Grupo
*/
IF lGroup
FOR nFor1 := 1 TO nGroups
IF !(aValueGroup[nFor1] == eval(::aGroups[nFor1]))
FOR nFor2 := nGroups TO nFor1 STEP -1
::nCurrGroup := nFor2
::NewGroup()
aValueGroup[nFor2] := eval(::aGroups[nFor2])
NEXT
EXIT
ENDIF
NEXT
ENDIF
ENDDO
/*
Impesión de totales
*/
IF ::nRow > 0
::End(.F.)
::NewPage()
ENDIF
END
Return Nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Totales por página │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD PageTotal() CLASS TReport
LOCAL nFor, nColumns
/*
Si no hay ningun total no hacer nada
*/
IF !(::lTotal)
RETU (NIL)
ENDIF
nColumns := len(::aColumns)
/*
Mostrar linea superior de totales
*/
FOR nFor := 1 TO nColumns
@ ::nRow, ::aAt[nFor] SAY ;
Replicate(::cTotalChr,::aColumns[nFor]:nWidth)
NEXT
::nRow++
/*
Imprimir los totales para las columnas que lo lleven
*/
FOR nFor := 1 TO nColumns
IF ::aColumns[nFor]:lTotal
@ ::nRow, ::aAt[nFor] SAY ::aColumns[nFor]:nTotal ;
PICTURE ::aColumns[nFor]:bTotalPict
ENDIF
NEXT
::nRow++
Return NIL
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Totales por grupo │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD GroupTotal() CLASS TReport
LOCAL nFor, nColumns
/*
Si no hay ningun total solo saltar una linea
*/
IF !(::lTotal)
::nRow++
retu nil
ENDIF
nColumns := len(::aColumns)
/*
Mostrar linea superior de subtotales
*/
FOR nFor := 1 TO nColumns
@ ::nRow, ::aAt[nFor] SAY ;
Replicate(::cSubTotChr,::aColumns[nFor]:nWidth)
NEXT
::nRow++
/*
Imprimir los subtotales para las columnas que lo lleven
*/
FOR nFor := 1 TO nColumns
IF ::aColumns[nFor]:lTotal
@ ::nRow, ::aAt[nFor] SAY ::aColumns[nFor]:aSubTotal[::nCurrGroup] ;
PICTURE ::aColumns[nFor]:bTotalPict
ENDIF
NEXT
::nRow++
Return NIL
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Titulo del listado │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Title() CLASS TReport
LOCAL aText
LOCAL nFor1, nFor2, nColumns, nTitle
nColumns := len(::aColumns)
nTitle := len(::aTitle)
/*
Generar matriz de trabajo para titulos
*/
aText := Array(nColumns,::nMaxTitle)
FOR nFor1 := 1 TO nColumns
FOR nFor2 := 1 TO ::nMaxTitle
if len(::aColumns[nFor1]:aTitle) < nFor2
aText[nFor1][nFor2] := {|| "" }
else
aText[nFor1][nFor2] := ::aColumns[nFor1]:aTitle[nFor2]
endif
NEXT
NEXT
/*
Imprimir titulos (centrados en la página)
*/
FOR nFor1 := 1 TO nTitle
@ ::nRow++ ,;
Int(::nMinWidth/2) - ;
Int(len(eval(::aTitle[nFor1]))/2) + ;
::nMargin ;
SAY eval(::aTitle[nFor1])
NEXT
::nRow++
/*
Imprimir linea superior de titulos
*/
FOR nFor1 := 1 TO nColumns
@ ::nRow, ::aAt[nFor1] SAY ;
Replicate(::aColumns[nFor1]:cColUpChar,::aColumns[nFor1]:nWidth)
NEXT
::nRow++
/*
Descriptores de titulos de cada columna
*/
FOR nFor1 := 1 TO ::nMaxTitle
FOR nFor2 := 1 TO nColumns
@ ::nRow, ::aAt[nFor2] SAY eval(aText[nFor2][nFor1])
NEXT
::nRow++
NEXT
/*
Imprimir linea inferior de titulos
*/
FOR nFor1 := 1 TO nColumns
@ ::nRow, ::aAt[nFor1] SAY ;
Replicate(::aColumns[nFor1]:cColDnChar,::aColumns[nFor1]:nWidth)
NEXT
::nRow++
Return nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Cabecera del listado │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Header() CLASS TReport
LOCAL nFor, nHeader
nHeader := len(::aHead)
FOR nFor := 1 TO nHeader
@ ::nRow++,::nMargin SAY eval(::aHead[nFor])
NEXT
::nRow++
Return nil
/*
┌─ Clase ──────────────────────────────────────────────────────────────────┐
│ Descripción: Footer del listado │
│ Autor: Ignacio Ortiz de Zúñiga Echeverría │
│ Fecha: 24/05/94 │
│ Hora: 18:07:14 │
│ Copyright: Ortiz de Zuñiga, S.L. │
└──────────────────────────────────────────────────────────────────────────┘
*/
METHOD Footer() CLASS TReport
LOCAL nFor, nFooter
nFooter := len(::aFoot)
::nRow++
FOR nFor := 1 TO nFooter
@ ::nRow++,::nMargin SAY eval(::aFoot[nFor])
NEXT
Return nil