Página 2 de 3

erro no set filter

Enviado: 22 Fev 2013 15:49
por cjp
Realmente tem um parêntese sobrando nesta linha:

Código: Selecionar todos

cSetFilter := cSetFilter + iif( !empty( AC1), [ .AND. ("] + alltrim( upper(AC1) ) + [" $ upper(acao)], [] )
Tentei fechá-lo em vários pontos, mas sempre dá erro de sintaxe.

Daí suprimi o parêntese, ficando assim:

Código: Selecionar todos

cSetFilter := cSetFilter + iif( !empty( AC1), [ .AND. "] + alltrim( upper(AC1) ) + [" $ upper(acao)], [] )
Assim não dá erro de sintaxe, mas continua não filtrando corretamente.

Ou seja, tirei zero na prova.

Por favor, me ajude, ainda não consegui entender a lógica dessa função.

Asimoes, o problema é que eu não sei usar a ordscope. Com índice temporário, como faria? Indexar simplesmente não resolve, pois continuaria aparecendo os demais campos da base. Eu quero que apareçam apenas os que correspondem ao critério escolhido pelo usuário. Só que eu só conheço o set filter pra isso.

erro no set filter

Enviado: 22 Fev 2013 17:13
por asimoes
Você pode criar indice com a clausula for
Veja um exemplo que utilizo:


cFiltro:="DtVenc <= Date() .AND. "
cFiltro+="Cobranca .AND. "
cFiltro+="DataPg > DtVenc .AND. "
cFiltro+=IF(!Empty(cVar),"Apto == "+"'"+cVar+"'",".T.")+" .AND. "
cFiltro+=IF(!Empty(fMultaMora.oMesAno.Value),"MesAno == "+"'"+RTrim(fMultaMora.oMesAno.Value)+"'",".T.")+" .AND. "
cFiltro+="!Deleted()"

INDEX ON Codigo TAG TEMPBOL TO TEMPBOL FOR &cFiltro.

erro no set filter

Enviado: 22 Fev 2013 18:51
por rochinha
Amiguinhos,

CJP - Não esquente, eu tambem passei por boas para chegar as minhas filtragem ao ponto de excelencia.

O fato é que ao colocarmos !deleted() .AND (...) estamos diminuindo o resultado da critica para somente dois. Ou seja, toda critica dentro do parentesis será analisada e termos: Somente os não deletados e verdadeiramente iguais à AC1, etc. Se voce tirar o parentesis irá dificultar a critica. Não devemos misturar operadores numa mesma sentença, assim como quando calculamos.

Na sentença 1 + 2 * 3 voce quer que 1 + 2 aconteça antes de 2 * 3. (1 + 2) * 3 é diferente de 1 + (2 * 3), portanto colocar operadores iguais dentro de um trecho resulta melhor do que tudo misturado.

Código: Selecionar todos

Set Delete Off
 
cSetFilter := [!deleted()]
 
cSetFilter := cSetFilter + iif( !empty( AC1), [ .AND. ("] + alltrim( upper(AC1) ) + [" $ upper(acao)], [] )
cSetFilter := cSetFilter + [)] // Isto fica assim e a linha anterior deve possuir o parentesis

cls
? "Filtro: ", cSetFilter
wait ""
 
dbSetFilter( {|| &cSetFilter. }, &cSetFilter. )
ASIMOES
O uso de ORDSCOPE pode diminuir o tamanho da área de filtragem, melhorando o uso do SET FILTER mas não é preciso criar indices temporários(para diminuir escritas).

Voce pode usar o escopo, criar um trecho de dados e usar set filter normalmente. já que voce reduziu drásticamente o trecho. Sua técnica é aliada e não estou contrariando-a.

Lembro-me de quando comecei a usar o subntx e como ele melhorou minhas filtragem no Clipper 5.2e e NTX. Gostei tanto de usá-lo que quando passei a usar Clipper 5.3 ainda usava NTX, mesmo sabendo do OrdScope, demorei para me acertar com o bicho mas quando consegui não larguei mais.

Mas, vejamos o CJP dominar a técnica padrão para que quando ele puder aliar ao uso de escopo não perca cabelos como eu.

erro no set filter

Enviado: 23 Fev 2013 01:25
por cjp
Fiz como vc disse, meu caro, mas continua não funcionando. Não dá erro, mas, como no set filter, ele não filtra todos os registros, só o primeiro.

Mas o exemplo do asimoes funcionou perfeitamente.

Muito obrigado a todos que ajudaram.

erro no set filter

Enviado: 23 Fev 2013 04:05
por rochinha
Amiguinho,

"Persistência é a chave. Desistir... jamais.".

erro no set filter

Enviado: 23 Fev 2013 11:32
por JoséQuintas
Tem horas que é melhor não economizar código, pra ficar mais legível:

Código: Selecionar todos

// cSetFilter := cSetFilter + iif( !empty( AC1), [ .AND. "] + alltrim( upper(AC1) ) + [" $ upper(acao)], [] )

IF .NOT. Empty( AC1 )
    cSetFilter += [ .AND. "] + Upper( AllTrim( Ac1 ) ) + [" $ Upper(Acao) ]
ENDIF
SET FILTER TO &( cSetFilter )
Por acaso tem .OR. no restante do filtro?
Isso poderia afetar o resultado, se não houver a indicação correta de ordem com parênteses.

erro no set filter

Enviado: 23 Fev 2013 16:00
por rochinha
Amiguinhos,
Isso poderia afetar o resultado, se não houver a indicação correta de ordem com parênteses.
Corretissimo. Quanto ao operador .OR. este é usado quando ele critica outras variaveis AC2,AC3,AC4 e AC5.

erro no set filter

Enviado: 27 Fev 2013 00:16
por cjp
Não desisti, Rochinha. É que o problema foi resolvido, embora de forma diversa da que vc sugeriu. Mas o importante é que foi resolvido.

erro no set filter

Enviado: 27 Fev 2013 13:41
por Pablo César
cjp escreveu:Não desisti, Rochinha. É que o problema foi resolvido, embora de forma diversa da que vc sugeriu. Mas o importante é que foi resolvido.
Ahhh mas amiguinho, depois de tanto trabalho, acho que cabe você postar o código de como foi resolvido. Desta forma, não somente servirá para demostrar que houve outra idéias como também servirá para outros colegas no futuro. Certo ?

erro no set filter

Enviado: 27 Fev 2013 14:10
por rochinha
Amiguinhos,
cjp escreveu:
Não desisti, Rochinha. É que o problema foi resolvido, embora de forma diversa da que vc sugeriu. Mas o importante é que foi resolvido.
Ahhh mas amiguinho, depois de tanto trabalho, acho que cabe você postar o código de como foi resolvido. Desta forma, não somente servirá para demostrar que houve outra idéias como também servirá para outros colegas no futuro. Certo ?
Na certa, as sugestões foram muitas e a solução só as complementará.

erro no set filter

Enviado: 28 Fev 2013 02:46
por cjp
Meus amigos, na verdade, acolhi integralmente a sugestão do colega, e funcionou. Ficou assim o código:

Código: Selecionar todos

do case
   case !empty(ac5)
        cFiltro:="ac1$acao .or. ac2$acao .or. ac3$acao .or. ac4$acao .or. ac5$acao"
   case !empty(ac4)
        cFiltro:="ac1$acao .or. ac2$acao .or. ac3$acao .or. ac4$acao"
   case !empty(ac3)
        cFiltro:="ac1$acao .or. ac2$acao .or. ac3$acao"
   case !empty(ac2)
        cFiltro:="ac1$acao .or. ac2$acao"
   otherwise
         cFiltro:="ac1$acao"
endcase
INDEX ON data TAG TEMPBOL TO TEMPBOL FOR &cFiltro.
go top

erro no set filter

Enviado: 01 Abr 2014 17:29
por Clash
Rochinha, tudo bem?

Vc em outro tópico...kkk bom te ver ativo na comunidade.
Combinando suas dicas do OrdScope() está realmente melhorando busca e relatórios no meu sistema.

Seguinte: Acontece um erro estranho (para mim, claro) na hora de um filtro.
Tabela indexada, ordscope beleza, mas quando executo:

Código: Selecionar todos

Store Space(10) to cReferencia
@ 10,10 Get cReferencia Pict "@!"
Read
Set Filter to REFERENCIA = cReferencia
Apresenta erro que a variável [cReferencia] não existe.
Agradeço.
[ ]s

erro no set filter

Enviado: 01 Abr 2014 18:45
por rochinha
Amiguinho,

Eu já falei pra galera, Se eu ficar mais de 6 meses sem postar podem colocar o avatar de cruz ou luto porque fui programar no céu. há! há! há!

Então serei: Divino Programador!

Brincadeiras a parte, voce ainda tá usando STORE ... isto era legal no dBase, seja mais audacioso.

Troque o:

Código: Selecionar todos

Store Space(10) to cReferencia
Por:

Código: Selecionar todos

cReferencia := Space(10)
Desta forma sua variavel já será reconhecida e tipada. Nada contra o uso do STORE mas se está acontecendo o erro pode ser pela falta vinculo de variavel e database.

O erro: variável [cReferencia] não existe não acontece porque ela não existe. Ela existe no código, mas não na tabela e isto vai depender do ponto de vista do aplicativo no momento da execução de achar que cReferencia é referente a um campo na tabela e não a uma variável de memória.

Olhando o código, daqui alguns anos quandos os cabelos cairem tão velozes quanto os neurônios ficarem ranzinzas a sintaxe...

Código: Selecionar todos

Set Filter to REFERENCIA = cReferencia
...te fará pensar se REFERENCIA é o campo e cReferencia a variável ou vice-versa.

Para que estes erros não ocorram adote as seguintes convenções:

Quando se referir a campos de uma tabela coloque o nome da tabela junto ao nome do campo, exemplo: tabela->campo
Quando se referir a uma variável, mesmo que o nome já esteja tipado com siglas coloque um denominador, exemplo: M->cCampoChar, M->nCampoNum, etc.

Então o seu código ficaria mais compreensível se voce escrevesse assim:

Código: Selecionar todos

M->cReferencia := Space(10)
@ 10,10 Get M->cReferencia Pict "@!"
Read
Set Filter to TABELA->REFERENCIA = M->cReferencia
Parece não ficar tão bonito, mas ficará muito mais fácil de encontrar problemas.

erro no set filter

Enviado: 08 Abr 2014 16:01
por Clash
Olá Rochinha,
Olhando o código, daqui alguns anos quandos os cabelos cairem tão velozes quanto os neurônios ficarem ranzinzas a sintaxe...
--> Essa foi otima, não está tão distante assim... kkk

Parceiro, valeu mais uma vez. Desenvolvimento em afoito, sem tempo para pesquisa.

Quanto as variáveis outra lição. Acha que era suficiente tratar nome de campos no simples (REFERENCIA, COD_CLIE) e quando
de memória, identificava por uma inicial cReferencia (caracter/memoria), nCod_Clie(numerica/memoria).

Essa referencia sua M-> identifica ser de memória?

Mas uma vez, muito obrigado.

Sucesso.

erro no set filter

Enviado: 09 Abr 2014 18:19
por rochinha
Amiguinho,

Quando você olha o seu código você o entende, pois você é o pai da criança.

CREFERENCIA é diferente mesmo de REFERENCIA, mas quem diz pra mim que um deles é um campo ou variável? somente o pai da criança.

Supondo que voce deva passar o know-how para seus herdeiros melhor que o código esteja mais detalhado.

Colocar TABELA-> e M-> ou _FIELD-> são detalhes mas informam muito mais rápido visualmente.

Eu uso _FIELD quando trabalho com campos onde passo o nome por codeblock, mas isto é outra estória.

Programação didática:

Código: Selecionar todos

nCampo1 := 123
USE tabela
APPEND BLANK
REPLACE campo1 WITH nCampo1
REPLACE campo2 WITH "TEXTO"
REPLACE campo3 WITH .T.
COMMIT
Programação avançada:

Código: Selecionar todos

M->Campo1 := 123
dbUseArea( tabela, ... )
dbAppend()
tabela->campo1 := M->Campo1
tabela->campo2 := "TEXTO"
tabela->campo3 := .T.
dbCommit()
Diferenças que não causam nenhuma diferença no processamento, mas para fins de aprendizado da linguagem nada melhor do que programar de forma tradicional.