Indices por Relacionamento

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Avatar do usuário
Clash
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 11 Set 2004 11:14
Localização: Divinópolis (MG)

Indices por Relacionamento

Mensagem por Clash »

Olá amigos,

O Clipper mais uma vez me surpreendendo! Então resolvi compartilhar com vocês.

Em relatórios, costumo usar índices temporários, uma vez que não acontecerá alterações nos dados da tabela, pois é só consulta, serão descartados. (Respeitando a aula me passada pelo amigo Rochinha na importância de índices, mesmo temporários, acompanhar os índices principais uma vez que utilizados em alterações). Bom mas continuando...

Em um relatório do Controle de Caixa, eu precisava separar documentos, por data e por situação/tipo (débito ou crédito) e ainda permitir ao usuário, escolher a ordem da listagem, por documento ou por emitente (alfabética), só que na tabela de CAIXA eu só armazeno o código ( COD_EMIT ).

Daí já fui logo pensando... -"Nossa, terei que criar uma tabela temporária, cópia da tabela CAIXA, porém com um campo EMITENTE para assim armazenar o nome. Mais tabelas temporárias, não!!" Então, pensei eu já relacionava a tabela CAIXA com CLIENTES para no DbEdit eu exibir o nome do EMITENTE, porque não tentar indexar por este relacionamento. Não é que deu certo!! Me preocupei se não ia bagunçar os índices nativos da tabela CLIENTES, mas não, está perfeito.

Vou tentar explicar mais durante o código...

Código: Selecionar todos

*----------------*      && RELATORIO DO CAIXA &&
PROCEDURE SCA0864
Save Screen to Rel0864
Sombra(12,09,18,63,tCorMold6,8)
Set Cursor On
nCodConta  := 0
dData_Ini    := Ctod("")
dData_Fim  := Ctod("")
cSituacao    := " "
cEntre_Dta  := "N"
cResumido   := "N"
cOrdem       := "1"
cExpressao  := ""
cConfirma   := "N"
Do While .t.
   **
   ** Monto a Tela para Solicitar as Opções **
   **
   @ 13,30 Say "(D)ébitos / (C)réditos / (A)mbos"
   @ 14,30 Say "(S)im / (N)ão"
   @ 15,30 Say "(S)im / (N)ão"
   @ 16,30 Say "(1) Emitente / (2) Documento"
   @ 17,30 Say "(S)im / (N)ão"
   **
   ** Agora os GET´s **
   **
   @ 13,10 Say "Tipo Documento:" Get cSituacao  Pict "!" Valid PROC_TIPO(cSituacao)
   @ 14,10 Say "Entre Datas...:" Get cEntre_Dta Pict "!" Valid PROC_CTDTA(cEntre_Dta)
   @ 15,10 Say "Totalizado....:" Get cResumido  Pict "!" Valid cResumido$"SN"
   @ 16,10 Say "Ordenado por..:" Get cOrdem     Pict "!" Valid cOrdem$"12"
   @ 17,10 Say "Confirma......:" Get cConfirma  Pict "!" Valid cConfirma$"SN"
   Read
   If Lastkey() == 27  &&--> Para sair do Loop de Confirmação das Opções pelo Usuário e sair da Rotina
      DBCLOSEALL()
      Exit
   EndIf
   If cConfirma == "N"
      Loop
   EndIf
   Exit
EndDo  &&--> Loop caso o Usuário não Confirme as Opções
*
If Lastkey() == 27 
   Rest Screen From Rel0864
   Return
Endif
*
* Aqui monto uma expressão para usar como condicional na criação do índice temporário
*
If cSituacao <> "A"
   cExpressao := "CAIXA->TIPO == '" + cSituacao + "'" + " "
EndIf
If cEntre_Dta <> "N"
   cExpressao := "CAIXA->DATA >= dData_Ini .and. CAIXA->DATA <= dData_Fim"
EndIf
*
Select 0
ABREARQ("CLIENTES", .t., "CLIENTES")
ORDSETFOCUS("CODIGO")
*
Select 0
ABREARQ("CAIXA", .t., "CAIXA")
Set Relation to COD_EMIT into CLIENTES   &&-->Relaciomento da Tabela CAIXA com CLIENTES.
*
If cOrdem == "1"  &&-->Ordem por Emitente (Alfabética)
   *
   Index on CLIENTES->NOME to &tLocal\TPCAIXA for &cExpressao    &&--> E aqui usei o Índice relacionado
   *
 ElseIf cOrdem == "2" &&-->Ordem por Documento (Numérica)
   *
   Index on NOTA to &tLocal\TPCAIXA for &cExpressao
   *
EndIf
Go Top
*
** Daqui para baixo monto o relatório.
*
Tentei deixar da forma mais clara possível, mas qualquer dúvida, estou a disposição.

Abraço aos amigos do fórum e VIVA o CLIPPER!!!
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Indices por Relacionamento

Mensagem por Pablo César »

Isso ai ! :)
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
billy1943
Usuário Nível 4
Usuário Nível 4
Mensagens: 570
Registrado em: 12 Mai 2009 17:33
Localização: Bauru-SP

Indices por Relacionamento

Mensagem por billy1943 »

O nosso amigo usou aquilo que sempre aparece na "área cinzenta" do Clipper, ou seja, o comando SET RELATION e uma utilização para o DBEDIT, o qual uso a larga em meus sistemas, ao contrário do TBROWSE.

Apenas acresceria que o comando SET RELATION funciona como um SEEK aplicado ao arquivo filho mas considerando SOFTSEEK como OFF, pois usamos sempre colocá-lo em ON, tentar o acesso e voltá-lo para OFF em seguida.

Muita válida a sugestão, visto que as expressões que poderão fazer parte do índice provisório podem ser inúmeras, facilitando enormemente a procura dos registros, e pode ser usado em arquivos de qualquer tamanho, por não ter
limitações de filtro ou outras ações que "seguram" o processamento.
O bom do computador é que ele resolve os problemas, sem nunca levantar nenhum.
Hoje atuo mais com Clipper 52E, e um pouquinho com XHarbour.
Avatar do usuário
Clash
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 11 Set 2004 11:14
Localização: Divinópolis (MG)

Indices por Relacionamento

Mensagem por Clash »

Obrigado Billy1943.

Eu já pensei muito em passar para o TBROWSE, mas eu só uso DbEdit, nos cadastros, em resultados de consulta, sempre me atendeu bem.

Abraço.
Eros
Usuário Nível 3
Usuário Nível 3
Mensagens: 291
Registrado em: 19 Dez 2008 19:23
Localização: Goiania

Indices por Relacionamento

Mensagem por Eros »

Bom, para esses casos, eu uso matrizes.. coloco o indice que o usuario desejar, sem precisar criar arquivos, sem criar indices temporarios, e com 1/4 do tempo de indexaçao.

Matriz é uma maravilha da matematica.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Indices por Relacionamento

Mensagem por JoséQuintas »

Na prática as opções se multiplicam.
Poderia também indexar por uma função, e a função retornar o que quiser.

A gente acha isso bom, até conhecer base SQL.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Clash
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 11 Set 2004 11:14
Localização: Divinópolis (MG)

Indices por Relacionamento

Mensagem por Clash »

Eros,

E como vc obteria o índice por ordem alfabética do nome do Cliente ele não estando na tabela CAIXA?

Valeu.
Eros
Usuário Nível 3
Usuário Nível 3
Mensagens: 291
Registrado em: 19 Dez 2008 19:23
Localização: Goiania

Indices por Relacionamento

Mensagem por Eros »

Na hora de adicionar elementos na matriz, você adiciona quais informações vc quer, inclusive, podendo buscar de mais de uma tabela. Depois dos elementos que você adicionou na matriz, vc ordena do jeito que escolher.

Para adicionar elementos (dados) numa tabela, pode ser assim:

Frw := { }

Reagro->( AAdd( Frw , CODIGO() +;
" " +;
ShowCont(8,COD_PRO) +; // Minha função para buscar o nome do cliente em outra tabela
" " +;
Str( QUANT ) +;
" " +;
TIPO +;
" " +;
NOTA +;
" " +;
USER +;
" " +;
Dtoc( DT_REC ) +;
" " +;
Dtoc( DT_NOTA ) ) )


Depois para ordenar os dados na matriz, pode ser usado assim:

aSort( Matriz ,,, { |x,y| x <= y } ) // Por codigo
Asort( MtzRel ,,, { |x,y| Ctod(x[2]) <= Ctod(y[2]) } ) // Por Data

Ou na ordem que voce desejar... tratando por elementos da matriz.

Isso acima, é só um exemplo da codificação. Mas não criei arquivo temporário nenhum e não criei arquivo de índice nenhum. Esta tudo na matriz, ordenado e acessado extremamente rápido.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Indices por Relacionamento

Mensagem por alxsts »

Olá!

Em Clipper, esta técnica esbarra na limitação da linguagem, de 4096 elementos por dimensão de cada matriz.

Já em Harbour, alem de não existir esta limitação, existe a possibilidade de se utilizar-se hash em lugar de array. Creio que ficaria mais rápido ainda...
[]´s
Alexandre Santos (AlxSts)
Eros
Usuário Nível 3
Usuário Nível 3
Mensagens: 291
Registrado em: 19 Dez 2008 19:23
Localização: Goiania

Indices por Relacionamento

Mensagem por Eros »

Sim.. vc tem limitação de 4096 linhas.. porem, voce pode trabalhar com mais de uma matriz... ai, depende do jeito que vc quer desenvolver ne... Essa limitação pra mim, nunca foi problema... mas... programação é igual nescau... tem 1001 maneiras diferentes de se fazer...
Avatar do usuário
Clash
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 11 Set 2004 11:14
Localização: Divinópolis (MG)

Indices por Relacionamento

Mensagem por Clash »

Boa Eros, valeu pela explicação. Bom conhecer mais um caminho. Em relatórios/consultas que trazem informações não muita extensas, pode ser uma boa.
Responder