RECORDSET AND REPORT
- Manuel Valdenebro
- Posts: 706
- Joined: Thu Oct 06, 2005 9:57 pm
- Location: Málaga-España
RECORDSET AND REPORT
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
------------------------------------------
..........
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
Manuel
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
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
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
- Manuel Valdenebro
- Posts: 706
- Joined: Thu Oct 06, 2005 9:57 pm
- Location: Málaga-España
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().-Moisoft wrote:Posiblemente usando el metodo bSkip del Report:
END REPORT
....
....
oReport:bSkip = { | nSkip | Skipper( oRs, nSkip ) }
ACTIVATE REPORT oReport
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
Manuel
- Manuel Valdenebro
- Posts: 706
- Joined: Thu Oct 06, 2005 9:57 pm
- Location: Málaga-España
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.
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
Manuel
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
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
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
- Manuel Valdenebro
- Posts: 706
- Joined: Thu Oct 06, 2005 9:57 pm
- Location: Málaga-España
Armando,Armando wrote:... no necesitas la función Skipper().
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
Manuel
Manuel:
En principio te dire lo que dicen los gurus, "Si funciona bien no le muevas" 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
En principio te dire lo que dicen los gurus, "Si funciona bien no le muevas" 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
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
- Manuel Valdenebro
- Posts: 706
- Joined: Thu Oct 06, 2005 9:57 pm
- Location: Málaga-España
Armando,Armando wrote: Me olvide de indicarte estas dos línea de código, tal vez por ahí esta el problema
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
Manuel
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
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
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
- Manuel Valdenebro
- Posts: 706
- Joined: Thu Oct 06, 2005 9:57 pm
- Location: Málaga-España