FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Ejemplo del uso del un recorset con xbrowse
Posts: 1818
Joined: Wed Oct 26, 2005 02:49 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Fri Feb 08, 2008 02:37 PM

Amigos del foro tengan buen dia, alguien me puede indicar de casualidad como se usa un recorset, directamente con un xbrowse.

De antemano gracias

Saludos
LEANDRO AREVALO
Bogot谩 (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 77
Joined: Wed Jun 28, 2006 06:38 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Sat Feb 16, 2008 02:10 AM

pues mira yo use WBROWSE y para usar recordset tienes que definir el tipo de cursor correcto, definierle lo codigos de blocks de navegacion asi como definir una funcion skipper especial...

         oLbx1:bLogicLen := { || oRecordSet:RecordCount }
         oLbx1:bGoTop    := { || oRecordSet:MoveFirst() }
         oLbx1:bGoBottom := { || oRecordSet:MoveLast() }
         oLbx1:bSkip     := { | nSkip | Skipper( oRecordSet, nSkip ) }

STATIC 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

Debo aclararte que no lo he hecho funcionar al 100% ya que cuando me muevo hacia la derecha en el browse me hace un efecto "extra帽o"...

Ojala te sirva de algo.
Saludos.
Alex.

Posts: 682
Joined: Tue Feb 14, 2006 09:48 AM
Ejemplo del uso del un recorset con xbrowse
Posted: Sat Feb 16, 2008 06:02 PM
...
//oRs tiene el recordset ya creado.
oBrw := TXBrowse():New( oWnd ) 
oBrw:SetAdo(oRs) 
oBrw:CreateFromCode() 
oWnd:oClient:=oBrw
...

Tambien puedes consultar este otro hilo http://fivetechsoft.com/forums/viewtopic.php?t=8231
Saludos desde Mallorca
Biel Maim贸
http://bielsys.blogspot.com/
Posts: 111
Joined: Thu Jan 19, 2006 11:47 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Sat Feb 16, 2008 06:52 PM
Biel:

Se me ocurre una idea, te la voy a proponer a ver si te animas..

Porque no haces un manual como para ni帽os de KINDER sobre como comenzar a utilizar ADO, yo leo tu BLOG y se que tu colaboras desinteresadamente a la comunidad de fivewineros.

Cuando yo aprendi clipper lo hice a punta de comprar libros y pr谩cticar y repasar y practicar y repasar hasta que fui aprendiendo. Y creo que si tenemos un manual de KINDER y despues para PRIMARIA y asi sucesivamente iremos haciendo la transicion a ADO.

L贸gico tu tiempo vale y por eso estaria dispuesto a pagar ($$ bueno Euros) por dicho manual. 驴Que te parece?; creo a que muchos nos serviria para dar ese salto.

Saludos
Edgar Mauricio Ar茅valo Mogoll贸n.
Bogot谩 DC. Colombia
FWH FTDN, xHarbour 1.2.1, Pelles C, Fivedit, Visual Studio Code, Borland 7.30, Mysql, Dbfs
http://www.hymplus.com http://www.hymlyma.com
Tratando de retomar la programaci贸n....
Posts: 711
Joined: Thu Oct 06, 2005 09:57 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Sat Feb 16, 2008 07:13 PM

Mauricio,

El tema de ADO es bastante simple y realmente no es necesario un manual. En la red existe bastante informaci贸n que es de donde (la mayor铆a) hemos ido aprendiendo.

http://www.w3schools.com/ado/default.asp

Pero si lo que se pretende es trabajar con una base de datos "seria" (cliente-servidor) tales como Oracle, MySql, SqlServer, etc. en mi opini贸n, habr铆a que dividir el tema en tres pasos:

1) Lenguaje SQL (fundamental)
2) ADO
3) Temas espec铆ficos de cada base de datos (por ejemplo, Oracle tiene su propio lenguaje).

Un saludo



Manuel
Posts: 111
Joined: Thu Jan 19, 2006 11:47 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Sat Feb 16, 2008 10:13 PM
Manuel:

Gracias

Y tienes toda la raz贸n, es trabajar con base de datos cliente\servidor, lo que es no plantear bien la duda o pregunta.

As铆 como lo planteas es perfecto para iniciarse.

El primer punto no habri谩 necesidad porque hay bastante documentaci贸n, cursos, manuales, etc...de hecho ya hago pruebas con MYSQL desde la linea de comandos (crear, modificar, consultas, etc.)

El segundo ADO tambien pasa.

Entonces seria el tercer punto.

Temas espec铆ficos de cada base de datos (por ejemplo, Oracle tiene su propio lenguaje).

Dominando este tema podriamos tener nuestros sistemas en diferentes versiones atacando DBF, MYSQL, ORACLE, etc..


PD: 驴Manuel y al f铆n no viniste a Colombia el a帽o pasado?, te teniamos una invitaci贸n a tomar puro cafecito colombiano.


Saludos,
Edgar Mauricio Ar茅valo Mogoll贸n.
Bogot谩 DC. Colombia
FWH FTDN, xHarbour 1.2.1, Pelles C, Fivedit, Visual Studio Code, Borland 7.30, Mysql, Dbfs
http://www.hymplus.com http://www.hymlyma.com
Tratando de retomar la programaci贸n....
Posts: 1364
Joined: Wed Jun 21, 2006 12:39 AM
Ejemplo del uso del un recorset con xbrowse
Posted: Sun Feb 17, 2008 01:36 AM

El problema de las BBDD cliente - servidor no es como atacarlas desde nuestros programas mediante Ado ( en el foro hay bastante documentaci贸n con respecto a este tema ). El mayor problema es cambiar la visi贸n que nosotros tenemos con respecto de las bases de datos que hemos venido manejando ( dbf ). Hasta ahora la l贸gica la manejabamos nosotros, desde nuestras aplicaciones pero cuando trabajamos sobre esta tecnolog铆a la l贸gica es manejada por el servidor mediante store procedures ( procedimientos almacenados ) y triggers ( disparadores ). y para trabajar con estas herramientas es necesario aprender el lenguaje de la BBDD. Creer que solamente con una cadena de conexi贸n y el comando SELECT tenemos todo resuelto es una ingenuidad. Si realmente queremos que nuestros sistemas sean eficientes debemos cambiar la mentalidad ( y estudiar bastante ). Yo he hecho pruebas con 200 o 300 registros y el rendimiento no ha variado significativamene con respecto a una base distribuida ( dbf ) pero hablar de m谩s de 3.000.000 de registros y conectarnos en forma remota es otra cosa. Los index no son iguales tal cual los conocemos. Es el servidor el que elige que index va a utilizar en las consultas y para eso nosotros debemos decidir que index crear. No quiero extenderme demasiado sobre este tema ( tampoco soy un entendido ) pero me parece que si decidimos trabajar en forma seria sobre esta tecnolog铆a har谩 falta mucho estudio y ver el manejo de datos de manera diferente . Espero que esto sirva.
saludos

Posts: 711
Joined: Thu Oct 06, 2005 09:57 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Sun Feb 17, 2008 10:05 AM

Horacio,

Podriamos clasificar la mayoria de las aplicaciones que venimos desarrollando los clipperos en dos grupos:

1) Programas dom茅sticos.
2) Programas para peque帽as/medianas empresas (multipuesto o multilugares)

En el segundo grupo es muy conveniente, por cuestiones de seguridad interna (p茅rdida de datos, reindexados, etc) y externa (encriptaci贸n de los datos, copias de seguridad, etc) el usar una base de datos cliente/servidor. Incluso a nivel comercial, no vende igual una aplicaci贸n que trabaje con Oracle/MySql que con dbf. Recuerdo que Oracle Express es gratuito.

En este caso, no es obligatorio un conocimiento profundo de la BD y con unos peque帽os cambios (sobre todo, si nos preparamos algunas funciones generales de apoyo), podemos poner a trabajar nuestra aplicaci贸n con una BD de garant铆a. En velocidad practicamente igual que con dbf.

Esta claro que si se tienen esos conocimientos y planteamos nuestra aplicaci贸n de otra forma (huir de los browse) la cosa mejora, pero lo que quiero decir es que no es OBLIGATORIO.

Otro tema muy importante (en mi opini贸n) ser铆a trabajar con una BD en un servidor externo (internet). Y quiz谩s con esta opci贸n, si podriamos organizar, entre los foreros que estuvieran interesados, unas pr谩cticas, contratando un servidor compartido y atacando, cada uno desde su ordenador como usuario, la misma BD.

Tambien ser铆a interesante, para no duplicar los comentarios y conseguir mas colaboradores, que el tema lo desarrollaramos exclusivamente en el foro INGLES, aunque se permitieran utilizar espa帽o/ingl茅s.

Un saludo



Manuel
Posts: 1818
Joined: Wed Oct 26, 2005 02:49 PM
Amigo...
Posted: Sun Feb 17, 2008 05:39 PM
Alex amigo:

Es posible que sea el tipo de cursor, lo estoy definiendo de la siguiente manera:

oRsPro:CursorLocation := adUseClient
oRsPro:LockType := adLockOptimistic
oRsPro:CursorType := adOpenDynamic
oRsPro:Source := "SELECT * FROM clientes ORDER BY clie_nom"
oRsPro:ActiveConnection(oCnx)

Es correcto o debo hacerlo de otra forma?

Te hago otra pregunta, como hago para refrescar el recorset en tiempo de ejecucci贸n?
Saludos
LEANDRO AREVALO
Bogot谩 (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 1818
Joined: Wed Oct 26, 2005 02:49 PM
Con ....
Posted: Sun Feb 17, 2008 05:43 PM

Con la respecto a la documentacion de ado creo que es suficiente para iniciar y poder hacer andar tu aplicaci贸n por lo menos a un 80%. El mayor problema para mi ha sido hacer funcionar el recorset en un browse. Es en donde me he topado con mas complicaciones, me gustaria que existiera un manual en donde se explicara el manejo del recorset sobre un browse, cualquiera que este sea.

Saludos
LEANDRO AREVALO
Bogot谩 (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 711
Joined: Thu Oct 06, 2005 09:57 PM
Ejemplo con ADO + RecordSet + Browse
Posted: Mon Feb 18, 2008 09:30 AM

Leandro,

No s茅 si esto es lo que necesitas:

Ejemplo para trabajar con ADO + RecordSet + Browse:

En una aplicaci贸n cliente servidor, debemos tener UNA SOLA
conexi贸n a la Base de Datos (BD). En cambio, tendremos
m煤ltiples RecordSet. Por tanto es conveniente disponer de una
funci贸n para facilitar la creaci贸n de estos RecordSet de una
forma sencilla. Tambien podemos tener en nuestra librer铆a,
las funciones SKIPPER() y ADOERROR().
En resumen, una vez creado el objeto RecordSet, la actuaci贸n
en el Browse es muy parecido a cuando usamos el objeto
Database de FiveWin.

/////////////////////////////////////////////////
Suponemos que ya tenemos en nuestra libreria la funci贸n
F_RecordSet y que en la aplicaci贸n que estamos programando,
ya existe una Conexi贸n a la BD que llamaremos oCon.
Ahora vamos a crear un objeto RecordSet y mostrarlo
en un Browse.
En nuestro ejemplo, se trata de un programa de recetas
de cocina,
/////////////////////////////////////////////////

FUNCTION BrwCocina(oCon)
Local lSalvar := .f., oDlg, oLbx, oBtn:= ARRAY(9)

// orden SQL
LOCAL cSql := 'SELECT * FROM RECETAS ORDER BY NOMBRE'

// crea recordset
Local oRs := F_RECORDSET ( oCon, cSql, .t. ) // ver al final

// F_recordset devuelve "nil" si hay error
IF oRs == nil
RETURN nil
ENDI

// Caja de Di谩logo -----------------------------------------------------
DEFINE DIALOG oDlg RESOURCE "RECETAS" ;
TITLE " Mi libro de recetas con ORACLE"

**
** campos del browse
**
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 ;
ON DBLCLICK F_ALTA(oRs, .F., oLbx )

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

** si pulsa <intro>
oLbx:bKeyDown := {|nK| if( nK != VK_RETURN, , F_ALTA(oRs,.F.,aCbx, oLbx) ) }

** para que el browse salga a dos colores
oLbx:nClrPane:={|| IIF(oRs:AbsolutePosition % 2==0,CLR_LGREEN,CLR_LGRAY)}

REDEFINE BUTTONBMP oBtn[1] ID 104 OF oDlg ;
ACTION F_ALTA( oRs, .T., oLbx) ;
MESSAGE "Alta de una nueva receta." ;
PROMPT SPACE(6)+ "&Alta" TEXTRIGHT ;
BITMAP "Alta3"

**
** Baja receta
**
REDEFINE BUTTONBMP oBtn[2] ID 105 OF oDlg ;
ACTION( O_SUPRIMIR ( oRs, "NOMBRE" ), ;
oLbx:Refresh(), ;
oLbx:SetFocus() ) ;
MESSAGE " Eliminar receta activa." ;
PROMPT SPACE(6)+ "&Baja" TEXTRIGHT ;
BITMAP "Cancelar"

// modificar receta
REDEFINE BUTTONBMP oBtn[3] ID 106 OF oDlg ;
ACTION F_ALTA( oRs, .F., oLbx ) ;
MESSAGE " Editar receta activa." ;
PROMPT SPACE(10) + "&Editar" ;
BITMAP "lapiz" TEXTRIGHT

// filtrar
REDEFINE BUTTONBMP oBtn[4] ID 107 OF oDlg ;
ACTION ( FILTRAR ( oRs ), ;
oLbx:Refresh(), ;
oLbx:SetFocus() ) ;
MESSAGE " Filtrar recetas." ;
PROMPT SPACE(10) + "&Filtrar" ;
BITMAP "buscar" TEXTRIGHT

// Imprimir
REDEFINE BUTTONBMP oBtn[5] ID 108 OF oDlg ;
ACTION ( I_LISTA( oRs ), ;
oLbx:REFRESH(), ;
oLbx:SETFOCUS()) ;
MESSAGE " Imprimir la receta activa." ;
PROMPT SPACE( 8 ) + "&Imprimir" ;
BITMAP "imprimir1" TEXTRIGHT

// boton salir
REDEFINE BUTTONBMP oBtn[6] ID 109 OF oDlg ;
ACTION oDlg:End() ;
MESSAGE " Salir del programa." ;
PROMPT SPACE(4)+ "&Salir" TEXTRIGHT ;
BITMAP "salir1"

oDlg:lHelpIcon:=.f.
ACTIVATE DIALOG oDlg CENTERED ;
ON INIT oLbx:SetFocus()

oRs:CLOSE()
oRS:=Nil

RETURN NIL

////////////////////////////////////////
/// funcion que crea un recordset
/// oCon = Objeto conexi贸n a la BD
/// cSql = Orden SQL
/// lVacio = .T./.F. avisar que Ors est谩 vacio
///////////////////////////////////////

FUNCTION F_RECORDSET (oCon, cSql, lVacio)
local oError
local oRs := CreateObject( "ADODB.Recordset" )

oRs:CursorLocation := 3 // adUseClient
oRs:LockType := 3 // adLockOptimistic
oRs:CursorType := 1 // adOpenKeyset
oRs:Source := cSql
oRs:ActiveConnection(oCon)

TRY
oRs:Open( )
CATCH oError
AdoError(oCon, oError)
RETURN nil
END

IF lVacio
IF oRs:EOF .and. oRs:BOF
msgstop ("Fichero vacio")
oRs:CLOSE()
oRs:=Nil
RETURN nil
ENDI
oRs:MoveFirst()
ENDI

RETURN oRs

//////////////////////////////////
/// skipper se usa para saltar en el oRs
/// cuando salta en el browse
////////////////////////////////////////////////////////
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

/////////////////////////////////////////
/// Para informar de un error ADO
////////////////////////////////////////
FUNCTION AdoError(oCon, oError)
LOCAL oTmp

FOR EACH oTmp IN oCon:Errors // oAdoErrors

   IF oError == nil
      oError := ErrorNew()
      oError:Description := "Error desconocido ADO"
   ELSE
      oError:SubCode := oTmp:NativeError //隆隆隆num. error nativo
      oError:Description := oTmp:Description
   ENDIF

NEXT

MSGSTOP ( (oError:Description + CRLF ) , ;
" Error " + oError:Operation + ' ' + oError:SubSystem )

RETURN (oError:SubCode) // C贸digo num. del error

///////////////////////////////////////

Para agregar o editar un registro, puedes ver este mensaje:

http://fivetechsoft.com/forums/viewtopi ... ght=#47676

Un saludo



Manuel
Posts: 1818
Joined: Wed Oct 26, 2005 02:49 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Mon Feb 18, 2008 03:00 PM

Gracias Manuel

Muchas gracias por las respuesta voy a probar y cualquier cosa te comento.

Amigo, cuando estoy trabajando con entorno MDI, debo hacer algo especial para que funcione bien el xbrowse?

Saludos
LEANDRO AREVALO
Bogot谩 (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 682
Joined: Tue Feb 14, 2006 09:48 AM
Ejemplo del uso del un recorset con xbrowse
Posted: Mon Feb 18, 2008 05:21 PM
Bueno este hilo parece que genera bastante interes, me alegro pues cada dia somos mas los que podemos ir aportando conocimientos sobre ADO.

Mauro, a mi no me importaria realizar un manual de ADO, pero como tu bien comentas el tiempo vale dinero, y muchas veces no dispongo de todo el tiempo que quisiera. De momento en el blog voy escribiendo cada cuando puedo, habra epocas con mas articulos, y otras de larga sequia. En cuaquier caso, el tema formacion es algo que me interesa, y puedo llegar a plantearmelo, siempre y cuando me compense la retribuci贸n a recibir a cambio.

Al tema, como bien han comentado otros por la red hay bastante informaci贸n del tema ADO, y en este foro cada vez mas, recuperar un recordset y visualizarlo en un browse con ventanas MDI no tien que llevar ning煤n problema.
He escrito en mi blog una nueva entrada, con un ejemplo muy b谩sico de ADO para visualizar una tabla en un xBroswe.
http://bielsys.blogspot.com/2008/02/usando-origenes-de-datos-ado-1.html
Espero que os pueda ser de utilidad.
Saludos desde Mallorca
Biel Maim贸
http://bielsys.blogspot.com/
Posts: 1818
Joined: Wed Oct 26, 2005 02:49 PM
Ejemplo del uso del un recorset con xbrowse
Posted: Tue Feb 19, 2008 05:15 PM
Biel y Manuel muchas gracias por la ayuda. Funciona de maravilla.

Pero tengo otra preguntica?

Como hago para actualizar el recorset. por ejemplo que quiera cambiar el orden en que se estan mostrando la consulta.

El recorset inicial es:

oVar   := "SELECT * from colores order by CODIGO"
TRY
  oLamcla:oRsColore:=tOleAuto():New("ADODB.RecordSet")
CATCH oError
  MsgStop( "No se ha podido crear el RECORDSET !","Error de Datos" )
END

oLamcla:oRsColore:CursorLocation  := adUseClient //adUseServer
oLamcla:oRsColore:LockType        := adLockOptimistic
oLamcla:oRsColore:CursorType      := adOpenKeyset
oLamcla:oRsColore:Source          := oVar
oLamcla:oRsColore:ActiveConnection( oLamcla:oServer )


Pero quiero actualizar el recorset con la siguiente consulta:

oVar   := "SELECT * from colores order by NOMBRE"


Como lo hago?

De antemano gracias por las respuesta.
Saludos
LEANDRO AREVALO
Bogot谩 (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 682
Joined: Tue Feb 14, 2006 09:48 AM
Ejemplo del uso del un recorset con xbrowse
Posted: Wed Feb 20, 2008 08:30 AM
Si lo 煤nico que quieres cambiar es el orden de los registros que ya tienes seleccionados, la mejor opci贸n es utilizar el metodo Sort del recordset.
oRs:Sort:="NOMBRE ASC"

Esta es la manera m谩s rapida y obtima, ya que no implica trafico de red ni carga en el servidor.

En el supuesto que quieras cambiar la sentencia SELECT, el mecanismo seria el siguiente:
      ::oRs:Close()
      ::oRs:Source:="SELECT * from colores order by NOMBRE"
      ::oRs:Open()
      ::oRs:Refresh()
Saludos desde Mallorca
Biel Maim贸
http://bielsys.blogspot.com/