Sign in to follow this  
Eder

Gerador De Mensalidades

Recommended Posts

Ola...tou com mais um problema agora com meu gerador de mensalidades..

tenho um programinha para uma ONG escola perto de minha casa...tou dando uma força pra galera lá..e neste programinha tem um gerador de mensalidade aonde a pessoa coloca o mês e ano e vencimento da mensalidade de depois clicka no botão e ai gera as mensalidade de todo o mês para uns 300 alunos.

funciona perfeito...porem quando o aluno paga a mensalidade adiantada......ai a mensalidade como ainda não está gerada ...porque é gerado mês a mês......então acaba sendo lançado em uma tela manualmente a mensalidade.....até aqui beleza...o problema que quando ai vem outro mês e é gerado a mensalidade torna a gerar novamente para aquele aluno que já pagou deixando duplicidade de mensalidades..

então eu gostaria de ao gerar a mensalidade ele verificasse se o aluno já tem a mensalidade na tabela...e ai não geraria de novo...para não haver duplicidade.

o codigo que eu gero a mensalidade é este abaixo:

procedure TFormGeraMensalidade.XiButton1Click(Sender: TObject);

var

dia : TDatetime;//Verifica se dia digitado na baixa é menor que a data atual

vaux: string;//verifica o codigo da turma...para pegar o valor da mensalidade de cada turma

begin

//

If Combobox1.text = '' then

Begin

Showmessage('Selecione o mês');

Combobox1.setfocus;

Exit;

End;

//

If Combobox2.text = '' then

Begin

Showmessage('Selecione o Ano');

Combobox2.setfocus;

Exit;

End;

//

If EditVencimento.text = ' / / ' then

Begin

Showmessage('Digite o Vencimento da Mensalidade!');

EditVencimento.setfocus;

Exit;

End;

//abaixo verifica de a data do vencimento é menor que a atual...

dia:=strtodate(EditVencimento.text);

if dia < date then

begin

showmessage('Esta Data de Vencimento é menor que a Data Atual, Favor Verificar.');

exit

end;

//INICIO

//Abaixo verifica se já foi gerado a mensalidao do mês/ano para não dar duplicidade

TABLE2.OPEN;//ABRO A TABELA MENSALIDADE

TABLE2.FIRST;//VOU PARA O PRIMEIRO REGISTRO

//ABAIXO VERIFIQUE SE AS MENSALIDADES já FORAM GERADAS.

while Table2.eof = false do begin

if ((Table2MES.asSTRING = (COMBOBOX1.TEXT)) and (Table2ANO.asSTRING = (COMBOBOX2.TEXT))) THEN

BEGIN

SHOWMESSAGE('Já esta gerado as Mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text+' - Favor Verificar..');

EXIT;

END;

table2.next;

End;

//FIM....

//Aqui começa a gerar as mensalidades automaticas...

TABLE1.open; //abro a tabela alunos

TABLE1.first; //vou para o primeiro registro

while TABLE1.eof = false do begin // enquanto fim da tabela for igual a FALSE

if (table1DATADEM.AsDateTime < 1) then begin

table2.Insert; // ou seja da um insert para cada aluno

table2codAluno.asinteger := table1codigo.asinteger; //alimento o campo cod_aluno com o registro da tabela alunos atual

vAux:= Table1Turma.AsString;// aqui recebe o cod da turma para pegar o valor mensalidade de cada turma

table2Data.asDateTime := (date);

table2Mes.asInteger := strtoint(combobox1.TEXT);

table2Ano.asInteger := strtoint(combobox2.TEXT);

table2Vencimento.asDateTime := StrToDate(EditVencimento.TEXT);

//abaixo filtra na query para filtrar o codigo da tuma e valor da mensalidade

{não esquecendo de configurar a query com uma instrução la dentro dela}

with Query1 do

begin

Close;

with SQL do

begin

Clear;

Add('Select Valormensalidade From Turma');

Add('Where Codigo = ' + QuotedStr(vAux));

end;

Open;

end;

Table2CodTurma.AsInteger:=StrToInt(Vaux);

Table2Valor.ascurrency := Query1ValorMensalidade.AsCurrency; //aqui coloca o valor filtrada da mensalidade

Table2Total.ascurrency := Query1ValorMensalidade.AsCurrency; //aqui coloca o valor filtrada da mensalidade

//table2Valor.ascurrency := STRTOFLOAT(EditValor.TEXT); // valor da mensalidade (irá a mesama para todos alunos, pois não esta sendo feito na matricula)

//table2Total.ascurrency := STRTOFLOAT(EditValor.TEXT); // valor da mensalidade (irá a mesama para todos alunos, pois não esta sendo feito na matricula)

Table2Descontos.ascurrency := 0;

Table2Acrescimo.ascurrency := 0;

Table2Total.ascurrency := Query1ValorMensalidade.AsCurrency;

Table2Baixa.asString := 'não';

Table2.Post; //Salvo a mensalidade deste aluno

END;

TABLE1.next; //avanço para o proximo aluno parar gerar a mesalidade do proximo

END;

SHOWMESSAGE('OK...Gerado as Mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text);

END;

A duvida é...Como eu faria este processo dentro do que eu já tenho acima...?? eu poderia gerar pro ano inteiro...para ai tem alunos que entrão e saem da escola...ai iria dar mais problemas..por isso eu gero mês a mês...

Grato

Share this post


Link to post
Share on other sites

Eder, vamos ver se conseguimos ajudar a resolver o problema... (1ª tentativa)

você não falou, mas imagino que esteja utilizando Paradox, certo?!

//INICIO

//Abaixo verifica se já foi gerado a mensalidao do mês/ano para não dar duplicidade

TABLE2.OPEN;//ABRO A TABELA MENSALIDADE

TABLE2.FIRST;//VOU PARA O PRIMEIRO REGISTRO

//ABAIXO VERIFIQUE SE AS MENSALIDADES já FORAM GERADAS.

while Table2.eof = false do begin

if ((Table2MES.asSTRING = (COMBOBOX1.TEXT)) and (Table2ANO.asSTRING = (COMBOBOX2.TEXT))) THEN

BEGIN

SHOWMESSAGE('Já esta gerado as Mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text+' - Favor Verificar..');

EXIT;

END;

table2.next;

End;

//FIM....

substituia este processo por um componente TQuery (vou chamar QryGerarMens) e coloque na propriedade SQL (em design-time) o seguinte código:
select CodAluno, Turma
from ALUNOS A
where not exists(select CodAluno
                 from MENSALIDADE M
                 where M.CodAluno = A.CodAluno
                   and M.mês = :mês
                   and M.ANO = :ano)
Explicando: o select que está na cláusula WHERE "irá retornar" os alunos com mensalidade lançadas para o mês e ANO informados; Como listamos na instrução SQL principal todos os alunos que NÃO (not) aparecem na listagem do sub-select, então teremos uma relação de apenas os que estão faltando. Com isso, não terá como um aluno que pague adiantado para o mês e ANO informados, aparecer na lista e, por conseqüência, você não duplicará a informação. O código substituto ficaria agora assim:
//INICIO
//Abaixo verifica se já foi gerado a mensalidao do mês/ano para não dar duplicidade
  QryGerarMens.ParamByName('mês').AsInteger := StrToInt(COMBOBOX1.TEXT);
  QryGerarMens.ParamByName('ANO').AsInteger := StrToInt(COMBOBOX2.TEXT);
  QryGerarMens.Open;
//FIM....  (mais ou menos o "fim")
  if not QryGerarMens.EOF then
  begin
  //Aqui começa a gerar as mensalidades automaticas...
    while not QryGerarMens.eof do   // *** prefira "Not TABLE1.eof" modo à "TABLE1.eof = false"
    begin
     // *** Se estiver usando um índice pelo CodAluno utilize o FindKey, do contrário Locate
    //  if Table1.FindKey([QryGerarMensCodAluno.AsInteger]) then 
      if Table1.Locate('CodAluno', QryGerarMensCodAluno.Value, []) then 
      begin
        Table2.Insert; // ou seja da um insert para cada aluno
        Table2codAluno.asinteger := Table1codigo.asinteger; //alimento o campo cod_aluno com o registro da tabela alunos atual
        Table2Data.asDateTime := Date;
        Table2Mes.asInteger := strtoint(combobox1.TEXT);
        Table2Ano.asInteger := strtoint(combobox2.TEXT);
        Table2CodTurma.AsInteger:= QryGerarMensTurma.AsInteger;
        Table2Vencimento.asDateTime := StrToDate(EditVencimento.TEXT);
        Table2Descontos.ascurrency := 0;
        Table2Acrescimo.ascurrency := 0;
        Table2Baixa.asString := 'não';

      //abaixo filtra na query para filtrar o codigo da tuma e valor da mensalidade
        Query1.ParamByName('Codigo').AsInteger := QryGerarMensTurma.AsInteger;
        Query1.Open;
        Table2Valor.ascurrency := Query1ValorMensalidade.AsCurrency; //aqui coloca o valor filtrada da mensalidade
        Table2Total.ascurrency := Query1ValorMensalidade.AsCurrency;
        Query1.Close;

        //Table2Valor.ascurrency := STRTOFLOAT(EditValor.TEXT); // valor da mensalidade (irá a mesama para todos alunos, pois não esta sendo feito na matricula)
        //Table2Total.ascurrency := STRTOFLOAT(EditValor.TEXT); // valor da mensalidade (irá a mesama para todos alunos, pois não esta sendo feito na matricula)
        Table2.Post; //Salvo a mensalidade deste aluno
      end;
      QryGerarMens.next; //avanço para o proximo aluno parar gerar a mesalidade do proximo
    end;
    SHOWMESSAGE('OK...Gerado as Mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text);
  end else
    SHOWMESSAGE('As mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text+'já foram geradas');
  QryGerarMens.Close;
Como você adiciona os campos de Query1 em deseing-time, tomei a liberdade de modificar sua "abertura" de modo que você deve alterar o conteúdo da propriedade SQL (em desing-time) para:
Select Valormensalidade From Turma
Where Codigo = :Codigo

Obs 1) Sempre que possível, utilize parametrização - facilita muito as coisas.

Obs 2) Os parâmetros e campos com o nome mês foram acentuados por conta do editor do forum. Não acentue nada (você deve saber, mas não custa lembrar)

Obs 3) Dê uma boa olhada na parte do loop, pois troquei um pouco a ordem das atribuições apenas para ficar mais claro para mim. :rolleyes:

Obs 4) Confira o nome do campo da turma, eu entendí que não é CodTurma, e sim, apenas Turma. Logo se estiver errado ajuste o código.

Bom, isto tudo é virtual, espero que na real funcione. :D

[]s

Share this post


Link to post
Share on other sites

:D

Michels..primeiramente muito obrigado pela ajuda...mais uma vez

Carinha....to meio que perdido agora depois que você montou o codigo....hehehe....deu uma alterada legal..mas beleza...se for pra melhor......está tudo joia.

Precisaria que você me desse algumas instruções..por favor...é o seguinte

você se diz que:

substitua este processo por um componente TQuery (vou chamar QryGerarMens) e coloque na propriedade SQL (em design-time) o seguinte código:

Resposta: o que seria sql em design-time ??? acredito que seria a instrução que a gente coloca direto no SQL(tstrings) ??

Bom se for isto..... eu auterei algumas coisinhas pois a tabela alunos na verdade se chama FILHOS.DB e a tabela mensalidade.db é na verdade MENSA.DB ai alterei esta instrução assim(por favor veja se esta ok):

select Codigo, Turma

from filhos A

where not exists(select CodAluno

from MENSA M

where M.CodAluno = A.Codigo

and M.mês = :mês

and M.ANO = :ano)

Acredito que deva algo que não está dando certo pois quando tento compilar o programa da erro nesta linha:

if Table1.Locate('Codigo', QryGerarMensCodigo.Value, []) then

error:

[Error] GeraMensa.pas(274): Undeclared identifier: 'QryGerarMensCodigo'

alias da sempre este erro....pois se eu desalibitar esta linha e tentar compilar de novo ai da erro nesta linha:

Table2CodTurma.AsInteger:= QryGerarMensTurma.AsInteger;

erro: [Error] GeraMensa.pas(281): Undeclared identifier: 'QryGerarMensTurma'

acho que tem algo errado na QryGerarMens :unsure:

Minha estrutura da tabela filhos.db é:

codigo, aluno, turma etc.........

mensa.db é:

codmensa, codaluno etc....

Turma.db é:

codigo etc....

Por favor de uma olhadinha no codigo que você montou derepende como você disse que foi montado e não testado derepende tem algo errado..se você achar que está certo..ai vou ter que quebrar a cabeça mais um pouco..

Bom é isto ai.....espero que você consiga entender .....

muito Grato..amigo....

Share this post


Link to post
Share on other sites
Carinha....to meio que perdido agora depois que você montou o codigo....hehehe....deu uma alterada legal..mas beleza...se for pra melhor......está tudo joia.
Eder, a idéia foi realmente de simplificar, mas não é garantia de nada enquanto não funcionar. Então, espero que antes de você sair alterando, você tenha feito um backup desta tela.

Só mais uma dica, que vale para todos é claro; Um código tão longo como o que você postou, fica mais legível se vê utilizar a tag CODE (botão # no editor), pois são mantidas as identações. Tudo alinhado à esquerda dá um nó nas ideias. :wacko:

você se diz que:

substitua este processo por um componente TQuery (vou chamar QryGerarMens) e coloque na propriedade SQL (em design-time) o seguinte código:

Resposta: o que seria sql em design-time ??? acredito que seria a instrução que a gente coloca direto no SQL(tstrings) ??

Perfeito!

Bom se for isto..... eu auterei algumas coisinhas pois a tabela alunos na verdade se chama FILHOS.DB e a tabela mensalidade.db é na verdade MENSA.DB ai alterei esta instrução assim(por favor veja se esta ok):

select Codigo, Turma

from filhos A

where not exists(select CodAluno

from MENSA M

where M.CodAluno = A.Codigo

and M.mês = :mês

and M.ANO = :ano)

Correto!

if Table1.Locate('Codigo', QryGerarMensCodigo.Value, []) then

error:

[Error] GeraMensa.pas(274): Undeclared identifier: 'QryGerarMensCodigo'

alias da sempre este erro....pois se eu desalibitar esta linha e tentar compilar de novo ai da erro nesta linha:

Table2CodTurma.AsInteger:= QryGerarMensTurma.AsInteger;

erro: [Error] GeraMensa.pas(281): Undeclared identifier: 'QryGerarMensTurma'

Quando utilizar um componente com o SQL adicinado em design-time, torna-se convenente que você adicione os field's. Porém, como utilizamos parâmetros, primeiro devemos adicionar estes:

- Na propriedade Params do comopente TQuery, click no botãozinho [...]

- Na caixinha que aparece, selecione parâmetro a parâmetro e na janela Object Inspector configure as propriedades DataType, ParamType;

No seu caso o parâmetro mês e Ano são do tipo inteiro, então set para ftInteger(o tipo do parâmetro é sempre igual ao tipo de dados na tabela); ParamType, em 99,99% dos casos é ptInput.

Agora podemos adicionar os fields, veja procedimento:

- Dê um duplo click no componente TQuery;

- Na caixinha que aparece, acesse o menu via click do botão direito do mouse;

- Selecione a opção Add All Fields.

Neste momento, já estará existindo o field QryGerarMensCodigo.

Mas se você não quizer utilizar esta abordagem, então terá que se referenciar aos campos retornados no TQuery pelo seu nome, via método FieldByName ou, como alguns gostam, pelo índice em Fields[<índice>]. Particularmente prefiro FieldByName porque estou certo de que campo estou buscando, sem contar que fica mais legígel para qualquer outra pessoa. Neste caso ficaria assim:

if Table1.Locate('Codigo', QryGerarMens.FieldByName('Codigo').Value, []) then

Table2CodTurma.AsInteger:= QryGerarMens.FieldByName('Turma').AsInteger;

Fica a gosto do freguês. Opções não faltam. beleza?!

...

Por favor de uma olhadinha no codigo que você montou derepende como você disse que foi montado e não testado derepende tem algo errado..se você achar que está certo..ai vou ter que quebrar a cabeça mais um pouco..
Acho que está ok. Depois de você fazer os ajustes para correção dos problemas encontrados, acho que não haverá mais problema de compilação.

[]s

p.s. Não é Michels e sim Micheus.

Share this post


Link to post
Share on other sites
:D Eder, a idéia foi realmente de simplificar, mas não é garantia de nada enquanto não funcionar. Então, espero que antes de você sair alterando, você tenha feito um backup desta tela.

Só mais uma dica, que vale para todos é claro; Um código tão longo como o que você postou, fica mais legível se vê utilizar a tag CODE (botão # no editor), pois são mantidas as identações. Tudo alinhado à esquerda dá um nó nas ideias.

R..Beleza desculpe vou tentar usar a tag code....e quanto ao backup eu fiz......beleza..

p.s. Não é Michels e sim Micheus.

R...Beleza..errei uma letrinha...hehehe...

Micheus.....carinha eu testei tudo agora e funcionou direitinho..exceto uma coisinha...acredito que você tenha esquecido de colocar no código....é quando o aluno sai da escola e dado baixa no seu cadastro então la no cadastro do aluno eu tenho este campo chamado DATADEM...no codigo antigo eu fazia uma verificação antes.....até tentei inserir dentro do seu codigo mas não deu certo...no codigo antigo ele verificava de o campo DATADEM estivesse NULL então ele mandada gerar a mensalidade..caso contrario não... :unsure:

eu só não to conseguindo colocar dentro do seu codigo...

o codigo antigo eu tinha a verificação assim:

//Aqui começa a gerar as mensalidades automaticas...

TABLE1.open; //abro a tabela alunos
TABLE1.first; //vou para o primeiro registro
while TABLE1.eof = false do begin // enquanto fim da tabela for igual a FALSE
if (table1DATADEM.AsDateTime < 1) then begin
table2.Insert; // ou seja da um insert para cada aluno

Carinha...muito grato...pela sua ajuda e explicação....seria muito dificil de eu montar este codigo sozinho..t+

Obrigadão..

:D

Share this post


Link to post
Share on other sites

Eder, altere apenas o SQL em QryGerarMens:

select CodAluno, Turma
from ALUNOS A
where DATADEM IS NULL
and not exists(select CodAluno
                 from MENSALIDADE M
                 where M.CodAluno = A.CodAluno
                   and M.mês = :mês
                   and M.ANO = :ano)

[]s

Share this post


Link to post
Share on other sites

Amigão.......beleza..nem tinha me tocado que era só configurar a query o aluno nulo

Beleza..Carinha..agora ficou 100% muito Obrigado pela ajuda...mais uma vez....

Haaaa.....é muito Grato pela paciência também....

Abraço..Carinha.

Eder

:D

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this