unit Pai;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB,DBCLient,SqlExpr, ImgList, ExtCtrls, DBCtrls, ComCtrls, ToolWin;

type
  TF_Pai = class(TForm)
    ToolBar1: TToolBar;
    BtnNovo: TToolButton;
    ToolButton2: TToolButton;
    BtnEditar: TToolButton;
    ToolButton1: TToolButton;
    BtnSalvar: TToolButton;
    ToolButton3: TToolButton;
    BtnCancelar: TToolButton;
    ToolButton4: TToolButton;
    BtnExcluir: TToolButton;
    ToolButton5: TToolButton;
    BtnPesquisar: TToolButton;
    ToolButton9: TToolButton;
    BtnRelatorio: TToolButton;
    ToolButton8: TToolButton;
    BtnNavegar: TDBNavigator;
    Panel3: TPanel;
    Panel2: TPanel;
    ImageList2: TImageList;
    ImageList1: TImageList;
    DataSource: TDataSource;
     Procedure Enter(parBotao : TToolButton; parTecha : Char); // Esta rotina simulará o click do botão salvar para que alterações ou inclusões de registros
                                                   // sejam salvar. Será ativada quando o usuário techar "ENTER"
    Procedure DataSourceStateChange(Sender: TObject);
    Procedure NovoRegistro;     // Adicinar um novo registro ao banco de dados
    Procedure ExcluirRegistro;
    Procedure DesejaSalvar(Var parAcao : TCloseAction);
    Procedure EstadoBotoes;
    Procedure BtnNovoClick(Sender: TObject);
    procedure BtnEditarClick(Sender: TObject);
    procedure BtnSalvarClick(Sender: TObject);
    procedure BtnCancelarClick(Sender: TObject);
    procedure BtnExcluirClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Procedure AutoIncrementar(parTabela : String; parCh_Primaria : TField);
     // O Procedimento acima recebe como parâmetro o nome de uma tabela, um Field q seja chave
     // primária da tabela. Atua como AutoIncremento.
     Procedure AplicarRegistro;
     Procedure EditarRegistro;   // Edição de registros
     Procedure CancelarRegistro; // Cancelamento de edições ou inclusões de registros
     Procedure SalvarRegistro;
     Function TemCampoEmBranco : Boolean; // Esta rotima verifica se existe algum field requerido pelo banco de dados e que esteja vazio.
      // Caso esteja vazio, não será salvo no banco de dados o registro que está sendo editado ou inserido.

  end;

var
  F_Pai: TF_Pai;

implementation

uses DMConexao;

{$R *.dfm}

{ TF_Pai }

procedure TF_Pai.AplicarRegistro;
begin
 Try
     (DataSource.DataSet As TClientDataSet).ApplyUpdates(-1); // Grava as atualizações ou inserções para o banco de dados
   Except
     On E : Exception do
       ShowMessage(E.Message);
   End;
end;

procedure TF_Pai.DataSourceStateChange(Sender: TObject);
begin
EstadoBotoes; // Habilita / Desabilita botões de manipulação de registros(Novo,Salvar,Excluir...)
end;

procedure TF_Pai.AutoIncrementar(parTabela: String;
  parCh_Primaria: TField);
 Var
  Qry : TSQLQuery;
begin
   If(DataSource.DataSet.State <> dsInsert)Then
     Exit;
   Qry := TSQLQuery.Create(Nil);
   Try// Está rotina é responsável pelo autoincremento dos campos que são chave primária de uma determinada tabela.
      // parTabela: Este parâmetro representa o nome da tabela pelo qual se quer adicionar um novo valor para sua chave primária.
      // parCh_Primaria: Este parâmetro representa um Field. Este Field deverá ser a chave primária da tabela que se quer
         // incluir um novo registro.
     Qry.SQLConnection := DM.SqlConexao;
     Qry.SQL.Add('SELECT MAX('+parCh_Primaria.FieldName+')From '+parTabela);
     Try
       Qry.Open; // Execução do Sql
       If(Qry.Fields[0].IsNull)Then
         parCh_Primaria.AsInteger := 1
       Else
         parCh_Primaria.AsInteger := Qry.Fields[0].AsInteger + 1; // O novo valor gerado é adicionado a chave primária da tabela.
     Except // Caso ocorra erro, será gerado o erro abaixo.
       On Exc: EDatabaseError Do
         MessageDlg('Erro ao abrir a query AUTOINCREMENTO: '+Exc.Message,mtError,[mbOk],0);
     End;
   Finally
     FreeAndNil(Qry); // Libera o objeto da memória.
   End;

end;

procedure TF_Pai.CancelarRegistro;
begin
 If(DataSource.DataSet.State In [dsInsert,dsEdit])Then
   Begin                           // Se DataSet estiver no modo de edião ou inserção, o mesmo será cancelado
      DataSource.DataSet.Cancel;
      EstadoBotoes; // Habilita / Desabilita botões de manipulação de registros(Novo,Salvar,Excluir...)
   End;
end;



procedure TF_Pai.DesejaSalvar(var parAcao: TCloseAction);
Var
  Resp : Word; // Armazenará a resposta do usuários (Se ele deseja salvar ou não as alterações/Inclusões)
begin
   If(Not(DataSource.DataSet.State In [dsInsert,dsEdit]))Then // Se Não estiver no modo de Edição ou Inclusão
   Begin                                                      // então sairá da rotina.
     DataSource.DataSet.Close; // Fecha a query;
     Exit;
   End;
   MessageBeep(64);
   Resp := MessageDlg('Deseja salvar as alterações?',mtInformation,mbYesNoCancel,0);
   If(Resp = mrYes)Then // Entrerá aqui quando o usuário responder que deseja salvar as alterações.
   Begin                // Então, o registro poderá ser salvo (Se não houver campos em branco) e a janela
                        // Será liberado de memória.
      If(Not(TemCampoEmBranco))Then // Se não tiver campo em branco o registro atual será salvo e a janela
                                      // será liberada de memória.
      Begin
         SalvarRegistro; // Salvar o Registro
         parAcao := caFree; // Libera a janela de memória (parAcao que é passado por referência)
         DataSource.DataSet.Close; // Fecha a query;
      End
      Else
        Begin // Entrará aqui quando o usuário responder que deseja salvar as alterções, mas existe campos requerido
              // em branco. Então, será exibido uma mensagem para o usuário informando qual foi o campo que ele não
              // preencheu corretamente(Quem faz isso é a rotina "TemCampoEmBranco") e a janela não será liberada de memória.
           parAcao := caNone; // Não liberação da janela de memória (Não fecha o formulário de Inclusão/Edição)
        End;
   End
   Else
     If(Resp = mrNo)Then // Entrará aqui quando o usuário responder que não deseja salvar as alterações. Então, o registro
     Begin // que se está editando ou incluindo será cancelado e o formulário será liberado de memória (Fecha a Janela de edição/inclusão)
       CancelarRegistro; // Cancelamento do registro;
       parAcao := caFree; // Liberação do objeto de memória;
       DataSource.DataSet.Close; // Fecha a query;
     End
     Else // Entrerá aqui quando o usuário responder que deseja cancelar ou fechar a janelinha da pergunta.
          // Então, a janela não será fechada, pois o usuário pedio o cancelamento da merda que ele fez.....
       Begin
          parAcao := caNone; // Não fecha a janela de inclusão/edição de registro;
       End;


end;

procedure TF_Pai.EditarRegistro;
begin
  If(DataSource.DataSet.State = dsBrowse)Then
     DataSource.DataSet.Edit; // Se DataSet estiver no modo de Visualização, o mesmo será Editado.
end;

procedure TF_Pai.Enter(parBotao: TToolButton; parTecha: Char);
begin
// Esta rotina simulará o click do botão salvar para que alterações ou inclusões de registros
   If(parTecha = #13)Then // sejam salvar. Será ativada quando o usuário techar "ENTER"
     parBotao.Click;
end;

procedure TF_Pai.EstadoBotoes;
begin
  With(DataSource.DataSet)Do  // registros, de acordo com o estado atual do DataSet.
   Begin
      BtnNovo.Enabled := State = dsBrowse;
      BtnSalvar.Enabled := State In [dsInsert,dsEdit];
      BtnEditar.Enabled := ((State = dsBrowse) And (RecordCount > 0));
      BtnCancelar.Enabled := State In [dsInsert,dsEdit];
      BtnExcluir.Enabled := ((State = dsBrowse) And (RecordCount > 0));
      BtnNavegar.Enabled := State = dsBrowse;
      BtnPesquisar.Enabled := ((State = dsBrowse) And (RecordCount > 0));
      BtnRelatorio.Enabled := ((State = dsBrowse) And (RecordCount > 0));
   End;
end;

procedure TF_Pai.ExcluirRegistro;
begin
// Se DataSet estiver no modo de Visualização, o mesmo será excluído
   If(DataSource.DataSet.State = dsBrowse)Then // caso o usuário confirme a exclusão.
   Begin
      MessageBeep(64);
      If(MessageDlg('Excluir Registro?',mtConfirmation,[mbYes,mbNo],0) = mrYes)Then
      Begin
         DataSource.DataSet.Delete; // Exclusão
         AplicarRegistro; // Exclui o registro do banco de dados
         EstadoBotoes; // Habilita / Desabilita botões de manipulação de registros(Novo,Salvar,Excluir...)
      End;
   End;
end;

procedure TF_Pai.NovoRegistro;
begin
// Se DataSet estiver no modo de Visualização, um novo registro será criado.
   If(DataSource.DataSet.State = dsBrowse)Then
     DataSource.DataSet.Insert;
end;

procedure TF_Pai.SalvarRegistro;
begin
  If(DataSource.DataSet.State In [dsInsert,dsEdit])Then
   Begin   // Se DataSet estiver no modo de Inserção ou Edição, Salvará as alterações ou Inclusões na memória.
      DataSource.DataSet.Post;
      AplicarRegistro; // Salvar as Alterações ou Inserções no Banco de Dados
end;
 end;
function TF_Pai.TemCampoEmBranco: Boolean;
 Var
  Cont : Byte; // Variável que controlará o laçõ em todos os Fields do DataSet
begin
   Result := False; // Supõe que todos os campos estejam preenchidos
   With(DataSource.DataSet)Do
   Begin
      For Cont := 0 To FieldCount -1 Do // Faz um laço em todos os Fields a procura de fields que são requeridos e estão
      Begin                             // em branco(não foi preenchido) e que tenha a tag = 0(zero). Caso encontre, o sistema entrará na rotina abaixo.
                                        // Todos os fields que são primary key terão sua propriedade requerid como false, pois os mesmos não deverão entrar nesta rotina,
                                        // já que seus velores são gerados pela rotina "AutoIncrementar()".
            If((Trim(Fields[Cont].AsString) = '')And(Fields[Cont].Required))Then
            Begin
               MessageBeep(64);
               MessageDlg(Format('Preencha o campo ''%s''',[Fields[Cont].DisplayLabel]),mtInformation,[mbOk],0);
               Fields[Cont].FocusControl; // Focaliza o cursor no Fields que não foi preenchido.
               Result := True; // Informa que existem campos requeridos que não forão preenchidos.
               Break; // Sai do laço
               Exit;  // Sai da Rotina
            End;
         End;
   End;
end;

procedure TF_Pai.BtnNovoClick(Sender: TObject);
begin
 NovoRegistro; // Chamada da rotina para inserir novo registro
  
end;

procedure TF_Pai.BtnEditarClick(Sender: TObject);
begin
EditarRegistro; // Chamada da rotina para Edição de registro
end;

procedure TF_Pai.BtnSalvarClick(Sender: TObject);
begin
If(Not(TemCampoEmBranco))Then // Se todos os fields forão preenchidos então salve no banco.
     SalvarRegistro;
end;

procedure TF_Pai.BtnCancelarClick(Sender: TObject);
begin
 CancelarRegistro; // Chamada da rotina para Cancelamento de Inclusões ou Alterações
end;

procedure TF_Pai.BtnExcluirClick(Sender: TObject);
begin
ExcluirRegistro; // Chamada da rotina para Exclusão de registro
   AplicarRegistro; // Exclui o registro do banco de dados
 
end;

end.
