Ir para conteúdo
Fórum Script Brasil
  • 0

Criar Calendário


Marcos Santana

Pergunta

Colega semanas atrás perguntou se tinhas como pintar uma célula de um calendário

No delphi pois preciso criar um calendário com os dias que os professores dão aula.

Por exemplo Professor Paulo tem aula de Matemática na segunda então em todas as

Segunda do calendário a célula dos dias de segunda ficam verdes, com o calendário do delphi ou outros componentes similares não deu certo então resolve usar o StringGrid é fiz assim:

{Janeiro por exemplo}

StringGrid1.Cells[0,0]:= 'D';

StringGrid1.Cells[1,0]:= 'S';

StringGrid1.Cells[2,0]:= 'T';

StringGrid1.Cells[3,0]:= 'Q';

StringGrid1.Cells[4,0]:= 'Q';

StringGrid1.Cells[5,0]:= 'S';

StringGrid1.Cells[6,0]:= 'S';

StringGrid1.Cells[0,1]:= '';

StringGrid1.Cells[0,2]:= '7';

StringGrid1.Cells[0,3]:= '14';

StringGrid1.Cells[0,4]:= '21';

StringGrid1.Cells[0,5]:= '28';

StringGrid1.Cells[1,1]:= '1';

StringGrid1.Cells[1,2]:= '8';

StringGrid1.Cells[1,3]:= '15';

StringGrid1.Cells[1,4]:= '22';

StringGrid1.Cells[1,5]:= '29';

StringGrid1.Cells[2,1]:= '2';

StringGrid1.Cells[2,2]:= '9';

StringGrid1.Cells[2,3]:= '16';

StringGrid1.Cells[2,4]:= '23';

StringGrid1.Cells[2,5]:= '30';

StringGrid1.Cells[3,1]:= '3';

StringGrid1.Cells[3,2]:= '10';

StringGrid1.Cells[3,3]:= '17';

StringGrid1.Cells[3,4]:= '24';

StringGrid1.Cells[3,5]:= '31';

StringGrid1.Cells[4,1]:= '4';

StringGrid1.Cells[4,2]:= '11';

StringGrid1.Cells[4,3]:= '18';

StringGrid1.Cells[4,4]:= '25';

StringGrid1.Cells[4,5]:= '';

StringGrid1.Cells[5,1]:= '5';

StringGrid1.Cells[5,2]:= '12';

StringGrid1.Cells[5,3]:= '19';

StringGrid1.Cells[5,4]:= '26';

StringGrid1.Cells[5,5]:= '';

StringGrid1.Cells[6,1]:= '6';

StringGrid1.Cells[6,2]:= '13';

StringGrid1.Cells[6,3]:= '20';

StringGrid1.Cells[6,4]:= '27';

StringGrid1.Cells[6,5]:= '';

{Fim}

Com um StringGrid faço um MonthCalendar é no evento DrawCell do StringGrid

Pinto as células que preciso só que ficou muito manual tenho 12 StringGrid no form

É tenho que colocar o valor é as cores de cada célula é mudar todo ano

Têm como atribuir os valores e pintar as células de cada StringGrid dinamicamente

Ou melhorar esse minha idéia.

Link para o comentário
Compartilhar em outros sites

10 respostass a esta questão

Posts Recomendados

  • 0
No delphi pois preciso criar um calendário com os dias que os professores dão aula.

Por exemplo Professor Paulo tem aula de Matemática na segunda então em todas as Segunda do calendário a célula dos dias de segunda ficam verdes, com o calendário do delphi ou outros componentes similares não deu certo então resolve usar o StringGrid é fiz assim:

{Janeiro por exemplo}

...

Com um StringGrid faço um MonthCalendar é no evento DrawCell do StringGrid Pinto as células que preciso só que ficou muito manual tenho 12 StringGrid no form

É tenho que colocar o valor é as cores de cada célula é mudar todo ano

Têm como atribuir os valores e pintar as células de cada StringGrid dinamicamente Ou melhorar esse minha idéia.

Marcos, tem como melhorar sim.

Mas algumas informações são importantes:

- Voce precisa mostrar o ano inteiro ou apenas um mês selecionado;

- você deve obter a informação sobre o professor e sua escala de aulas em alguma tabela. Que informações pertinentes você tem;

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Foram-me passados dois arquivos, um com uma tabela com os horários de cada dia, turmas, professores e suas matérias e outro com o calendário, fica mais ou menos assim:

Calendário

Calendário com os doze meses do ano, é se no mês de janeiro no dia 10 for um feriado cadastro pelo usuário ou um dia de reunião, a célula do SgringGrid que representa esse dia fique na cor que o usuário escolher não tenho uma tabela de feriados ainda

Grade de Horários

------------------------------------

Horário Noturno

------------------------------------

Segunda-Feira

------------------------------------

Série - Turma

------------------------------------

Horário | 1ª Ens.Médio

------------------------------------

18:00-18:50 | Química

18:50-19:40 | Química

19:40-20:30 | Inglês

20:50-21:40 | Ed Física

21:40-22:30 | Ed Física

------------------------------------

Legenda:

------------------------------------

Adriana | Claudino | Marcos -> Professor

------------------------------------

Nessa legenda cada nome tem uma cor é sua matéria e da cor do nome do professor

Então criei as tabelas: Horário com os campos (cd_Horario, id_Turma, de_DiaSemana, de_Horario) que tem uma relação 1 para N com a tabela Turma assim uma turma tem vários horários mas um horário pertence a uma turma (cd_Turma, de_Turma)

Assim eu tenho para cada dia da semana e turno as horários.

Outro problema:

Se o professor Marcos tem duas aulas de Física na segunda-feira, então ele deve dar 80 aulas no ano, ou seja para cada aula que um professor da na semana, ele deve dar 40 aulas por ano

Exemplo: Carlos da 2 aulas por semana = 80 Aulas anuais

Jorge da 3 aulas por semana = 120 Aulas anuais

De posse dessas informações criei uma tabela chamada Calendário (cd_Calendario, id_Professor, id_Materia, id_Turma, id_Horario) que se relaciona com as tabelas:

Professor, Matéria, Turma e Horário todas 1 pra N não sei se é a melhor opção

Eu preciso do seguinte: Se um professor da duas aulas por semana isso soma 80 aulas ano é o usuário for cadastrar esse professor.

Ficaria assim, as aulas são na segunda-feira é são duas aulas, vou tem que inserir na tabela calendário que aquele professor vai dar aula dia + horário + Matéria + Turma e contar se já tem a quantidade de aulas no ano

Se não tiver incluo más um registro se dever incluído em todas as segunda-feira do ano é a quantidade de aulas ainda não foi a que o professor deve dar no ano

O usuário deve escolher outro dia da semana, terça-feira por exemplo até que a quantidade de aulas seja completada é assim podemos saber quando começa e termina as aulas de cada professor é em que dia elas ocorreram.

Se não foi claro e´só me passar onde.

Link para o comentário
Compartilhar em outros sites

  • 0
que tal voce tentar este componente, acho que vai resolver

http://www.tmssoftware.com/download/PLANNERCAL.ZIP

abraço

Bem colega da outra vez que você me deu essa idéia o arquivo de baixai não tinha compilado no Delphi 7, pois era de Delphi 5.

Más esse tem todas as versões é complicou no Delphi 7 é no 2006.

Vou testar é post o resultado obrigado

Link para o comentário
Compartilhar em outros sites

  • 0

Colegas onde estou errando nesse código

procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  CarregarGrid;
  if (ACol = Coluna) and (ARow = Linha) then
    Grid.Canvas.Brush.color := clBlue;
  Grid.canvas.fillRect(Rect);
  Grid.Canvas.TextRect(Rect, Rect.Left,
  Rect.Top,Grid.Cells[Coluna, Linha]);
end;
----------------------------------------------------------- CarregarGrid é assim:
with qryAuxiliar do
    begin
      Close;
      SQL.Clear;
      SQL.Add('Select de_Coluna, de_Linha, de_Cor From Tab_Grid');
      Open;
    end;
    if qryAuxiliar.RecordCount > 0 then
      begin
        Coluna:= qryAuxiliar.FieldByName('de_Coluna').AsInteger;
        Linha:= qryAuxiliar.FieldByName('de_Linha').AsInteger;
      end;
Se eu fizer assim:
Coluna:= 1;
Linha:= 2;
if (ACol = Coluna) and (ARow = Linha) then
  Grid.Canvas.Brush.color := clBlue;
Grid.canvas.fillRect(Rect);
Grid.Canvas.TextRect(Rect, Rect.Left,
     Rect.Top,Grid.Cells[Coluna, Linha]);

Funciona onde estou errando?, pois quero pegar os valores de Coluna e Linha que vem de uma tabela no Access.

:wacko:

Editado por Micheus
Adicionado o delimitador de código [code] [/code]. Lembre-se de utilizá-lo para melhor visualização
Link para o comentário
Compartilhar em outros sites

  • 0

Colegas onde estou errando nesse código

 

procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
   CarregarGrid;   /// Esta chamada esta errada, não deve ser feita aqui 

   if (ACol = Coluna) and (ARow = Linha) then
     Grid.Canvas.Brush.color := clBlue;
   Grid.canvas.fillRect(Rect);
   Grid.Canvas.TextRect(Rect, Rect.Left,
   Rect.Top,Grid.Cells[Coluna, Linha]);
end;

OBS: no evento GridDrawCell voce esta fazendo uma chamada a uma procedure ou função ( essa chamada não funciona ) por isso quando voce coloca os valores manualmente funciona;

Citar
CarregarGrid é assim:
 

with qryAuxiliar do
begin
   Close;
   SQL.Clear;
   SQL.Add('Select de_Coluna, de_Linha, de_Cor From Tab_Grid');
   Open;
end;

if qryAuxiliar.RecordCount > 0 then
begin
   Coluna:= qryAuxiliar.FieldByName('de_Coluna').AsInteger;
   Linha:= qryAuxiliar.FieldByName('de_Linha').AsInteger;
end;

Se voce perceber, a cada chamada somente um valor sera retornado ( o primeiro registro), mesmo que voce tenha mais de um registro Forma correta :

 
var  : integer;

with qryAuxiliar do
begin
   Close;
   SQL.Clear;
   SQL.Add('Select de_Coluna, de_Linha, de_Cor From Tab_Grid');
   Open;
end;

if qryAuxiliar.RecordCount > 0 then
begin
   for i := 1 to qryAuxiliar.RecordCount do  // aqui voce consegue trazer todos os registros da query
       begin 
            Coluna:= qryAuxiliar.FieldByName('de_Coluna').AsInteger;
            Linha:= qryAuxiliar.FieldByName('de_Linha').AsInteger;
            qryAuxiliar.Next;
       end;
end;

 

 

 

se esta chamada estiver num botao por exemplo, voce vai perceber que a cada registro lido, o evento GridDrawCell refletirá os valores lidos da query

defina as variaveis coluna e linha como publicas

 

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Jhonas vendo exemplo mudei um pouco o código ficou assim:

procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
  var 
  vetor_1 :array[1..31] of string;
  wAux, InicioTermino:string;
  wind,wPos :integer;
begin
  InicioTermino:= '1,9,11,20';
  for wind := 1 to 31 do
    vetor_1[wind] := '';
  wAux := InicioTermino;
  wind := 1;
  while wAux <> '' do
  begin
    wPos := pos(',',waux);
    if wPos > 0 then
    begin
      vetor_1[wind] := copy(waux,1,wPos-1);
      delete(wAux,1,wPos);
      inc(wind);
    end
    else
    begin
      vetor_1[wind] := waux;
      wAux := '';
    end;
  end;
--------------
if InicioTermino <> '' then
begin 
  for wind := 1 to high(vetor_1) do
  begin 
    if (vetor_1[wind] = '') then
      break
    else
    if (vetor_1[wind] = Grid.Cells[Acol,Arow]) then
    begin
      Grid.Canvas.Brush.Color := ColorBox1.Selected;
      Grid.Canvas.FillRect(Rect);
      grid.Canvas.TextRect(Rect, Rect.Left, Rect.Top, Grid.Cells[Acol,Arow]);
      break;
    end;
  end;
end;

Funciona corretamante se os valores forem apartir de 10 ou seja

Se InicioTermino:= 1 até 9 --> não pinta

Se InicioTermino:= 10 até 31 --> pintar

Onde está errado? :mellow:

Editado por Micheus
Adicionado o delimitador de código [code] [/code]. Lembre-se de utilizá-lo para melhor visualização
Link para o comentário
Compartilhar em outros sites

  • 0
Onde está errado?

if InicioTermino <> '' then
begin 
  for wind := 1 to high(vetor_1) do
  begin 
    if (vetor_1[wind] = '') then
      break
    else
    if (vetor_1[wind] = Grid.Cells[Acol,Arow]) then
    begin
      Grid.Canvas.Brush.Color := ColorBox1.Selected;
      Grid.Canvas.FillRect(Rect);
      grid.Canvas.TextRect(Rect, Rect.Left, Rect.Top, Grid.Cells[Acol,Arow]);
      break;
    end;
  end;
end;

OBS: Testei apenas este codigo que voce postou ... o erro esta nesta rotina ... o for wind varia apenas 4 vezes e como o vetor_1[wind] sera igual a Grid.Cells[Acol,Arow], se esta comparando apenas um numero do vetor ?

use o debugging do delphi para visualizar o que ocorre...

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Ola pessoal, Jhonas desculpe a demora para responder

Realmente o erro estava aqui:

if (vetor_1[wind] = Grid.Cells[Acol,Arow]) then
O correto é assim
if (vetor_1[wind] = Trim(Grid.Cells[Acol,Arow])) then
O resto está certo obrigado pela dica. Bem para completar esse post só falta uma idéia na segui-te questão: Como posso Salvar no banco (Access 2003) um calendário com todas as aulas de um determinado professor? Ex: Se o professor Marcos tem duas aulas de Física na semana, então ele deve dar 80 aulas no ano, ou seja, para cada aula que um professor da na semana, ele deve dar 40 aulas por ano. Exemplo: Carlos da 2 aulas por semana = 80 Aulas anuais Jorge da 3 aulas por semana = 120 Aulas anuais Como posso gravar de uma só vez: Carlos da 2 aulas por semana na segunda Todos os dias do mês que sejam segunda-feira, até que complete 80 aulas, caso a quantidade de segundas não complete a conta, passo a gravar em um outro dia da semana previamente informado, pois nas segundas que forem feriado. (Existe um tabela com todos os feriados cadastrados) a inclusão pule esse dia é passe para outro dia válido Estou fazendo assim:
{ Declarando o Array... creio que 5 elementos são suficientes, não me recordo 
  se é possível que um mes tenha o mesmo dia da semana 6 vezes...}
  ArrayDeDias: Array[0..5] of TDateTime;

Function DiadaSemana(Data : String) : string;
const
  semana : array[1..7] of string = ('Domingo','Segunda-feira','Terça-feira',
                                    'Quarta-feira','Quinta-feira','Sexta-feira',
                                    'Sábado');
begin
  Result := semana[DayOfWeek(strtodate(Data))]
end;

{ A Procedure que irá acumular os dias de Segunda por Ex... } 
procedure GuardaDias(Mes, Ano: Integer); 
var 
i, Dia: Byte;
Num : integer;
begin 
  { "Zerando" o Array...}
  for i:= 0 to 5 do ArrayDeDias[i]:= 0;
  { Guardando as datas } 
  i:= 0;
  for Dia:= 1 to 31 do 
  begin 
    if IsValidDate(Ano, Mes, Dia) then
      if DayOfTheWeek(EncodeDate(Ano, Mes, Dia)) = Num then // Num paga o Índice de uma combo
      begin 
        ArrayDeDias[i]:= EncodeDate(Ano, Mes, Dia); 
        i:= i + 1;
      end;
   end;
end;

{ Exemplo de uso... }
procedure TForm1.Button1Click(Sender: TObject);
var i: Byte;
dat: string;
begin
  Memo1.Clear;
  cont:= 0;
  Num:= cbbDia.ItemIndex + 1;
  GuardaDias(1,2007);
  Memo1.Lines.Add('Mês de Janeiro');
  for i:= 0 to Length(ArrayDeTercas) - 1 do
    if (ArrayDeDias[i] <> 0) then
    if ContarAulas < 80 then
      begin
      with qryAuxiliar do
        begin
          Close;
          SQL.Clear;
          SQL.Add('Insert Into Tab_Calendario (dt_Aula, id_Professor, id_Materia) values(');
          SQL.Add('"' + datetostr(ArrayDeDias[i]) + '",');
          SQL.Add('"' + TRIM(GetStrEsquedo(cbbProfessor.text,'-')) + '",');
          SQL.Add('"' + TRIM(GetStrEsquedo(cbbMateria.text,'-')) + '"');
          SQL.Add(')');
          ExecSQL;
        end;
      dat:= DateToStr(ArrayDeDias[i]);
      Memo1.Lines.Add(DateToStr(ArrayDeDias[i]) + ' - ' + DiadaSemana(dat));
      Cont:= Cont + 1;
      end
      else
      Exit;
      Memo1.Lines.Add('----------------------------------------------');

Funciona corretamente só que mesmo o professor dando duas ou três aulas no dia da semana assim só grava um dia.

Como posso gravar de modo que se é dado duas aulas num dia, é a primeira segunda for 07/01/2007 assim que grava conte como se fossem duas aulas ao invés de um como está gravando?

Editado por Marcos Santana
Link para o comentário
Compartilhar em outros sites

  • 0
Como posso gravar de uma só vez:

Carlos da 2 aulas por semana na segunda

Todos os dias do mês que sejam segunda-feira, até que complete 80 aulas, caso a quantidade de segundas não complete a conta, passo a gravar em um outro dia da semana previamente informado, pois nas segundas que forem feriado.

(Existe um tabela com todos os feriados cadastrados) a inclusão pule esse dia é passe para outro dia válido

Marcos, acho que a lógica seria mais ou menos essa:

// DiaInicial - equivalente ao dia da semana de onde começar
// QtdAulas - quantidades de aulas a gerar para o dia
procedure GeraAulas(DiaInicial :TDateTime; QtdAulas :Byte);
var
  DiaInicial,
  DiaFinal :TDateTime;
begin
  // inicialização da querie de feriados
  with qryFeriados do
  begin
    Close;
    SQL.Clear;
    SQL.Add('Select dt_Feriado');
    SQL.Add('From Tab_Feriado');
    SQL.Add('Where dt_Feriado = :dt_Feriado');
  end;

  // inicialização da querie para inserção 
  with qryAuxiliar do
  begin
    SQL.Clear;
    SQL.Add('Insert Into Tab_Calendario (dt_Aula, id_Professor, id_Materia) ');
    SQL.Add('values(:dt_Aula, :id_Professor, :id_Materia)');
  end;

  DiaFinal := <data>; // indica a última data do ano a ser considerada
  while DiaInicial < DiaFinal do
  begin
   // verificar se o dia sendo processado está cadastrado como feriado
    qryFeriados.ParamByName('dt_Feriado').AsDateTime := DiaInicial;
    qryFeriados.Open;
    if not qryFeriados.RecordCount = 0 then 
    begin
     // repetiremos a inclusão para a quantidade de aulas do dia
     // talvez, você precise adicionar um campo na tabela que indique 
     // de que aula está tratando (1ª, 2ª ou 3ª)
      for Idx := 1 to QtdAulas do
      begin
        qryAuxiliar.ParamByName('dt_Aula').AsDateTime := DiaInicial;
        qryAuxiliar.ParamByName('id_Professor').AsInteger := StrToInt(Trim(GetStrEsquedo(cbbProfessor.text,'-')));
        qryAuxiliar.ParamByName('id_Materia').AsInteger := StrToInt(Trim(GetStrEsquedo(cbbMateria.text,'-')))
        qryAuxiliar.ExecSQL;
      end;
    end;
    qryFeriados.Close;

   // avançamos uma semana para gerar aulas no mesmo dia da semana seguinte
    DiaInicial := DiaInicial +7
  end;
end;

Veja se seria por aí.

Abraços

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...