Estou compartilhando com vocês um calendário que desenvolvi, visto que não encontrei nada "pronto" que pudesse me ajudar.
Para exibição do calendário foram criados botões simples, a fim de gerar uma interação no programa de acordo com o dia selecionado. Conforme imagem anexada.
Após criar os objetos da tela conforme o seu gosto para representar o calendário inclua as seguintes procedures:
---------------------------------------------------------------------------------
--Procedure..: Preenche_Calendario --
--Autor......: Marcelo Fachinetto --
--Objetivo...: Modificar a propriedade Label dos botões de acordo com os --
-- dias do mês. --
--Descrição..: Esta procedure busca o primeiro dia da semana do mês da tela e --
-- seta os rótulos dos botões com os dias como um calendário, --
-- identificando o botão por um nome de objeto fixado na lógica. --
---------------------------------------------------------------------------------
PROCEDURE Preenche_Calendario IS
vs_data varchar2(20);
Vs_priDia varchar2(20);
Vi_priDia number(1);
vi_ult_dia number(2);
vd_data date;
vs_label varchar2(5);
vi_semana number(1);
vi_dia number(1);
vs_MesAno varchar2(30);
vb_Marca boolean;
v_item_botao varchar2(10);
BEGIN
--:mês é o campo da tela que armazena a descrição do mês
vs_MesAno := :mês;
vs_MesAno := REPLACE(vs_MesAno,'JANEIRO','01');
vs_MesAno := REPLACE(vs_MesAno,'FEVEREIRO','02');
vs_MesAno := REPLACE(vs_MesAno,'MARÇO','03');
vs_MesAno := REPLACE(vs_MesAno,'ABRIL','04');
vs_MesAno := REPLACE(vs_MesAno,'MAIO','05');
vs_MesAno := REPLACE(vs_MesAno,'JUNHO','06');
vs_MesAno := REPLACE(vs_MesAno,'JULHO','07');
vs_MesAno := REPLACE(vs_MesAno,'AGOSTO','08');
vs_MesAno := REPLACE(vs_MesAno,'SETEMBRO','09');
vs_MesAno := REPLACE(vs_MesAno,'OUTUBRO','10');
vs_MesAno := REPLACE(vs_MesAno,'NOVEMBRO','11');
vs_MesAno := REPLACE(vs_MesAno,'DEZEMBRO','12');
vs_data := '01/'||vs_MesAno;
vd_data := To_Date(vs_data,'dd/mm/RRRR');
--Para encontrar o primeiro dia. Solicita retorno em idioma específico=Inglês
Vs_priDia := RTRIM(UPPER(To_char(vd_data,'day','NLS_DATE_LANGUAGE=ENGLISH')),' ');
IF Vs_priDia = 'SUNDAY' THEN Vi_priDia := 1;
ELSIF Vs_priDia = 'MONDAY' THEN Vi_priDia := 2;
ELSIF Vs_priDia = 'TUESDAY' THEN Vi_priDia := 3;
ELSIF Vs_priDia = 'WEDNESDAY' THEN Vi_priDia := 4;
ELSIF Vs_priDia = 'THURSDAY' THEN Vi_priDia := 5;
ELSIF Vs_priDia = 'FRIDAY' THEN Vi_priDia := 6;
ELSE Vi_priDia := 7;
END IF;
vi_ult_dia := to_number(LPAD(TO_CHAR(LAST_DAY(VD_DATA)),2));
--preenche os dias:
vi_semana := 1;
vi_dia := 1;
FOR A IN 1..35 LOOP --são 35 botoes no total. Varre todos os botões e seta o label corespondente
IF A < Vi_priDia OR A >= (vi_ult_dia + Vi_priDia) THEN
vs_label := ' '; --se não estiver no calendário preenche em branco
ELSE
vs_label := to_char(A-Vi_priDia+1); --caso esteja preenche com o dia
END IF;
--o controle é feito pelo nome do objeto botão aqui chamei de B_11, B12,B_21,B_22
--ande o B_ é fixo e os numeros representam a linha e a coluna dessa grade de botões
v_item_botao := ('B_'||vi_semana||vi_dia);
--Coloca o dia como label do botão
SET_ITEM_PROPERTY(v_item_botao, LABEL, vs_label);
vi_dia := vi_dia+1;
IF (vi_dia > 7) THEN
vi_semana := vi_semana+1;
vi_dia := 1;
END IF;
END LOOP;
END;
----------------------------------------------------------------------------------
--Procedure..: Altera_mês --
--Autor......: Marcelo Fachinetto --
--Objetivo...: Remontar o calendário conforme é alterado o mês --
--Descrição..: Esta procedure faz o controle do botao responsável por --
-- avançar/retornar o mês e a chamada da rotina de preenchimento --
-- do calendário --
--Parmâmetros: PM_PROXIMO: Identificador para saber se avança ou retorna o mês. --
----------------------------------------------------------------------------------
PROCEDURE Altera_mês (PM_PROXIMO IN BOOLEAN) IS
vs_MesAno varchar(30);
vi_mês number(2);
vi_Ano number(4);
BEGIN
--:mês é o campo da tela que armazena a descrição do mês
vs_MesAno := :mês;
vs_MesAno := REPLACE(vs_MesAno,'JANEIRO','01');
vs_MesAno := REPLACE(vs_MesAno,'FEVEREIRO','02');
vs_MesAno := REPLACE(vs_MesAno,'MARÇO','03');
vs_MesAno := REPLACE(vs_MesAno,'ABRIL','04');
vs_MesAno := REPLACE(vs_MesAno,'MAIO','05');
vs_MesAno := REPLACE(vs_MesAno,'JUNHO','06');
vs_MesAno := REPLACE(vs_MesAno,'JULHO','07');
vs_MesAno := REPLACE(vs_MesAno,'AGOSTO','08');
vs_MesAno := REPLACE(vs_MesAno,'SETEMBRO','09');
vs_MesAno := REPLACE(vs_MesAno,'OUTUBRO','10');
vs_MesAno := REPLACE(vs_MesAno,'NOVEMBRO','11');
vs_MesAno := REPLACE(vs_MesAno,'DEZEMBRO','12');
vi_mês := to_number(SUBSTR(vs_MesAno,1,2));
vi_Ano := to_number(SUBSTR(vs_MesAno,4,4));
IF PM_PROXIMO = TRUE THEN
vi_mês := vi_mês + 1;
IF (vi_mês > 12) THEN
vi_mês := 1;
vi_Ano := vi_Ano + 1;
END IF;
ELSE
vi_mês := vi_mês - 1;
IF (vi_mês = 0) THEN
vi_mês := 12;
vi_Ano := vi_Ano - 1;
END IF;
END IF;
IF vi_mês = 1 THEN vs_MesAno := 'JANEIRO';
ELSIF vi_mês = 2 THEN vs_MesAno := 'FEVEREIRO';
ELSIF vi_mês = 3 THEN vs_MesAno := 'MARÇO';
ELSIF vi_mês = 4 THEN vs_MesAno := 'ABRIL';
ELSIF vi_mês = 5 THEN vs_MesAno := 'MAIO';
ELSIF vi_mês = 6 THEN vs_MesAno := 'JUNHO';
ELSIF vi_mês = 7 THEN vs_MesAno := 'JULHO';
ELSIF vi_mês = 8 THEN vs_MesAno := 'AGOSTO';
ELSIF vi_mês = 9 THEN vs_MesAno := 'SETEMBRO';
ELSIF vi_mês = 10 THEN vs_MesAno := 'OUTUBRO';
ELSIF vi_mês = 11 THEN vs_MesAno := 'NOVEMBRO';
ELSIF vi_mês = 12 THEN vs_MesAno := 'DEZEMBRO';
END IF;
vs_MesAno := vs_MesAno||'/'||vi_Ano;
:mês := vs_MesAno;
Preenche_Calendario;
END;
Observe que os dias do mês são exibidos como label em cada botão, então o nome do objeto botão segue uma lógica definida por mim que indica a linha e a coluna (como uma analogia as semanas e aos dias da semana do mês).
Acho que ficou bem legível para entender. Os botões podem ser substituídos por caixa de texto caso prefiram. No meu caso optei por fazer desse jeito.
Qualquer dúvida perguntem.
Abraço a todos e bom trabalho!