Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Repetir Valor do Edit


Eder

Pergunta

Ola...

Tenho que montar uma somatório de 84 edit´s, tipo uma calculadora, porem somar os 84 edit´s.

mas tipo....se o usuario digitar no edit1 = 10,00 e se a proxima soma(edit2) for também 10,00 ele não precisasse digitar de novo 10,00 e sim um simples ENTER(tipo calculadora)...o edit2 copiaria o valor do edit 1 para o edit2, algo assim.

Como poderia fazer este processo já que são 84 edit´s...

Obs: tenho que mostrar os 84 edit´s, este processo serve pra conferência de valores, por isto deve ser travalhado com os 84 edit´s, pois caso o somatório não bater com a documentação, o usuario podera tirar as vias de documentos com os 84 edit´s e tentar achar o furo da soma.

Grato

F E L I Z 2 0 0 8

Link para o comentário
Compartilhar em outros sites

15 respostass a esta questão

Posts Recomendados

  • 0
Tenho que montar uma somatório de 84 edit´s, tipo uma calculadora, porem somar os 84 edit´s.

mas tipo....se o usuario digitar no edit1 = 10,00 e se a proxima soma(edit2) for também 10,00 ele não precisasse digitar de novo 10,00 e sim um simples ENTER(tipo calculadora)...o edit2 copiaria o valor do edit 1 para o edit2, algo assim.

Como poderia fazer este processo já que são 84 edit´s...

Eder, e voce quer adicionar estes edits em run-time, ou vai colocá-los em design-time mesmo?

- Uma idéia seria padronizar o nome deles, de modo que você consiga buscá-los pelo nome facilmente (usando FindComponent);

- Se o procedimento de ao teclar ENTER copiar o valor do edit anterior é padrão também, dá para implementar de forma genérica apenas em um único evento;

- Esta impressão, vai ser feita através de que componente? Quick ou Fortes?

- Para cada Edit, provavelmente haverá um label e imagino que seu conteúdo seja também impresso.

Vai pensando a respeito, veja se consegue implementar algo. Logo mais eu dou uma olhada e conforme o caso tento deixar um exemplo.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Eder, e voce quer adicionar estes edits em run-time, ou vai colocá-los em design-time mesmo?
R.: Design_Time

- Se o procedimento de ao teclar ENTER copiar o valor do edit anterior é padrão também, dá para implementar de forma genérica apenas em um único evento;

R.: ok.....mas não sei como fazer isto...sendo que só vou repetir o valor do edit anterior, quando de um enter no campo sem digitar nada.

- Esta impressão, vai ser feita através de que componente? Quick ou Fortes?

- Para cada Edit, provavelmente haverá um label e imagino que seu conteúdo seja também impresso.

R.: Não há Impressão...apenas é um form de conferencia de valores....bem simples...sem impressão alguma..

Vai pensando a respeito, veja se consegue implementar algo. Logo mais eu dou uma olhada e conforme o caso tento deixar um exemplo.

R.: eu tenho tudo pronto...exceto esta parte...que estou pedindo ajuda, e não to conseguindo resolver...na verdade o usuário já usa o aplicativo há muito tempo, e ele me pediu pra ver se da pra imprementar, pois as vezes ele tem que somar varios valores iguais.....e ai é um saco...e concordo com ele...é muito chato...rs..

muito Grato...Micheus...

Forte Abraço....final de semana vejo sua resposta lá de casa....aqui na empresa fecho meu expediente...rs...

t+ ;)

Link para o comentário
Compartilhar em outros sites

  • 0
Forte Abraço....final de semana vejo sua resposta lá de casa....aqui na empresa fecho meu expediente...rs...
Eder, vai ter que esperar até dia 2.

O trabalho hoje estava corrido e só deu para olhar o forum agora, antes de ir para casa.

Abraços e boas festas...

ps.: faltou luz na sua casa hoje por volta das 18:10, durante alguns minutos? (fiquei fazendo relatórios até agora. :angry:)

Link para o comentário
Compartilhar em outros sites

  • 0
Eder, vai ter que esperar até dia 2.

O trabalho hoje estava corrido e só deu para olhar o forum agora, antes de ir para casa.

R.: sem problemas...também só volto dia 2....até lá :D

ps.: faltou luz na sua casa hoje por volta das 18:10, durante alguns minutos? (fiquei fazendo relatórios até agora. )

R.: Felizmente não faltou não.....hehehe, mas deu uma trovoada daquelas, mora na Fortaleza.....é de vez enquando é bom trabalhar....rs...brincadeirinha.. :blush:

Abraços e boas festas...

R.: Pra você também tudo de bom... :D

t+

Editado por Eder
Link para o comentário
Compartilhar em outros sites

  • 0

Eder, segue anexo a minha sugestão.

O código está comentado, então não entrarei em detalhes aqui.

Observe que o exemplo não é 100% à prova de falhas.

Por ex., se ao invés de ENTER (o que você solicitou) o usuário teclar TAB e o edit estiver vazio, será apresentada a mensagem de que o valor não é válido. Isto porque, não adianta testar no OnKeyDown (além de Key=VK_RETURN), se a tecla pressionado foi VK_TAB porque, neste caso, o evento OnExit ocorre sem que o evento OnKeyDown seja gerado.

Outro caso, poderia ser uma configuração de números no padrão americano (pouco provável), mas que no caso de utilizado um número "1,500.00" deverá resultar em erro, já que estou removendo o "." para a correta conversão via StrToFloat.

Dê uma conferida e veja o que precisa ser melhorado/ajustado.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Oba....Desculpa a demora..estava com problemas no meu D4.....

Carinha...baixei o arquivo porem não consegui abrir o arquivo que esta dentro do zip...tentei pelo bloco de notas, pelo proprio delphi...mas só aparece caracteres invalidos dentro dele...

poderias verificar??

Grato

Link para o comentário
Compartilhar em outros sites

  • 0

Eder, lembrei de que você utiliza o Delphi 4 (se não me engano), então, caso você ocorra um erro de compilação informando de que a função StringReplace não está definida, é porque ela realmente não existe na sua versão (no Delphi 7, ela está na unit SysUtil).

Bom, se for o seu caso, segue minha versão da função que fiz no Delphi 3 (deve ficar compatível com o 4):

function StringReplace(S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
var
  Idx,
  Offset :Integer;
  S_Case,
  OldPattern_Case: string;
begin
  if rfIgnoreCase in Flags then
  begin
    S_Case := UpperCase(S);
    OldPattern_Case := UpperCase(OldPattern);
  end else
  begin
    S_Case := S;
    OldPattern_Case := OldPattern;
  end;
  Idx := Pos(OldPattern_Case, S_Case);
  Offset := Idx;
  if Idx > 0 then
  repeat
    Delete(S, Offset, Length(OldPattern));
    Insert(NewPattern, S, Offset);
    Delete(S_Case, 1, Idx);
    Idx := Pos(OldPattern_Case, S_Case);
    Offset := Offset +Length(NewPattern)+ Idx -1;
  until not(rfReplaceAll in Flags) or
        ((Idx = 0) and (rfReplaceAll in Flags));
  Result := S;
end;
Depois de tê-la feito, é que lembrei de recortá-la do fonte disponível no Delphi 7 :blush: :
function StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
var
  SearchStr, Patt, NewStr: string;
  Offset: Integer;
begin
  if rfIgnoreCase in Flags then
  begin
    SearchStr := AnsiUpperCase(S);
    Patt := AnsiUpperCase(OldPattern);
  end else
  begin
    SearchStr := S;
    Patt := OldPattern;
  end;
  NewStr := S;
  Result := '';
  while SearchStr <> '' do
  begin
    Offset := AnsiPos(Patt, SearchStr);
    if Offset = 0 then
    begin
      Result := Result + NewStr;
      Break;
    end;
    Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern;
    NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt);
    if not (rfReplaceAll in Flags) then
    begin
      Result := Result + NewStr;
      Break;
    end;
    SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt);
  end;
end;
Para ambas as opções, você deverá declarar na cláusula TYPE o conjunto (SET) de flags TReplaceFlags:
type
  TReplaceFlags = set of (rfReplaceAll, rfIgnoreCase);

Observe, ainda, que no Delphi 3 não é conveniente o uso da cláusula CONST no cabeçalho da função (como está definida na do Delphi 7), pois haverá erro de compilação do código. Pode ser que também ocorra isto no Delphi 4, no caso de você optar pela codificação da Borland.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Micheus.....já havia conseguido abrir seu exemplo no D4 e compilei legal....sem nenhum problema...

Só to meio perdido no seu código ainda..hehehe....pois achava que era simples o lance de repetir os edit´s...e é bem complicadinho...

Eu uso o aplicativo...bem diferente do seu exemplo...tipo eu coloco no OnExit do edit1 assim:

Var
Valor1, valor2, valor3 : real;
begin
valor1:=StrToFloat(edit1.text);
valor2:=StrToFloat(edit2.text);
valor3:=StrToFloat(edit3.text);
LabelResultado.Caption:=FloatToStr(Valor1+Valor2+Valor3);

e ai eu aponto no Onexit do edit2 e edit3 pra o OnExit do edit1

Resumindo:

a medida que vou lançando o valor nos edit´s o resultado vai somando no LabelREsultado...

Como vê é diferente do seu exemplo.....

valeu...bom final de semana

Grato :)

Editado por Eder
Link para o comentário
Compartilhar em outros sites

  • 0
Só to meio perdido no seu código ainda..hehehe....pois achava que era simples o lance de repetir os edit´s...e é bem complicadinho...
Eu diria que apenas parece. Talvez porque você não consiga visualizar exatamente a operação com os edits, se comparado com a forma como você postou seu exemplo.

Mas, eu esperava realmente que você fizesse alguns questionamentos. É mais fácil você dizer do que tem dúvida, do que eu sair escrevendo um monte (como agora) e você já saber metade do que estou escrevendo.

Eu uso o aplicativo...bem diferente do seu exemplo...tipo eu coloco no OnExit do edit1 assim:

Var
Valor1, valor2, valor3 : real;
begin
valor1:=StrToFloat(edit1.text);
valor2:=StrToFloat(edit2.text);
valor3:=StrToFloat(edit3.text);
LabelResultado.Caption:=FloatToStr(Valor1+Valor2+Valor3);
e ai eu aponto no Onexit do edit2 e edit3 pra o OnExit do edit1 Resumindo: a medida que vou lançando o valor nos edit´s o resultado vai somando no LabelREsultado... Como vê é diferente do seu exemplo.....
Diferente em termos: - É também no OnExit que o meu exemplo faz o cálculo, porém não faz só isto - ele reformata o texto, caso o cara digite "15", será atualizado o edit para "15,00". - O somatório que você coloca em um único label, também pode ser assim colocado no meu exemplo, já que ele coloca sub-totais por valor digitado. Basta que utilizemos apenas um label para mostrar o valor, ao invés de uma a cada edit. Como está, no último label, você terá o valor total de qualquer modo - questão de adaptar. Mas, realmente há mais trabalho do que o necessário para o que você queria. É que entendi que você queria visualizar o sub-total ao lado de cada item, como em um extrato bancário. :blush: Vou colocar cada pedaço aqui sem os comentários existentes no fonte para que não pareça mais complicado do que é, bem como vou utilizar apenas um label para o total. A forma como você exemplificou que o seu código está hoje, não é muito viável para a quantidade de Edits que você pretende utilizar (84, se bem que nada que um copiar colar não resolva...). Então, a idéia é a de que tenhamos um procedimento para somar, em um loop, o valor de todos estes edits (procedure CalcValues). Para fazer isto, da forma mais automatizada possível, torna-se importante padronizar o nome dos edits, de modo a acessarmos eles através de seu nome. Foi o que fiz quando dei a eles o nome Valor<n> (onde <n> corresponde a um número sequencial, que no seu caso, seria de 1 a 84). Este procedimento nos viabiliza o uso do método FindComponent(<nome_componente>) (do Form), que nos retorna o componente (neste caso um Edit), do qual podemos converter seu valor textual em valor numérico, em um loop, para que possamos chegar ao resultado final (o valor total digitado nos edits) a ser colocado em um label (ValorTotal):
// Procedimento para totalizar Edits
procedure TForm1.CalcValues;
const
  MaxNumEdits = 8;  // define máximo indexador dos Edits a verificar - no seu caso será 84
var
  Idx :Byte;
  Total :Double;
  edValue :TEdit;
begin
  Total := 0;
  for Idx := 1 to MaxNumEdits do
  begin
    edValue := FindComponent(Format('Valor%d', [Idx])) as TEdit;
    if Assigned(edValue) and
       (edValue.Text <> '') then
      Total := Total +StrToFloat(StringReplace(edValue.Text, '.', '', [rfReplaceAll]));
  end;
  ValorTotal.Caption := FormatFloat('#,##0.00', Total);
end;
Bom, este procedimento para totalização deverá atualizar o label ValorTotal, a cada valor informado. Para isso, como você já havia instruído, teremos que fazê-lo no evento OnExit de cada Edit. Mas não vamos escrever o mesmo código para o evento de cada um dos edits do form, já que todos farão a mesma coisa. Assim, já que sabemos que o parâmetro Sender neste evento, diz respeito ao edit que o chamou, escreveremos o procedimento genérico para um e depois atribuímos ao evento dos outros Edits. Neste procedimento faremos a validação do valor digitado para, só depois, chamar o procedimento de totalização, já com um valor válido:
// procedimento do evento OnExit do 1º edit, posteriormente atribuído ao evento dos demais
procedure TForm2.Valor1Exit(Sender: TObject);
var
  Value :Double;
begin
  try
    Value := StrToFloat(StringReplace(TEdit(Sender).Text, '.', '', [rfReplaceAll]));
    TEdit(Sender).Text := FormatFloat('#,##0.00', Value);  // reformatamos o edit
    CalcValues;  // atualiza label com valor total
  except
    on E:Exception do
    begin
      E.Message := Format('"%s" não é um valor válido!', [TEdit(Sender).Text]);
      TEdit(Sender).SetFocus;
      raise;
    end;
  end;
end;
E por último, tem a questão de que ao teclar ENTER, estando o edit nulo, deve ser verificado o valor do edit anterior e atribuído a este último. Ainda incrementando esta questão, automaticamente passamos o foco para o próximo edit, agilizando a digitação. Para isto, de modo similar ao feito com evento OnExit, criamos o procedimento para o evento OnKeyDown do 1º edit e o atribuímos ao respectivo evento dos demais:
// procedimento do evento OnExit do 1º edit, posteriormente atribuído ao evento dos demais
procedure TForm2.Valor1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  Edit :TEdit;
begin           
  if (Key = VK_RETURN) and (Shift = []) then
  begin
    if (TEdit(Sender).Tag > 1) and
       (Trim(TEdit(Sender).Text) = '') then
    begin
      Edit := FindComponent(Format('Valor%d', [TEdit(Sender).Tag -1])) as TEdit;
      TEdit(Sender).Text := Edit.Text;
    end;
    FindNextControl(TEdit(Sender), True, True, True).SetFocus;
  end;
end;

Como é possível observar, também fiz uso da propriedade TAG. Para cada edit, também atribuí a esta propriedade o respectivo número seqüencial. Este procedimento, otimiza bastante a obtenção da posição (número) do edit (atual, anterior e posterior).

Este processo de atribuir o evento do 1º componente para os demais, não tem nada de tedioso. Basta que selecione todos os componentes edit e na propriedade OnExit e OnKeyDown (via janela Object inspector) selecione o respectivo procedimento que aparecerá na lista.

Alguém poderia ainda questionar o porque de eu não ter utilizado o evento OnKeyDown do Form (tendo sua propriedade KeyPreview habilitada), ao invés de utilizar o de cada edit. Na verdade, poderia ser feito deste modo sim. Apenas optei por esta abordagem, porque caso hajam outros edits no form o código teria que ser um pouco mais truncado. Isto porque, monitorando todos os evento OnKeyDown que o form recebe, deveríamos testar a classe do sender, para saber se trata-se de um TEdit e, sendo um, teríamos de verificar se por acaso seria um dos que desejamos processar e não outro.

Bom, segue anexo esta nova versão (os comentários do código estão nela). Espero que seja de maior utilidade agora e que tenham diminuídas as suas dúvidas (aguardo as próximas ;)).

Abraços

ProjEder2.zip

Link para o comentário
Compartilhar em outros sites

  • 0
Bom, segue anexo esta nova versão (os comentários do código estão nela). Espero que seja de maior utilidade agora e que tenham diminuídas as suas dúvidas (aguardo as próximas

R.: Ola..Micheus...o arquivo esta corrompido com o exemplo, mas beleza montei um exemplo com a sua explicação, funcionou certinho..ficou fácil agora colocar até mais edit´s(mais de 84), pois é só acrescentar e direcionar os codigos pra eles...e mudar a Procedure atraves do números de edit´s no FOR.

Haaa..agora que entendi a funcionalizadade das TAG, nunca havia usado ela pra nada, pelo menos que me lembro.

Beleza...valeu muito grato, desta vez não tive dúvidas hehehe....

Se aparecer......dou um toque..

t+abraços.

:D

Link para o comentário
Compartilhar em outros sites

  • 0
R.: Ola..Micheus...o arquivo esta corrompido com o exemplo, mas beleza montei um exemplo com a sua explicação, funcionou certinho..
Pois eu baixei o danado aqui e não deu problemas denovo. :wacko:

Parece que você está premiado.

ficou fácil agora colocar até mais edit´s(mais de 84), pois é só acrescentar e direcionar os codigos pra eles...
Se os edits forem todos do mesmo tamanho e posição, ficaria mais fácil é adicionar eles em run-time.

e mudar a Procedure atraves do números de edit´s no FOR.
você quiz dizer apenas trocar o número (valor) da constante MaxNumEdits - este é o objetivo dela, facilitar este tipo de alteração. Pensando na possibilidade de adicionar os Edits em run-time, esta constante deveria ficar global à unit (não a procedure), e assim, ao alterá-la automaticamente você estaria modificando a quantidade de edits processados na função de totalização, bem como na de criação dos edits. ;)

Haaa..agora que entendi a funcionalizadade das TAG, nunca havia usado ela pra nada, pelo menos que me lembro.
pois é, tem que servir para alguma coisa. hehehe

Observe que ela é do tipo Inteiro (longo), assim, va pode armazenar qualquer coisa nestes 4bytes (até um ponteiro, fazendo um type-cast)

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --Sueli --
Micheus.....já havia conseguido abrir seu exemplo no D4 e compilei legal....sem nenhum problema...

Só to meio perdido no seu código ainda..hehehe....pois achava que era simples o lance de repetir os edit´s...e é bem complicadinho...

Eu uso o aplicativo...bem diferente do seu exemplo...tipo eu coloco no OnExit do edit1 assim:

Var
Valor1, valor2, valor3 : real;
begin
valor1:=StrToFloat(edit1.text);
valor2:=StrToFloat(edit2.text);
valor3:=StrToFloat(edit3.text);
LabelResultado.Caption:=FloatToStr(Valor1+Valor2+Valor3);

e ai eu aponto no Onexit do edit2 e edit3 pra o OnExit do edit1

Resumindo:

a medida que vou lançando o valor nos edit´s o resultado vai somando no LabelREsultado...

Como vê é diferente do seu exemplo.....

valeu...bom final de semana

Grato :)

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...