terça-feira, 28 de dezembro de 2010

Como traduzir as mensagens do Delphi

Boa tarde,
Abaixo uma dica valiosa de como traduzir as mensagens que o delphi retorna, após identificar uma operação ilegal.
O arquivo das mensagens que você deverá traduzir está em \Arquivos de Programas\ Borland\ Delphixx\ Source\ Vcl\ Consts.pas.
Traduza as mensagens normalmente. Depois de alterar o arquivo, eu salvo uma cópia na pasta \bin e na pasta \lib. O programa já funciona com os alertas traduzidos.
Você deverá traduzir também o arquivo DBConsts.pas que contém as mensagens relativas a componentes database.

segunda-feira, 20 de dezembro de 2010

Cálculo do Dígito Verificador da Chave de Acesso do CT-e

Fonte:  www.activedelphi.com.br

Antes de demonstrar como gerar o digito verificador, vamos entender do que é composta a chave de acesso.
A Chave de Acesso do Conhecimento de Transporte Eletrônico é representada por uma seqüência de 44 caracteres numéricos, representados da seguinte forma:
Código da UF - Código da UF do emitente do Documento Fiscal (Tamanho 2 caracteres)
Ano e Mês da Emissão (AAMM) - Ano e Mês de emissão do CT-e (Tamanho 4 caracteres)
CNPJ - CNPJ do emitente (Tamanho 14 caracteres)
Modelo - Modelo do Documento Fiscal (Tamanho 2 caracteres)
Série - Série do Documento Fiscal (Tamanho 3 caracteres)
Numero do CTe - Número do Documento Fiscal (Tamanho 9 caracteres)
Código Numérico - Código Numérico que compõe a Chave de Acesso (Tamanho 9 caracteres)
Digito - Dígito Verificador da Chave de Acesso (Tamanho 1 caractere)

O Cálculo
O dígito verificador da chave de acesso do CT-e é baseado em um cálculo do módulo 11. O módulo 11 de um número é calculado multiplicando-se cada algarismo pela seqüência de multiplicadores 2,3,4,5,6,7,8,9,2,3, ... posicionados da direita para a esquerda.
A somatória dos resultados das ponderações dos algarismos é dividida por 11 e o DV (dígito verificador) será a diferença entre o divisor (11) e o resto da divisão:
DV = 11 - (resto da divisão)
Quando o resto da divisão for 0 (zero) ou 1 (um), o DV deverá ser igual a 0 (zero).
Vamos exemplificar toda essa teoria no Delphi.
Primeiro devemos desenhar o formulário. Nesse exemplo estou utilizando dois edit’s para exemplificar melhor o funcionamento, porém em seu projeto poderá realizar tudo no mesmo Edit. Coloquei também um botão para acionar o evento do cálculo quando clicar. Veja como ficou a interface na figura 1:
 O primeiro Edit vamos chamá-lo de edtChave. O segundo Edit, de edtDV.
No edtChave, vamos informar uma chave de exemplo, retirada da página 74 do Manual de Integração – Contribuinte Padrões Técnicos de Comunicação.

Chave Exemplo: 5206043300991100250655012000000780026730161. O dígito verificador dessa chave deverá ser igual à “5”
Agora vamos ao código do botão.  O algoritmo foi montada de forma bem primária para facilitar o entendimento, mas lembre-se que você pode usar arrays para facilitar:
procedure TForm1.btnGerarDigitoClick(Sender: TObject);
Var
  // Essas serão as variáveis responsáveis por armazenar cada numero da chave
  V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17,
    V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30, V31, V32,
    V33, V34, V35, V36, V37, V38, V39, V40, V41, V42, V43: Real;
 
  // as variáveis abaixo serão responsáveis por armazenar os resultados
  //das multiplicações
  R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17,
    R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32,
    R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43: Real;
 
  // Utilizaremos as variáveis abaixo para formulação do resultado
  Soma, Divisao, Resultado: Real;
  SomaI: integer;
begin
  // Através do código abaixo, vamos separar os valores com a “função Copy”
  //da chave de acesso
  V1 := StrToFloat(Copy(edtChaveAcesso.Text, 1, 1));
  V2 := StrToFloat(Copy(edtChaveAcesso.Text, 2, 1));
  V3 := StrToFloat(Copy(edtChaveAcesso.Text, 3, 1));
  V4 := StrToFloat(Copy(edtChaveAcesso.Text, 4, 1));
  V5 := StrToFloat(Copy(edtChaveAcesso.Text, 5, 1));
  V6 := StrToFloat(Copy(edtChaveAcesso.Text, 6, 1));
  V7 := StrToFloat(Copy(edtChaveAcesso.Text, 7, 1));
  V8 := StrToFloat(Copy(edtChaveAcesso.Text, 8, 1));
  V9 := StrToFloat(Copy(edtChaveAcesso.Text, 9, 1));
  V10 := StrToFloat(Copy(edtChaveAcesso.Text, 10, 1));
  V11 := StrToFloat(Copy(edtChaveAcesso.Text, 11, 1));
  V12 := StrToFloat(Copy(edtChaveAcesso.Text, 12, 1));
  V13 := StrToFloat(Copy(edtChaveAcesso.Text, 13, 1));
  V14 := StrToFloat(Copy(edtChaveAcesso.Text, 14, 1));
  V15 := StrToFloat(Copy(edtChaveAcesso.Text, 15, 1));
  V16 := StrToFloat(Copy(edtChaveAcesso.Text, 16, 1));
  V17 := StrToFloat(Copy(edtChaveAcesso.Text, 17, 1));
  V18 := StrToFloat(Copy(edtChaveAcesso.Text, 18, 1));
  V19 := StrToFloat(Copy(edtChaveAcesso.Text, 19, 1));
  V20 := StrToFloat(Copy(edtChaveAcesso.Text, 20, 1));
  V21 := StrToFloat(Copy(edtChaveAcesso.Text, 21, 1));
  V22 := StrToFloat(Copy(edtChaveAcesso.Text, 22, 1));
  V23 := StrToFloat(Copy(edtChaveAcesso.Text, 23, 1));
  V24 := StrToFloat(Copy(edtChaveAcesso.Text, 24, 1));
  V25 := StrToFloat(Copy(edtChaveAcesso.Text, 25, 1));
  V26 := StrToFloat(Copy(edtChaveAcesso.Text, 26, 1));
  V27 := StrToFloat(Copy(edtChaveAcesso.Text, 27, 1));
  V28 := StrToFloat(Copy(edtChaveAcesso.Text, 28, 1));
  V29 := StrToFloat(Copy(edtChaveAcesso.Text, 29, 1));
  V30 := StrToFloat(Copy(edtChaveAcesso.Text, 30, 1));
  V31 := StrToFloat(Copy(edtChaveAcesso.Text, 31, 1));
  V32 := StrToFloat(Copy(edtChaveAcesso.Text, 32, 1));
  V33 := StrToFloat(Copy(edtChaveAcesso.Text, 33, 1));
  V34 := StrToFloat(Copy(edtChaveAcesso.Text, 34, 1));
  V35 := StrToFloat(Copy(edtChaveAcesso.Text, 35, 1));
  V36 := StrToFloat(Copy(edtChaveAcesso.Text, 36, 1));
  V37 := StrToFloat(Copy(edtChaveAcesso.Text, 37, 1));
  V38 := StrToFloat(Copy(edtChaveAcesso.Text, 38, 1));
  V39 := StrToFloat(Copy(edtChaveAcesso.Text, 39, 1));
  V40 := StrToFloat(Copy(edtChaveAcesso.Text, 40, 1));
  V41 := StrToFloat(Copy(edtChaveAcesso.Text, 41, 1));
  V42 := StrToFloat(Copy(edtChaveAcesso.Text, 42, 1));
  V43 := StrToFloat(Copy(edtChaveAcesso.Text, 43, 1));
 
  // Conforme explicado anteriormente neste artigo, faremos a multiplicação
  // por  2,3,4,....9
  R43 := V43 * 2;
  R42 := V42 * 3;
  R41 := V41 * 4;
  R40 := V40 * 5;
  R39 := V39 * 6;
  R38 := V38 * 7;
  R37 := V37 * 8;
  R36 := V36 * 9;
  R35 := V35 * 2;
  R34 := V34 * 3;
  R33 := V33 * 4;
  R32 := V32 * 5;
  R31 := V31 * 6;
  R30 := V30 * 7;
  R29 := V29 * 8;
  R28 := V28 * 9;
  R27 := V27 * 2;
  R26 := V26 * 3;
  R25 := V25 * 4;
  R24 := V24 * 5;
  R23 := V23 * 6;
  R22 := V22 * 7;
  R21 := V21 * 8;
  R20 := V20 * 9;
  R19 := V19 * 2;
  R18 := V18 * 3;
  R17 := V17 * 4;
  R16 := V16 * 5;
  R15 := V15 * 6;
  R14 := V14 * 7;
  R13 := V13 * 8;
  R12 := V12 * 9;
  R11 := V11 * 2;
  R10 := V10 * 3;
  R9 := V9 * 4;
  R8 := V8 * 5;
  R7 := V7 * 6;
  R6 := V6 * 7;
  R5 := V5 * 8;
  R4 := V4 * 9;
  R3 := V3 * 2;
  R2 := V2 * 3;
  R1 := V1 * 4;
 
  // Somaremos os valores obtidos dos resultados das multiplicações
  Soma := R1 + R2 + R3 + R4 + R5 + R6 + R7 + R8 + R9 + R10 + R11 + R12 + R13 +
    R14 + R15 + R16 + R17 + R18 + R19 + R20 + R21 + R22 + R23 + R24 + R25 +
    R26 + R27 + R28 + R29 + R30 + R31 + R32 + R33 + R34 + R35 + R36 + R37 +
    R38 + R39 + R40 + R41 + R42 + R43;
 
  SomaI := Trunc(Soma);
  Divisao := (SomaI mod 11);
  Resultado := 11 - Divisao;
 
  // Compara se o resultado é igual a 1 (Se for deverá ser = 0)
  if Resultado = 1 then
    edtDV.Text := '0'
  else
    edtDV.Text := FloatToStr(Resultado);
end;
Pronto!! Agora é só adaptar o algoritmo ao seu projeto. Para customizar e reduzir o tamanho do código, você poderá utilizar arrays para alimentação das variáveis e multiplicação dos resultados.

quarta-feira, 3 de novembro de 2010

Trabalhando com horas

Se você esta querendo fazer um acumulador de horas, você pode criar dois acumuladores, um para horas, e, outro para minutos.

 

Exemplo:

 

Type

TypeHora:Array[1..2] of interger;

 

Procedure Acumula:TypeHora;

Var

Hora,minuto:Integer;

Begin

  Hora:=Hora+StrToInt(Copy(DateTimeToStr(Time()),1,2));

  Minuto:=Minuto+StrToInt(Copy(DataTimeToStr(Time()),4,5));

  If Minuto >= 60 Then Begin

      Hora:=Hora+1;

      Minuto:=0;

  end;

  Acumula[1]:=Hora;

  Acumula[2]:=Minuto;

End;

Desta forma voce pode armazemar por exemplo o numero de horas que uma pessoa trabalhou durante o mes...

Validar datas

try

   StrToDate(Edit1.Text); //--Entre parenteses informar a data a ser validada.

except

   on EConvertError do

   ShowMessage ('Data Inválida!');

end;

Obtendo o extenso do mês passado por parâmetro

Function MesExtenso (xMes : Variant) : string;

Var

  Dia, Mes, Ano : Word;

begin

  Mes := 0;

  Case VarType (xMes) of

  VarDate : DecodeDate (xMes, Ano, Mes, Dia);

  VarString :

  Try

   Mes := StrToInt (xMes);  

  Except

  End;

  else

  Try

   Mes := Round (xMes);

  Except

  End;

end;

 case Mes of

 1: Result := 'Janeiro';

 2: Result := 'Fevereiro';

 3: Result := 'Março';

 4: Result := 'Abril';

 5: Result := 'Maio';

 6: Result := 'Junho';

 7: Result := 'Julho';

 8: Result := 'Agosto';

 9: Result := 'Setembro';

 10: Result := 'Outubro';

 11: Result := 'Novembro';

 12: Result := 'Dezembro';

 else

  Result := '';

 end;

end;

 

Obtendo o próximo dia útil caso a data informada caia em um fim de semana

Function ProximoDiaUtil (dData : TDateTime) : TDateTime;

begin

    if DayOfWeek(dData) = 7 then

         dData := dData + 2

    else

    if DayOfWeek(dData) = 1 then

         dData := dData + 1;

    ProximoDiaUtil := dData;

end;

 

Quantos fins de semana já se passaram no corrente ano

A função abaixo retorna quantos finais de semana já se passaram no ano corrente:

 

function WeekNum(const TDT:TDateTime) : Word;

var

                Y,M,D:Word;

                dtTmp:TDateTime;

begin

                DecodeDate(TDT,Y,M,D);

                dtTmp := EnCodeDate(Y,1,1);

                Result := (Trunc(TDT-dtTmp)+(DayOfWeek(dtTmp)-1)) DIV 7;

                if Result = 0 then begin

                       Result := 51

                end

                else

                begin

                       Result := Result-1;

                end;

End;

Curso de Delphi: 7.Consultas SQL