Clipper On Line • Ver Tópico - testar sintaxe

testar sintaxe

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

 

testar sintaxe

Mensagempor Amparo » 11 Out 2018 11:08

ola amigos

gostaria de saber se existe alguma função que teste uma expressão de comando para evitar erro no sistema, por exemplo
em uma tabela tenho os seguintes campos

CEP C 10
CREDITO N 14,4
DT_COMPRA D

preciso fazer uma filtro e é o usuário quem montara a expressão, ele vai ter o campo para escolher, os operadores para escolher, mas terá que digitar qual o resultado esperado.:

a variável contendo a expressão fica +/- assim:

CLIENTES->CEP = "04005000" .AND. CLIENTES->CREDITO >= 1500.00 .AND. CLIENTES->DT_COMPRA = CTOD("11/10/2018")
onde: 04005000, 1500.00 e 11/10/2018 serão digitados pelo usuário

nesta sintaxe vai rodar sem erro, suponhamos que o usuário não coloque o CEP estre aspas ou não coloque a data dentro CTOD ou mesmo dentro de CTOD sem as aspas, isso ocorrera em erro e consequentemente a saída do sistema, existe como testar esta sintaxe ou então uma rotina que apresente o erro mas não saia do sistema e volte para a function ou procedure que a chamou?

sera que alguém tem algum material para estudo?

desde já agradeço.

Amparo
Avatar de usuário

Amparo
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 337
Data de registro: 20 Ago 2010 10:38
Cidade/Estado: caieiras / sao paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

testar sintaxe

Mensagempor alxsts » 11 Out 2018 13:08

Olá!

Amparo escreveu:gostaria de saber se existe alguma função que teste uma expressão de comando para evitar erro no sistema

Poderá ser usada a função Type()

Amparo escreveu: existe como testar esta sintaxe ou então uma rotina que apresente o erro mas não saia do sistema e volte para a function ou procedure que a chamou?

Coloque o código dentro de um bloco BEGIN SEQUENCE...RECOVER...END SEQUENCE
   PRIVATE cExpr    // ===> Type() Só funciona com variáveis PUBLIC ou PRIVATE
   LOCAL cType, GetList := {}

   CLS

   WHILE .T.
      BEGIN SEQUENCE
         cExpr := Space(255)
         @10,10 SAY "Digite a expressão:" GET cExpr PICT "@S40"
         READ
         
         IF LastKey() == K_ESC
            EXIT
         ENDIF
         
         cType := Type( cExpr )

         IF At( "U", cType ) > 0
            BREAK
         ELSE
            Exit
         ENDIF     

      RECOVER
         Alert( "Erro na expressão")
         LOOP
      END SEQUENCE
   ENDDO     
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

testar sintaxe

Mensagempor JoséQuintas » 11 Out 2018 13:52

Algumas opções:

- o usuário digitar o filtro, e fazer o teste evitando erro
- o usuário escolher campos, e fazer o filtro pelo programa
- filtros a vontade

@ 0, 0 GET cComando VALID MacroType( cComando ) == "L"

FUNCTION MacroType( cExpression )

   LOCAL cType := "U", bBlock

   BEGIN SEQUENCE WITH __BreakBlock()
      bBlock := hb_MacroBlock( cExpression )
      cType  := ValType( Eval( bBlock ) )
   END SEQUENCE

   RETURN cType


O mais interessante pode ser colocar opções diversas, e até evitar erros com variáveis locais/etc.
E deste jeito vai poder ajustar os comandos pra DBF, SQL, etc.

Exemplo:

filotros.png


         IF ! Empty( mAtivo )
            // Ativo = Ativo + Proposta
            mFiltro += iif( mAtivo == "A", " AND ( ESTADO NOT IN ( 'I', 'V', 'E' ) )", " AND ESTADO = " + StringSql( mAtivo ) )
         ENDIF
         mFiltro += iif( Empty( mEndereco ),      "", " AND " + MySqlEnderecoLike( mEndereco ) )
         mFiltro += iif( Empty( mClassi ),        "", " AND CLASSI = " + StringSql( mClassi ) )
         IF mMaisFiltros1 == "S"
            mFiltro += iif( mPrecoMin == 0,          "", " AND VALOR >= " + LTrim( Str( mPrecoMin ) ) )
            mFiltro += iif( mPrecoMax == 0,          "", " AND VALOR <= " + LTrim( Str( mPrecoMax ) ) )
            mFiltro += iif( Empty( mBairro ),        "", " AND BAIRRO LIKE " + StringSql( "%" + Trim( mBairro ) + "%" ) )
            mFiltro += iif( Empty( mRegiao ),        "", " AND REGIAO LIKE " + StringSql( "%" + Trim( mRegiao ) + "%" ) )
            mFiltro += iif( Empty( mCidade ),        "", " AND CIDADE LIKE " + StringSql( "%" + Trim( mCidade ) + "%" ) )
            IF ! Empty( mSetor )
               mFiltro += " AND ( "
               nTamanhoFiltro := Len( mFiltro )
               cnMySql:cSql := "SELECT * FROM HLBAIRRO WHERE BASETOR = " + StringSql( mSetor )
               cTmpFile := cnMySql:SqlToDbf()
               SELECT 0
               USE ( cTmpFile ) ALIAS temp
               DO WHILE ! Eof()
                  mFiltro += " BABAIRRO=" + StringSql( temp->baBairro ) + " OR "
                  SKIP
               ENDDO
               CLOSE DATABASES
               FErase( cTmpFile )
               IF nTamanhoFiltro == Len( mFiltro ) // pra completar o .OR.
                  mFiltro += "CODI = CODI"
               ELSE
                  mFiltro += "CODI <> CODI"
               ENDIF
               mFiltro += " )"
            ENDIF
         ENDIF
         IF mMaisFiltros2 == "S"
            mFiltro += iif( Empty( mDormitorioMin ), "", " AND DORMITORIO >= " + LTrim( Str( mDormitorioMin ) ) )
            mFiltro += iif( Empty( mDormitorioMax ), "", " AND DORMITORIO <= " + LTrim( Str( mDormitorioMax ) ) )
            mFiltro += iif( Empty( mVagasMin ),      "", " AND GARAGEM >= " + LTrim( Str( mVagasMin ) ) )
            mFiltro += iif( Empty( mVagasMax ),      "", " AND GARAGEM <= " + LTrim( Str( mVagasMax ) ) )
            mFiltro += iif( Empty( mDataMin ),       "", " AND DATAINC >= " + DateSql( mDataMin ) )
            mFiltro += iif( Empty( mDataMax ),       "", " AND DATAINC <= " + DateSql( mDataMax ) )
         ENDIF
         IF mMaisFiltros3 == "S"
            mFiltro += iif( Empty( mFinanciado ),    "", " AND FINANCIADO = " + StringSql( mFinanciado ) )
            mFiltro += iif( Empty( mCodC ),          "", " AND ( CODC=" + NumberSql( mCodc ) + " OR CODC2=" + NumberSql( mCodc ) + " OR CODC3=" + NumberSql( mCodc ) + " )" )
            mFiltro += iif( Empty( mNomePropriet ),  "", " AND PROPRNOME LIKE " + StringSql( "%" + Trim( mNomePropriet ) + "%" ) )
            mFiltro += iif( Empty( mIdadeMin ),      "", " AND IDADE >= " + LTrim( Str( mIdadeMin ) ) )
            mFiltro += iif( Empty( mIdadeMax ),      "", " AND IDADE <= " + LTrim( Str( mIdadeMax ) ) )
            mFiltro += iif( Empty( mExposicao ),     "", " AND EXPOSICAO = " + StringSql( mExposicao ) )
            mFiltro += iif( Empty( mPlaca ),         "", " AND " + iif( mPlaca == "N", "PLACA<>'S'", "PLACA=" + StringSql( mPlaca ) ) )
         ENDIF
      ENDIF
...

cnMySQl:Execute( "SELECT * FROM IMOVEL WHERE " + mFiltro )


Note que neste caso as variáveis são usadas pra criar o filtro, mas o filtro não depende delas depois.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18012
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

testar sintaxe

Mensagempor Amparo » 11 Out 2018 14:14

ola amigos

obrigado pela ajuda, vou testar estas rotinas.

abraço
Avatar de usuário

Amparo
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 337
Data de registro: 20 Ago 2010 10:38
Cidade/Estado: caieiras / sao paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

testar sintaxe

Mensagempor alxsts » 11 Out 2018 16:48

Olá!

Amparo escreveu:é o usuário quem montara a expressão,
JoséQuintas escreveu:- o usuário digitar o filtro, e fazer o teste evitando erro

Nem preciso dizer que, dependendo do que o usuário puder digitar, isto é um perigo...

Amparo escreveu:ele vai ter o campo para escolher, os operadores para escolher
JoséQuintas escreveu: o usuário escolher campos, e fazer o filtro pelo programa

Esta forma sim, é segura.

Amparo escreveu:mas terá que digitar qual o resultado esperado.

Isto eu não entendi...

JoséQuintas escreveu:Type  := ValType( Eval( bBlock ) )

E se o codeblock retornar NIL, como em:
? Valtype( Eval( { || dbSelectArea( 'temp' ) } ) )
?
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

testar sintaxe

Mensagempor JoséQuintas » 11 Out 2018 21:16

alxsts escreveu:E se o codeblock retornar NIL, como em:


Ou vamos piorar....
Se o usuário digitar:

fErase( "arquivo" )
dbDelete()

Realmente...
Nunca se sabe como será o usuário, se ele não vai usar como ferramenta pra outras coisas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18012
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

testar sintaxe

Mensagempor Amparo » 18 Out 2018 09:05

ola amigos

desculpe a demora ao responder mais vamos la

na tela de clientes em GRID tenho varias colunas como, CODIGO, CNPJ/CPF, CEP, NOME, LIMITE CREDITO e CONCEITO

o usuário quer que aparece em tela somente os clientes do CEP = 0400500 o CONCEITO = BOM e o LIMITE DE CREDITO = 500.00

como fica esta sintaxe:

SET FILTER TO CLIENTES->CEP = "0400500" .AND. CLIENTES->CONCEITO = "BOM" .AND. CLIENTES->LIM_CREDIT >= 500.00

A ideia é mostrar os campos existentes no grid e o usuário escolher o campo e os operadores e digitar o resultado esperado

ALXSTS, voce disse que não entendeu quando escrevi o resultado esperado, na verdade o resultado que eu quis dizer é quando ele escolhe o campo CEP o usuario deve digitar qual cep ele quer filtrar e assim por diante.

JoséQuintas, vc diz que é um perigo mas, todo o contudo digitado pelo usuário sera usado no comando SET FILTER TO &CONTEUDO_FILTRO.

entao aqui sempre vai vir um texto +- assim CLIENTES->CEP = ... ou CLIENTES->CEP $ ou CLIENTES->LIM_CREDIT >= ou = ou <=

o usuário nunca terá o campo livre para digitar, os operadores =,==,>,>=,<,<= !$, $ serão botoes que ele deve escolher como .OR. ou .AND. ou "(" ou ")" também sera botoes.

apos ele fazer toda essa escolha eu gostaria de testar a sintaxe antes de aplicar o resultado pois de tiver algum erro de expressão o sistema não aborte, apenas mostre que houve erro de expressão e volte no form do filtro.

em anexo tenho um print da tela não esta completa mas da uma ideia do que estou montando.
Anexos
tela de cliente.png
Avatar de usuário

Amparo
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 337
Data de registro: 20 Ago 2010 10:38
Cidade/Estado: caieiras / sao paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

testar sintaxe

Mensagempor JoséQuintas » 18 Out 2018 13:10

um fonte antigo de teste:

https://github.com/JoseQuintas/JoseQuintas/blob/master/source/ze_filterclass.prg

Dá uma olhada no MediaMonkey de músicas, a criação de listas automáticas, é interessante.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18012
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

testar sintaxe

Mensagempor JoséQuintas » 18 Out 2018 13:14

filtro.png


filtro2.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18012
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

testar sintaxe

Mensagempor JoséQuintas » 18 Out 2018 15:48

Faltou uma nota: o gênero, é o gênero musical. Não se trata de homem, mulher, gay, lésbica, etc..... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18012
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes




Retornar para MiniGui

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 6 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro