CALCULO DE FERIAS DO TRABALHADOR

PROGRAMADORVB6 08/04/2012 18:05:32
#399328
Olá boa tarde.
Estou a tentar fazer uma rotina que me indique a data limite em que um colaborador pode gozar férias, com base na indicação dos dias atribuidos.

Para cáculo de Feriados usei este módulo :


Module Calculo_Feriados
[ô]Dias Feriados
Public Function DiaFeriado(ByVal Data As Date) As Boolean
Dim Dia As Integer = Data.Day
Dim Mes As Integer = Data.Month
Dim Ano As Integer = Data.Year

[ô]Festas moveis
If Data.Date = Carnaval(Ano).Date Then Return True [ô][Ô]Entrudo/Carnaval[Ô]
If Data.Date = SextaFeiraSanta(Ano).Date Then Return True [ô] [Ô]Sexta-Feira Santa[Ô]
If Data.Date = Pascoa(Ano).Date Then Return True [ô][Ô]Páscoa[Ô]
If Data.Date = CorpoDeDeus(Ano).Date Then Return True [ô][Ô]Corpo de Deus[Ô]

[ô]Feriados e dias Santos Fixos
If Dia = 1 And Mes = 1 Then Return True [ô][Ô]Ano Novo[Ô]
If Dia = 25 And Mes = 4 Then Return True [ô][Ô]Dia da Liberdade[Ô]
If Dia = 1 And Mes = 5 Then Return True [ô][Ô]Dia do Trabalhador[Ô]
If Dia = 10 And Mes = 6 Then Return True [ô][Ô]Dia de Portugal[Ô]
If Dia = 15 And Mes = 8 Then Return True [ô][Ô]Assunção de Maria[Ô]
If Dia = 5 And Mes = 10 Then Return True [ô][Ô]Implantação da República[Ô]
If Dia = 1 And Mes = 11 Then Return True [ô][Ô]Todos os Santos[Ô]
If Dia = 1 And Mes = 12 Then Return True [ô][Ô]Restauração da Independência[Ô]
If Dia = 8 And Mes = 12 Then Return True [ô][Ô]Imaculada Conceição[Ô]
If Dia = 25 And Mes = 12 Then Return True [ô][Ô]Natal[Ô]

[ô]Feriados Locais
[ô]If Dia = 1 And Mes = 7 Then Return [Ô]R[Ô] [ô][Ô]Feriado Regional(Madeira)[Ô]
[ô]If Dia = 21 And Mes = 8 Then Return [Ô]M[Ô] [ô][Ô]Feriado Municipal(Funchal)[Ô]
[ô]etc...

Return False [ô][Ô]Dia Util[Ô]
End Function

[ô]Festas Moveis
Public Function Carnaval(ByVal Ano As Integer) As Date
Dim D As Date = Pascoa(Ano)
Return DateSerial(Ano, D.Month, D.Day - 47)
End Function

Public Function SextaFeiraSanta(ByVal Ano As Integer) As Date
Dim D As Date = Pascoa(Ano)
Return DateSerial(Ano, D.Month, D.Day - 2)
End Function

Public Function Pascoa(ByVal Ano As Integer) As Date

Dim A As Integer = Ano Mod 19
Dim B As Integer = Int(Ano / 100)
Dim C As Integer = Ano Mod 100
Dim D As Integer = Int(B / 4)
Dim E As Integer = B Mod 4
Dim F As Integer = Int((B + 8) / 25)
Dim G As Integer = Int((B - F + 1) / 3)
Dim H As Integer = (19 * A + B - D - G + 15) Mod 30
Dim I As Integer = Int(C / 4)
Dim J As Integer = C Mod 4
Dim L As Integer = (32 + 2 * E + 2 * I - H - J) Mod 7
Dim M As Integer = Int((A + 11 + H + 22 * L) / 451)

Dim Mes As Integer = Int((H + L - 7 * M + 114) / 31)
Dim Dia As Integer = 1 + ((H + L - 7 * M + 114) Mod 31)

Return DateSerial(Ano, Mes, Dia)
End Function

Public Function CorpoDeDeus(ByVal Ano As Integer) As Date
Dim D As Date = Pascoa(Ano)
Return DateSerial(Ano, D.Month, D.Day + 60)
End Function

End Module


No Form fiz assim :
Public Class Form1
Private Function AdicionaTempo(pDataInicial As DateTime, pDias As Integer) As DateTime
Dim resultado As DateTime = pDataInicial


While pDias > -1
[ô]Se é sábado=2 (ando dois dias para a frente), domingo ou feriado=1 (ando um dia para frente)

If resultado.DayOfWeek = DayOfWeek.Saturday Then
resultado = resultado.AddDays(2)
ElseIf resultado.DayOfWeek = DayOfWeek.Sunday Then
resultado = resultado.AddDays(1)
ElseIf DiaFeriado(resultado).Equals(True) And Not resultado.DayOfWeek = DayOfWeek.Saturday Or resultado.DayOfWeek = DayOfWeek.Sunday Then
resultado = resultado.AddDays(1)
[ô]Ou se quiser adicionar um dia útil (X horas trabalhadas = 1 dia útil)
ElseIf pDias > 0 Then
resultado = resultado.AddDays(1)
pDias -= 1
[ô]Se a data final for no fim de semana ou feriado
ElseIf pDias = 0 Then
While resultado.DayOfWeek = DayOfWeek.Saturday OrElse resultado.DayOfWeek = DayOfWeek.Sunday OrElse DiaFeriado(resultado).Equals(True)
MsgBox([Ô][Ô])
[ô]Se é sábado=2 (ando dois dias para a frente), domingo ou feriado=1 (ando um dia para frente)
If resultado.DayOfWeek = DayOfWeek.Saturday Then
resultado = resultado.AddDays(2)
ElseIf resultado.DayOfWeek = DayOfWeek.Sunday Then
resultado = resultado.AddDays(1)
ElseIf DiaFeriado(resultado).Equals(True) And Not resultado.DayOfWeek = DayOfWeek.Saturday Or resultado.DayOfWeek = DayOfWeek.Sunday Then
resultado = resultado.AddDays(1)

End If
End While
pDias = -1
End If
End While
Return resultado
End Function
[ô]=================================================================================================
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
[ô]Acréscimo de 13 dias a serem gozados pelo trabalhador.
MsgBox(AdicionaTempo([Ô]27/04/2012[Ô], 13))
End Sub

End Class


========== || ========
Acrescentei 13 dias para serem gozados pelo trabalhador, começando no dia 27/04/2012 ; com a indicação de + 13 dias (úteis) irá terminar as suas Férias no dia 16/05/2012 (Já com o Feriado do dia 01/05/2012 descontado e também os dias não úteis)
O problema é que ele não indica a data certa.

Grato desde já pela vossa atenção.
Atentamente
ProgramadorVB6
Deixo também
PROGRAMADORVB6 09/04/2012 20:56:56
#399406
Olá boas noite.
Finalmente consegui com que os dados batessem certo, só que me deparei com o problema da rapidez de cáculo, que demora alguns segundos.
Existe alguma maneira de [ô]Limpar[ô] um pouco + esta minha função para que fique mais rápida?
Deixo aqui a função:

  Public Function Total_Dias(Data_Inicial As Date, Data_Final As Date) As Integer

Dim Calculo_TimeSpan As TimeSpan
Dim Numero_de_dias As Integer = 0
Dim Conta_Fins_de_Semana As Integer = 0
Dim Conta_Feriados As Integer = 0
Dim Faz_Soma_Total As String

[ô]Calcula o periodo de dias entre uma data a outra.
Calculo_TimeSpan = Data_Final.Subtract(Data_Inicial)
[ô]Variável que retém esse periodo
Numero_de_dias = Calculo_TimeSpan.Days

For i As Integer = 1 To Numero_de_dias [ô] Ciclo que percorre o inicio da data indicada até ao seu término.
Data_Inicial = Data_Inicial.AddDays(1) [ô]Incrementa (1) dia ao anterior.
[ô]Conta apenas Fims de semana.
If Data_Inicial.DayOfWeek = DayOfWeek.Sunday Or Data_Inicial.DayOfWeek = DayOfWeek.Saturday Then
Conta_Fins_de_Semana += 1
End If
[ô]Conta apenas Feriados, com a condição de não se enquadrarem em Fims de semana.
If Data_Inicial.DayOfWeek <> DayOfWeek.Sunday AndAlso Data_Inicial.DayOfWeek <> DayOfWeek.Saturday Then
If DiaFeriado(Data_Inicial).Equals(True) Then [ô]Pesquisa se o dia é um Feriado (Função do módulo em cima )
Conta_Feriados += 1
End If
End If
Next
[ô]Faz o cálculo, Subtraindo ao Total_de_dias; o nº total de Fims de semana + Feriados.
Faz_Soma_Total = Val(Numero_de_dias + 1) - Val(Conta_Fins_de_Semana + Conta_Feriados)

Return Faz_Soma_Total [ô]Total_Dias
End Function


Grato desde já pela vossa atenção.
Atenciosamente
Programadorvb6
LVFIOROT 09/04/2012 22:52:12
#399416
coloquei esses parametros e retornou em menos de 1 seg
MsgBox(Total_Dias(CDate([Ô]01/01/1900[Ô]), CDate([Ô]01/01/2013[Ô])))
quais parametros vc usou?
PROGRAMADORVB6 10/04/2012 05:07:00
#399422
Olá LVFIOROT
Eu coloquei assim :
 MsgBox([Ô]Total de dias => [ 01/01/1900 ] até [ 01/01/2013 ] = [Ô] & Total_Dias([Ô]01/01/1900[Ô], [Ô]01/01/2013[Ô])  


Mas isto é só para 1 empregado, acontece que eu tenho que fazer o cálculo para cerca de 2000 empregados (Siemens) que o cliente tem a seu cargo em poucos segundos.
Resumindo : A função terá que ser bastante robusta, daí eu pedir ajuda pelo menos para se tentar limpar um pouco + o código .
Grato desde já pela sua atenção e colaboração.
Atentamente.
Programadorvb6
Tópico encerrado , respostas não são mais permitidas