Página 1 de 1

Filtro pelo setscope

Enviado: 13 Set 2004 11:07
por negrao
pessoal , to tendo dificuldade na seguinte situacao:

Tenho um arquivo que contem os seguintes dados(ex):
Nºlanc conta1 conta2
1 123 456
2 789 123
3 001 987

supondo que eu queira filtrar as contas que tenham o conteudo "123" , o resultado seria os registros (1 e 2).
Utilizo o six2 como o comando setscope, muito bom por sinal, que filtra de acordo com meu indice.
Hoje tenho 2 indice para fazer isso: por conta1 e conta2
primeiro uso o indice 1(conta1) , filtro e lanco em um arquivo TMP
Depois uso o indice 2 (conta2) , filtro e lanco em um arquivo TMP
e depois trabalho com a informacao.

Mas queria saber se nao tem como criar apenas um indice e filtrar de uma vez , sem ter que ficar fazendo isso que faco hoje.

Obrigado

Enviado: 13 Set 2004 11:58
por Dudu_XBase
Era bom tb pra mim se alguém soubesse...eu tenho q gerar sempre tmps...qdo o assunto eh filtrar dessa forma....tentei fazer algo pra amenizar isso meses atrás mas naum obtive sucesso...

Pegando um Gancho.

Enviado: 13 Set 2004 13:08
por Marcos
Pegando um gancho neste tópico, como faço para utilizar este filtro setscope, em minha rotina de venda utilizo o Set Filter para filtrar os Itens da Notas de uma Referida Venda, ou seja, para amarrar os Itens de venda a Venda utilizo o Set Filter que por sinal é muito lento, utilizo Indices NSX, como ficaria o código abaixo com Setscope?

Select ITENVEND
DbSetOrder(2)
Set filter to CODIGO_SAI = Res_Codi .and. TIPO = "PEDIDO_S"
Goto bottom


Agradeço a ajuda, se puderem é claro.
Marcos
Da Roça.

sx_setscope

Enviado: 13 Set 2004 13:51
por negrao
Marcos, eu faco da seguinte maneira

Set filter to CODIGO_SAI = Res_Codi .and. TIPO = "PEDIDO_S"
Goto bottom

//==> vc deve ter um indice no formato do seu filtro
estou supondo que vc tenha um indice nesse padrao:
str(codigo_sai,5)+tipo

select(alias)
dbsetorder(ordem que esta seu indice)
sx_setscope(0,str(res_codi,5)+pedido_s )
sx_setscope(1,str(res_codi,5)+pedido_s )
browse()

//==> apaga filtro
sx_clrscope(0)
sx_clrscope(1)

//==> espero ter ajudado

Dúvida ainda.

Enviado: 13 Set 2004 16:32
por Marcos
Negrão, eu entendi perfeitamente o seu exemplo, só que fiquei com umas dúvidas ainda:
- Porque que para fazer só um filtro precisa de 2 linhas de código?
sx_setscope(0,str(res_codi,5)+pedido_s )
sx_setscope(1,str(res_codi,5)+pedido_s )

- Como usar o sx_setscope no código abaixo:

@ 9, 7 say "C¢digo Cliente :" get xcod_cli picture "999999"
@10, 7 SAY "Data Inicial :" Get xdataIni Picture "99/99/9999"
@11, 7 SAY "Data Final :" Get xdataFin Picture "99/99/9999"
read
Select ITENVEND
DbSetOrder(1)
Set Filter To CODIGO_CLI == xcod_cli .and. AJUSTE == "-" .and. Ctod (DATA_SAIDA) >= Ctod(xDataIni) .AND. Ctod(DATA_SAIDA) <= Ctod(xdataFin)
Goto Top

É mais complexo, e não entendo, isto é um relatório.
Desde já obrigado.
Marcos
Da Roça.

Enviado: 14 Set 2004 00:53
por Dudu_XBase

Código: Selecionar todos

/************ EXEMPLO 1 ****************************/
#include "SIXNSX.CH"

USE CLIENTES VIA "SIXNSX"        // Abre TESTE
INDEX ON  UF TAG 1          // Indice pelo estado do cabra
Sx_SetScope( 0, "AC" )      // Inicio do Escopo com o valor "AC"
Sx_SetScope( 1, "AM" )      // Fim do Escopo com valor "AM"
GO TOP                         // vai pro primeiro
Browse()                       // Mostra todo os registros com UF DE AC-AM
Sx_ClrScope(0)             // Fecho Escopo Inicio
Sx_ClrScope(1)             // Fecho Escopo Fim



/************ PARTE DO SEU RELATÓRIO ***************/
Select ITENVEND 
DbSetOrder(1) 

sx_setscope(0,CODIGO_CLI == xcod_cli .and. AJUSTE == "-" .and. Ctod (DATA_SAIDA) >= Ctod(xDataIni) .AND. Ctod(DATA_SAIDA) <= Ctod(xdataFin) )

sx_setscope(1,CODIGO_CLI == xcod_cli .and. AJUSTE == "-" .and. Ctod (DATA_SAIDA) >= Ctod(xDataIni) .AND. Ctod(DATA_SAIDA) <= Ctod(xdataFin) )

dbgotop()
While !eof()
  ? intenvend->DATA_SAIDA 
  dsbkip()
enddo

Sx_ClrScope(0)
Sx_ClrScope(1)


Re: Filtro pelo setscope

Enviado: 14 Set 2004 01:26
por Maligno
negrao escreveu:queria saber se nao tem como criar apenas um indice e filtrar de uma vez , sem ter que ficar fazendo isso que faco hoje.
Você não especificou como armazena os números de contas no arquivo de dados, mas imagino que seja, conforme o seu próprio exemplo, desta forma:

Código: Selecionar todos

1123456
2789123
3001987
Ou seja, sem espaços intermediários ou pontuação. Se for assim mesmo (o que me parece ser a forma mais correta), vejo uma dificuldade em usar algo que eu poderia sugerir, que é a função sx_WildSeek(), que permite buscar uma substring em qualquer posição da chave. A título de exemplo, e ainda continuando no seu próprio exemplo ao buscar todas as contas iguais a "123", note a dificuldade neste outro conjunto:

Código: Selecionar todos

Contas: 1 234 567
        1 321 234
A função sx_WildSeek(), apesar de parecer servir como uma luva no seu caso, encontraria dois registros errados, que contém essa string "123", mas que não fazem parte de conta alguma, como você pode ver. Essa confusão até poderia ser resolvida com o acréscimo de uma máscara. Se você armazenasse as contas já formatadas (não gosto dessa idéia), sx_WildSeek() resolveria, de fato.

Código: Selecionar todos

Contas: 1.234.567
        1.123.456
O código que poderia, neste caso especial de armazenamento, seria muito simples. Algo parecido com:

Código: Selecionar todos

aCtas := ListaCtas("*123")
if Len(aCtas) > 0
   // Você conseguiu encontrar todas as contas
end
--------------------------------------------------------
function ListaCtas(cStr)
local aTemp := {}
local lMore := sx_WildSeek(cStr)
while lMore
   AAdd(aTemp,field->CONTA)  // recupera o dado da conta
   lMore := sx_WildSeek(cStr,.T.)
end
return aTemp
Este exemplo não foi testado e serve apenas de base para o uso desta função.
Planos de contas, normalmente, e onde tenho visto (e feito), são separados por níveis. Em contabilidade eu uso direto, mas nunca tive necessidade de encontrar contas em níveis diferentes. Normalmente se busca apenas em um nível. O mesmo número residindo em níveis diferentes é novidade pra mim. Talvez você tenha uma necessidade especial.

Não uso pois nunca tive necessidade, mas você também poderia pesquisar alguma coisa sobre o sistema Hyper-SEEK da SIX. Parece ser muito interessante, apesar da dificuldade mencionada acima ainda existir.

Finalmente,... Você disse que hoje tem duas chaves para conta1 e conta2, a fim de conseguir resolver o problema mais facilmente. É uma alternativa boa. Não vejo problema nisso. Aliás, em um grande programa de controle de produção industrial, fiz o estoque de matérias-primas baseado num plano de contas semelhante, e eu uso duas chaves para partes diferentes da identificação dos produtos.
A única coisa que me causa alguma estranheza é a sua necessidade de levar essas contas para um arquivo temporário. Se for um volume muito grande de dados (não conheço seu ramo) até se justifica. Se não, use uma matriz. É muito mais prático, inclusive no descarte, quando não for mais necessária.

[]'s
Maligno
http://www.buzinello.com/prg

+ Dúvidas

Enviado: 14 Set 2004 09:15
por Marcos
Eduardo, obrigado pelo seu exemplo, eu substitui meu código onde havia o Set Filter só que não deu nenhum resultado, acho que não estou gerando o índice corretamente, veja abaixo o índice:

Desta forma dá "erro de argumentos: +"

INDEX ON Str(CODIGO_CLI) + AJUSTE + Ctod(DATA_SAIDA) TAG 6 FOR !DELETED()

Desta forma não dá erro, só que também não filtra nada, nem mesmo o Cliente.

INDEX ON Str(CODIGO_CLI) + AJUSTE + DATA_SAIDA TAG 6 FOR !DELETED()

No DBF o CODIGO_CLI é numérico, o AJUSTE é character e o DATA_SAIDA é character com 10 espaços

Mais uma vez, obrigado.
Marcos

Sem solução.

Enviado: 14 Set 2004 15:24
por Marcos
Ainda continuo sem solução, preciso deste código para fazer um relatório importantissimo pra mim.
Marcos