FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Ado - consulta en xbrowse
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 04:38 AM
ok, tengo la siguiente situación con ado
Code (fw): Select all Collapse
oRS:Source = " select * from ventas where fecha='2013-08-01' "

REDEFINE XBROWSE ... DATASOURCE oRS


hasta aca todo bien, pero como puedo hacer para que sin cerra el dialogo con el browese, cambiar el source del recordset y muestre otros datos, (cambio la fecha) pensaba algo asi:
Code (fw): Select all Collapse
function changeData( oBrw )
?oRS, oRS:Source //muestra los datos correctos
oRS:Source = " select * from ventas where fecha='2013-08-15' "  //aca falla indicando que oRS es indefinido
oRS:Requery()
oBrw:Refresh()
oBrw:Gotop()
return 0


pero falla indicando que oRS es invalido, aun cuando es una var statica y he validado su contenido.

intente haciendo un
Code (fw): Select all Collapse
oRS:Close()
oRS:Source = " select * from ventas where fecha='2013-08-15' "

pero ahi revienta el xbrowse
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 06:06 AM

1. In ADO we can not change oRs:Source and ReQuery. Requery() is possible only with the same Source ( SQL )

2. Switching Recordset of XBrowse dynamically during runtime:

Conditions:
a) All fields are identical in both RecordSets
b) Good xbrowse programming uses command syntax and you do not directly use oRs in your code.

Procedure:
Creating xbrowse first time

oRs:Open()
@ 0,0 XBROWSE oBrw DATASOURCE oRs COLUMNS "FIRST","LAST","SALARY" ................. etc

Switching:
Open new Recset
oNewRs:Open( ..... )
oBrw:GoTop()
oBrw:oRs := oRsNew
oRs:Close()
oBrw:Refresh()

Regards



G. N. Rao.

Hyderabad, India
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 02:46 PM

Rao, excelente.
thank you.

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 04:09 PM
Carlos:

Yo lo hago así y funciona bien:

Al principio de PRG abro la tabla creando el RecordSet considerando el mes y año actuales
y se crea el xBrowse, posteriormente el usuario puede elegir otro mes u otro año y el resultado
se muestra en el mismo browse. Este es el código donde se re crea el recordset:

Code (fw): Select all Collapse
            REDEFINE COMBOBOX aGets[01] VAR nMes ID 101 OF oDlg UPDATE;
                PROMPTS aMeses;
                ON CHANGE (FilHdr(oBrw),oBrw:SetFocus(),oBrw:GoTop(),oDlg:UPDATE());
                MESSAGE "Elija el nombre del mes de las facturas que desea mostrar"

            REDEFINE GET aGets[02] VAR nAmo ID 102 OF oDlg UPDATE;
                PICTURE "9999" SPINNER;
                ON CHANGE (FilHdr(oBrw),oBrw:SetFocus(),oBrw:GoTop(),oDlg:UPDATE());
                MESSAGE "Año de las facturas a mostrar"

........
........
.........
STATIC FUNCTION FilHdr(oBrw)
    IF oRsHdr <> NIL
        IF oRsHdr:State() = adStateOpen
            oRsHdr:Close()
        ENDIF
    ENDIF

    oRsHdr:Source               := "SELECT " +;
                                            "*," +;
                                            "Metodos.*," +;
                                            "Monedas.* " +;
                                        "FROM " +;
                                            "HdrFac " +;
                                        "LEFT JOIN " +;
                                            "Metodos " +;
                                        "ON " +;
                                            "Hdr_Mdp = Metodos.Met_Met " +;
                                        "LEFT JOIN " +;
                                            "Monedas " +;
                                        "ON " +;
                                            "Hdr_Mon = Monedas.Mon_Num " +;
                                        "WHERE " +;
                                            "YEAR(Hdr_Fde) = " + STR(nAmo,4,0) + " " +;
                                        "AND " +;
                                            "MONTH(Hdr_Fde) = " + STR(nMes,2,0) + " " +;
                                        "AND " +;
                                            "Hdr_Tip = 'FA' " +;
                                        "ORDER BY " +;
                                            "Hdr_Ser,Hdr_Num"

    TRY
        oRsHdr:Open()
        oRsHdr:Refresh()
    CATCH oError
        MsgStop( "No se ha podido abrir el RECORDSET de Encabezado de Facturas !", oApp:cAplicacion)
        ShowError(oError)
        RETURN(.F.)
    END

    oBrw:Refresh()
    oBrw:SetFocus()
    oBrw:GoTop()
RETURN(.T.)


Como ves, todo es con el mismo recordset y con el mismo xBrowse

Un detalle más, el recordset lo tengo definido como STATIC

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
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 04:22 PM

Mr Armando

Your method is
1. close recordset under browse
2. open recordset with new sql

This has risks:
1. If for some reason, browse is refreshed ( can happen for many reasons not in our control) after the recordset is closed, browse will crash with runtime error
2. if seond record set is not open, you can not keep the browse open.

I suggested in my post, safe way to switch the recordsets:

  1. Open new recordset
  2. Take browse to Top
  3. Assign new recordset to the browse
  4. Close old recordset

this order is safe

Regards



G. N. Rao.

Hyderabad, India
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 05:52 PM
rao,
este es mi prg de prueba, me ha funcionado como usted me indico, pero es de mi interés solamente usar una sola variable oRS, por que al igual que armando es una var estatica.
armando, usando tu logica que es la mas evidente me falla el browse al momento del cambio, es como indica rao. :-)

Code (fw): Select all Collapse
      oNRS := GetRecSet( "'2013-08-27'", "10" )
      oBrw:GoTop()
      oBrw:oRS := oNRS
      oRS:Close()      
      oBrw:Refresh()


ejemplo completo, uso ado con ads. es rapidísimo, mas que la version dbf

Code (fw): Select all Collapse
   @ 10,10 XBROWSE oBrw SIZE -10,-10 PIXEL OF oDlg ;
      COLUMNS "REVISADO","APROBADO","NUM_CLIE", "NOMBRE", "FECHA_SOLI", "FECHA_DESE", "PLAZO", "MONTO_SOLI", "MONTO_APRO","CIUDAD","RUTA" ;
      HEADERS "REVISADO","APROBADO","NUM_CLIE", "NOMBRE", "FECHA_SOLI", "FECHA_DESE", "PLAZO", "MONTO_SOLI", "MONTO_APRO","CIUDAD","RUTA" ;
      DATASOURCE oRS ;
      CELL LINES NOBORDER FOOTERS      
      
   WITH OBJECT oBrw
      :MONTO_SOLI:nFooterType        := AGGR_SUM
      :MONTO_APRO:nFooterType        := AGGR_SUM
      :bKeyDown                      := {|nKey| Editar( nKey, oBrw ) }
      :nStretchCol                   := 1      
      :MakeTotals()      
   END

   oBrw:CreateFromCode()
 
   ACTIVATE DIALOG oDlg CENTERED ON INIT oBrw:GoTop()
   
   RELEASE FONT oFont
   
   oRS:Close()
   oCon:Close()
   
return

static function ConnectToAdsSrv()
   local lConnect  := .f.   
   local oError, xError, cError := ""
   local cStrCon  := "Provider=Advantage OLE DB Provider;"+;
                     "Data Source=\\CREDICOM.NO-IP.ORG:6263\DATOS\CREDICOM.ADD;"+;
                     "ServerType=ADS_AIS_SERVER;"+;
                     "TableType=ADS_ADT;"+;
                     "LockMode=ADS_COMPATIBLE_LOCKING;"+;
                     "User ID=MyUsuario;"+;
                     "Password=MyClave;"   
   
   if oCon == nil
      oCon                  := TOleAuto():new("ADODB.Connection")
      oCon:ConnectionString := cStrCon      
      TRY
         oCon:Open()
         lConnect := .t.
      CATCH oError
         IF oCon:Errors:Count()>0
            FOR EACH xError IN oCon:Errors
               cError += CStr( xError:Source  ) + " / " + CStr( xError:Description ) + HB_OsNewLine()
            NEXT
            MsgAlert( cError, "Error en ADO" )
         ENDIF            
         oCon := nil
         MsgInfo('Connect Fail' + oError:description )        
      END
   else
      lConnect := .t.
   endif

return lConnect

static function GetRecSet( cFecha, cCiudad )
   local cStrSQL, oError, oRecSet
   
   cSQL := "SELECT P.REVISADO, P.APROBADO, P.NUM_CLIE, P.NOMBRE, P.FECHA_SOLI, P.FECHA_DESE, P.PLAZO, P.MONTO_SOLI, P.MONTO_APRO, P.NUM_CIUD, P.ADESEMBOLSO, " + ;
           "K.NOMCOR AS CIUDAD, J.NOMCOR AS RUTA " + ;
           "FROM PROGRAMACION P " + ;
           "LEFT OUTER JOIN CLIENTES AS C ON P.NUM_CLIE=C.NUM_CLIE " + ;
           "LEFT OUTER JOIN CIUDADES AS K ON C.NUM_CIUD=K.NUM_CIUD " + ;
           "LEFT OUTER JOIN RUTAS    AS J ON C.NUM_RUTA=J.NUM_RUTA " + ;
           "WHERE FECHA_SOLI=%1 AND P.NUM_CIUD=%2 AND P.ADESEMBOLSO<>TRUE "
   cStrSQL := StrFormat( cSQL, cFecha, cCiudad )
   
   if oCon != nil
      oRecSet                     := TOleAuto():new( "ADODB.RecordSet" )
      oRecSet:ActiveConnection    := oCon
      oRecSet:Source              := cStrSQL
      oRecSet:LockType            := adLockOptimistic
      oRecSet:CursorType          := adOpenKeyset
      oRecSet:CursorLocation      := adUseClient
      oRecSet:CacheSize           := 100
      TRY
         oRecSet:Open()
         oRecSet:Sort := "NOMBRE"
      CATCH oError
         oRecSet := NIL
         MsgInfo('Access Table Open Failure - ' + oError:description )
      END
      
   endif  
   
return oRecSet

procedure editar( nKey, oBrw )
   local cDato, nPos 
   local cStrSQL
      
   IF nKey == 13
      nPos := oRS:AbsolutePosition
      cDato := oRS:Fields( "NOMBRE" ):Value
      IF MsgGet( "Titulo", "Text", @cDato )
         oRS:Fields( "NOMBRE" ):Value := cDato
         oRS:Update()
         oRS:Requery()
         oRS:AbsolutePosition := nPos
      ENDIF
   ELSEIF nKey == 65 // usuario presiono A
      oNRS := GetRecSet( "'2013-08-27'", "10" )
      oBrw:GoTop()
      oBrw:oRS := oNRS
      oRS:Close()      
      oBrw:Refresh()
   ENDIF      
      
return   

init procedure PrgInit

   SET DATE BRIT
   SET CENTURY ON
   SET TIME FORMAT TO "HH:MM:SS"
   SET EPOCH TO YEAR(DATE())-50

   SET DELETED ON
   SET EXCLUSIVE OFF

   RDDSETDEFAULT( "DBFCDX" )

return
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 06:53 PM
#1) Can you please let me know the version of FWH you are using?
After you reply I shall post an improved working sample

#2) I use google translate to understand your posting. Did you say you are using one static variable oRs and use oRs in the program to refer to the recordset being browsed?

If so you can do
(a) Add one line in this code
Code (fw): Select all Collapse
  ELSEIF nKey == 65 // usuario presiono A
      oNRS := GetRecSet( "'2013-08-27'", "10" )
      oBrw:GoTop()
      oBrw:oRS := oNRS
      oRS:Close()      
      oBrw:Refresh()
      oRs := oBrw:oRs  // Add this line here
  ENDIF

Then rest of your code will work normally.

Some other advices:
1. After modifying a field is NOT necessary or desirable to call ReQuery(). It is not a good practice to call Requery() except when it is "essential". This is a very slow operation.

2. If you want to refer to oRs in program code, it is always better to use oBrw:oRs
Example
Instead of oRs:fields( 2 ):Value
Use oBrw:oRs:Fields( 2 ):Value
This habit of coding enables swithing oRs at runtime easier.

3. As far as possible, you may use built in edit features of xbrowse.

I can advise better if I know your version of FWH
Regards



G. N. Rao.

Hyderabad, India
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 08:02 PM

fwh 13.02, xharbour, bcc650

salu2
carlos vargas

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 08:10 PM
carlos vargas wrote:fwh 13.02, xharbour, bcc650

salu2
carlos vargas

Thanks for the info.

Have you read my posting above? ( revised).
Does it help you?

In your version, the inbuilt edit of ado browse should work well. Edited values are automatically saved and updated without your having to write code.
Regards



G. N. Rao.

Hyderabad, India
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Thu Aug 29, 2013 08:25 PM

rao,

probare esta noche y dejo comentarios.

gracias por el soporte.

salu2
carlos vargas

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Fri Aug 30, 2013 03:18 AM
Rao,
is working well. It is wonderful how quickly ado. I have a question, as I change the source of the query, the application consumption is rising more and more. I think it is reference previous consultations. I modified the code a bit you could take a peek.
Code (fw): Select all Collapse
procedure editar( nKey, oBrw )
   local cDato, nPos 
   local cStrSQL, oNewRS
      
   IF nKey == 13
      nPos := oRS:AbsolutePosition
      cDato := oRS:Fields( "NOMBRE" ):Value
      IF MsgGet( "Titulo", "Text", @cDato )
         oRS:Fields( "NOMBRE" ):Value := cDato
         oRS:Update()
      ENDIF
      oBrw:RefreshCurrent()
   ELSEIF nKey == 65
      oNewRS := GetRecSet( MsgDate( date() ) , 10 )
      oBrw:GoTop()
      oBrw:oRS := oNewRS
      oRS:Close()
      oRS:=NIL
      oBrw:Refresh()
      oBrw:MakeTotals()
      oRS := oBrw:oRS
      oNewRS := NIL      
   ENDIF      
      
return
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Fri Aug 30, 2013 03:31 AM
memory up. :-)

Code (fw): Select all Collapse
      oBrw:GoTop()
      oBrw:oRS := GetRecSet( MsgDate( date() ) , 10 )
      oRS:Close()
      oRS:=NIL
      oRS := oBrw:oRS      
      oBrw:MakeTotals()
      oBrw:GoTop()
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Fri Aug 30, 2013 03:45 AM
Code (fw): Select all Collapse
#include "FiveWin.Ch"
#include "xbrowse.ch"
#include "adodef.ch"

REQUEST DBFCDX

static oCon
static cSQL

memvar oRS

procedure Main()
   local oDlg, oBrw, oFont
   private oRS
   
   DEFINE FONT oFont NAME 'TAHOMA' SIZE 0,-12  
   
   IF ConnectToAdsSrv()
      oRS := GetRecSet( date(), 10 )
      IF oRS == NIL
         oCon:Close()
         return
      ENDIF         
   ENDIF      
   
   DEFINE DIALOG oDlg SIZE 900, 500 PIXEL FONT oFont
 
   @ 10,10 XBROWSE oBrw SIZE -10,-10 PIXEL OF oDlg ;
      COLUMNS "REVISADO","APROBADO","NUM_CLIE", "NOMBRE", "FECHA_SOLI", "FECHA_DESE", "PLAZO", "MONTO_SOLI", "MONTO_APRO","CIUDAD","RUTA" ;
      HEADERS "REVISADO","APROBADO","NUM_CLIE", "NOMBRE", "FECHA_SOLI", "FECHA_DESE", "PLAZO", "MONTO_SOLI", "MONTO_APRO","CIUDAD","RUTA" ;
      DATASOURCE oRS ;
      CELL LINES NOBORDER FOOTERS      
      
   WITH OBJECT oBrw
      :MONTO_SOLI:nFooterType        := AGGR_SUM
      :MONTO_APRO:nFooterType        := AGGR_SUM
      :bKeyDown                      := {|nKey| Editar( nKey, oBrw ) }
      :nStretchCol                   := 1      
      :MakeTotals()      
   END

   oBrw:CreateFromCode()
 
   ACTIVATE DIALOG oDlg CENTERED ON INIT oBrw:GoTop()
   
   RELEASE FONT oFont
   
   oRS:Close()
   oCon:Close()
   
return

static function ConnectToAdsSrv()
   local lConnect  := .f.   
   local oError, xError, cError := ""
   local cStrCon  := "Provider=Advantage OLE DB Provider;"+;
                     "Data Source=\\CREDICOM.NO-IP.ORG:6260\DATOS\CREDICOM2.ADD;"+;
                     "ServerType=ADS_AIS_SERVER;"+;
                     "TableType=ADS_ADT;"+;
                     "LockMode=ADS_COMPATIBLE_LOCKING;"+;
                     "User ID=Usuario;"+;
                     "Password=Clave;"   
   
   if oCon == nil
      oCon                  := TOleAuto():new("ADODB.Connection")
      oCon:ConnectionString := cStrCon      
      TRY
         oCon:Open()
         lConnect := .t.
      CATCH oError
         IF oCon:Errors:Count()>0
            FOR EACH xError IN oCon:Errors
               cError += CStr( xError:Source  ) + " / " + CStr( xError:Description ) + HB_OsNewLine()
            NEXT
            MsgAlert( cError, "Error en ADO" )
         ENDIF            
         oCon := nil
         MsgInfo('Connect Fail' + oError:description )        
      END
   else
      lConnect := .t.
   endif

return lConnect

static function GetRecSet( dFecha, nCiudad )
   local cStrSQL, oError, oRecSet
   
   IF cSQL == NIL
      cSQL := "SELECT P.REVISADO, P.APROBADO, P.NUM_CLIE, P.NOMBRE, P.FECHA_SOLI, P.FECHA_DESE, P.PLAZO, P.MONTO_SOLI, P.MONTO_APRO, P.NUM_CIUD, P.ADESEMBOLSO, " + ;
              "K.NOMCOR AS CIUDAD, J.NOMCOR AS RUTA " + ;
              "FROM PROGRAMACION P " + ;
              "LEFT OUTER JOIN CLIENTES AS C ON P.NUM_CLIE=C.NUM_CLIE " + ;
              "LEFT OUTER JOIN CIUDADES AS K ON C.NUM_CIUD=K.NUM_CIUD " + ;
              "LEFT OUTER JOIN RUTAS    AS J ON C.NUM_RUTA=J.NUM_RUTA " + ;
              "WHERE FECHA_SOLI=%1 AND P.NUM_CIUD=%2 AND P.ADESEMBOLSO<>TRUE "
   ENDIF
   
   cStrSQL := StrFormat( cSQL, Data2ADO( dFecha ), Data2ADO( nCiudad ) )
   
   if oCon != nil
      oRecSet                     := TOleAuto():new( "ADODB.RecordSet" )
      oRecSet:ActiveConnection    := oCon
      oRecSet:Source              := cStrSQL
      oRecSet:LockType            := adLockOptimistic
      oRecSet:CursorType          := adOpenKeyset
      oRecSet:CursorLocation      := adUseClient
      oRecSet:CacheSize           := 100
      TRY
         oRecSet:Open()
         oRecSet:Sort := "NOMBRE"
      CATCH oError
         oRecSet := NIL
         MsgInfo('Access Table Open Failure - ' + oError:description )
      END
      
   endif  
   
return oRecSet

procedure editar( nKey, oBrw )
   local cDato, nPos 
   local cStrSQL, oNewRS
      
   IF nKey == 13
      nPos := oRS:AbsolutePosition
      cDato := oRS:Fields( "NOMBRE" ):Value
      IF MsgGet( "Titulo", "Text", @cDato )
         oRS:Fields( "NOMBRE" ):Value := cDato
         oRS:Update()
      ENDIF
      oBrw:RefreshCurrent()
   ELSEIF nKey == 65 
      oBrw:GoTop()
      oBrw:oRS := GetRecSet( MsgDate( date() ) , 10 )
      oRS:Close()
      oRS:=NIL
      oRS := oBrw:oRS      
      oBrw:MakeTotals()
      oBrw:GoTop()     
   ENDIF      
      
return   

init procedure PrgInit

   SET DATE BRIT
   SET CENTURY ON
   SET TIME FORMAT TO "HH:MM:SS"
   SET EPOCH TO YEAR(DATE())-50

   SET DELETED ON
   SET EXCLUSIVE OFF

   RDDSETDEFAULT( "DBFCDX" )

return

FUNCTION Data2ADO( xValue )
   LOCAL cValue := "''"

   DO CASE
   CASE HB_IsString( xValue )
      cValue := "'" + xValue + "'"
   CASE HB_IsNumeric( xValue )
      cValue := AllTrim( CStr( xValue ) )
   CASE HB_IsLogical( xValue )
      cValue := IIf( xValue, 'True', 'False' )
   CASE HB_IsDate( xValue )
      cValue := "'" + Transform(  DToS( xValue ), "@R 9999-99-99" )  + "'"
   CASE HB_IsDateTime( xValue )
      cValue := "'" + Transform(  TToS( xValue ), "@R 9999-99-99 99:99:99" ) + "'"
   CASE HB_IsNil( xValue )
      cValue := "'NULL'"
   ENDCASE

RETURN cValue
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Ado - consulta en xbrowse
Posted: Fri Aug 30, 2013 03:49 AM

Yes, setting oRs and oNewRs to nil is Good :)
Hope everything is working fine.

Regards



G. N. Rao.

Hyderabad, India
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Ado - consulta en xbrowse
Posted: Fri Aug 30, 2013 02:24 PM

rao,
memory continues to increase. :-(

salu2

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)