Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 4168 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Olá pessoal, estou com um problema na inclusao dos itens que é o seguinte

 

tenho um procedimento que insere o item no BD e envia para impressora

 

porém se eu  digitar o Código muito rápido duas vezes seguida ele não vai..

 

então estava vendo o component LCB para criar uma fila... ele le o Código guarda na Fila, executa o procedimento para enviar na impressora e no BD, enquanto isso verifico se a impressora ainda está ocupada se estiver vou armazenando os itens na fila, usando o

acbrLCB.Fila.add(codigo_item)

 

Criei uma thread para não travar a aplicação e permitir que digite o Código rápidamente, Resolveu o problema de digitar o código rápidamente, ele recebe os Códigos, da um erro aparentemente por entrar duas vezes na trhead sem ter terminado a eecução anterior..

 

Alguém tem um exemplo usando o acbrLCB com fila (mesmo sem o Leitor de Barras)

 

ex:

acbrlcb.Fila.add(codigo); //Adicionei na Fila

 

Depois coloco na trhead

 

if (not acbrecf.aguardandoimpressao) and (acbrlcb.Fila.count > 0) then

begin

codigo_item := acbrlcb.lerLista;

inserirProduto(CODIGO_ITEM); //Aqui chamo o Procedimento que inclui o Produto

end;

 

Alguém pode me ajudar... parece que algumas pessoas usaram um timer para enviar os itens da fila, mas não sei se estou fazendo corretamente.. alguém pode me dar um exemplo para resolver esse problema?

Postado

Juliomar, não olhei.. vou olhar o Evento... mas eu tinha Feito o procedimento, ja tratando tudo se der algum problema não grava etc.. Mas devia ter olhado os eventos primeiro né... mas acho que isso não resolve o problema da Lentidão, pq para graver no BD é rápido, o problema é a hora de registrar no ECF

  • Consultores
Postado

     Como o Daniel sugeriu, pesquise sobre venda frenética e venda em fila tanto nesse como no fórum antigo.

 

     O uso do timer ou de uma thread é de sua livre escolha.

     Boa parte dos programadores preferem um timer pois acham mais fácil controlar um timer para este fim do que uma thread. De qualquer forma, deve-se levar em conta que o ECF só consegue tratar um comando por vez que recebe na porta (serial ou usb). Assim você precisa esperar a resposta de um comando na sua aplicação antes de enviar o outro. Não envie um segundo comando antes de receber a resposta do primeiro, seja usando uma thread ou um timer.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Postado

EMBArbosa, certo...

 

Fiz exatamente como no tópico que o Daniel passou, melhorou o tempo de resposta, mas ainda tem que esperar um pouquinho de um item para outro...

isso é normal??

 

e  a abertura do cupom tenho que aguardar tipo uns 6 segundos.. não da para ir armazenando os itens na fila??

  • Consultores
Postado

Você só pesquisou aquele tópico. Tem outros tratando do assunto, tanto naquele fórum como neste que estamos agora. Pelo que me lembro, eles respondem essas perguntas.

 

Em todo caso, como disse acima (itálico adicionado para facilitar o entendimento):

deve-se levar em conta que o ECF só consegue tratar um comando por vez que recebe na porta (serial ou usb). Assim você precisa esperar a resposta de um comando do ECF na sua aplicação antes de enviar o outro ao ECF. Não envie um segundo comando ao ECF antes de receber a resposta do primeiro, seja usando uma thread ou um timer.

Em outras palavras, você pode adicionar os itens à fila. Quantos itens quiser. Mas não envie ao ECF enquanto ele estiver ocupado.

 

Só pra deixar mais claro. Pesquise os outros tópicos além do que o Daniel mencionou.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Postado

 TimerVendeItem.Enabled := False;
  try
           // Verifica se o ACBrECF está ocupado, Se estiver não vende, tentará novamente no próximo evento do Timer //
           // FVendendo é liga no inicio de VendeItem e desligada no Final
         if not ( FVendendo or ACBrECF1.AguardandoResposta) then                
         
begin
                CodBarras := ACBrLCB1.LerFila;
                VendeItem( CodBarras );
         end;
  finally
         TimerVendeItem.Enabled := (ACBrLCB1.Fila.Count > 0);
  end;
 

 

 

Certo ele ja faz isso aqui, mas o que ele não esta fazendo é deixar eu inserir varios Códigos na Fila, e ir lendo os códigos conforme o ECF termina a Ultima operação..

 

Entende o que eu quero dizer??

mesmo eu usando esse exemplo  com o acbrlcb ele continua executando item a item, e não deixa inserir varios itens na fila enquanto vai processando um a um!

  • Consultores
Postado
Certo ele ja faz isso aqui, mas o que ele não esta fazendo é deixar eu inserir varios Códigos na Fila, e ir lendo os códigos conforme o ECF termina a Ultima operação..

 

Entende o que eu quero dizer??

mesmo eu usando esse exemplo  com o acbrlcb ele continua executando item a item, e não deixa inserir varios itens na fila enquanto vai processando um a um!

Como assim? O evento KeyPress do Edit não é executado? Antes de trabalhar com fila, por acaso, você desligou o ACBrECF.Device.ProcessMessages? Ligou novamente?

ACBrECF.Device.ProcessMessages := True;

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Postado

tentando explicar melhor...

 

Eu digito um código no edit e pressiono enter, se rápidamente eu digitar outro código e pressionar enter, ele não escreve o código, ele dica aproximadamente 1 Segundo travado até permitir que eu digite outro código!

 

eu queria permitir que o usuario digitasse o outro código, mesmo antes do procedimento anterior ter terminado

  • Consultores
Postado

A interface fica travada pois a Janela (Form) não está processando as mensagens que recebe do S.O.

Você precisa verificar o motivo disso. E foi para detectar isso que eu fiz as perguntas anteriores.

 

Você não precisa ficar colocando o processmessages como true diversas vezes. De fato, o padrão é true. Algumas das vezes muda-se para false para conseguir o mesmo funcionamento das dlls.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
  • Consultores
Postado

Não sei ao certo. Como disse anteriormente, você precisa verificar o motivo do form não estar tratando mais as mensagens. É muito difícil de eu lhe dar mais detalhes sem ver o código que você fez ou ter um exemplo onde o erro acontece.

 

Procure responder você mesmo as perguntas que fiz no post anterior. Talvez isso possa lhe ajudar a encontrar o problema.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Postado (editado)
//Edit que recebe o Código do Produto
procedure TFrmPdv.CODIGO_PRODUTOPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
  var
    mensagem : string;
begin
  if not statusCaixa(mensagem) then
  begin
    DisplayValue := '';
    CODIGO_PRODUTO.Clear;
    STATUS_CAIXA.Caption := mensagem;
    STATUS_CAIXA.Refresh;
    exit;
  end;
  if not ACBrECF1.Ativo then
  begin
    STATUS_CAIXA.Caption := 'NÃO FOI POSSIVEL COMUNICAR A IMPRESSORA!';
    Exit;
  end;
  //Fecho o Menu se ele Estiver aberto
  if abre_menu then
  begin
    fecha_menu := true;
    abre_menu := false;
    TimerMenu.Enabled := True;
    TimerMenuTimer(sender);
  end;

  PDV_CODIGO_PRODUTO := CODIGO_PRODUTO.Text;
  CODIGO_PRODUTO.Clear;
  DisplayValue := '';
  if CONSULTAPRECO then
  begin
    //Faço a Consulta de Preço
    ConsultaPrecoProduto;
  end else
  begin
    //Insere o Produto
    ACBrLCB1.Fila.Add( PDV_CODIGO_PRODUTO ); 
    TimerVendeItem.Enabled := True; 
    //InsereProduto;
  end;
end;

//Timer que deveria ler a Fila do ACBRLCB
procedure TFrmPdv.TimerVendeItemTimer(Sender: TObject);
begin
  TimerVendeItem.Enabled := False;
  try

    // Verifica se o ACBrECF está ocupado, Se estiver não vende, tentará novamente no próximo evento do Timer //
    // FVendendo é liga no inicio de VendeItem e desligada no Final
    Application.ProcessMessages;
    if not ( fEmVenda or ACBrECF1.AguardandoResposta) then
    begin
      PDV_CODIGO_PRODUTO := ACBrLCB1.LerFila;
      InsereProduto;
    end;
  finally
    TimerVendeItem.Enabled := (ACBrLCB1.Fila.Count > 0);
  end;
end;
//Procedimento que Válida os dados do Produto e Insere no ECF e no BD
procedure TFrmPdv.InsereProduto;
var
  mensagem, vAliquota, PDV_CODIGO_PROD_BALANCA : string;
  PRODUTO_BALANCA : boolean; //Verificar se o Cod do Produto é de Balança
begin
  fEmVenda := True ;
  try
    if statusCaixa(mensagem) then
    begin
      if not VENDAINICIADA then
      begin
        IniciarVenda;
      end;

      if (Trim(PDV_CODIGO_PRODUTO) <> '') and (VENDAINICIADA) then
      begin
        PRODUTO_BALANCA := false;
        //Verificar se o Produto é de Balança
        if (strToInt(copy(PDV_CODIGO_PRODUTO,1,1))=parametrosBalanca.FieldByName('identificador_codigo_balanca').AsInteger)
        and (length(PDV_CODIGO_PRODUTO)=13) then
        begin
          PRODUTO_BALANCA := true;
          total_item.Value := StrTocurr(copy(PDV_CODIGO_PRODUTO,parametrosBalanca.FieldByName('posicao_inicial_valor').AsInteger,parametrosBalanca.FieldByName('posicao_final_valor').AsInteger))/100;
          PDV_CODIGO_PRODUTO := copy(PDV_CODIGO_PRODUTO,parametrosBalanca.FieldByName('posicao_inicial_codigo').AsInteger,parametrosBalanca.FieldByName('posicao_final_codigo').AsInteger);
        end;
        Produtos.Close;
        Produtos.SQL.Clear;
        Produtos.SQL.Add('select codigo, nome, aliquota, valor_aliquota, un, ncm, custo, preco_vista, imagem, balanca from produtos where codigo = :pCod');
        Produtos.ParamByName('pCod').AsString := PDV_CODIGO_PRODUTO;
        Produtos.Open;

        if Produtos.RecordCount <= 0 then
        begin
          NOME_PRODUTO.Style.Font.Color := clRed;
          NOME_PRODUTO.Caption := 'Produto não encontrado';
          NOME_PRODUTO.Refresh;
          VALOR_UN.Text := '0,00';
          quantidade.Text := '1,000';
          total_item.Text := '0,00';
          PDV_CODIGO_PRODUTO := '';
          Exit;
        end else
        begin
          if ALTEROU_QTD = 1 then
          begin
            quantidade.Value := 1;
            ALTEROU_QTD := 0;
          end;

          NOME_PRODUTO.Style.Font.Color := clWindowText;
        //Busco a Aliquota do Produto
          if Trim(Produtos.FieldByName('aliquota').AsString) = 'T' then
            vAliquota := Produtos.FieldByName('valor_aliquota').AsString
          else
          vAliquota := Produtos.FieldByName('aliquota').AsString;
          //Fim da Aliquota
          //Recupera os Valores
          NOME_PRODUTO.Caption := Produtos.FIeldByName('nome').AsString;
          VALOR_UN.Value := Produtos.FIeldByName('preco_vista').AsCurrency;

         //Calcula o Valor Total do ITEM
          if not CALCULA_QTD then     //Verifica se é para calcular a QTD do ITEm quando informar o Valor total do item
          begin
             //Verificar se o Produto é de Balança
            if PRODUTO_BALANCA then
            begin
              quantidade.Value := RoundABNT(total_item.Value / Produtos.FIeldByName('preco_vista').AsCurrency,3);
              quantidade.Refresh;
            end else
            begin
              total_item.Value := quantidade.Value * Produtos.FIeldByName('preco_vista').AsCurrency;
            end;
            //Fim da Verificação se é Balança ou se é Produto Normal
          end else
          begin
            quantidade.Value := RoundABNT(total_item.Value / Produtos.FIeldByName('preco_vista').AsCurrency,3);
            CALCULA_QTD := False;
          end;
          //Verifico se o Valor Será Arredondado ou Truncado
          //se for modo Arredondamento (A)
          if ModoArredondar = 'A' then
          begin
            total_item.Value := RoundTo(total_item.Value, -2);
          end;
          //se for modo Arredondamento (T)
          if ModoArredondar = 'T' then
          begin
            total_item.Value := TruncFix(total_item.Value,2);
          end;

          //Verifico se a Quantidade foi alterada para depois volta-la para 1 quando incluir um novo Item
          if quantidade.Value <> 1 then
          begin
            ALTEROU_QTD := 1;
          end;

          Application.ProcessMessages; 
          //Chama o Procedimento que Insere o Produto no Banco e Imprime na Impressora
          if IncluirItensVenda(PDV_CODIGO_PRODUTO, Produtos.FieldByName('nome').AsString,vAliquota,Produtos.FIeldByName('un').AsString, Produtos.FIeldByName('ncm').AsString ,Produtos.FIeldByName('custo').AsCurrency, Produtos.FIeldByName('preco_vista').AsCurrency,0, quantidade.Value, total_item.Value, true ) then
          begin
            STATUS_CAIXA.Caption := 'VENDA INICIADA...';
            //CODIGO_PRODUTO.Clear;
          end;
          NOME_PRODUTO.Refresh;
        end;  
      end;
    end else
    begin
      STATUS_CAIXA.Caption := 'Para Fazer Vendas o Caixa precisa ser aberto';
    end;
  finally
      fEmVenda := False ;
  end;
end;

Elton, segue Acima o Código que desenvolvi, o problema que o corre, é que ao inserir um item o cursor fica travado por quase um Segundo no edit antes de liberar para eu digitar o próximo código, não sei se é isso, mas o ACBRCF tem uma propriedade que trava o mouse e teclado??

ja tentei varias coisas aqui, mas o mais rápido que consegui é esse tempo ai que da quase 1 Segundo de um código para outro!

Editado por netsolutions
  • Consultores
Postado

   Qual valor você colocou na propriedade Interval do TTimer?

 

   Não tem propriedade de bloquear teclado. Tem aquela que passei alguns posts acima que habilita ou desabilita o processmessages. Se estiver desabilitada aí o programa fica parecendo que está travado enquanto estiver se comunicando com o ECF.

 

   Deixa ver se eu entendi, se você vender 60 itens, vai ter que esperar 1 segundo entre cada um dos itens, num total de mais de um segundo? É isso?

 

   Algumas sugestões:

  • O processo de pegar o valor do código de produtos da fila e passar para uma variável local deve ser condicionado à venda. Em outras palavras, passe a linha "PDV_CODIGO_PRODUTO := ACBrLCB1.LerFila;" para dentro do método InsereProduto logo depois do fEmVenda := True Deixa isso pra lá. Não acho que isso vá influenciar...
  • Você está fazendo muitas validações do código do produto depois de adicionar o valor na fila. Deve fazer o contrário. Valide o código antes de adicionar na fila. Exemplo: se o código do produto não existir, a mensagem deve ser dada ao usuário na hora que ele digitou, e não depois.

A propósito. Não faço uso do método PropertiesValidate. Por que você não usou o onKeyPress como sugerido no post do Daniel?

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
  • Consultores
Postado

 o Interval do timer eu coloquei o Valor   "1"  antes estava "100"

 

E isso resolveu? Pois eu acho que 1 é muito pouco. Não acredito que algo será capaz de acontecer em menos 20 milissegundos. Assim, o método onTimer seria chamado muitas vezes desnecessariamente.

   Acredito que um valor entre 20 e 60 seria um valor razoável. Mas olhando a grosso modo, visto que já está num valor abaixo de 199, acredito que a mudança do parâmetro teria pouca ou nenhuma interferência com seu código atual.

 

EDIT: Outra sugestão que me ocorreu agora para melhorar seu código seria usar um profilier. Não sei porque eu não pensei nisso antes.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Postado

não resolve, mexer no interval do timer aparentemente não altera em nada aumentei o timer para 60 agora.. acho que vou manter aqui no 60 mesmo...

 

Usar um o quê???  como faço isso???

 

profilier?? 

 

em vista de quando abri o tópico, ja consegui uma melhora significativa no tempo de resposta, mudei as validações como você disse... mas precisava melhorar mais

 

como funciona esse profilier?

  • Consultores
Postado

Na verdade o nome é profiler, sem o i. Digitei errado no outro post. Vem de profiling.

 

   Dizendo a grosso modo e de modo simples, um profiler é uma ferramenta (software ou conjunto de métodos) para medir o tempo e a quantidade de execuções das procedures, functions do seu aplicativo. Dessa maneira você pode ver o que está atrasando a execução do seu sistema e onde deve procurar otimizar.

   Algumas dessas ferramentas para Delphi são alistadas nesta pergunta do StackOverflow: http://stackoverflow.com/q/291631/460775

 

   Infelizmente não me lembro de nenhum blog de programador Delphi brasileiro que abordou sobre o assunto em português.

 

   Se você usa o Delphi XE ou superior, ele já vem com o AQTime que tem essa função. Caso use uma versão mais antiga, os mais fáceis para iniciantes que eu usei foram o ProDelphi que possui uma versão gratuita, e o gpProfiler.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
  • Este tópico foi criado há 4168 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...