RECORDSET AND REPORT

Post Reply
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

RECORDSET AND REPORT

Post by Manuel Valdenebro »

En una aplicacion Oracle + Ado, capturo un RecordSet con varios registros que muestro en un Browse con tres columnas:


..........

REDEFINE LISTBOX oLbx ;
FIELDS oRs:Fields("CLASE"):value, ;
oRs:Fields("NOMBRE"):value, ;
NUM2STR(oRs:Fields("CONTROL"):value, 10, 0) ;
HEADERS PADC("Clase",18) , ;
PADC("Nombre",80), ;
PADC("Ref.",10) ;
FIELDSIZES 90, 290, 20 ;
ID 101 ;
OF oDlg

oLbx:aJustify ={.F.,.F.,.t.}
oLbx:bLogicLen = { || oRs:RecordCount }
oLbx:bGoTop = { || oRs:MoveFirst() }
oLbx:bGoBottom = { || oRs:MoveLast() }
oLbx:bSkip = { | nSkip | Skipper( oRs, nSkip ) }
oLbx:cAlias = "ARRAY"

Desearía imprimir el browse (todos los registros) con la clase Report, pero solo consigo que me salga, varias veces, el primer registro. He intentado poniendo un bucle FOR/NEXT ó de la manera usual con un array (bSkip), pero no resulta. ¿Alguna ayudita por favor?

----------------------------------------------------------
STATIC FUNCTION I_LISTA( oRs )
LOCAL oReport, oFont1, oFont2, oFont3, oPen1, oPen2

DEFINE FONT oFont1 NAME "ARIAL" SIZE 0,-8
DEFINE FONT oFont2 NAME "ARIAL" SIZE 0,-12 BOLD
DEFINE FONT oFont3 NAME "ARIAL" SIZE 0,-16 BOLD

REPORT oReport ;
CAPTION " Mi libro de Cocinas" ;
TITLE "*** Listado de Recetas ***" ;
HEADER DTOC(DATE()) , " " FONT oFont1, ;
oFont2, ;
oFont3 ;
FOOTER "Página Número: " + STR (oReport:nPage, 3) CENTER ;
PREVIEW
COLUMN TITLE "Clas" DATA oRs:Fields("clase"):value
COLUMN TITLE "Nombre" DATA oRs:Fields("nombre"):value
COLUMN TITLE "Refª" DATA oRs:Fields("control"):value

END REPORT

oReport:oTitle:aFont[1] := {|| 3 }
oReport:oHeader:aFont[1] := {|| 2 }
oReport:oDevice:SetPortrait()
oReport:oDevice:lPrvModal := .T. // preview modal

ACTIVATE REPORT oReport

oFont1:End()
oFont2:End()
oFont3:End()
oRs:MoveFirst()

RETURN NIL

------------------------------------------
Un saludo

Manuel
Moisoft
Posts: 10
Joined: Wed Oct 19, 2005 7:49 am

Post by Moisoft »

Posiblemente usando el metodo bSkip del Report:

END REPORT

....
....
oReport:bSkip = { | nSkip | Skipper( oRs, nSkip ) }

ACTIVATE REPORT oReport
User avatar
Armando
Posts: 2479
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México
Contact:

Post by Armando »

Manuel:

Yo lo hago así con MySql, espero que te funcione con Oracle:

Dentro de la función para la impresión tengo

FUNCTION Imprime()

LOCAL nLinea := 1
LOCAL nHasta := oRsPro:RecordCount()

oRsPro:MoveFirst()

Aquí van los DEFINE de fonts y REPORT

// Creo que aqui esta el truco
IF oReporte:lCreated
oReporte:bSkip := { || (nLinea++, oRsPro:MoveNext())}
ENDIF

Y finalmente al activar el reporte:

ACTIVATE REPORT oReporte ;
WHILE nLinea <= nHasta


Espero esto te ayude, Saludos
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Post by Manuel Valdenebro »

Moisoft wrote:Posiblemente usando el metodo bSkip del Report:
END REPORT
....
....
oReport:bSkip = { | nSkip | Skipper( oRs, nSkip ) }

ACTIVATE REPORT oReport
Moisés, muchas gracias por tu ayuda. Ahora lista perfectamente el Recordset, pero repite "infinitamente" el último registro. Me imagino que es la función Skipper, que al encontrar oRs:EOF ejecuta MoveLast().-
He intentado solucionándolo añadiendo:

ACTIVATE REPORT oReport WHILE (oRs:AbsolutePosition < oRs:RecordCount)

pero no sale el ultimo registro y si le pongo:
(oRs:AbsolutePosition <= oRs:RecordCount), estamos igual que antes, es decir, repite el ultimo registro infinitamente.

En Listbox, tenemos oLbx:bLogicLen = { || oRs:RecordCount }, pero no he encontrado su sustituto en la clase Report.

Esta es mi funcion Skipper:

FUNCTION SKIPPER( oRs, nSkip )
LOCAL nRec := oRs:AbsolutePosition
oRs:Move( nSkip )
IF oRs:EOF; oRs:MoveLast(); ENDIF
IF oRs:BOF; oRs:MoveFirst(); ENDIF
RETURN oRs:AbsolutePosition - nRec

Me imagino que la cosa ahora no es complicada, pero a mi no se me ocurre ninguna solución.
Un saludo

Manuel
Moisoft
Posts: 10
Joined: Wed Oct 19, 2005 7:49 am

Post by Moisoft »

Prueba a dejar la funcion skipper más sencilla:

FUNCTION SKIPPER( oRs, nSkip )
LOCAL nRec := oRs:AbsolutePosition
oRs:Move( nSkip )
RETURN oRs:AbsolutePosition - nRec

ya que cuando sea eof el Reporte Termine.
User avatar
mmercado
Posts: 782
Joined: Wed Dec 19, 2007 7:50 am
Location: Salamanca, Gto., México

Post by mmercado »

Hola Manuel:

1.- Ya probaste el Method Report del Browser que estás usando?
2.- Ya probaste usando la Cláusula FOR en lugar de la cláusula WHILE en ACTIVATE REPORT?

Saludos.

Manuel Mercado
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Post by Manuel Valdenebro »

Moises, Armando y D. Manuel, muchas gracias por contestar.

Al final la solución la he encontrado haciendo un popurrí con todo lo dicho por Vdes.

1) He utilizado:
local nHasta := oRs:RECORDCOUNT(), nLinea := 1
.....
oReport:bWhile := { || nLinea <= nHasta }
IF oReport:lCreated
oReport:bSkip := { | | nLinea++, Ors:MOVENEXT() }
ENDI

2) He modificado la funcion Skipper quedando:

FUNCTION SKIPPER( oRs, nSkip )
LOCAL nRec := oRs:AbsolutePosition

IF oRs:EOF
oRs:MoveLast()
ELSE
oRs:Move( nSkip )
ENDIF

IF oRs:BOF; oRs:MoveFirst(); ENDIF

RETURN oRs:AbsolutePosition - nRec


Ya está funcionando estupendamente. De nuevo, muchas gracias a los tres.
Un saludo

Manuel
User avatar
Armando
Posts: 2479
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México
Contact:

Post by Armando »

Manuel:

Me alegra saber que todo funciona bien ahora, sin embargo creo que puedes reducir tu código, en realidad pienso que no necesitas la función Skipper().

Es solo una sugerencia.

Saludos
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Post by Manuel Valdenebro »

Armando wrote:... no necesitas la función Skipper().
Armando,

En un principio lo hice como me dices. Sale perfecto el "preview" de Treport, pero al pulsar Imprimir/Salir marcaba un error de ADO/ors, al volver al Browse. Por eso incluí el Skipper que creo sincroniza el Ors:Fields con el registro del browse.

Yo utilizo tWbrowse.- ¿Que browse estás tu utilizando con Mysql?
Un saludo

Manuel
User avatar
Armando
Posts: 2479
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México
Contact:

Post by Armando »

Manuel:

En principio te dire lo que dicen los gurus, "Si funciona bien no le muevas" :D perooo solo por no dejar.

1.- Yo uso TXBrowse, no se si eso tengo algo que ver

2.- Me olvide de indicarte estas dos línea de código, tal vez por ahí esta el problema

LOCAL nLinea := 1
LOCAL nHasta := oRsPro:RecordCount()
LOCAL nBookMark := oRsPro:BookMark

....
....
....


ACTIVATE REPORT oReporte ;
ON STARTPAGE Alinea(oReporte,1,2);
ON END oRsPro:BookMark := nBookMark;
WHILE nLinea <= nHasta

Creo que el RecordSet es muy quisquilloso en cuanto al apuntador.

Saludos, Armando
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Post by Manuel Valdenebro »

Armando wrote: Me olvide de indicarte estas dos línea de código, tal vez por ahí esta el problema
Armando,

Llevabas mucha razón. Aunque funcionaba al imprimir cuando cambie la función Skipper, al moverme normalmente en el browse, cuando llegaba al final daba error. He modificado la función de la siguiente forma:

STATIC FUNCTION I_LISTA( oRs )
local nLinea := 1, nHasta := oRs:RECORDCOUNT(), ;
nBookMark := oRs:BookMark

oRs:MoveFirst()

REPORT oReport ;
CAPTION .....
...................
END REPORT

oReport:bWhile := { || nLinea <= nHasta }
oReport:oTitle:aFont[1] := {|| 3 }
oReport:oHeader:aFont[1] := {|| 2 }
oReport:oDevice:SetPortrait()
oReport:oDevice:lPrvModal := .T. // preview modal
IF oReport:lCreated
oReport:bSkip := { | | nLinea++, Ors:MOVENEXT() }
ENDI

ACTIVATE REPORT oReport ;
ON END oRs:BookMark := nBookMark

oRs:MoveFirst()
RETURN NIL

--------------------------------

¿ Para que pones ON STARTPAGE Alinea (oReport,1,2) ?
Un saludo

Manuel
User avatar
Armando
Posts: 2479
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México
Contact:

Post by Armando »

Manuel:

Me algera que funcione bien.


La función ALINEA() es porque a mi me gustan los encabezados así

Fecha: 22/Ene/2008 Página No. 1
=========================================
COLUMNA COLUMNA COLUMNA COLUMNA
=========================================

Así defino los encabezados

TITLE "Fecha: "+Date2Txt(DATE()),;
"Hoja No:"+STR(oReporte:nPage,3)

Al ser dos elementos del arreglo TITLE me los pone uno en una línea y el otro en la línea siguiente

Fecha: 22/Ene/2008
Página No. 1

Entonces la función ALINEA() me sirve para cambiarle la línea al segundo elemento dandole la misma línea que el primer elemento y me quedan en una misma línea.

Esepero haberme explicado.

Saludos, Armando
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Post by Manuel Valdenebro »

Armando wrote: Esepero haberme explicado.
Armando,

Te has explicado magnificamente. Gracias por todo.
Un saludo

Manuel
Post Reply