Página 1 de 2

pesquisa um nome concatenado com data de nascimento !!!!

Enviado: 18 Fev 2008 15:10
por mmaciel11
Ola a todos,


AMIGOS em clipper eu tenho uma funcao de procurar paciente assim

seek alltrim(nome)+dtos(dt_nasc)
If Found()
MsgStop("Paciente ja cadastrado")
Else
MsgStop("Inclusão de Paciente")
Endif


O meu INDICE esta ASSIM :

index on str(codpac,7) TAG pacient1 TO (_caminho)+'paciente.cdx'
index on nome TAG pacient2 TO (_caminho)+'paciente.cdx'
index on alltrim(nome)+dtos(dt_nasc) TAG pacient3 TO (_caminho)+'paciente.cdx'


UM DETANHE QUANDO MANDO PROCURAR POR NOME DA LEGALZINHO

MAIS QUANDO PROCURAR NOME+DATA DE NASCIMENTO..


FICO NO AGUARDO.


MARCO MACIEL

Enviado: 18 Fev 2008 16:33
por Maligno
Se você permite que incluam nomes em maiúsculas e/ou minúsculas, sua chave deveria ser armazenada sempre em maiúsculas OU minúsculas, justamente pra evitar problemas na pesquisa. É o seu caso?

De resto, à primeira vista, não vejo nada de errado. Eu ia perguntar se você está mudando de índice na hora da pesquisas, mas isso não precisa perguntar, né? :)

Enviado: 19 Fev 2008 09:29
por mmaciel11
amigo maligo,

armazeno tudo em maiusculo e mudo sim o indice vou postar meu codigo:

// MEU INDICE---------------------*
Function UsePacientes()
* CriaAliasDBF(DBF,alias)
If !file(_caminho+'paciente.dbf')
MsgStop('Banco de Dados PACIENTE.DBF não existe','Banco de Dados')
Return(.f.)
Endif

If !file(_caminho+'paciente.Cdx')
If CriaAliasDbf('paciente','Paciente',.f.)
index on str(codpac,7) TAG pacient1 TO (_caminho)+'paciente.cdx'
index on nome TAG pacient2 TO (_caminho)+'paciente.cdx'
index on alltrim(nome)+dtos(dt_nasc) TAG pacient3 TO (_caminho)+'paciente.cdx'
Endif
DbCloseArea()
Endif

If CriaAliasDbf('paciente','Paciente',.t.)
Set Index to (_caminho)+'paciente.cdx'
Endif
Return(nil)
*-------------------------------------*




*** minha procura

DbSelectArea('Paciente')
OrdSetFocus('Pacient3')
Paciente->(DbGoTop())

** so pra mostrar se o paciente é o mesmo digitado na textbox
MsgStop(frm_PACIENTE_Novo.txt_nome.Value +' '+dtoc(frm_PACIENTE_Novo.txt_dt_nasc.value))

Seek alltrim(frm_PACIENTE_Novo.txt_nome.Value)+dtos(frm_PACIENTE_Novo.txt_dt_nasc.value)

If Found()
MsgStop(Paciente->nome +' '+dtoc(Paciente->dt_nasc))
Else
MsgStop('Paciente nao cadastrado)
Endif


MALIGNO QUAL O COMANDO QUE VEJO QUAL O INDICES ESTOU USANDO ??

Enviado: 19 Fev 2008 10:13
por Maligno
mmaciel11 escreveu:MALIGNO QUAL O COMANDO QUE VEJO QUAL O INDICES ESTOU USANDO ??
A própria função OrdSetFocus(). Sem parâmetro ela só mostra a tag selecionada.

Confira os nomes digitados. Se eles estão ok. Não parece ter nada errado com o código em si. Acho que o problema está é na digitação. Se faltar uma letra no final do nome, por exemplo, não vai encontrar na tag 3 (a que tem a data). Mas mesmo faltando uma letra, vai encontrar na tag 1 (a que só tem o nome). Portanto, dê uma conferida nisso.

Enviado: 19 Fev 2008 11:00
por mmaciel11
ja fiz de tudo ... o indice selecionado e o pacient3 ... vou fazer uma gambiarra ...

obrigado... se alguem tiver algum exemplo pratico por favor postem... obrigado maligno pela atencao... vc é o maximo.
]
abraços

Enviado: 19 Fev 2008 11:10
por Pablo César
mmaciel, eu acho que o seu erro está ao utilizar ALLTRIM(nome) como chave de indexação (isso é um crime). Principalmente quando você precisa a segunda chave (que seria a data de nascimento). Quando se fala em indexar data, não tem nada melhor que indexar com DTOS() no padrão AAAAMMDD. Essa chave (data de nascimento), não faz com que o registro seja único, portanto você deveria re-avaliar a necessidade de indexar por data. Assim como ja disse o colega Maligno.

Você poderia indexar por NOME e despois de localizado o nome seguiria num DO WHILE comparando os seguinte registros que tenha NOMES iguais e com tal data.

Enviado: 19 Fev 2008 11:31
por Maligno
À parte das alternativas, o fato é que string é string. Com AllTrim() ou não. Um caso prático:

Código: Selecionar todos

Valores digitados pelo usuário:
nome = "   Pablo Cesar  "
data = 19/02/2008

Valores gravados no banco de dados:
nome = "Pablo Cesar         "
data = 19/02/2008

Chave do índice, pela expressão alltrim(nome)+dtos(data):
"Pablo Cesar20080219"

String utilizada na pesquisa (usa a mesma expressão):
"Pablo Cesar20080219"
Conforme ilustrado, se for feita a pesquisa pelo que o usuário digitou, o registro será encontrado. Agora, conforme comentei antes, se o usuário digitar "Pablo Cesa" (faltando o R final), a pesquisa falhará. Por outro lado, se a pesquisa for apenas por nome, essa mesma string "mutilada" será bem sucedida.

Portanto, não será alltrim() o vilão da história. O problema está em outro lugar. Provavelmente uma coisa pequena, fruto da distração do nosso colega. Essas coisas acontecem o tempo todo. :)

Críticas quanto ao procedimento em si não resolvem o problema original, mas...
Particularmente, eu jamais faria uma pesquisa desse tipo, pois ela precisa que o usuário digite o nome totalmente correto. E usuário sempre erra. Prefiro usar um número de documento. RG que seja. Melhor seria CPF, que segue um formato nacional.

Enviado: 19 Fev 2008 11:32
por MARCELOG
Olá pessoal,
lá vai eu falando bobagem de novo.

Se vc criou o índice com alltrim(upper((cnome + dtos(dnasc))), o seu índice ficou +/- assim:

MARCELO GIOVANE19800101 (nome maiúsculo e data normal como string sem espaço no ínicio ou fim).

Então confira se o argumento de pesquisa se parece com isso.

É que, "MARCELO GIOVANE 19800101" não vai funcionar (tem espaço entre o final do nome e data).

Da mesma forma "MARCELOGIOVANE19800101" também não, pois tá tudo junto, etc.

Acho que indexkey() ou &indexkey() vai retornar a chave pesquisada, confira o seu formato e adeqüe se necessário.

Como na sua função você faz referencia a dtoc e dtos, também pode ser esse o problema.

Espero ter ajudado.

MarceloG

Enviado: 19 Fev 2008 11:39
por Maligno
MARCELOG escreveu:Se vc criou o índice com alltrim(upper((cnome + dtos(dnasc))), o seu índice ficou +/- assim:

MARCELO GIOVANE19800101 (nome maiúsculo e data normal como string sem espaço no ínicio ou fim).
Exatamente. Upper() é importante também para evitar os erros do usuário ao digitar o nome. É outra fonte de problema que se soma ao que informei antes.
É que, "MARCELO GIOVANE 19800101" não vai funcionar (tem espaço entre o final do nome e data).
Funcionará se a expressão da pesquisa for igual a expressão da chave.
Da mesma forma "MARCELOGIOVANE19800101" também não, pois tá tudo junto, etc.
Funcionará também. Pelo mesmo motivo. :)

Não importa o que se grava na chave do índice, desde que o procedimento para obter a string a pesquisar seja exatamente o mesmo. Se é o nome invertido, tudo bem. É só inverter também na pesquisa. :)

Agora, é claro que há procedimentos mais suscetíveis a erros, já que existe uma interação com o usuário. Como usuário sempre erra, é muito mais fácil já brecar os erros na formação da expressão da chave de indexação. É a finalidade do Upper(), por exemplo.
Como na sua função você faz referencia a dtoc e dtos, também pode ser esse o problema.
O uso de DTOS() está correto. Mas DTOC() ele só usou para imprimir uma mensagem no vídeo. Para efeito de teste, creio eu. :)

Enviado: 19 Fev 2008 14:50
por mmaciel11
O uso de DTOS() está correto. Mas DTOC() ele só usou para imprimir uma mensagem no vídeo. Para efeito de teste, creio eu. :)

realmente usei o dtoc so pra impressao.


Você poderia indexar por NOME e despois de localizado o nome seguiria num DO WHILE comparando os seguinte registros que tenha NOMES iguais e com tal data.

VOU FAZER ASSIM MESMO... APESAR QUE EM CLIPPER... EU UTILIZO A 20 ANOS E NAO DAR PROBLEMA TENHO UM BANCO DE DADOS SEM DUPLICACAO DE NOME (HOMONIMOS EM BANCO DE DADOS)


OBRIGADO A TODOS.

Enviado: 19 Fev 2008 14:56
por Maligno
Conselho de amigo: nunca desconsidere o erro do usuário. É dele que partem os piores erros. Mesmo usando o esquema do WHILE sua pesquisa pode falhar na identificação de um usuário que já existe. Exemplo: LUIZ e LUIS. São a mesma pessoa, mas o digitador errou na última letra. Por conta disso, você acabará incluindo quem já está cadastrado. Por isso eu sempre prefiro checar identidade pelo número de algum documento.

Enviado: 19 Fev 2008 15:06
por mmaciel11
certo..

Enviado: 19 Fev 2008 17:53
por mmaciel11
duvida !!!

@ 035,130 TEXTBOX TXT_nome width 290 maxlength 40 uppercase

Seek Alltrim(frm_PACIENTE_Novo.txt_nome.Value)+dtos(frm_PACIENTE_Novo.txt_dt_nasc.value)

existe alguma diferenca de receber os dados com TXT_nome ou seja TXT maisculo e procurar no seek com txt_nome ... txt minusculo

isso influencia ???

Enviado: 19 Fev 2008 17:58
por Maligno
Influencia e muito. Cada caractere na tabela ASCII tem um valor numérico. Uma letra maiúscula tem valor diferente da mesma letra minúscula. A pesquisa é sempre feita por comparações numéricas. Portanto, tanto a string a pesquisar como a chave montada no índice devem ter uma mesma caixa, seja ela maiúscula ou minúscula.

Enviado: 20 Fev 2008 10:49
por MARCELOG
Caro amigo,
pelo jeito você está usando a minigui e obtendo os argumentos de pesquisa com um textbox, certo?

Então, use alltrim() nos argumentos para retirar espaços no início ou fim do texto para formatá-lo.

Outro detalhe, se você pega a data como texto, transforme-a em data e depois string para a pesquisa.

Ex:
20/01/2008 vira 20080120, que vira '20080120' certo?
...
cnome :=upper(alltrim(form.txtnome.value))
cdata := upper(dtos(ctod(alltrim(form.txtnome.value))))

alias->(dbseek(cnome+cdata))

Tem funcionar uai!

MarceloG

Ps: se dt_nasc é realmente um campo data, mude o índice para:

index on upper(alltrim(nome)+dtos(dt_nasc)) TAG pacient3 TO (_caminho)+'paciente.cdx'