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 >
Text File  |  1994-06-09  |  29KB  |  906 lines

  1. /*
  2. NOTA para Antonio Linares:
  3.  
  4.      De momento dejo comentarios por que soy un forofo de ellos, ya los qui-
  5.      tare al final si tu lo deseas.
  6.  
  7.      Lo mismo digo con las variables, ya las agruparé por tipos.
  8. */
  9.  
  10. /*
  11. ┌─ Programa ───────────────────────────────────────────────────────────────┐
  12. │      Fichero: REPORT.PRG                                                 │
  13. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  14. │        Fecha: 24/05/94                                                   │
  15. │         Hora: 16:18:32                                                   │
  16. │    Copyright: 1994 by Ortiz de Zuñiga, S.L.                              │
  17. └──────────────────────────────────────────────────────────────────────────┘
  18. */
  19.  
  20. #include "FiveWin.ch"
  21. #include "common.ch"
  22.  
  23. /*
  24. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  25. │  Descripción: Generador de listados                                      │
  26. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  27. │        Fecha: 24/05/94                                                   │
  28. │         Hora: 16:18:37                                                   │
  29. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  30. └──────────────────────────────────────────────────────────────────────────┘
  31. */
  32. CLASS TReport
  33.  
  34.    DATA nWidth     ,;   // ancho                                    *
  35.         nHeight    ,;   // alto                                     *
  36.         aTitle     ,;   // matriz de bTitulos                       *
  37.         aHead      ,;   // matriz de bHeader                        *
  38.         aFoot      ,;   // matriz de bFoot                          *
  39.         aGroups    ,;   // matriz de bGroups                        *
  40.         aSummary   ,;   // matriz de lResumen para aGroups          *
  41.         aEjects    ,;   // matriz de Eject para aGroups             *
  42.         aFont      ,;   // matriz de oFonts                         *
  43.         aColumns   ,;   // matriz de oColumns                       *
  44.         aTotals    ,;   // matriz de totales                        *
  45.         aAt        ,;   // matriz de columna de impresión           *
  46.         bFor       ,;   // Condición bFor                           *
  47.         bWhile     ,;   // Condición bWhile                         *
  48.         bInit      ,;   // Block de inicio                          *
  49.         bEnd       ,;   // Block de fin                             *
  50.         bNewLine   ,;   // Block de Nueva linea                     *
  51.         bNewPage   ,;   // Block de nueva pagina                    *
  52.         bNewGroup  ,;   // Block de Nuevo Grupo                     *
  53.         bSkip      ,;   // Block para skip                          *
  54.         bEject     ,;   // Block de eject                           *
  55.         cRptFile   ,;   // Fichero Data                             *
  56.         cResName   ,;   // Recursos Data                            *
  57.         lPreview   ,;   // si .T. preview                           *
  58.         lStable    ,;   // verdadero si esta estable                *
  59.         lTotal     ,;   // hay algun total                          *
  60.         lFinish    ,;   // el listado esta terminando               *
  61.         lNewGroup  ,;   // si se esta generado nuevo grupo          *
  62.         nMargin    ,;   // margen izquierdo                         *
  63.         nRow       ,;   // fila actual del listado                  *
  64.         nPage      ,;   // nº de pagina                             *
  65.         nSkipRow   ,;   // nº de lineas a saltar en cada newline    *
  66.         nMinWidth  ,;   // Ancho mínimo calculado del listado       *
  67.         nMaxTitle  ,;   // máximo número de titulos                 *
  68.         nMaxData   ,;   // máximo número de datos                   *
  69.         aValGroup  ,;   // matriz de valores actuales de cada grupo *
  70.         nCurrGroup ,;   // grupo actual en proceso                  *
  71.         cTotalChr  ,;   // caracter para linea totales              *
  72.         cSubTotChr      // caracter para linea subtotales           *
  73.  
  74.      METHOD New( nWidth, nHeight, aTitle, aHead, ;
  75.                  aFoot, aFont, cRptFile, cResName) CONSTRUCTOR
  76.  
  77.      //METHOD FromFile() CONSTRUCTOR
  78.      //METHOD Resource() CONSTRUCTOR
  79.  
  80.      METHOD AddColumn(oColumn) INLINE Aadd(::aColumns,oColumn) ,;
  81.                                       ::lStable := .F.
  82.  
  83.      METHOD DelColumn(nColumn) INLINE Adel(::aColumns,nColumn) ,;
  84.                                       Asize(::aColumns,len(::aColumns)-1) ,;
  85.                                       ::lStable := .F.
  86.  
  87.      METHOD InsColumn(oColumn ,;
  88.                       nColumn) INLINE Ains(::aColumns,nColumn) ,;
  89.                                       ::aColumns[nColumn]:= oColumn ,;
  90.                                       ::lStable := .F.
  91.  
  92.      METHOD AddGroup(bGroup   ,;
  93.                      lSummary ,;
  94.                      lEject)   INLINE Aadd(::aGroups,bGroup)    ,;
  95.                                       Aadd(::aSummary,lSummary) ,;
  96.                                       Aadd(::aEjects,lEject)    ,;
  97.                                       ::lStable := .F.
  98.  
  99.      METHOD DelGroup(nGroup)   INLINE Adel(::aGroups,nGroup)   ,;
  100.                                       Adel(::aSummarys,nGroup) ,;
  101.                                       Adel(::aEjects,nGroup)   ,;
  102.                                       Asize(::aGroups,len(::aGroups)-1)   ,;
  103.                                       Asize(::aSummary,len(::aSummary)-1) ,;
  104.                                       Asize(::aEjects,len(::aEjects)-1)   ,;
  105.                                       ::lStable := .F.
  106.  
  107.      METHOD InsGroup(bGroup   ,;
  108.                      lSummary ,;
  109.                      lEject   ,;
  110.                      nGroup)   INLINE Ains(::aGroups,nGroup)    ,;
  111.                                       Ains(::aSummary,nGroup)   ,;
  112.                                       Ains(::aEjects,nGroup)    ,;
  113.                                       ::aGroups[nGroup] := bGroup   ,;
  114.                                       ::aSummary[nGroup]:= lSummary ,;
  115.                                       ::aEjects[nGroup] := lEject   ,;
  116.                                       ::lStable := .F.
  117.  
  118.      METHOD Stabilize()
  119.      METHOD Skip(n)
  120.      METHOD Eject()
  121.  
  122.      METHOD Init()
  123.      METHOD End(lAbort)
  124.  
  125.      METHOD Newline()
  126.      METHOD Newpage()
  127.      METHOD Newgroup()
  128.      METHOD NeedNewPage()
  129.  
  130.      METHOD PageTotal()
  131.      METHOD GroupTotal()
  132.  
  133.      METHOD Title()
  134.      METHOD Header()
  135.      METHOD Footer()
  136.  
  137.      METHOD Activate(bFor, bWhile, bInit, bEnd, bNewPage, ;
  138.                      bNewGroup, bNewLine, lPreview)
  139.  
  140. ENDCLASS
  141.  
  142. /*
  143. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  144. │  Descripción: Constructor de clase TReport                               │
  145. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  146. │        Fecha: 24/05/94                                                   │
  147. │         Hora: 18:07:14                                                   │
  148. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  149. └──────────────────────────────────────────────────────────────────────────┘
  150. */
  151. METHOD New( nWidth, nHeight, aTitle, aHead, ;
  152.             aFoot, aFont, cRptFile, cResName) CLASS TReport
  153.  
  154.      DEFAULT nWidth      := 75           ,;
  155.              nHeight     := 60           ,;
  156.              aTitle      := {{|| ""} }   ,;
  157.              aHead       := {{|| ""} }   ,;
  158.              aFoot       := {{|| ""} }   ,;
  159.              aFont       := {""}         ,;
  160.              cRptFile    := ""           ,;
  161.              cResName    := ""
  162.  
  163.      ::nWidth     = nWidth
  164.      ::nHeight    = nHeight
  165.      ::aTitle     = aTitle
  166.      ::aHead      = ahead
  167.      ::aFoot      = aFoot
  168.      ::aFont      = aFont
  169.      ::cRptFile   = cRptFile
  170.      ::cResName   = cResName
  171.      ::aGroups    = {}
  172.      ::aSummary   = {}
  173.      ::aEjects    = {}
  174.      ::aColumns   = {}
  175.      ::aAt        = {}
  176.      ::aValGroup  = {}
  177.      ::nRow       = 0
  178.      ::nPage      = 1
  179.      ::nMargin    = 0
  180.      ::nSkipRow   = 1
  181.      ::nMinWidth  = 0
  182.      ::nMaxTitle  = 0
  183.      ::nMaxData   = 0
  184.      ::nCurrGroup = 0
  185.      ::cTotalChr  = "="
  186.      ::cSubTotChr = "-"
  187.      ::lStable    = .F.
  188.      ::lPreview   = .F.
  189.      ::lTotal     = .F.
  190.      ::lNewGroup  = .F.
  191.      ::lFinish    = .F.
  192.  
  193. Return NIL
  194.  
  195. /*
  196. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  197. │  Descripción: Estabilizador del listado en clase TReport                 │
  198. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  199. │        Fecha: 24/05/94                                                   │
  200. │         Hora: 18:07:14                                                   │
  201. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  202. └──────────────────────────────────────────────────────────────────────────┘
  203. */
  204. METHOD Stabilize() CLASS TReport
  205.  
  206.      LOCAL nColumns, nGroups, nFor
  207.  
  208.      nColumns := len(::aColumns)
  209.      nGroups  := len(::aGroups)
  210.  
  211.      IF nColumns == 0
  212.           Retu (.F.)                           // No hay columnas
  213.      ENDIF
  214.  
  215.      /*
  216.      Inicializa la matriz de subtotales por cada grupo en cada objeto
  217.      columna, su dimensión es igual al número de grupos
  218.      */
  219.  
  220.      AEval(::aColumns,{|Val| Val:aSubTotal:= Afill(Array(nGroups),0) })
  221.  
  222.      /*
  223.      Cálculo del número maximo de titulos y datos pasados a los objetos
  224.      columna
  225.      */
  226.  
  227.      ::nMaxTitle := 0
  228.      ::nMaxData  := 0
  229.  
  230.      Aeval(::aColumns, {|Val| ::nMaxTitle := Max(len(Val:aTitle),::nMaxTitle) })
  231.      Aeval(::aColumns, {|Val| ::nMaxData  := Max(len(Val:aData),::nMaxData) })
  232.  
  233.     /*
  234.     Comprobar si hay algun total
  235.     */
  236.  
  237.      ::lTotal := .F.
  238.      aeval(::aColumns,{|Val| iif(Val:lTotal,::lTotal := .T. ,NIL ) })
  239.  
  240.      /*
  241.      Cálculo del ancho del listado
  242.      */
  243.  
  244.      ::nMinWidth := 0
  245.  
  246.      aeval(::aColumns,{|Val| ::nMinWidth += Val:nWidth+1 })
  247.  
  248.      ::nMinWidth--
  249.  
  250.      aeval(::aTitle,{|Val| ::nMinWidth := max(::nMinWidth,len(eval(Val))+1) })
  251.      aeval(::aHead ,{|Val| ::nMinWidth := max(::nMinWidth,len(eval(Val))+1) })
  252.      aeval(::aFoot ,{|Val| ::nMinWidth := max(::nMinWidth,len(eval(Val))+1) })
  253.  
  254.     /*
  255.      Margen del Listado
  256.     */
  257.  
  258.      ::nMargin := max(Int((::nWidth-::nMinWidth)/2),0)
  259.  
  260.     /*
  261.      Calculo de las distintas columnas del listado
  262.     */
  263.  
  264.      Asize(::aAt,nColumns)
  265.  
  266.      ::aAt[1] := iif(::aColumns[1]:nCol>0, ::aColumns[1]:nCol, ::nMargin)
  267.  
  268.      FOR nFor := 2 TO nColumns
  269.           IF ::aColumns[nFor]:nCol>0
  270.                ::aAt[nFor] := ::aColumns[nFor]:nCol
  271.           ELSE
  272.                ::aAt[nFor] := ::aAt[nFor-1] + ::aColumns[nFor-1]:nWidth + 1
  273.           ENDIF
  274.     NEXT
  275.  
  276.      /*
  277.      Indicar que ya esta estable
  278.      */
  279.  
  280.      ::lStable := .T.
  281.  
  282. Return (.T.)
  283.  
  284. /*
  285. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  286. │  Descripción: Inicialización del listado despues de aTitle de columnas   │
  287. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  288. │        Fecha: 24/05/94                                                   │
  289. │         Hora: 18:07:14                                                   │
  290. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  291. └──────────────────────────────────────────────────────────────────────────┘
  292. */
  293. METHOD Init() CLASS TReport
  294.  
  295.      if ::bInit != nil
  296.           Eval( ::bInit )
  297.      endif
  298.  
  299. Return Nil
  300.  
  301. /*
  302. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  303. │  Descripción: Finalización del listado                                   │
  304. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  305. │        Fecha: 24/05/94                                                   │
  306. │         Hora: 18:07:14                                                   │
  307. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  308. └──────────────────────────────────────────────────────────────────────────┘
  309. */
  310. METHOD End(lAbort) CLASS TReport
  311.  
  312.      ::lFinish := .T.
  313.  
  314.      if lAbort
  315.           Break(NIL)
  316.      endif
  317.  
  318.      if ::bEnd != nil
  319.           Eval( ::bEnd )
  320.      endif
  321.  
  322. Return Nil
  323.  
  324. /*
  325. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  326. │  Descripción: Salto de registro o equivalente en clase TReport           │
  327. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  328. │        Fecha: 24/05/94                                                   │
  329. │         Hora: 18:07:14                                                   │
  330. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  331. └──────────────────────────────────────────────────────────────────────────┘
  332. */
  333. METHOD Skip( n ) CLASS TReport
  334.  
  335.      if ::bSkip != nil
  336.           retu Eval( ::bSkip, n )
  337.      endif
  338.  
  339. Return DbSkip( n )
  340.  
  341. /*
  342. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  343. │  Descripción: Salto de página o equivalente en clase TReport             │
  344. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  345. │        Fecha: 24/05/94                                                   │
  346. │         Hora: 18:07:14                                                   │
  347. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  348. └──────────────────────────────────────────────────────────────────────────┘
  349. */
  350. METHOD Eject() CLASS TReport
  351.  
  352.      if ::bEject != nil
  353.           Eval( ::bEject )
  354.      else
  355.           EJECT
  356.      endif
  357.  
  358.      ::nRow := 0
  359.  
  360. Return NIL
  361.  
  362. /*
  363. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  364. │  Descripción: Salto de linea en clase TReport                            │
  365. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  366. │        Fecha: 24/05/94                                                   │
  367. │         Hora: 18:07:14                                                   │
  368. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  369. └──────────────────────────────────────────────────────────────────────────┘
  370. */
  371. METHOD NewLine() CLASS TReport
  372.  
  373.      if ::bNewLine != nil
  374.           Eval( ::bNewLine)
  375.      endif
  376.  
  377.      ::nRow++
  378.  
  379.      if ::NeedNewPage()
  380.           ::NewPage()
  381.      endif
  382.  
  383. Return nil
  384.  
  385. /*
  386. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  387. │  Descripción: Salto de pagina en clase TReport                           │
  388. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  389. │        Fecha: 24/05/94                                                   │
  390. │         Hora: 18:07:14                                                   │
  391. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  392. └──────────────────────────────────────────────────────────────────────────┘
  393. */
  394. METHOD NewPage() CLASS TReport
  395.  
  396.      if ::bNewPage != nil
  397.           Eval( ::bNewPage)
  398.      endif
  399.  
  400.      ::PageTotal()
  401.      ::Footer()
  402.      ::Eject()
  403.  
  404.      if !(::lFinish)
  405.           ::nPage++
  406.           ::Header()
  407.           ::Title()
  408.      endif
  409.  
  410. Return nil
  411.  
  412. /*
  413. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  414. │  Descripción: Nuevo grupo en clase TReport                               │
  415. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  416. │        Fecha: 24/05/94                                                   │
  417. │         Hora: 18:07:14                                                   │
  418. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  419. └──────────────────────────────────────────────────────────────────────────┘
  420. */
  421. METHOD NewGroup() CLASS TReport
  422.  
  423.      ::lNewGroup := .T.
  424.  
  425.      if ::bNewGroup != nil
  426.           Eval( ::bNewGroup)
  427.      endif
  428.  
  429.      if ::NeedNewPage()
  430.           ::NewPage()
  431.      endif
  432.  
  433.      ::GroupTotal()
  434.  
  435.      IF ::aEjects[::nCurrGroup]
  436.           ::NewPage()
  437.      ELSE
  438.           ::NewLine()
  439.      ENDIF
  440.  
  441.      Aeval(::aColumns,{|Val| Val:aSubTotal[::nCurrGroup] := 0 })
  442.  
  443.      ::lNewGroup := .F.
  444.  
  445. Return nil
  446.  
  447. /*
  448. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  449. │  Descripción: Necesidad de nueva hoja                                    │
  450. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  451. │        Fecha: 24/05/94                                                   │
  452. │         Hora: 18:07:14                                                   │
  453. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  454. └──────────────────────────────────────────────────────────────────────────┘
  455. */
  456. METHOD NeedNewPage() CLASS TReport
  457.  
  458.      LOCAL nMaxRow
  459.  
  460.      nMaxRow := ::nHeight                             -;
  461.                 (iif(::lTotal,3 ,0 )                  +;
  462.                 iif(::lNewGroup,3 ,0 )                +;
  463.                 iif(len(::aFoot)>0,len(::aFoot)+1,0) )
  464.  
  465. Return (::nRow > nMaxRow)
  466.  
  467. /*
  468. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  469. │  Descripción: Activación del listado                                     │
  470. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  471. │        Fecha: 24/05/94                                                   │
  472. │         Hora: 18:07:14                                                   │
  473. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  474. └──────────────────────────────────────────────────────────────────────────┘
  475. */
  476. METHOD Activate(bFor, bWhile, bInit, bEnd, bNewPage, ;
  477.                 bNewGroup, bNewLine, lPreview) CLASS TReport
  478.  
  479.      LOCAL aData, aPicture, aValueGroup
  480.      LOCAL nColumns, nGroups, nFor1, nFor2, nFor3
  481.      LOCAL lGroup, lSummary
  482.  
  483.      DEFAULT bFor     := {|| !eof() } ,;
  484.              bWhile   := {|| .T. }    ,;
  485.              lPreview := .F.
  486.  
  487.      ::bFor      = bFor
  488.      ::bWhile    = bWhile
  489.      ::bInit     = bInit
  490.      ::bNewPage  = bNewPage
  491.      ::bNewGroup = bNewGroup
  492.      ::bNewLine  = bNewLine
  493.      ::lPreview  = lPreview
  494.  
  495.      /*
  496.      Si no esta estabilizado salir
  497.      */
  498.  
  499.      if !(::lStable)
  500.           Retu NIL
  501.      endif
  502.  
  503.      /*
  504.      Si es un preview salir
  505.      */
  506.  
  507.      if ::lPreview                               // OTRA HISTORIA
  508.           Retu NIL
  509.      endif
  510.  
  511.      nColumns := len(::aColumns)
  512.      nGroups  := len(::aGroups)
  513.  
  514.      /*
  515.      Inicializar variables segun existencia de grupos
  516.      */
  517.  
  518.      if nGroups > 0
  519.           aValueGroup  := Array(nGroups)
  520.           lGroup       := .T.
  521.           lSummary     := ::aSummary[1]          // ???
  522.      else
  523.           lGroup       := .F.
  524.           lSummary     := .F.
  525.      endif
  526.  
  527.      /*
  528.      Inicializar dos matrices de trabajo aData y aPicture para la impresión
  529.      del cuerpo del listado, es más rapido que ir comprobando siempre lo
  530.      mismo por cada linea, esto es así ya que una columna puede tener un ele-
  531.      mento aData y otra tres, lo cual complica bastante el listado.
  532.      Prefiero utilizar dos matrices de trabajo en vez de modificar los obje-
  533.      tos oColumn en el proceso de estabilización.
  534.      */
  535.  
  536.      aData    := Array(nColumns,::nMaxData)
  537.      aPicture := Array(nColumns,::nMaxData)
  538.  
  539.      FOR nFor1 := 1 TO nColumns
  540.           FOR nFor2 := 1 TO ::nMaxData
  541.                if len(::aColumns[nFor1]:aData) < nFor2
  542.                     aData[nFor1][nFor2] := {|| "" }
  543.                else
  544.                     aData[nFor1][nFor2] := ::aColumns[nFor1]:aData[nFor2]
  545.                endif
  546.                if len(::aColumns[nFor1]:aPicture) < nFor2
  547.                     aPicture[nFor1][nFor2] := ""
  548.                else
  549.                     aPicture[nFor1][nFor2] := ::aColumns[nFor1]:aPicture[nFor2]
  550.                endif
  551.           NEXT
  552.      NEXT
  553.  
  554.     /*
  555.      Comienzo de la Impresión
  556.     */
  557.  
  558.     BEGIN SEQUENCE
  559.  
  560.      ::Header()
  561.      ::Title()
  562.      ::Init()
  563.  
  564.     /*
  565.      Bucle de rastreo
  566.     */
  567.  
  568.      DO WHILE eval(::bFor)
  569.  
  570.           /*
  571.           Comprobar condición While
  572.           */
  573.  
  574.           IF !eval(::bWhile)
  575.                EXIT
  576.           ENDIF
  577.  
  578.           /*
  579.         Condición de Grupo
  580.         */
  581.  
  582.           IF lGroup
  583.                FOR nFor1 := 1 TO nGroups
  584.                     aValueGroup[nFor1]:= eval(::aGroups[nFor1])
  585.                NEXT
  586.         ENDIF
  587.  
  588.         /*
  589.         Cuerpo del Listado
  590.         */
  591.  
  592.           FOR nFor1 := 1 TO ::nMaxData
  593.  
  594.                FOR nFor2 := 1 TO nColumns
  595.  
  596.                     if !lSummary
  597.                          @ ::nRow ,::aAt[nFor2];
  598.                               SAY eval(aData[nFor2][nFor1]) ;
  599.                               PICTURE aPicture[nFor2][nFor1]
  600.                     endif
  601.  
  602.                 /*
  603.                 Control Sumas
  604.                 */
  605.  
  606.                     IF ::lTotal                                  .AND. ;
  607.                        ::aColumns[nFor2]:lTotal                  .AND. ;
  608.                        valtype(eval(aData[nFor2][nFor1])) == "N" .AND. ;
  609.                        eval(::aColumns[nFor2]:bTotalExpr)
  610.  
  611.                          ::aColumns[nFor2]:ntotal += eval(aData[nFor2][nFor1])
  612.                          if lGroup
  613.                               FOR nFor3 := 1 TO nGroups
  614.                                    ::aColumns[nFor2]:aSubtotal[nFor3] += ;
  615.                                      eval(aData[nFor2][nFor1])
  616.                               NEXT
  617.                          endif
  618.  
  619.                 ENDIF
  620.  
  621.             NEXT
  622.  
  623.                /*
  624.                Si no es resumen nueva linea
  625.                */
  626.  
  627.                IF !lSummary
  628.                     ::NewLine()
  629.                ENDIF
  630.  
  631.         NEXT
  632.  
  633.           /*
  634.           Proximo registro o equivalente
  635.         */
  636.  
  637.           ::Skip(1)
  638.  
  639.         /*
  640.         Control Grupo
  641.         */
  642.  
  643.           IF lGroup
  644.                FOR nFor1 := 1 TO nGroups
  645.                     IF !(aValueGroup[nFor1] == eval(::aGroups[nFor1]))
  646.                          FOR nFor2 := nGroups TO nFor1 STEP -1
  647.                               ::nCurrGroup := nFor2
  648.                               ::NewGroup()
  649.                               aValueGroup[nFor2] := eval(::aGroups[nFor2])
  650.                          NEXT
  651.                          EXIT
  652.                     ENDIF
  653.                NEXT
  654.         ENDIF
  655.  
  656.      ENDDO
  657.  
  658.     /*
  659.     Impesión de totales
  660.     */
  661.  
  662.      IF ::nRow > 0
  663.           ::End(.F.)
  664.           ::NewPage()
  665.     ENDIF
  666.  
  667.      END
  668.  
  669. Return Nil
  670.  
  671. /*
  672. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  673. │  Descripción: Totales por página                                         │
  674. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  675. │        Fecha: 24/05/94                                                   │
  676. │         Hora: 18:07:14                                                   │
  677. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  678. └──────────────────────────────────────────────────────────────────────────┘
  679. */
  680. METHOD PageTotal() CLASS TReport
  681.  
  682.      LOCAL nFor, nColumns
  683.  
  684.     /*
  685.     Si no hay ningun total no hacer nada
  686.     */
  687.  
  688.      IF !(::lTotal)
  689.         RETU (NIL)
  690.     ENDIF
  691.  
  692.      nColumns := len(::aColumns)
  693.  
  694.      /*
  695.     Mostrar linea superior de totales
  696.     */
  697.  
  698.      FOR nFor := 1 TO nColumns
  699.           @ ::nRow, ::aAt[nFor] SAY ;
  700.                Replicate(::cTotalChr,::aColumns[nFor]:nWidth)
  701.      NEXT
  702.  
  703.      ::nRow++
  704.  
  705.      /*
  706.     Imprimir los totales para las columnas que lo lleven
  707.     */
  708.  
  709.      FOR nFor := 1 TO nColumns
  710.  
  711.           IF ::aColumns[nFor]:lTotal
  712.                @ ::nRow, ::aAt[nFor] SAY ::aColumns[nFor]:nTotal ;
  713.                      PICTURE ::aColumns[nFor]:bTotalPict
  714.         ENDIF
  715.  
  716.     NEXT
  717.  
  718.      ::nRow++
  719.  
  720. Return NIL
  721.  
  722.  
  723. /*
  724. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  725. │  Descripción: Totales por grupo                                          │
  726. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  727. │        Fecha: 24/05/94                                                   │
  728. │         Hora: 18:07:14                                                   │
  729. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  730. └──────────────────────────────────────────────────────────────────────────┘
  731. */
  732. METHOD GroupTotal() CLASS TReport
  733.  
  734.      LOCAL nFor, nColumns
  735.  
  736.     /*
  737.      Si no hay ningun total solo saltar una linea
  738.     */
  739.  
  740.      IF !(::lTotal)
  741.           ::nRow++
  742.           retu nil
  743.     ENDIF
  744.  
  745.      nColumns := len(::aColumns)
  746.  
  747.      /*
  748.      Mostrar linea superior de subtotales
  749.     */
  750.  
  751.      FOR nFor := 1 TO nColumns
  752.           @ ::nRow, ::aAt[nFor] SAY ;
  753.                Replicate(::cSubTotChr,::aColumns[nFor]:nWidth)
  754.      NEXT
  755.  
  756.      ::nRow++
  757.  
  758.      /*
  759.      Imprimir los subtotales para las columnas que lo lleven
  760.     */
  761.  
  762.      FOR nFor := 1 TO nColumns
  763.  
  764.           IF ::aColumns[nFor]:lTotal
  765.                @ ::nRow, ::aAt[nFor] SAY ::aColumns[nFor]:aSubTotal[::nCurrGroup] ;
  766.                      PICTURE ::aColumns[nFor]:bTotalPict
  767.         ENDIF
  768.  
  769.     NEXT
  770.  
  771.      ::nRow++
  772.  
  773. Return NIL
  774.  
  775. /*
  776. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  777. │  Descripción: Titulo del listado                                         │
  778. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  779. │        Fecha: 24/05/94                                                   │
  780. │         Hora: 18:07:14                                                   │
  781. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  782. └──────────────────────────────────────────────────────────────────────────┘
  783. */
  784. METHOD Title() CLASS TReport
  785.  
  786.      LOCAL aText
  787.      LOCAL nFor1, nFor2, nColumns, nTitle
  788.  
  789.      nColumns := len(::aColumns)
  790.      nTitle   := len(::aTitle)
  791.  
  792.      /*
  793.      Generar matriz de trabajo para titulos
  794.      */
  795.  
  796.      aText := Array(nColumns,::nMaxTitle)
  797.  
  798.      FOR nFor1 := 1 TO nColumns
  799.           FOR nFor2 := 1 TO ::nMaxTitle
  800.                if len(::aColumns[nFor1]:aTitle) < nFor2
  801.                     aText[nFor1][nFor2] := {|| "" }
  802.                else
  803.                     aText[nFor1][nFor2] := ::aColumns[nFor1]:aTitle[nFor2]
  804.                endif
  805.           NEXT
  806.      NEXT
  807.  
  808.      /*
  809.      Imprimir titulos (centrados en la página)
  810.      */
  811.  
  812.      FOR nFor1 := 1 TO nTitle
  813.  
  814.           @ ::nRow++                            ,;
  815.             Int(::nMinWidth/2) -                 ;
  816.             Int(len(eval(::aTitle[nFor1]))/2) +  ;
  817.             ::nMargin                            ;
  818.             SAY eval(::aTitle[nFor1])
  819.     NEXT
  820.  
  821.      ::nRow++
  822.  
  823.      /*
  824.      Imprimir linea superior de titulos
  825.      */
  826.  
  827.      FOR nFor1 := 1 TO nColumns
  828.           @ ::nRow, ::aAt[nFor1] SAY ;
  829.                Replicate(::aColumns[nFor1]:cColUpChar,::aColumns[nFor1]:nWidth)
  830.      NEXT
  831.  
  832.      ::nRow++
  833.  
  834.     /*
  835.      Descriptores de titulos de cada columna
  836.     */
  837.  
  838.      FOR nFor1 := 1 TO ::nMaxTitle
  839.  
  840.           FOR nFor2 := 1 TO nColumns
  841.                @ ::nRow, ::aAt[nFor2] SAY eval(aText[nFor2][nFor1])
  842.         NEXT
  843.  
  844.           ::nRow++
  845.  
  846.     NEXT
  847.  
  848.      /*
  849.      Imprimir linea inferior de titulos
  850.      */
  851.  
  852.      FOR nFor1 := 1 TO nColumns
  853.           @ ::nRow, ::aAt[nFor1] SAY ;
  854.                Replicate(::aColumns[nFor1]:cColDnChar,::aColumns[nFor1]:nWidth)
  855.      NEXT
  856.  
  857.      ::nRow++
  858.  
  859. Return nil
  860.  
  861. /*
  862. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  863. │  Descripción: Cabecera del listado                                       │
  864. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  865. │        Fecha: 24/05/94                                                   │
  866. │         Hora: 18:07:14                                                   │
  867. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  868. └──────────────────────────────────────────────────────────────────────────┘
  869. */
  870. METHOD Header() CLASS TReport
  871.  
  872.      LOCAL nFor, nHeader
  873.  
  874.      nHeader := len(::aHead)
  875.  
  876.      FOR nFor := 1 TO nHeader
  877.           @ ::nRow++,::nMargin SAY eval(::aHead[nFor])
  878.      NEXT
  879.  
  880.      ::nRow++
  881.  
  882. Return nil
  883.  
  884. /*
  885. ┌─ Clase ──────────────────────────────────────────────────────────────────┐
  886. │  Descripción: Footer del listado                                         │
  887. │        Autor: Ignacio Ortiz de Zúñiga Echeverría                         │
  888. │        Fecha: 24/05/94                                                   │
  889. │         Hora: 18:07:14                                                   │
  890. │    Copyright: Ortiz de Zuñiga, S.L.                                      │
  891. └──────────────────────────────────────────────────────────────────────────┘
  892. */
  893. METHOD Footer() CLASS TReport
  894.  
  895.      LOCAL nFor, nFooter
  896.  
  897.      nFooter := len(::aFoot)
  898.  
  899.      ::nRow++
  900.  
  901.      FOR nFor := 1 TO nFooter
  902.           @ ::nRow++,::nMargin SAY eval(::aFoot[nFor])
  903.      NEXT
  904.  
  905. Return nil
  906.