terça-feira, 28 de dezembro de 2010
Como traduzir as mensagens do Delphi
segunda-feira, 20 de dezembro de 2010
Cálculo do Dígito Verificador da Chave de Acesso do CT-e
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;
-
function GetIP:string;//--> Declare a Winsock na clausula uses da unit var WSAData: TWSAData; HostEnt: PHostEnt; Name:string; begin...
-
Vamos criar uma API REST simples em Delphi. Para isso, usaremos o Delphi 7 com Indy components (se for o que você tem disponível) ou, se est...