Olá galera, nesta Quick Tips, irei mostrar como podemos trabalhar com o MonthCalendar, para que o mesmo liste em negrito todos os dias que forem feriados, a partir de uma tabela simples. Vamos então começar a criar o Banco de Dados:

Nome da tabela: Feriado

Criaremos 4 campos, como podemos ver abaixo:

Figura 1
Figura 1

Com a nossa tabela pronta podemos começar a construir o exemplo, este Banco de Dados esta feito em Firebird, mas nada impede de você usar outro Banco, ou até mesmo sua tabela de feriados ou aniversários de “Clientes”.

Vamos construir nosso exemplo, criaremos um Form, e salvar a sua Unit como uFrmPrincipal.pas para tal feito. Vamos adicionar neste Form:

  • 1 TPanel(Panel1);
  • 1 TMonthCalendar (MonthCalendar1);
Figura 2
Figura 2

Após a construção do Formulário, vamos criar uma conexão com nosso Banco de Dados, criaremos agora nosso DataModule, e vamos salvar a unit do mesmo como uDM.pas, logo em seguida vamos adicionar :

  • 1 TSQLConnection(SqlConnctDBFeriados);
  • 1 TSQLDataSet(TSQLDataSet);
  • 1 TDataSetProvider(DSPFeriado);
  • 1 TClientDataSet(CDSFeriado);
Figura 3
Figura 3

Apos adicionarmos os componentes no nosso DataModule, vamos agora ligar os mesmos da maneira tradicional

  • SDSFeriado - > SQLConnection = SqlConnctDBFeriados
  • SDSFeriado - > CommandText = ‘SELECT * FROM FERIADO ORDER BY DATA’
  • DSPFeriado - > DataSet = SDSFeriado
  • CDSFeriado - > ProviderName = DSPFeriado

Agora vamos voltar ao FrmPrincipal, e no evento GetMonthInfo, vamos implementar o código abaixo:


procedure TFrmPrincipal.MonthCalendar1GetMonthInfo(Sender: TObject; Month: Cardinal; 
var MonthBoldInfo: Cardinal);
var
   ano,mes,dia : word;
   xDataAtual : TDateTime;
   x: array of Cardinal;
   i: integer;
begin
   x := Nil;
   DecodeDate(MonthCalendar1.Date, ano, mes, dia);
   case Month of
   1: if mes = 12 then
      ano := ano + 1;
   12: if mes = 1 then
      ano := ano - 1;
   end;
 
   xDataAtual := EncodeDate(ano, Month, 1);
   i := -1;
   with DM.CDSFeriado do
   begin
      mes := mes +1;
      Close;
      Filtered := False;
      Filter := 'DATA >= ' + QuotedStr(DateTimeToStr(StartOfTheMonth(xDataAtual)))     
      + ' AND DATA <= ' + QuotedStr(DateTimeToStr(EndOfTheMonth(xDataAtual)));
      Filtered := True;
      Open;
      if IsEmpty then
         Exit;
      SetLength(x, RecordCount);
      while not(Eof) do
      begin
         Inc(i);
         DecodeDate( FieldByName('DATA').AsDateTime, ano, mes, dia);
         x[i] := dia;
         Next;
      end;
   Close;
   end;
   MonthCalendar1.BoldDays(x, MonthBoldInfo);
end;
procedureTFrmPrincipal.MonthCalendar1GetMonthInfo(Sender: TObject; Month: 
Cardinal;varMonthBoldInfo: Cardinal);
Nota: As functions StartOfTheMontheEndOfTheMonth estão declaras em DateUtils, então devemos dar uses nesta unit. A finalidade desta é justamente pegar o o primeiro e o último dia do mês, passando uma data como parâmetro.

Seguindo a dica do amigo Rogério Roncolato, segue abaixo como pegar o nome do Feriado ao clicar na data. Para isso vamos adicionar uma StatusBar, e nela um Panel, porém nada lhe impede de fazer com um Edit, ou Label, vamos a implementação.

No evento onClick do Montcalendar1, implemente o seguinte:


procedure TFrmPrincipal.MonthCalendar1Click(Sender: TObject);
begin
  with DM.CDSFeriado do
  begin
     Close;
      Filtered := False;
      Filter := 'DATA = ' + QuotedStr(DateTimeToStr(MonthCalendar1.Date));
      Filtered := True;
      Open;
      if not IsEmpty then
         StatusBar1.Panels[0].Text := FieldByName('DESCRICAO').AsString + ' - ' + 
         FieldByName('Dia').AsString
      else
           StatusBar1.Panels[0].Text := DateTimeToStr(MonthCalendar1.Date);
  end;
end;

Fico por aqui até a próxima Quick Tip. Baixe o exemplo completo neste post.