|
Usuários |
|
80 Usuários Online
|
|
[Artigos]
Como Trabalhar com data e moeda no Delphi/Interbase |
Publicado por invdjhack : Sexta, Setembro 24, 2004 - 09:13 GMT-3 (34257 leituras)
7 Comentários Enviar para um amigo Versão para impressão
|
Bom, esse como é meu primeiro artigo para o site da Active espero não decepcionar, pois vou abordar um assunto que com certeza deve assombrar milhares de programadores iniciantes. E talvez alguns mais experientes; trabalhar com Datas e Valores Monetários utilizando o Delphi como ferramenta de programação e o Interbase como servidor de banco de dados existe alguns contratempos, nesse esclarecimento foram utilizados o Delphi 6 e Interbase 6, para que não haja dúvidas com relação a incompatibilidades ou coisas do tipo, bom chega de enrrolação e vamos ao que interessa. Sempre tive problemas em trabalhar com Datas e Moedas (valores monetários) no Delphi e Interbase pelo motivo de a Data nos Estados Unidos ser utilizada mm/dd/yyyy (mês/dia/Ano) e no Brasil ser “dd/mm/yyyy” ou “dd/mm/aaaa” (dia/mês/Ano);
Quando eu utilizava valores de datas nos meus programas utilizando o campo específico para tratamento de datas no Interbase (Dt_Pedido Date), sempre tinha problemas na hora de guardar o valor através de comandos SQL (Insert ou Update) pelo motivo do Interbase automaticamente fazer essa conversão e dar um erro, porque quando eu mandava guardar por exemplo a data 13/09/2004 (treze de setembro de 2004), ele tentava guardar dessa mesma forma só que tem um porém, lá fora o formato é diferente, ele enxerga 13/09/2004 como mm/dd/aaaa ou seja, mês/dia/ano e o mês “13” não existe, SACOU O QUE EU ESTOU TENTANDO DIZER?
Para contornar o problema, ao gravar o valor da data eu faço um macete antes, crio uma variável do tipo Tdate, mando guardar o valor do edit.text ou maskedit.text da data, faço a conversão “ShortDateFormat := 'mm/dd/yyyy'”, depois e pego o valor da variável Tdate e jogo devolta no edit.text e mando gravar ou atualizar o banco de dados (Insert ou Update), e depois para não haver maiores complicações eu dou o comando ShortDateFormat de novo só que ao contrário “ShortDateFormat := 'dd/mm/yy'yy”, só que para fazer isso, primeiro você deve definir com qual formato de data você deseja trabalhar (dd/mm/yyyy ou dd/mm/yy) e para fazer isso verifique em Painel de Controle/Configurações Regionais/Data/Estilo de Data Abreviada no Windows;
Exemplo do comando
Var
Data : Tdate;
Begin
{pegar o valor do campo e jogar na variável}
Data := StrtoDate(Maskedti1.text);
{converter para o formato americano}
ShortDateFormat := 'mm/dd/yyyy'
{pegar o valor da variável já formatado e jogar de volta no campo}
Maskedit1.text:= DatetoStr(Data);
{executar os comandos SQL (Insert ou Update}
..........
{retornar o formato de data para o português}
ShortDateFormat := 'dd/mm/yyyy'
End;
Para se trabalhar com valores monetários, existem muitos tipos no Interbase (Decimal, Double, Numeric) mais para escolher o melhor fica a critério de cada um, tive uma experiência semelhante com a data só que o problema era ao se trabalhar com valores quebrados (centavos), utilizando o tipo de dado Double ao gravar um valor tipo R$ 1,00, ele guarda “1”, só que ao guardar R$ 1,50 ele guarda “1,50678595759”, e isso gera um problema ao recuperar o valor de volta, porque pela lógica, na hora de arredondar este valor ele viria com R$1,51, alguns devem pensar UM CENTAVO? QUE DIFERENÇA ISSO FAZ? MUITO É A RESPOSTA, pois de grão em grão a galinha enche o papo, em programas em que o cálculo é crucial para um fechamento de caixa exato, os centavos, fazem muita diferença, pois a cada mudança nos dados, o valor iria aumentar.
Então depois de muita procura e decidi usar o campo NUMERIC no formato 9,2 (Vl_Venda Numeric(9,2)), assim ele guarda o valor exato no formato moeda (exemplo R$1,50 = 1,5) assim não tem erro, mas E NA HORA DE GRAVAR? O esquema é o mesmo. Criar uma variável do tipo DOUBLE e:
Var
Valor : Double;
Begin
{pegar o valor do campo e jogar na variável}
Valor := StrtoFloat(Trim(edti1.text));
{converter para o formato americano}
DecimalSeparator := '.';
{pegar o valor da variável já formatado e jogar de volta no campo}
Edit1.text:= FloattoStr(Valor); ou Edit1.text:= Format(‘&f’, [Valor]);
{executar os comandos SQL (Insert ou Update}
..........
{retornar o formato de data para o português}
DecimalSeparator := ',';
End;
Explicação:
“Nos Estados Unidos o ponto decimal de moeda é “.”(ponto) e não “,” (vírgula), ou seja, no Brasil hum mil em reais se é representado monetariamente por 1.000,00, já hum mil dólares é 1,000.00, notou a diferença da vírgula pelo ponto, bom para programadores experientes isso é mais do que claro, mais para quem esta começando vai esclarecer muitas dúvidas, pode ter certeza.
A respeito do formato do campo ser Numeric(9,2) :
9 = números de caracteres a direita do ponto decimal (exemplo até 100.000.000,00 cem milhões)
2= números de casa após a vírgula (exemplo 0,12)
Se quiser, voce também pode utilizar Numeric(18,2) que é para valores monetários de grande quantidade (exemplo até 100.000.000.000.000.000,00 cem quadrilhões).
Veja um exemplo de um comando completo, trabalhando com datas e valores:
Var
vl1,vl2: double;
d1 : Tdate;
begin
{pegar o valor dos campos valor e jogar na variável do tipo double}
vl1:= strtoFloat(editdesc.Text);
vl2:= strtoFloat(lblvl.Caption);
{pegar o valor do campos data e jogar na variavel do tipo data}
d1:=strtodate(lbldtloc.Caption); //dt locação
{converter o formato da data e moeda para ingles ao gravar}
ShortDateFormat := 'mm/dd/yyyy';
DecimalSeparator := '.';
{jogar a data em formato ingles de volta no campo}
lbldtloc2.Caption:= DatetoStr(d1);
{jogar os valores em formato ingles de volta nos campos}
Editdesc.text:=Format('%f', [vl1]);
lblvl.Caption:=Format('%f', [vl2]);
{comando para gravar}
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add('Insert into Locacao (Dt_loc, cod_cli, desconto, vl_tot) values ('#39+lbldtloc.Caption+#39','#39+lblcodcliente.Caption+#39','#39+editdesc.Text+#39','#39+lblvl.Caption+#39')');
IBQuery1.ExecSQL;
{esse comando é para confirmar a gravação e atualizar o banco de dados}
IBTransaction1.Commit;
{converter o formato da data e moeda para o portugues}
DecimalSeparator := ',';
ShortDateFormat := 'dd/mm/yyyy';
End;
Só para finalizar, as pessoas devem perguntar; para que ter esse trabalho todo já que se pode também trabalhar com Campos do tipo Varchar e Char?
Resposta: Estão nos comandos SQL disponíveis;
1-) para se ter todos os pedidos realizados no mês 09/2004 exibidos em um BDGrid é só fazer:
Var
C : string;
begin
Mskdata.text = ‘09’;
Eano.text = ‘2004’;
C:='Select * from Locacao where (extract(MONTH from dt_conf) = '#39+mskdata.Text+#39') and (extract(YEAR from dt_conf) = '#39+eano.Text+#39')';
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add(C);
IBQuery1.Open;
if IBQuery1.EOF = False Then
end;
2-) para se ter o valor total dos pedidos realizados no mesmo mês e guardar esse valor em uma variável para exibílo em um Label por exemplo, é só fazer:
var
vl : double;
begin
C:='Select sum(vl_tot) AS Total from Locacao where (extract(MONTH from dt_conf) = '#39+mskdata.Text+#39') and (extract(YEAR from dt_conf) = '#39+eano.Text+#39')';
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add(C);
IBQuery1.Open;
if IBQuery1.EOF = False Then
begin
lalel1.Caption:= dm1.IBQuery1.FieldbyName('Total').AsString;
vl:=StrToFloat(trim(label1.Caption));
label2.caption:=Format('%m', [vl]);
end;
Bom, essa foi a minha pequena contribuição para o site Active, agradeço pela atenção, e logo estarei postando outras dúvidas para programadores iniciantes.
Contato:
Email: invdjhack@uol.com.br
MSN: djandx@msn.com
|
|
Comentários | |
| | Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos. |
por: hugoleonardo : Set 25, 2004 - 01:26 (Informações sobre o membro | Enviar uma mensagem)
http://planeta.terra.com.br/informatica/novoportal
|
Puxa que arrodeio para tratar datas e valores monetários com Interbase.
Tenho saudades do velho Clipper que embutia tudo isso automaticamente para nós bastando um simples SET DATE BRITISH no início do módulo principal!
Parece que ao contrário da facilitar essas linguagens novas acabam nos impondo certas convenções que terminam complicando tudo de novo.
Estou començando a migrar meu método programação de tabelas dbase e paradox para FireBird e espero que hajam outros mecanismos mais automáticos ou embutidos para trabalharmos com as datas e valores monetários.
Quando ao artigo está nota 10.
|
por: wilsioneLessa : Out 22, 2004 - 11:12 (Informações sobre o membro | Enviar uma mensagem)
|
Fala aí ...
Sou programador iniciante, e ando tendo um problema que se chama "VALIDAR DATAS", até que se encontra na internet uma função que valida com a seguinte idéia:
- Converter um texto para data (strtodate)
- Se o texto não for válido ocorrerá um erro
- Se houver um erro Showmessage('data inválida')
Legal, a idéia é boa só que quando acontece a conversão o programa trava antes da menssagem aparecer.
Deu pra notar que, em se falando em data e hora, vc não é bobo.
vc têm alguma solução pra mim????
Valeu.
|
por: invdjhack : Out 24, 2004 - 03:26 (Informações sobre o membro | Enviar uma mensagem) http:// | Caro Amigo, se afunção que vc esta falando é
try
StrToDate(Edit1.Text);
except
on EConvertError do
ShowMessage ('Data Inválida!');
end;
a função está certa, mas deve ser usada no evento ao sair do edit, mas se estiver travando seu programa, verifique seu código fonte, pois pode haver alguma outra função que está entrando em um tipo de conflito, vê se voce não colocou alguma outra função que não esta usando e esqueceu de tirá-la da Unit | [ Comentários não permitidos para usuários anônimos. Por gentileza, registre-se ou conecte-se ao sistema
por: invdjhack : Dez 16, 2004 - 06:59 (Informações sobre o membro | Enviar uma mensagem) http:// | | Se liga, eu andei meio ocupado, a solução para a tua dúvida caso não tenha conseguido encontrar ainda é a seguinte: a função é um except, e se vc estiver tentando executar o programa com o delphi aberto vai dar erro mesmo, faz o seguinte, compila o programa e roda ele fora do delphi, sacou???? | [ Comentários não permitidos para usuários anônimos. Por gentileza, registre-se ou conecte-se ao sistema
por: getulio.gomes : Nov 18, 2004 - 09:53 (Informações sobre o membro | Enviar uma mensagem) http:// | se vc usar DateTimePicker (componente delphi - Win32) ele nao pernite data invalida, e se a data for vazia voce pode avaliar da seguinte maneira.
IF DT_CADASTRO.DATE = 0 THEN
SHOWMESSAGE('INFORME A DATA DE CADASTRO' ) THEN .... | [ Comentários não permitidos para usuários anônimos. Por gentileza, registre-se ou conecte-se ao sistema
por: getulio.gomes : Nov 18, 2004 - 09:49 (Informações sobre o membro | Enviar uma mensagem)
http://
|
|
Bem. eu trabalho com D6 e IB6 a um bom tempo e nunca os problemas descritos no artigo, porem venho ultimamente tendo um outro problema relacionado a data. Quando grava um registro que contenha um campo data e este nao e informado, (nao sei se é o D6 ou o IB6) é gravado uma data maluca "30/11/1899". Ja tentei de todas as formas e nao conseguir descubir o porque.
|
por: invdjhack : Dez 16, 2004 - 07:01 (Informações sobre o membro | Enviar uma mensagem) http:// | | Se liga, se eu não me engano, essa data é a data origem, de onde começa a contar todas as datas do delphi, o motivo é pq vc esta gravando uma data vazia, ai o interbase tenta corrigir o problema susbtituindo o vazio por uma data qualquer, o problema é que ele põe a data nº 1, tem um artigo aqui no site dizendo a respeito de como fazer cálculo de datas, procura e da uma lida nele que vc vai saber do que eu estou falando, valeu | [ Comentários não permitidos para usuários anônimos. Por gentileza, registre-se ou conecte-se ao sistema
|
|
Edição 112 |
|
|
50 Programas Fontes |
|
|
Produtos |
|
|