Página 1 de 1
Dias trabalhados entre Datas - RESOLVIDO
Enviado: 23 Mar 2021 às 17:14
por JCabral
Boa tarde
Precisava de uma ajuda porque não sei o que está errado na macro para calculo do número de dias trabalhados entre duas datas.
Na planilha que anexo tenho uma macro que deveria calcular o número de dias uteis entre duas datas e tenho três ranges nomeados que são os feriados e tolerâncias de ponto que preciso descontar, nomeadamente F_NACIONAIS (feriados nacionais), F_MUNICIPAIS (feriados municipais/locais) e TOLERANCIAS (tolerâncias de ponto que funcionam como mais um "feriado")
O que faço é fazer a união deste três ranges nomeados e aplicar a formula do VBA - WorksheetFunction.NetworkDays, só que está a dar erro.
O que estou a fazer de errado?
Obrigado pela ajuda
Jorge Cabral
Re: Dias trabalhados entre Datas
Enviado: 24 Mar 2021 às 08:12
por osvaldomp
Salve, Jorge.
Me parece que não é aceito mais do que um intervalo como parâmetro.
Uma solução seria agrupar os três intervalos na coluna G e utilizar:
Código: Selecionar todosdt = Application.NetworkDays(dti, dtf, Range("F_NACIONAIS"))
#
Outra solução seria manter como está a lista em G, agrupar as outras duas listas na coluna I e utilizar:
Código: Selecionar todosdt = Application.NetworkDays(dti, dtf, Range("F_NACIONAIS")) + Application.NetworkDays(dti, dtf, Range("F_MUNICIPAIS")) - Application.NetworkDays(dti, dtf)
Re: Dias trabalhados entre Datas
Enviado: 24 Mar 2021 às 08:24
por JCabral
Bom dia Caro Osvaldo
Mais uma vez obrigado pela sua ajuda.
De facto tb acho que só aceita um intervalo - The list can be either a range of cells that contains the dates or an array constant of the serial numbers that represent the dates. - só que, como também aceita um array , tem como agregar as três colunas de datas num só array?
Re: Dias trabalhados entre Datas
Enviado: 24 Mar 2021 às 08:58
por osvaldomp
Me parece que sim, e nesse caso acho que você precisaria montar no próprio código uma matriz com as datas dos feriados, sem referenciar os intervalos da planilha. Ou talvez carregar alguma Collection a partir das listas contidas na planilha.
Re: Dias trabalhados entre Datas
Enviado: 24 Mar 2021 às 14:55
por JCabral
@osvaldomp,
Depois de muitas tentativas cheguei a este código, mas não sei é possível melhorá-lo e/ou simplificá-lo, dá para dar uma vista de olhos?
Código: Selecionar todosFunction ReadRangeRowsToCollection(r As Range, c As Collection) As Collection
Dim iRow As Long
Dim iCol As Long
Dim rangeArr As Variant
Dim rowArr As Variant
'
rangeArr = r.Value
'Dados para a Collection
For iRow = 1 To r.Rows.Count
ReDim rowArr(1 To r.Columns.Count)
For iCol = 1 To r.Columns.Count
rowArr(iCol) = rangeArr(iRow, iCol)
Next iCol
c.Add rowArr
Next iRow
Set ReadRangeRowsToCollection = c
End Function
Sub Test_Coll()
Dim ws As Worksheet
Dim Rng As Range
Dim collectionAll As Collection, c1 As Collection, c2 As Collection, c3 As Collection
Dim dArr() As Long
Set ws = Worksheets("SETTINGS")
Set collectionAll = New Collection
Set c1 = New Collection
Set c2 = New Collection
Set c3 = New Collection
Set c1 = ReadRangeRowsToCollection(ws.Range("F_NACIONAIS"), collectionAll)
Set c2 = ReadRangeRowsToCollection(ws.Range("F_MUNICIPAIS"), collectionAll)
Set c3 = ReadRangeRowsToCollection(ws.Range("TOLERANCIAS"), collectionAll)
Dim aux() As Variant: ReDim aux(0 To collectionAll.Count - 1): ReDim dArr(0 To collectionAll.Count - 1)
Dim i As Integer
For i = 1 To collectionAll.Count
aux(i - 1) = collectionAll.Item(i)
Next
dti = #4/1/2021#
dtf = #4/30/2021#
For i = 0 To collectionAll.Count - 1
dArr(i) = DateSerial(Year(aux(i)(1)), Month(aux(i)(1)), Day(aux(i)(1)))
Next i
dt = WorksheetFunction.NetworkDays(dti, dtf, dArr)
MsgBox dt
End Sub
Obrigado
Re: Dias trabalhados entre Datas
Enviado: 25 Mar 2021 às 12:46
por osvaldomp
Salve, Jorge.
Carregando uma matriz com as datas dos três intervalos funciona aqui. Resultado em L12.
Código: Selecionar todosSub ContaDiasDeTrabalho()
Dim dArr() As Long, dt As Long, c As Range, i As Long, dti As Date, dtf As Date, rng As Range
Set rng = Range("F_NACIONAIS,F_MUNICIPAIS,TOLERANCIAS")
ReDim dArr(rng.Cells.Count)
For Each c In rng
dArr(i) = DateSerial(Year(c.Value), Month(c.Value), Day(c.Value))
i = i + 1
Next c
dti = #4/1/2021#
dtf = #4/30/2021#
dt = Application.NetworkDays(dti, dtf, dArr)
[L12] = dt
End Sub
Re: Dias trabalhados entre Datas
Enviado: 25 Mar 2021 às 14:24
por JCabral
@osvaldomp,
Com a sua dica anterior fui pesquisar as Collections e com uns códigos que fui encontrando montei a rotina acima, mas o seu código está clean e muito simples, como sempre. TOP!
Muito obrigado mais uma vez
Jorge