RECORDSET AND REPORT

RECORDSET AND REPORT

Postby Manuel Valdenebro » Sat Jan 19, 2008 10:52 am

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
User avatar
Manuel Valdenebro
 
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Postby Moisoft » Sat Jan 19, 2008 3:03 pm

Posiblemente usando el metodo bSkip del Report:

END REPORT

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

ACTIVATE REPORT oReport
Moisoft
 
Posts: 10
Joined: Wed Oct 19, 2005 7:49 am

Postby Armando » Sat Jan 19, 2008 6:01 pm

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
Armando
 
Posts: 3235
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Postby Manuel Valdenebro » Sat Jan 19, 2008 7:12 pm

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
User avatar
Manuel Valdenebro
 
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Postby Moisoft » Sun Jan 20, 2008 8:20 pm

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.
Moisoft
 
Posts: 10
Joined: Wed Oct 19, 2005 7:49 am

Postby mmercado » Sun Jan 20, 2008 10:33 pm

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
mmercado
 
Posts: 782
Joined: Wed Dec 19, 2007 7:50 am
Location: Salamanca, Gto., México

Postby Manuel Valdenebro » Mon Jan 21, 2008 12:18 am

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
Manuel Valdenebro
 
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Postby Armando » Mon Jan 21, 2008 1:23 am

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
Armando
 
Posts: 3235
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Postby Manuel Valdenebro » Mon Jan 21, 2008 3:48 pm

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
Manuel Valdenebro
 
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Postby Armando » Mon Jan 21, 2008 4:00 pm

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
Armando
 
Posts: 3235
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Postby Manuel Valdenebro » Mon Jan 21, 2008 9:35 pm

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
Manuel Valdenebro
 
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Postby Armando » Mon Jan 21, 2008 11:55 pm

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
Armando
 
Posts: 3235
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Postby Manuel Valdenebro » Tue Jan 22, 2008 2:52 pm

Armando wrote:Esepero haberme explicado.


Armando,

Te has explicado magnificamente. Gracias por todo.
Un saludo

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


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 52 guests