set filter con xbrowse da error

Post Reply
riesrovi
Posts: 18
Joined: Mon Oct 24, 2005 4:36 pm

set filter con xbrowse da error

Post by riesrovi »

Quisiera saber si hay solución para este error que sucede cuando se aplica un filtro usando un control xbrowse

******************************************
Application
===========
Path and name: C:\DATASOL\Datasol.Exe (32 bits)
Size: 3,490,304 bytes
Time from start: 0 hours 0 mins 19 secs
Error occurred at: 27/09/2008, 15:12:51
Error description: Error BASE/1004 No exported method: EVAL
Args:
[ 1] = L .T.

Stack Calls
===========
Called from: => EVAL(0)
Called from: C:\FWH808\source\classes\xbrowse.prg => TXBROWSE:DELREPOS(873)
Called from: C:\FWH808\source\classes\xbrowse.prg => TXBROWSE:REFRESH(836)
Called from: PROVEEDO.PRG => (b)DEFPROV(254)
Called from: .\source\classes\TIMER.PRG => TIMEREVENT(0)
Called from: WINDOW.PRG => (b)TWINDOW:TWINDOW(592)
Called from: => TWINDOW:TIMER(0)
Called from: => TWINDOW:HANDLEEVENT(0)
Called from: WINDOW.PRG => _FWH(3299)
Called from: => DIALOGBOX(0)
Called from: DIALOG.PRG => TDIALOG:ACTIVATE(270)
Called from: PROVEEDO.PRG => DEFPROV(723)
*********************************************

El filtro aplicado es " Set Filter to Sto->activo ", donde es un campo lógico.
Con wBrowse funciona perfecto.
Agradezco su ayuda
Ricardo
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Ricardo,

Prueba a aplicar el filtro asi:

SET FILTER TO Sto->activo == .T.

y a continuación haz:

MsgInfo( DbFilter() )

para comprobar que la expresión es la escrita

De paso comprueba que tengas esta línea en el método DelRepos() de la Clase TXBrowse y que no falte la "&":

bFilter := ( ::cAlias )->( &cFilter )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Este ejemplo funciona bien aqui:

Code: Select all

#include "FiveWin.ch" 
#include "XBrowse.ch" 

function Main() 

   local oWnd, oBrw, oCol, nRecords

   USE Customer 
   
   SET FILTER TO Left( Customer->First, 1 ) == "S"
   COUNT TO nRecords
   GO TOP

   DEFINE WINDOW oWnd 
    
   @ 0, 0 XBROWSE oBrw OF oWnd ALIAS "Customer" 
    
   oCol = oBrw:AddCol() 
   oCol:bStrData = { || Customer->First } 
   oCol:cHeader = "First" 
    
   oBrw:CreateFromCode() 
   oBrw:bKeyCount = { || nRecords }
   oBrw:VSetRange( 1, nRecords )
   oBrw:oVScroll:GoTop()
    
   oWnd:oClient = oBrw 

   ACTIVATE WINDOW oWnd 

return nil 
regards, saludos

Antonio Linares
www.fivetechsoft.com
riesrovi
Posts: 18
Joined: Mon Oct 24, 2005 4:36 pm

Parcialmente funcionó

Post by riesrovi »

Antonio, me funcionó de la forma que tu me sugieres, pero si utilizo macro en la lína de filtro me da el mismo error, pude notar que bfilter puede devolver una cadena de caracteres como valor lógico.
A mi browse le hago un filtro luego de creado para filtrar los clientes de una base de datos de acuerdo a lo que se ingrese, detallo mi función.
La función DelRePos() está correcta con el &


***************************
Static Function FiltroCO(oBrw,nCual)
***************************
Local nCant:=0
Local cTxt
Public cField

Default nCual to 1

if nCual=1
cTxt:="Filtrar clientes según detalle de Observación"
cfield:="observ"
elseif nCual=2
cTxt:="Filtrar clientes según el nombre"
cField:="nombre"
endif
m->cFiltroDbf:=space(20)

MsgGet(cTxt,"Filtro...",@m->cfiltroDbf)

m->cFiltroDbf := upper(cFiltroDbf)

DbSelectArea("CLI")

if !empty(m->cFiltroDbf)
set filter to at( alltrim( m->cFiltroDbf ) , cli->&( m->cField ) ) > 0
else
set filter to
release cField
endif
go top
if !empty( m->cFiltroDbf )
count to nCant
Msginfo( alltrim( str( nCant ) ) + " COINCIDENCIAS" , "...")
endif
DbGoTop()
oBrw:Refresh()
//////////////////
Return
//////////////////
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

> pero si utilizo macro en la lína de filtro me da el mismo error

Si, pues al aplicarle macro a una expresión que empieza por & dará error.

Me alegro que esté solucionado :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
riesrovi
Posts: 18
Joined: Mon Oct 24, 2005 4:36 pm

??

Post by riesrovi »

Antonio, no entendí tu comentario anterior cuanto dices que dará error si le aplico macro a la expresión que comienza por &, pero mi filtro es:at( alltrim( m->cFiltroDbf ) , cli->&( m->cField ) ) > 0, no comienza por macro, o solamente por tenér macro en algún lugar me dará siempre error ?
Qué me sugieres tu para poder realizar el filtro en este caso, he probado realizar un índice adicional con un for, pero el tiempo que demora en realizarlo es muy superior que el filtrado.
Agradezco mucho tu sugerencia y explicación sobre el error del filtro en este caso.

Ricardo
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Ricardo,

Da error pues la expresión contiene &.

Puedes cambiar:

at( alltrim( m->cFiltroDbf ) , cli->&( m->cField ) ) > 0

por:

at( alltrim( m->cFiltroDbf ) , cli->( FieldGet( FieldPos( m->cField ) ) ) ) > 0
regards, saludos

Antonio Linares
www.fivetechsoft.com
riesrovi
Posts: 18
Joined: Mon Oct 24, 2005 4:36 pm

Gracias...

Post by riesrovi »

Gracias por la sugerencia, la verdad que no se me había ocurrido.
Voy a probar.
Ricardo
riesrovi
Posts: 18
Joined: Mon Oct 24, 2005 4:36 pm

Todavía sin solución

Post by riesrovi »

Eduardo, el error persiste, pude ver que el valor de bFilter es lógico y al dejar la función como está da error porque intenta evaluar algo que no es bloque de código, le hice esta modificación y me está funcionando aparentemente.

METHOD DelRepos() CLASS TXBrowse

local lRepos := .f.
local cFilter, bFilter

if ::nDataType == DATATYPE_RDD
if ::nLen > 0
if Set( _SET_DELETED ) .and. ( ::cAlias )->( Deleted() )
( ::cAlias )->( dbSkip( 1 ) )
if ( ::cAlias )->( eof() )
( ::cAlias )->( DbGoBottom() )
endif
lRepos := .t.
elseif ! Empty( cFilter := ( ::cAlias )->( dbFilter() ) )
bFilter := ( ::cAlias )->( &cFilter )

//Modificación
if Valtype(bfilter)="C"
if &bFilter
( ::cAlias )->( dbSkip( 1 ) )
if ( ::cAlias )->( eof() )
( ::cAlias )->( DbGoBottom() )
endif
lRepos := .t.
endif

elseif valtype(bfilter)="L"
if bFilter
( ::cAlias )->( dbSkip( 1 ) )
if ( ::cAlias )->( eof() )
( ::cAlias )->( DbGoBottom() )
endif
lRepos := .t.
endif
elseif valtype(bFilter)="B"
//Fin de modificación

if ( ::cAlias )->( Eval( bFilter ) )
( ::cAlias )->( dbSkip( 1 ) )
if ( ::cAlias )->( eof() )
( ::cAlias )->( DbGoBottom() )
endif
lRepos := .t.
endif
* endif
endif
endif
endif

return lRepos
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Ricardo,

usando: SET FILTER TO Customer->Married

que es un campo lógico, el ejemplo que te hemos proporcionado funciona correctamente, sin necesidad de cambiar nada en la Clase TXbrowse.
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply