Página 2 de 3

Calendário, marcar dia trabalhado

Enviado: 04 Jun 2025 21:33
por JoséQuintas
Ficou interessante, não sei se acrescento nos exemplos da hwgui.

Sobre a função de dias do mês...

Vai que não tem no xharbour, e inventam de criar função na hwgui....

Tem essa também.

Aqui usava UltimoDia() mas mudei o nome pra parecido com MySQL.

Código: Selecionar todos

FUNCTION LastDayOfMonth( dData )
   dData := dData -Day( dData ) + 35
   dData := dData - Day( dData )
   RETURN Day( dData )
Zera a data pro suposto primeiro dia e soma 35, cai no mes seguinte.
Tirando o dia da data, cai no último dia do mês.
Aí, só pegar o Day()
Procurei deixar no básico mesmo.

Calendário, marcar dia trabalhado

Enviado: 04 Jun 2025 21:55
por alxsts
Olá!

Não sei se faz parte dos requisitos mas, penso que, além de saber se trabalhou, o ideal seria saber quantas horas trabalhou.

Isto levaria a um formulário para entrada de horários de entradas e saídas em uma data, podendo haver vários registros por funcionário em cada data, possibilitando cálculos de total de horas trabalhadas, valores a pagar e estatísticas.

Quanto mais informações, mais recursos se tornam disponíveis...

Calendário, marcar dia trabalhado

Enviado: 04 Jun 2025 22:05
por alxsts
Olá!
Itamar M. Lins Jr. escreveu:Tem a função eom() não sei se é da CT que eu uso.
Não tenho certeza mas acho que o Harbour tem a função EOMONTH() nativa. Dê um Find aí...

BOM(), EOM() já usei mas não lembro de qual lib...

Calendário, marcar dia trabalhado

Enviado: 05 Jun 2025 09:21
por Itamar M. Lins Jr.
Olá!
Não sei se faz parte dos requisitos mas, penso que, além de saber se trabalhou, o ideal seria saber quantas horas trabalhou.
Neste caso é diferente. São contratados.
Tem o salário do mês + os dias extras. Embarcados. Só o fato de está no barco, fora do dia normal deles, já é 1 dia extra.(não tem horas)
1 mês de folga/descanso, só que eles são chamados e ai tem o extra. A maioria aceita, outros são substituídos.

Saudações,
Itamar M. Lins Jr.

Calendário, marcar dia trabalhado

Enviado: 05 Jun 2025 16:41
por JoséQuintas
Parece que a lista de alternativas é grande

Código: Selecionar todos

hbmk2 -find day

Harbour core (installed):
   Day()
   Days()
   hb_CDay()
hbct.hbc (installed):
   DaysInMonth()
   DaysToMonth()
   LastDayOM()
hbmisc.hbc (installed):
   ADays()
   hbmisc_DaysInMonth()
hbnf.hbc (installed):
   ft_DayOfYr()
   ft_DayToBoW()
   ft_FDay()
   ft_LDay()
   ft_PickDay()
   ft_Workdays()
xhb.hbc (installed):
   TimeOfDay()

Calendário, marcar dia trabalhado

Enviado: 06 Jun 2025 10:28
por JoséQuintas
browsecal.png
browsecal2.png
Apenas pra curiosidade, ou pra mais opções.
Na HMG Extended tem estes exemplos em samples\advanced\tsb_calendar

Eles são criados usando browse array
Achei interessante quando vi, porque nunca tinha pensado em usar um browse pra isso.
E se é browse, dá pra fazer nas outras LIBs também.

Calendário, marcar dia trabalhado

Enviado: 06 Jun 2025 11:14
por JoséQuintas
Putz...
Acabo de pensar numa versão mais doida ainda.... em SQL !!!!!
Um SELECT retornando um calendário !!!!!
Se dá pra fazer com browse, que seria uma lista, o retorno do SQL também é uma lista !!!!!
Talvez até com marcações de trabalhado ou não......

É a imaginação... de repente, pra facilitar, número positivo trabalhado e negativo não trabalhado, um único valor definindo tudo.
ABS() retorna o dia, e iif( x > 0, BLUE, RED ) pra cor.

Algum doido no mundo já deve ter pensado nisso, talvez encontre no google.

Calendário, marcar dia trabalhado

Enviado: 06 Jun 2025 11:39
por JoséQuintas
calendarsql.png
Eu não disse kkkkkkkkk
Calendário pra 100 anos kkkkk

Calendário, marcar dia trabalhado

Enviado: 06 Jun 2025 16:51
por JoséQuintas
calsql.png
Teste básico.
O trem é doido.
(atualizei o post anterior)

Calendário, marcar dia trabalhado

Enviado: 06 Jun 2025 17:48
por alxsts
Olá!

Dependendo da versão do banco, é possível utilizar uma CTE:

Código: Selecionar todos

WITH recursive Datas AS (
	      -- "Membro Âncora"
	      SELECT
	        Cast( '2025-06-01' As Date) as Data
	      UNION ALL
	        -- "Membro Recursivo"
	      SELECT
	         Date_Add( Data, INTERVAL 1 DAY)
	      FROM Datas  /* Resultado da última iteração */
	      WHERE
	        Data < Cast( '2025-06-30' as Date)
	)
	SELECT *     
	  FROM datas
	ORDER BY DATA

Calendário, marcar dia trabalhado

Enviado: 19 Jun 2025 19:26
por JoséQuintas
Mais doido ainda, só pra testar possibilidades.
Calendário com marcação dos compromissos.

Código: Selecionar todos

SET @dDate := DATE( NOW() );
SET @dInicial := DATE_SUB( @dDate, INTERVAL DAY( @dDate ) - 1 DAY );
SET @dInicial := DATE_SUB( @dInicial, INTERVAL WEEKDAY( @dInicial ) + 1 DAY );

SELECT DISTINCT
   if( MONTH( A ) = MONTH( @dDate ), CONCAT( lpad(DAY( A ),2), if( fa.horadata IS NULL, '', '*' ), '' ), '' ) AS SUN,
   if( MONTH( B ) = MONTH( @dDate ), CONCAT( DAY( B ), if( fb.horadata IS NULL, '', '*' ), '' ), '' ) AS MON,
   if( MONTH( C ) = MONTH( @dDate ), CONCAT( DAY( C ), if( fc.horadata IS NULL, '', '*' ), '' ), '' ) AS TUE,
   if( MONTH( D ) = MONTH( @dDate ), CONCAT( DAY( D ), if( fd.horadata IS NULL, '', '*' ), '' ), '' ) AS WED,
   if( MONTH( E ) = MONTH( @dDate ), CONCAT( DAY( E ), if( fe.horadata IS NULL, '', '*' ), '' ), '' ) AS THU,
   if( MONTH( F ) = MONTH( @dDate ), CONCAT( DAY( F ), if( ff.horadata IS NULL, '', '*' ), '' ), '' ) AS FRI,
   if( MONTH( G ) = MONTH( @dDate ), CONCAT( DAY( G ), if( fg.horadata IS NULL, '', '*' ), '' ), '' ) AS SAT

FROM
(
SELECT
   DATE_ADD( @dInicial, INTERVAL X + 0 DAY ) AS A,
   DATE_ADD( @dInicial, INTERVAL X + 1 DAY ) AS B,
   DATE_ADD( @dInicial, INTERVAL X + 2 DAY ) AS C,
   DATE_ADD( @dInicial, INTERVAL X + 3 DAY ) AS D,
   DATE_ADD( @dInicial, INTERVAL X + 4 DAY ) AS E,
   DATE_ADD( @dInicial, INTERVAL X + 5 DAY ) AS F,
   DATE_ADD( @dInicial, INTERVAL X + 6 DAY ) AS G
FROM
(
SELECT 0 AS X
UNION ALL SELECT 7
UNION ALL SELECT 14
UNION ALL SELECT 21
UNION ALL SELECT 28
UNION ALL SELECT 35
 ) AS X
) AS Y
left JOIN jptabhorario AS fa ON fa.horadata = a 
left JOIN jptabhorario AS fb ON fb.horadata = b
left JOIN jptabhorario AS fc ON fc.horadata = c
left JOIN jptabhorario AS fd ON fd.horadata = d
left JOIN jptabhorario AS fe ON fe.horadata = e
left JOIN jptabhorario AS ff ON ff.horadata = f
left JOIN jptabhorario AS fg ON fg.horadata = g

ORDER BY sun
calendario.png
detalhe: 0,015 segundos pra retornar pronto.

Calendário, marcar dia trabalhado

Enviado: 19 Jun 2025 21:11
por alxsts
Olá!

A imagem parece mostrar o mês de jun/2025. Por que a linha 1 está em branco?

Dá a impressão de que o mês tem 6 semanas, o que não é verdade...

Calendário, marcar dia trabalhado

Enviado: 19 Jun 2025 21:59
por JoséQuintas
Sim.
É que a rotina cria um intervalo maior que o mês, pra mostrar as possíveis semanas.
Em STORED PROCEDURE seria mais flexível, ou talvez em MariaDB ou MySQL mais moderno.
Vou ver o que dá pra fazer, talvez um limite.

Calendário, marcar dia trabalhado

Enviado: 19 Jun 2025 22:10
por JoséQuintas
Até que foi rápido

if() na inicial, pra não adicionar linha desnecessária

Código: Selecionar todos

SET @dInicial := IF( WEEKDAY( @dInicial ) == 0, @dInicial, DATE_SUB( @dInicial, INTERVAL WEEKDAY( @dInicial ) + 1 DAY ) );
uma dFinal

Código: Selecionar todos

SET @dFinal   := LAST_DAY( @dDate );
o where pra evitar linha a mais

Código: Selecionar todos

WHERE A <= @dFinal

Código: Selecionar todos


SET @dDate := DATE( NOW() );
SET @dInicial := DATE_SUB( @dDate, INTERVAL DAY( @dDate ) - 1 DAY );
SET @dInicial := IF( WEEKDAY( @dInicial ) == 0, @dInicial, DATE_SUB( @dInicial, INTERVAL WEEKDAY( @dInicial ) + 1 DAY ) );
SET @dFinal   := LAST_DAY( @dDate );

SELECT DISTINCT
   IF( MONTH( A ) = MONTH( @dDate ), CONCAT( LPAD( DAY( A ), 2 ), IF( fa.horadata IS NULL, '', '*' ), '' ), '' ) AS SUN,
   IF( MONTH( B ) = MONTH( @dDate ), CONCAT( DAY( B ), IF( fb.horadata IS NULL, '', '*' ), '' ), '' ) AS MON,
   IF( MONTH( C ) = MONTH( @dDate ), CONCAT( DAY( C ), IF( fc.horadata IS NULL, '', '*' ), '' ), '' ) AS TUE,
   IF( MONTH( D ) = MONTH( @dDate ), CONCAT( DAY( D ), IF( fd.horadata IS NULL, '', '*' ), '' ), '' ) AS WED,
   IF( MONTH( E ) = MONTH( @dDate ), CONCAT( DAY( E ), IF( fe.horadata IS NULL, '', '*' ), '' ), '' ) AS THU,
   IF( MONTH( F ) = MONTH( @dDate ), CONCAT( DAY( F ), IF( ff.horadata IS NULL, '', '*' ), '' ), '' ) AS FRI,
   IF( MONTH( G ) = MONTH( @dDate ), CONCAT( DAY( G ), IF( fg.horadata IS NULL, '', '*' ), '' ), '' ) AS SAT

FROM
(
SELECT
   DATE_ADD( @dInicial, INTERVAL X + 0 DAY ) AS A,
   DATE_ADD( @dInicial, INTERVAL X + 1 DAY ) AS B,
   DATE_ADD( @dInicial, INTERVAL X + 2 DAY ) AS C,
   DATE_ADD( @dInicial, INTERVAL X + 3 DAY ) AS D,
   DATE_ADD( @dInicial, INTERVAL X + 4 DAY ) AS E,
   DATE_ADD( @dInicial, INTERVAL X + 5 DAY ) AS F,
   DATE_ADD( @dInicial, INTERVAL X + 6 DAY ) AS G
FROM
(
SELECT 0 AS X
UNION ALL SELECT 7
UNION ALL SELECT 14
UNION ALL SELECT 21
UNION ALL SELECT 28
UNION ALL SELECT 35
 ) AS X
) AS Y
LEFT JOIN jptabhorario AS fa ON fa.horadata = a 
LEFT JOIN jptabhorario AS fb ON fb.horadata = b
LEFT JOIN jptabhorario AS fc ON fc.horadata = c
LEFT JOIN jptabhorario AS fd ON fd.horadata = d
LEFT JOIN jptabhorario AS fe ON fe.horadata = e
LEFT JOIN jptabhorario AS ff ON ff.horadata = f
LEFT JOIN jptabhorario AS fg ON fg.horadata = g

WHERE A <= @dFinal

ORDER BY sun
cal2.png

Calendário, marcar dia trabalhado

Enviado: 19 Jun 2025 22:30
por JoséQuintas
Comentário, parece que não comentei antes:

O calendário é montado usando uma lista de números.
Significa que um browse array no harbour faria igual.
Os cálculos e SEEK (no caso de DBF) poderiam ser feitos no codeblock de coluna.
É interessante porque a lógica pode ser usada fora do SQL também.