Estimado Jorge,
Es más fácil de lo que parece: la búsqueda incremental de TXBrowse se ejecuta a través del codeblock bSeek, que es un DATA
público y reemplazable (está declarado en source/classes/xbrowse.prg:169 con el comentario "block expression for autoincremental
search"). Cada datasource solo le pone un default (SetAdo asigna {|c| ::AdoIncrSeek(c)} en la lÃnea 7044), asà que basta con
asignar el tuyo después de cargar los datos.
Tenés dos caminos, según cómo estés trayendo los datos:
Opción 1 (recomendada si usás ADO): lIncrFilter + bFilterExp
En modo lIncrFilter := .t., AdoIncrSeek (xbrowse.prg:8213) evalúa bFilterExp con el texto tipeado y aplica lo que devuelvas como
oRs:Filter. O sea, no reconsultás al servidor: ADO filtra el recordset local, y tu bloque arma la condición multi-palabra.
oBrw:lIncrFilter := .t.
oBrw:bFilterExp := { | cSeek | FiltroStock( cSeek ) }
function FiltroStock( cSeek )
local cExpr := ""
local cWord
for each cWord in hb_ATokens( AllTrim( cSeek ), " " )
if ! Empty( cWord )
cExpr += If( Empty( cExpr ), "", " AND " ) + ;
"Descri LIKE '*" + StrTran( cWord, "'", "''" ) + "*'"
endif
next
// Ojo: con cSeek vacÃo hay que devolver algo siempre-verdadero,
// porque AdoIncrSeek solo toca oRs:Filter si cExpr no está vacÃo
return If( Empty( cExpr ), "1=1", cExpr )
Detalle importante: la propiedad Filter de ADO usa * (también acepta %) como comodÃn, no la sintaxis de SQL Server. El resultado
equivale a tu LIKE '%APLI%' AND LIKE '%350%' AND LIKE '%ZIO%'.
Opción 2 (cualquier datasource): reemplazar bSeek y reconsultar
Si preferÃs ir al servidor con tu SELECT exacto, asigná bSeek con tu función, que recibe el string tipeado y debe devolver .T.
si encontró algo (el método Seek() en xbrowse.prg:9798 evalúa ese bloque y hace el Refresh solo si devolvés verdadero):
oBrw:bSeek := { | cSeek | BuscarStock( oBrw, oCn, cSeek ) }
function BuscarStock( oBrw, oCn, cSeek )
local cWhere := ""
local cWord, oRs
for each cWord in hb_ATokens( AllTrim( cSeek ), " " )
if ! Empty( cWord )
cWhere += If( Empty( cWhere ), "", " AND " ) + ;
"s.Descri LIKE '%" + StrTran( cWord, "'", "''" ) + "%'"
endif
next
oRs := oCn:Execute( "SELECT * FROM dbo.Stock AS s " + ;
If( Empty( cWhere ), "", "WHERE " + cWhere ) + " ORDER BY s.Descri" )
if oRs:RecordCount > 0
oBrw:SetAdo( oRs ) // re-carga el browse con el nuevo recordset
return .t.
endif
return .f.
La opción 2 tiene sentido si la tabla es grande y no querés bajar todo el stock al recordset; para un ABM tÃpico, la opción 1
filtrando local es más fluida (una sola consulta al abrir).
Un par de notas:
• Asigná bSeek/bFilterExp después del SetAdo() (o del NewFrom... que uses), porque esos métodos pisan el default.
• Si tu fuente no es ADO (por ejemplo Dolphin/MySQL), bFilterExp no aplica — ahà usá la opción 2, o fijate que lSeekWild := .t.
ya te da LIKE '%texto%' pero solo con una palabra.
¿Con qué datasource estás trabajando en ese ABM (ADO recordset, conexión directa SQL Server, otra)? Si me pasás el fragmento
donde creás el xBrowse te lo dejo ajustado.