Page 1 of 1

Problema con Inkey y BKEYDOWN

Posted: Mon Mar 03, 2008 9:47 pm
by Ruben
Buenas tardes Antonio y Amigos del Foro, Saben tengo una duda referente a una búsqueda Tengo mi ListBox en donde tengo visualizado la lista de clientes de un dbf, en ese listbox quiero hacer una búsqueda por aproximación varios compañeros del foro me han dado sugerencias pero no he podido sacar este problemita. Quisiera que vieras el código y de favor me hicieras una sugerencia, soy principiante en la programación y pues algunas cosas que me comentan no las comprendo del todo bien, te envio el código de mi ListBox y de mis funciones.


Listbox

function BrwClientes()

local oDlg, oBrw, oBrow
local oLbx
local cVar
local n
local oDlg1
//modificar := .F.


local aHBitMaps:= { ReadBitmap( 0, "..\bitmaps\Level1.bmp" ), ; // BitMaps de 14 x 32
ReadBitmap( 0, "..\bitmaps\Level2.bmp" ), ;
ReadBitmap( 0, "..\bitmaps\Level3.bmp" ), ;
ReadBitmap( 0, "..\bitmaps\Level4.bmp" ),;
ReadBitmap( 0, "..\bitmaps\Level5.bmp" ) }

aXDts := {"5","40","30","30","5","40","13","20","12","1","3","12" }

USE Cat_cli

if RecCount() == 0
APPEND BLANK
endif

INDEX ON cat_cli->clave TO clave
SET INDEX TO clave

GO TOP

DEFINE DIALOG oDlg FROM 3, 3 TO 41, 85 TITLE "Administrador de Clientes"
@ 2, 2 SAY oSay PROMPT "Datos Generales"
@ 2, 3 say oSay Prompt "Generales" of oDlg

@ 0, 1 SAY " &LISTADO DE CLIENTES" OF oDlg
@ 10, 1 SAY " &DATOS GENERALES" OF oDlg
@ 10.5, 1.5 SAY "Clave" OF oDlg
@ 10.5, 5.5 SAY "Nombre" OF oDlg
@ 10.5, 33.5 SAY "RFC" OF oDlg
@ 12, 1.5 SAY "Calle" OF oDlg
@ 12, 22.5 SAY "Colonia" OF oDlg
@ 13.2, 1.5 SAY "Ciudad/Estado" OF oDlg
@ 13.2, 30 SAY "Código Postal" OF oDlg
@ 14.6, 1 SAY "Telefono" OF oDlg
@ 14.6, 15 SAY "Saldo" OF oDlg
@ 14.6, 23 SAY "Tipo" OF oDlg
@ 14.6, 25 SAY "Cve" OF oDlg
@ 14.6, 30 SAY "Importe" OF oDlg

@ 13, 1 get aXDts[1] OF oDlg UPDATE when .F. SIZE 20,12
//1 CLAVE
@ 13, 4 get aXDts[2] OF oDlg UPDATE when .F. SIZE 160,12
//2 NOMBRE
@ 14.5, 1 get aXDts[3] OF oDlg UPDATE when .F. SIZE
120,12 //4 CALLE
@ 14.5, 17 get aXDts[4] OF oDlg UPDATE when .F. SIZE
120,12 //5 COLONIA
@ 16, 1 get aXDts[6] OF oDlg UPDATE when .F. SIZE 160,
12 //6 CIUDAD
@ 16, 23 get aXDts[5] OF oDlg UPDATE when .F. SIZE 20,12
//7 CODIGO
@ 13, 25 get aXDts[7] OF oDlg UPDATE when .F. SIZE 52,12
//3 RFC
@ 17.5, 1 get aXDts[8] OF oDlg UPDATE when .F. SIZE
60,12 //8 TELEFONO
@ 17.5, 10 get aXDts[9] OF oDlg UPDATE when .F. SIZE
48,12 //9 SALDO
@ 17.5, 17 get aXDts[10] OF oDlg UPDATE when .F. SIZE
10,12 //10 TIPO
@ 17.5, 19 get aXDts[11] OF oDlg UPDATE when .F. SIZE
12,12 //11 CVE
@ 17.5, 22 get aXDts[12] OF oDlg UPDATE when .F. SIZE
52,12 //12 IMPORTE


@ 16, 1 SAY "Busqueda por Aproximación" OF oDlg
@ 19.5, 1 get aXDts[2] OF oDlg SIZE 160,12
oBrow:inkey:= {|nKey,nFlags| (ValidKeyClientes1(nKey,oDlg,oBrow,oGet),oBrow:Refresh())}



@ 1, 1 LISTBOX oLbx FIELDS;

alltrim( str( val( cat_cli->clave ) )), AllTrim( cat_cli->Nombre ),;
cat_cli->RFC;
HEADERS "CLAVE", "NOMBRE", "RFC";
FIELDSIZES 50, 300, 100;
ON CHANGE ( aXDts[1] := cat_cli->clave, aXDts[2] := cat_cli->Nombre, aXDts[3] := cat_cli->calle,;
aXDts[4] := cat_cli->colonia, aXDts[5] := cat_cli->codigo, aXDts[6] := cat_cli->ciudad,;
aXDts[7] := cat_cli->rfc, aXDts[8] := cat_cli->telefono, aXDts[9] := Transform(cat_cli->saldo,"999,999.99"),;
aXDts[10] := cat_cli->tipo, aXDts[11] := cat_cli->cve, aXDts[12] := Transform(cat_cli->impte,"999,999.99"),;
oDlg:Update() ) ;
SIZE 284, 137 OF oDlg



oLbx:aJustify = {.f., .f., .t.}

@ 15, 1 BUTTON "&Agregar" OF oDlg1 action cli_cap(.T.,oLbx) SIZE 40,
12
@ 15, 10 BUTTON "&Modificar" OF oDlg action cli_cap(.F., oLbx) SIZE 40,
12
@ 15, 21 BUTTON "&Borrar" OF oDlg ACTION DelClient( oLbx ) SIZE 40, 12
@ 15, 37 BUTTON "&Imprimir" OF oDlg SIZE 40, 12
//ACTION oLbx:Report( "clients Report", .t. ) ; // .t. --> wants preview
//SIZE 40, 12

@ 15, 47 BUTTON "&Salir" OF oDlg ACTION oDlg:End() SIZE 40, 12

ACTIVATE DIALOG oDlg

USE

AEval( aHBitmaps, { | hBmp | DeleteObject( hBmp ) } )

return nil



Y ESTA ES MI FUNCION

FUNCTION ValidKeyClientes1(nKey,oDlg,oBrow,oGet)
DO CASE
CASE (nKey>=48 .AND. nKey<=57) .OR. (nKey>=65 .AND. nKey<=90) .OR. nKey=8 .OR. nKey=32
IF oBrow:nColAct=1 .OR.
oBrow:nColAct=2
Select MAECLITE
IF oBrow:nColAct = 1

OrdSetFocus(1)
ELSEIF oBrow:nColAct = 2

OrdSetFocus(2)
ENDIF
DbGoTop()
IF nKey = 8

IF Len(oGet[9,2]) > 0

oGet[9,2] := Substr(oGet[9,2],1,Len(oGet[9,2])-1)

ENDIF
ELSE

oGet[9,2] += Chr(nKey)

oGet[9,1]:Refresh()
ENDIF
IF oBrow:nColAct = 1

//DbSeek(StrCeros(7,Val(oGet[9,2])))
ELSE

DbSeek(oGet[9,2])
ENDIF
ENDIF
ENDCASE
oBrow:Refresh()
RETURN


SI ME COMPILA Y NO ME MANDA NINGUN ERROR, EL DETALLE ES AL MOMENTO DE ABRIR EL LISTADO DE CLIENTES YA QUE ME ENVIA EL SIGUIENTE ERROR

Application
===========
Path and name: C:\APLICACIONES\CXC\cxc.Exe (32 bits)
Size: 1,486,848 bytes
Time from start: 0 hours 0 mins 2 secs
Error occurred at: 03/03/08, 13:22:25
Error description: Error BASE/1005 Class: 'NIL' has no property: INKEY
Args:
[ 1] = B {|| ... }

Stack Calls
===========
Called from: => _INKEY(0)
Called from: cxc.prg => BRWCLIENTES(232)
Called from: cxc.prg => (b)CREAMENU(50)
Called from: MENU.PRG => TMENU:COMMAND(0)
Called from: WINDOW.PRG => TWINDOW:COMMAND(0)
Called from: WINDOW.PRG => TWINDOW:HANDLEEVENT(0)
Called from: WINDOW.PRG => _FWH(0)
Called from: => WINRUN(0)
Called from: WINDOW.PRG => TWINDOW:ACTIVATE(0)
Called from: cxc.prg => MAIN(40)

Posted: Tue Mar 04, 2008 8:10 am
by Antonio Linares
Ruben,

Aqui tienes un ejemplo simple y típico de como hacer búsquedas incrementales en un browse:

Code: Select all

#include "FiveWin.ch"

REQUEST DBFCDX

function Main()

   local oWnd, oBrw, hBmp := ReadBitmap( CurDir() + "\go.bmp" )
   local oSay, cSearch := ""

   USE ( CurDir() + "\Customer" ) VIA "DBFCDX"
   if ! File( CurDir() + "\LAST.CDX" )
      INDEX ON Customer->Last TO ( CurDir() + "\LAST" )
   endif   
   Customer->( OrdSetFocus( "LAST" ) )
   Customer->( DbGoTop() )

   DEFINE WINDOW oWnd TITLE "IncSearch"
   
   @ 1, 1 LISTBOX oBrw ;
      FIELDS hBmp, Customer->Last, Customer->First ;
      HEADERS "", "Last", "First" ;
      SIZE 220, 167
   
   oBrw:bKeyChar = { | nKey, nFlags | Search( nKey, @cSearch ), oBrw:Refresh(), oSay:Refresh() } 
   
   @ 14,  2 SAY "Searching:" SIZE 60, 30
   @ 14, 12 SAY oSay PROMPT cSearch SIZE 80, 30
   
   ACTIVATE WINDOW oWnd
   
return nil

function Search( nKey, cSearch )

   if nKey = 8 
      cSearch = SubStr( cSearch, 1, Len( cSearch ) - 1 ) 
   else 
      cSearch += Upper( Chr( nKey ) ) 
   endif
    
   Customer->( DbSeek( cSearch, .t. ) ) 

return nil
En tu código no está definida la variable oBrow, ni los browses soportan el dato Inkey. Eso es precisamente lo que te indica el error.log:

Code: Select all

oBrow:inkey := ...

OK Antonio lo voy a probar

Posted: Tue Mar 04, 2008 2:13 pm
by Ruben
Muchas gracias Antonio, lo voy adaptar a mi PRG y si tengo alguna duda te lo hare saber.


Saludos desde Mexico

Trate de Adecuarlo pero me marca error

Posted: Tue Mar 04, 2008 2:51 pm
by Ruben
Trate de adecuar la funcion que me enviaste a mi prg pero me envia el siguiente error

Error description: Error BASE/1005 Class: 'NIL' has no property: BKEYCHAR

a que se debe????

te envio el codigo con mi adecuacion


function BrwClientes()

local oBrow, nKey, oGet
local oDlg, oBrw
local oLbx
local cVar
local n
local oDlg1


local aHBitMaps:= { ReadBitmap( 0, "..\bitmaps\Level1.bmp" ), ; // BitMaps de 14 x 32
ReadBitmap( 0, "..\bitmaps\Level2.bmp" ), ;
ReadBitmap( 0, "..\bitmaps\Level3.bmp" ), ;
ReadBitmap( 0, "..\bitmaps\Level4.bmp" ),;
ReadBitmap( 0, "..\bitmaps\Level5.bmp" ) }

aXDts := {"5","40","30","30","5","40","13","20","12","1","3","12" }

USE Cat_cli

if RecCount() == 0
APPEND BLANK
endif

INDEX ON cat_cli->clave TO clave
SET INDEX TO clave

cat_cli->(OrdSetFocus("Clave"))
cat_cli->(DbGoTop())

//GO TOP

DEFINE DIALOG oDlg FROM 3, 3 TO 41, 85 TITLE "Administrador de Clientes"
@ 2, 2 SAY oSay PROMPT "Datos Generales"
@ 2, 3 say oSay Prompt "Generales" of oDlg

@ 0, 1 SAY " &LISTADO DE CLIENTES" OF oDlg
@ 10, 1 SAY " &DATOS GENERALES" OF oDlg
@ 10.5, 1.5 SAY "Clave" OF oDlg
@ 10.5, 5.5 SAY "Nombre" OF oDlg
@ 10.5, 33.5 SAY "RFC" OF oDlg
@ 12, 1.5 SAY "Calle" OF oDlg
@ 12, 22.5 SAY "Colonia" OF oDlg
@ 13.2, 1.5 SAY "Ciudad/Estado" OF oDlg
@ 13.2, 30 SAY "Código Postal" OF oDlg
@ 14.6, 1 SAY "Telefono" OF oDlg
@ 14.6, 15 SAY "Saldo" OF oDlg
@ 14.6, 23 SAY "Tipo" OF oDlg
@ 14.6, 25 SAY "Cve" OF oDlg
@ 14.6, 30 SAY "Importe" OF oDlg

@ 13, 1 get aXDts[1] OF oDlg UPDATE when .F. SIZE 20,12 //1 CLAVE
@ 13, 4 get aXDts[2] OF oDlg UPDATE when .F. SIZE 160,12 //2 NOMBRE
@ 14.5, 1 get aXDts[3] OF oDlg UPDATE when .F. SIZE 120,12 //4 CALLE
@ 14.5, 17 get aXDts[4] OF oDlg UPDATE when .F. SIZE 120,12 //5 COLONIA
@ 16, 1 get aXDts[6] OF oDlg UPDATE when .F. SIZE 160, 12 //6 CIUDAD
@ 16, 23 get aXDts[5] OF oDlg UPDATE when .F. SIZE 20,12 //7 CODIGO
@ 13, 25 get aXDts[7] OF oDlg UPDATE when .F. SIZE 52,12 //3 RFC
@ 17.5, 1 get aXDts[8] OF oDlg UPDATE when .F. SIZE 60,12 //8 TELEFONO
@ 17.5, 10 get aXDts[9] OF oDlg UPDATE when .F. SIZE 48,12 //9 SALDO
@ 17.5, 17 get aXDts[10] OF oDlg UPDATE when .F. SIZE 10,12 //10 TIPO
@ 17.5, 19 get aXDts[11] OF oDlg UPDATE when .F. SIZE 12,12 //11 CVE
@ 17.5, 22 get aXDts[12] OF oDlg UPDATE when .F. SIZE 52,12 //12 IMPORTE


//oBrow:bkeychar := {|nKey,nFlags| (ValidKeyClientes1(nkey,oDlg,oBrow,oGet),oBrow:Refresh())}
oBrw:bKeyChar = { | nKey, nFlags | Search( nKey, @cSearch ), oBrw:Refresh(), oSay:Refresh() }
@ 16, 1 SAY "Busqueda por Aproximación" OF oDlg
@ 19.5, 1 SAY oSay PROMPT cSearch SIZE 80, 30
//@ 19.5, 1 get aXDts[2] OF oDlg1 SIZE 160,12 PICTURE "@K"

@ 1, 1 LISTBOX oLbx FIELDS;
alltrim( str( val( cat_cli->clave ) )), AllTrim( cat_cli->Nombre ),;
cat_cli->RFC;
HEADERS "CLAVE", "NOMBRE", "RFC";
FIELDSIZES 50, 300, 100;
ON CHANGE ( aXDts[1] := cat_cli->clave, aXDts[2] := cat_cli->Nombre, aXDts[3] := cat_cli->calle,;
aXDts[4] := cat_cli->colonia, aXDts[5] := cat_cli->codigo, aXDts[6] := cat_cli->ciudad,;
aXDts[7] := cat_cli->rfc, aXDts[8] := cat_cli->telefono, aXDts[9] := Transform(cat_cli->saldo,"999,999.99"),;
aXDts[10] := cat_cli->tipo, aXDts[11] := cat_cli->cve, aXDts[12] := Transform(cat_cli->impte,"999,999.99"),;
oDlg:Update() ) ;
SIZE 284, 137 OF oDlg

oLbx:aJustify = {.f., .f., .t.}

@ 15, 1 BUTTON "&Agregar" OF oDlg1 action cli_cap(.T.,oLbx) SIZE 40, 12
@ 15, 10 BUTTON "&Modificar" OF oDlg action cli_cap(.F., oLbx) SIZE 40, 12
@ 15, 21 BUTTON "&Borrar" OF oDlg ACTION DelClient( oLbx ) SIZE 40, 12
@ 15, 29 BUTTON "&Buscar" OF oDlg ACTION buscar_cli(oBrow) SIZE 40, 12
@ 15, 37 BUTTON "&Imprimir" OF oDlg SIZE 40, 12
//ACTION oLbx:Report( "clients Report", .t. ) ; // .t. --> wants preview
//SIZE 40, 12

@ 15, 47 BUTTON "&Salir" OF oDlg ACTION oDlg:End() SIZE 40, 12

ACTIVATE DIALOG oDlg

USE

AEval( aHBitmaps, { | hBmp | DeleteObject( hBmp ) } )

return nil

//**********************************************************************
function Search( nKey, cSearch )

if nKey = 8
cSearch = SubStr( cSearch, 1, Len( cSearch ) - 1 )
else
cSearch += Upper( Chr( nKey ) )
endif

cat_cli->( DbSeek( cSearch, .t. ) )

return nil

Posted: Tue Mar 04, 2008 5:30 pm
by Antonio Linares
Ruben,

Despues de estas líneas:

@ 1, 1 LISTBOX oLbx FIELDS;
...

es cuando has de hacer:

oLbx:bKeyChar = { | nKey, nFlags | Search( nKey, @cSearch ), oLbx:Refresh(), oSay:Refresh() }

Fíjate que estabas usando oBrw en vez de oLbx. Y es al objeto oLbx al que le tienes que asignar el dato bKeyChar

Aun no funciona

Posted: Tue Mar 04, 2008 6:00 pm
by Ruben
OK Antonio ya lo hice, lo coloque donde me comentaste pero no me ejecuta nada capturo una letra y no recorre la lista de nombres, no se ubica en el inicio de los nombres con esa letra



lo seguire checando

Posted: Tue Mar 04, 2008 11:22 pm
by Armando
Rubén:

Este es el PROCEDURE que uso, la verdad no recuerdo quien la puso en el foro :oops: , hace tanto tiempo de eso !.

PROCEDURE Busca(cKey,oLbx,nLong)
LOCAL nSeekRec := RECNO()
DEFAULT nLong := 0
IF nLong > 0
cKey := STR(VAL(cKey),nLong,0)
ENDIF
IF GETASYNCKEY(VK_BACK)
cKey := SUBSTR(cKey,1,LEN(cKey)-1)
ENDIF
SEEK cKey SOFTSEEK
IF ! FOUND()
GO nSeekRec
ENDIF
oLbx:REFRESH()
oLbx:oVScroll:SETPOS(RECNO())
RETURN


Y el get desde donde buscas es el siguiente:

REDEFINE GET oGet VAR cBusca ID 101 OF oDlg UPDATE;
PICTURE "@!K";
ON CHANGE(SELF:ASSIGN(),;
Busca(SUBSTR(cBusca,1,SELF:nPos-1)+UPPER(CHR(nKey)),oLbx),oLbx:REFRESH());
MESSAGE "Teclee el nombre del cliente que desea localizar"

Una condición es que el archivo donde vas a buscar debe tener un indice por el campo a buscar, en mi ejemplo busco el nombre del cliente entonces tengo un índice por el nombre del cliente.

Otra condición es que el campo a buscar debe ser alfanumerico, pero con algunos pequeños ajustes al procedure se logra buscar en un campo númerico.

Saludos

OK TKS

Posted: Wed Mar 05, 2008 6:31 pm
by Ruben
OK ARMANDO TRATARE DE ADECUAR ESTE PROCEDIMIENTO A MI PRG.
CUALQUIER COSAS QUE DE TE AVISO

SALUDOS

ATTE.
RUBEN