Numeração sequencial com ano em documentos diferentes

Delphi

22/05/2013

Preciso criar uma função para gerar um número sequencial e adicionar o ano, por exemplo 0001/2013, 0002/2013..., e quando mudar o ano a numeração recomeça, por exemplo 0123/2013, 0124/2013, 0001/2014, 0002/2014...

Essa numeração servirá para um sistema de protocolo, sendo que os documentos protocolados são de vários tipos e deverão ter numeração própria, por exemplo:
Projeto de Lei Ordinária 0001/2013 o próximo deverá ser 0002/2013 e seguir assim até mudar o ano.

Se no mesmo dia ou em outro momento for cadastrado um outro tipo de documento a numeração deverá ter outra sequencia, como se segue:
Indicação 0001/2013 o próximo deverá ser 0002/2013 e seguir assim até mudar o ano.

Chegando um momento, em que de acordo com a quantidade diferenciada de documentos protocolados teremos:
Projeto de Lei Ordinária 0039/2013
Indicação 0128/2013

No formulário de cadastro de protocolo existe uma DBLookupCombobox, onde eu seleciono o tipo do documento, esta DBLookupCombobox está ligada a um ClientDataSet.

Até agora eu consegui fazer exatamente nada, não consigo pensar numa lógica pra gerar a numeração sequencial e diferenciada de acordo com o tipo escolhido.

Alguém pode me dar uma ajuda com duas mãos e um cérebro delphiano?
Celso Souza

Celso Souza

Curtidas 1

Respostas

Carlos Felippe

Carlos Felippe

22/05/2013

Como você esta identificando esse Tipos de Doc´s no BD?
GOSTEI 0
M. C.

M. C.

22/05/2013

Olá,

Você pode criar uma tabela só para controlar as sequencias de cada tipo de documento. Tanto você pode fazer em colunas uma para cada tipo de documento como por meio de registros. Quando você for gravar na tabela de movimentos você incrementa o valor atual na tabela de controle, recupera o valor e concatena com o ano da data atual. Simples, o resto é só teste de condição no ano de uma virada de ano.

Espero ter ajudado.

Boa Sorte!
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013

Como você esta identificando esse Tipos de Doc´s no BD?


O sistema é para gerenciamento do processo legislativo, os documentos criados fisicamente no BrOffice são denominados de PROPOSIÇÕES, o usuário depois de criar a proposição, vai até o sistema e cadastra a proposição criada, os dados são arquivados no banco de dados(Data, Tipo da Proposição, Autor, Ementa e Caminho) na tabela "TBL_PROPOSICAO", ao efetuar o cadastro o usuário tem que informar o tipo da proposição e ai o sistema vai buscar essa informação na tabela "TBL_TIPOPROPOSICAO", ao final do cadastro ele anexa o arquivo físico e o caminho de destino é salvo no banco de dados.

A numeração em questão, será necessária quando for protocolar em um outro formulário a Proposição cadastrada anteriormente, os dados desse formulário protocolo (Data do Protocolo, Hora do Protocolo, Nº do Protocolo, Tipo de Proposição, Nº da Proposição) são arquivados no banco de dados na tabela "TBL_PROTOCOLO", onde campo "Nº do Protocolo recebe a numeração sequencial com o ano e o campo Nº da Proposição recebe uma numeração sequencial com ano, e cada tipo de proposição terá a sua .

Será que consegui explicar o que você queria meu caro amigo?
Abraços
Celso
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013

Olá,

Você pode criar uma tabela só para controlar as sequencias de cada tipo de documento. Tanto você pode fazer em colunas uma para cada tipo de documento como por meio de registros. Quando você for gravar na tabela de movimentos você incrementa o valor atual na tabela de controle, recupera o valor e concatena com o ano da data atual. Simples, o resto é só teste de condição no ano de uma virada de ano.

Espero ter ajudado.

Boa Sorte!


Boa Noite Aprendiz!

Meu camarada, pega leve comigo, tenho 3 meses de Delphi. Perdoe a minha ignorância, mas eu não sei como passar a sua dica para a prática, mas mesmo assim muito obrigado por responder o tópico.
GOSTEI 0
M. C.

M. C.

22/05/2013

Olá,

Você pode criar uma tabela só para controlar as sequencias de cada tipo de documento. Tanto você pode fazer em colunas uma para cada tipo de documento como por meio de registros. Quando você for gravar na tabela de movimentos você incrementa o valor atual na tabela de controle, recupera o valor e concatena com o ano da data atual. Simples, o resto é só teste de condição no ano de uma virada de ano.

Espero ter ajudado.

Boa Sorte!


Boa Noite Aprendiz!

Meu camarada, pega leve comigo, tenho 3 meses de Delphi. Perdoe a minha ignorância, mas eu não sei como passar a sua dica para a prática, mas mesmo assim muito obrigado por responder o tópico.


Desculpa, não foi a minha intensão! (rs)

O procedimento que eu descrevi para você é bem simples, não tem misterio não.

Analise com calma o que eu descrevi e você conseguirá fazer o que deseja sem complicação alguma.

Se você sabe manipular dados com tabela e registros utilizando componentes DataSet, saberá fazer o que foi mencionado por mim.

Aposto em você e qualquer coisa é só perguntar.

Boa sorte!
GOSTEI 0
Alisson Santos

Alisson Santos

22/05/2013

Boa noite amigo.

Assim amigo, existe muitas maneiras de se fazer.
No caso, imaginemos que quando for efetuar a gravação do registro ele tem que gerar esse código para você.
Poderia fazer um sql pegando a quantidade de registro existente na tabela que vai ser gravado e somar mai 1. Ex: select count(*) + 1 from tabela passando o resultado para uma variavel e acrescentando o ano atual.
Pode ser utilizado um generator no banco de dados para fazer isso também pegando o numero que ele tem disparando mais um.
Pode ser feito pelo banco de dados direto, utilizando uma trigger.
Isso varia muito do seu conhecimento e regras de negócios.
Se precisar de auxilio me envie um e-mail em alissonsantoslp@hotmail.com.br que eu posso lhe auxiliar ou pode postar aqui sua duvida que vamos ajudando você a montar.
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013

Não esquenta não Aprendiz, eu estava apenas descontraindo.

Voce e o amigo Alisson, me deram uma direção, e eu vou partir nela, mas com certeza vou retornar neste tópico com os montes de erros que o sistema irá apresentar, hahahahahahahaha.

Estou pensando em criar no banco de dados uma trigger, que no evento before insert da tabela TBL_PROTOCOLO chame uma procedure, também do banco de dados, para gravar em uma outra tabela TBL_NUMERACAO, somente o tipo de proposição e a numeração da maldita, certo? Na procedure eu escrevo o código para incrementar a numeração com o ano, mas o problema é que eu não sei e nem achei nenhum código para excecutar o incremento dessa numeração com o ano.
GOSTEI 0
M. C.

M. C.

22/05/2013

Não esquenta não Aprendiz, eu estava apenas descontraindo.

Voce e o amigo Alisson, me deram uma direção, e eu vou partir nela, mas com certeza vou retornar neste tópico com os montes de erros que o sistema irá apresentar, hahahahahahahaha.

Estou pensando em criar no banco de dados uma trigger, que no evento before insert da tabela TBL_PROTOCOLO chame uma procedure, também do banco de dados, para gravar em uma outra tabela TBL_NUMERACAO, somente o tipo de proposição e a numeração da maldita, certo? Na procedure eu escrevo o código para incrementar a numeração com o ano, mas o problema é que eu não sei e nem achei nenhum código para excecutar o incremento dessa numeração com o ano.


Pra inicio você não precisa "complicar" muito não. Cria as tabela no "basicão", a cada novo documento que for entrar você soma + 1 ao número anterior e pronto. Quanto ao ano você faça a veificação de o ano mudou, daí registra isso novamente (iniciando um novo sequencia na tabela de "controle") e pronto, passa incrementar a novo sequencia. Simples!

Qualquer coisa, é só perguntar.
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013


Pra inicio você não precisa "complicar" muito não. Cria as tabela no "basicão", a cada novo documento que for entrar você soma + 1 ao número anterior e pronto. Quanto ao ano você faça a veificação de o ano mudou, daí registra isso novamente (iniciando um novo sequencia na tabela de "controle") e pronto, passa incrementar a novo sequencia. Simples!

Qualquer coisa, é só perguntar.


Boa noite Aprendiz.

Cara o lance de fazer as tabelas é uma boa ideia, mas tem um porém, os tipos de documento são 13 então, neste caso, eu deveria criar nove tabelas diferentes pra cada tipo?
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013

A função para verificar o ano e gerar a numeração já está pronta! Tá andando o troço! Quando estiver tudo pronto e funcionando eu posto aqui o resultado.

function Tfrm_Protocolo.Numerar(Num, Calendar: string): string;
var
 S, D: integer;
 Ano, Mes, Dia: string;
    begin
        Ano := '/' + IntToStr(YearOf(Date));
            if MonthOf(Date) < 10 then
              Mes := '/0' + IntToStr(MonthOf(Date))
              else
              Mes := '/' + IntToStr(MonthOf(Date));
            if DayOf(Date) < 10 then
              Dia := '/0' + IntToStr(DayOf(Date))
              else
              Dia := '/' + IntToStr(DayOf(Date));
        if  Calendar = 'Ano' then
            Calendar := Ano;
        if  Calendar = 'Mes' then
            Calendar := Mes;
        if  Calendar = 'Dia' then
            Calendar := Dia;
        if (Num <> '') and (Calendar = Copy(Num, Pos('/', Num), Length(Calendar))) then
            begin
              D := (Pos('/', Num) - 1);
              S := StrToInt(Copy(Num, 1, D)) + 1;
              FmtStr(Num, '%.' + IntToStr(D) + 'd', [S]);
              Result := Num + Calendar;
            end
        else
            Result := '0001' + Calendar;
    end;
end.
GOSTEI 0
M. C.

M. C.

22/05/2013


Pra inicio você não precisa "complicar" muito não. Cria as tabela no "basicão", a cada novo documento que for entrar você soma + 1 ao número anterior e pronto. Quanto ao ano você faça a veificação de o ano mudou, daí registra isso novamente (iniciando um novo sequencia na tabela de "controle") e pronto, passa incrementar a novo sequencia. Simples!

Qualquer coisa, é só perguntar.


Boa noite Aprendiz.

Cara o lance de fazer as tabelas é uma boa ideia, mas tem um porém, os tipos de documento são 13 então, neste caso, eu deveria criar nove tabelas diferentes pra cada tipo?


Antes de mais nada me desculpa na demora em lhe respoder.

Não, não!!!

Você pode cria uma única tabela, daí você cria 13 colunas. Entendeu?

Exemplo:

-----------------
Tabela Sequencias
-----------------
coluna 1 -> seq_doc_tipo_a (coloca o nome que você achar melhor)
coluna 2 -> seq_doc_tipo_b
...

Conforme o documento você pega o valor referente ao tipo na sua coluna incrementa + 1 e salva na tabela de "movimentos". Simples!

Tenta aí e qualquer coisa é só perguntar.
GOSTEI 0
M. C.

M. C.

22/05/2013


Pra inicio você não precisa "complicar" muito não. Cria as tabela no "basicão", a cada novo documento que for entrar você soma + 1 ao número anterior e pronto. Quanto ao ano você faça a veificação de o ano mudou, daí registra isso novamente (iniciando um novo sequencia na tabela de "controle") e pronto, passa incrementar a novo sequencia. Simples!

Qualquer coisa, é só perguntar.


Boa noite Aprendiz.

Cara o lance de fazer as tabelas é uma boa ideia, mas tem um porém, os tipos de documento são 13 então, neste caso, eu deveria criar nove tabelas diferentes pra cada tipo?


Outra:

Tem outra maneira mais "profisional". Na tabela de movimentos você cria um campo/coluna na tabela de "movimentos" e toda as vezes que você for inserir um novo registro você primeiro da um select contanto a quantidade de registros do "tipo" em questão, incrementa + 1 e depois salva na tabela de "movimentos". Simples também!!!

Tente para o momento o "BASICÃO", pois o que importa é funcionar corretamente e quando puder você melhora o processo.

Boa sorte!
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013

Bom dia galera, ainda estou quebrando tudo por causa deste tópico. Bem eu achei melhor deixar a numeração por tipos de documentos pra uma outra hora, mesmo porque, eu não estou conseguindo nem fazer a numeração de um tipo só.

O Sistema que estou desenvolvendo é de protocolos de documentos, acho que já expliquei isso, pois bem, como todo protocolo ele requer uma numeração tipo: protocolo nº 0234/2013, então eu fiz uma tabela de teste com os campos COD_TESTES E NUMERO_TESTES, no aplicativo criei um DataMódulo e coloquei nele o trio fantástico SQLDataSet(TBL_TESTES) , DataSetProvider(DSP_TBL_TESTES) e um ClientDataSet(CDS_TBL_TESTES) ligados a tabela TBL_TESTES, beleza né? Coloquei também mais um SQLDataSet(qry_teste)com a seguinte instrução na sua propriedade CommandText: select MAX(NUMERO_TESTES) AS MAIOR from TBL_TESTES WHERE COD_TESTES = :COD.

Criei um formulário, coloquei os fields do CDS_TBL_TESTES e um botão nele, no código do botão coloquei o seguinte código:

procedure Tfrm_teste.Button1Click(Sender: TObject);
begin
     DM.qry_teste.Close;
     DM.qry_teste.ParamByName('cod').Value := '%' + IntToStr(YearOf(Date));
     DM.qry_teste.Open;
     DM.CDS_TBL_TESTES.Append;
     DM.CDS_TBL_TESTESNUMERO_TESTES.Value := Numerar(DM.qry_testeMAIOR.Value, 'Ano');
     DM.CDS_TBL_TESTES.ApplyUpdates(0);
end;


o "Numerar" é da função que eu já passei lá em cima em outro post.

Quando eu aperto o botão ele dá erro dizendo que não pode converter uma variavel do tipo UnicodeString para Boolean "Cold not convert variant of type(UnicodeString) into type(Boolean), eu, como era de se esperar, não entendi nada!

Alguém ai tem alguma experiência para poder repassar?
GOSTEI 0
M. C.

M. C.

22/05/2013

Bom dia galera, ainda estou quebrando tudo por causa deste tópico. Bem eu achei melhor deixar a numeração por tipos de documentos pra uma outra hora, mesmo porque, eu não estou conseguindo nem fazer a numeração de um tipo só.

O Sistema que estou desenvolvendo é de protocolos de documentos, acho que já expliquei isso, pois bem, como todo protocolo ele requer uma numeração tipo: protocolo nº 0234/2013, então eu fiz uma tabela de teste com os campos COD_TESTES E NUMERO_TESTES, no aplicativo criei um DataMódulo e coloquei nele o trio fantástico SQLDataSet(TBL_TESTES) , DataSetProvider(DSP_TBL_TESTES) e um ClientDataSet(CDS_TBL_TESTES) ligados a tabela TBL_TESTES, beleza né? Coloquei também mais um SQLDataSet(qry_teste)com a seguinte instrução na sua propriedade CommandText: select MAX(NUMERO_TESTES) AS MAIOR from TBL_TESTES WHERE COD_TESTES = :COD.

Criei um formulário, coloquei os fields do CDS_TBL_TESTES e um botão nele, no código do botão coloquei o seguinte código:

procedure Tfrm_teste.Button1Click(Sender: TObject);
begin
     DM.qry_teste.Close;
     DM.qry_teste.ParamByName('cod').Value := '%' + IntToStr(YearOf(Date));
     DM.qry_teste.Open;
     DM.CDS_TBL_TESTES.Append;
     DM.CDS_TBL_TESTESNUMERO_TESTES.Value := Numerar(DM.qry_testeMAIOR.Value, 'Ano');
     DM.CDS_TBL_TESTES.ApplyUpdates(0);
end;


o "Numerar" é da função que eu já passei lá em cima em outro post.

Quando eu aperto o botão ele dá erro dizendo que não pode converter uma variavel do tipo UnicodeString para Boolean "Cold not convert variant of type(UnicodeString) into type(Boolean), eu, como era de se esperar, não entendi nada!

Alguém ai tem alguma experiência para poder repassar?


Aparentemente você está fazendo tudo certinho, ou seja, está no caminho certo...

Com relação ao seu erro deve ser alguma no "result" da sua função. Confira os tipos das variáveis dentro da sua função e provavelmente você resolverá essa pequena falha.
GOSTEI 0
Celso Souza

Celso Souza

22/05/2013

Quase tudo certo amigo Aprendiz, mas era um quase muito grande. hhhahahahahahaha

Começando pela commandtext da query eu coloquei:
select MAX(NUMERO_TESTES) AS MAIOR from TBL_TESTES WHERE COD_TESTES = :COD


Tava errado depois do WHERE, como eu estou querendo filtrar todos os registros que terminam com o ano corrente eu o campo certo seria NUMERO_TESTES e e também como eu estou utilizando o operador "%" tenho que usar o LIKE ao invés do igual ( = ):

Então a instrução sql ficou assim:
select MAX(NUMERO_TESTES) AS MAIOR from TBL_TESTES WHERE NUMERO_TESTES LIKE :COD



No formulário Segundo, utilizei o AsString nesta linha: DM.qry_teste.ParamByName('cod').Value := '%' + IntToStr(YearOf(Date));


Então ficou assim:
 DM.qry_teste.ParamByName('cod').AsString := '%' + IntToStr(YearOf(Date));


Está funcionando muito bem, agora vou adaptar para quando o sistema escolher o tipo de documento ele gerar a numeração da seguinte forma:

Projeto de Lei Ordinária 0039/2013
Projeto de Lei Ordinária 0040/2013

e se escolher outro tipo de documento fazer a numeração diferenciada
Indicação 0001/2013
Indicação 0002/2013
GOSTEI 0
M. C.

M. C.

22/05/2013

Quase tudo certo amigo Aprendiz, mas era um quase muito grande. hhhahahahahahaha

Começando pela commandtext da query eu coloquei:
select MAX(NUMERO_TESTES) AS MAIOR from TBL_TESTES WHERE COD_TESTES = :COD


Tava errado depois do WHERE, como eu estou querendo filtrar todos os registros que terminam com o ano corrente eu o campo certo seria NUMERO_TESTES e e também como eu estou utilizando o operador "%" tenho que usar o LIKE ao invés do igual ( = ):

Então a instrução sql ficou assim:
select MAX(NUMERO_TESTES) AS MAIOR from TBL_TESTES WHERE NUMERO_TESTES LIKE :COD



No formulário Segundo, utilizei o AsString nesta linha: DM.qry_teste.ParamByName('cod').Value := '%' + IntToStr(YearOf(Date));


Então ficou assim:
 DM.qry_teste.ParamByName('cod').AsString := '%' + IntToStr(YearOf(Date));


Está funcionando muito bem, agora vou adaptar para quando o sistema escolher o tipo de documento ele gerar a numeração da seguinte forma:

Projeto de Lei Ordinária 0039/2013
Projeto de Lei Ordinária 0040/2013

e se escolher outro tipo de documento fazer a numeração diferenciada
Indicação 0001/2013
Indicação 0002/2013


Bom saber que você conseguiu!

Quando a coisa tá meio obscura, a gente cria um "protótipo" da coisa... e daí vai refinando, melhorando. Fazendo assim, a coisa vai "clariando" e a gente acaba encontrado o caminho certo.

Desde o inicio eu lhe falei que é simples, o problema maior está em "como fazer" e como isso você já descobriu... agora é só sucesso!
GOSTEI 0
Guilherme Wiethaus

Guilherme Wiethaus

22/05/2013

O problema não é nem linguagem ou ferramenta é lógica de programação....Para tudo, pensa o que deseja fazer, desenha no papel como será sua interação do banco de dados com sua aplicação / regra de negócio e exibição. Se fosse em .net, cobol, java, c++ não seria diferente. Parar um tempo e pensar no assunto rende mais em pouco tempo do que somente sair programando. Eu faço assim e sempre dá resultados.

Abraços.
GOSTEI 0
POSTAR