I have a table with several operation codes and its hours, and I need to sum every Thursday the hours spent on each code.
Despite being able to figure it out an IF formula would do the job I got stuck with the sum of the ranges, I could get it working via VBA but I can´t apply that same solution on Formula:
WorksheetFunction.Sum(Range("E" & cCell.Row & ":E" & cCell.Row - 6))
Dim Counter As Integer
Dim cCell As Range
Dim intToday As Integer
Dim CountDate As Integer
Dim strWsName As String
strWsName = ActiveSheet.Name
Dim xWs As Worksheet
Set xWs = Worksheets(strWsName)
'Clause 101
For Counter = 4 To 34
Set cCell = xWs.Cells(Counter, 4)
If WorksheetFunction.WeekDay(cCell.Value) = 5 Then
If cCell.Row = 4 Then
xWs.Range("Q" & cCell.Row) = WorksheetFunction.Sum(Range("E" & cCell.Row & ":E" & cCell.Row))
Else
If cCell.Row >= 34 Then
xWs.Range("Q" & cCell.Row) = WorksheetFunction.Sum(Range("E" & cCell.Row & ":E" & cCell.Row))
Else
If cCell.Row - 6 <= 0 Then
xWs.Range("Q" & cCell.Row) = WorksheetFunction.Sum(Range("E" & cCell.Row & ":E4"))
Else
xWs.Range("Q" & cCell.Row) = WorksheetFunction.Sum(Range("E" & cCell.Row & ":E" & cCell.Row - 6))
End If
End If
End If
End If
Next Counter
End Sub
I would like to know how I could transform that piece of code to a formula on Excel.
After doing a research on formulas and variables ranges I have managed to set this formula and it is working like a charm:
=IF(WEEKDAY($D9)=5;IF(ROW(E9)<=6;SUM(OFFSET(E9;;;-ROW()));SUM(OFFSET(E9;;;-7)));"")
NOTE: My locale settings uses ";" instead of "," on formulas, so bear in mind you must change it to your locale settings.
Explanation:
The "=IF(WEEKDAY($D9)=5" formula will assess if the date is a Thursday, if it is not it will exhbit "" on the column;
The IF(ROW(E9)<=6 clause will serve to identify the limits to the top of my spreadsheet, depding on its value it will SUM diferent ranges:
If the date´s row is smaller than 6 it will run this:
SUM(OFFSET(E9;;;-ROW())). The offset will be the same as the row where the
date is.
Now if the row is bigger than 6 then I will be able to set a fixed
offset of 7 rows: SUM(OFFSET(E9;;;-7))
If one needs to change the calculation to Wednesday all you have to do is to change the number "5" on "=IF(WEEKDAY($D9)=5" numbers of the weekdays intended, here is the list:
1 to Sundays
2 to Mondays
3 to Tuesdays
4 to Wednesdays
5 to Thursdays
6 to Fridays
7 to Saturdays
Thanks to articles found on Excel Jet and Extend Office I managed to build this solution!
I hope more people can use this solution!
The best way to solve this was by creating a UDF, I had the help from WideBoyDixon at ExcelForum:
Public Function SumWeek(sumRange As Range, dateRange As Range, endDate)
Application.Volatile
Dim prevSheetName As String
Dim prevSheet As Worksheet
SumWeek = Application.WorksheetFunction.SumIfs(sumRange, dateRange, "<=" & CStr(CLng(endDate)), dateRange, ">" & CStr(CLng(endDate - 7)))
prevSheetName = Mid("DecJanFebMarAprMayJunJulAugSepOctNov", Month(endDate) * 3 - 2, 3) & CStr(Year(endDate) - IIf(Month(endDate) = 1, 1, 0))
On Error Resume Next
Set prevSheet = Worksheets(prevSheetName)
If Not (prevSheet Is Nothing) Then
SumWeek = SumWeek + Application.WorksheetFunction.SumIfs(prevSheet.Range(sumRange.Address), prevSheet.Range(dateRange.Address), "<=" & CStr(CLng(endDate)), prevSheet.Range(dateRange.Address), ">" & CStr(CLng(endDate - 7)))
End If
End Function
Related
Hello I'm new to vba and I have a project which at first seems quite simple but when I started to look at the range references I was totally lost. The Goal is to make a sum of multiple columns with one or two criterias.
For j = 9 To 12
For i = 3 To 6
datecol = 3
Cells(i, j).FormulaR1C1 = "=SUMIFS(R3C" & datecol & ":R" & Lastrow2 & "c" & datecol & ", R3C2:R" &
Lastrow2 & "C2, R" & i & "C8"
Next i
datecol = datecol + 1
Next j
End sub
What I have understand is that Cells(i,j) is where the output of my formula will be write.
.FormulaR1C1 return the formula as a string in the cell (i,j) -I think this is why we have ="=sumifs()-
Then we have SUMIFS(R3C" & datecol & ":R" & Lastrow2 & "c" & datecol & ") but what ":R", "c", & " mean ?
I know that this argument is the range use by the formula to make the sum but I don't understand the way ranges are referenced, and I have the same question for R3C2:R" "C2, R".
Help would be very appreciated, thank you.
Review and Suggestions
What do :R, c, & mean ?
In the context of R1C1 style R means row and C column. The & is a concatenation operator used to join the values of two variables or constants. Very common used to create String variables.
For the macro you are trying to code you don't need to complicate yourself with .FormulaR1C1 use .Formula instead.
The line datecol = datecol + 1 is useless because datecol = 3 is inside the loop, so datecol will go back to 3 everytime the macro is looping. To solve this, datecol = 3 should be outside the loop.
When working with VBA is better to use functions that are meant to be runned in VBA and not in Excel, unless you wish to insert Excel formulas in cells. For instance the SUMIF function in VBA is: application.worksheetfunction.sumif(range,criteria,sum_range) Example of use: SumIfResult = Application.WorksheetFunction.SumIf(Range("A1:A10"), "In", Range("B1:B10"))
Descriptive Variables: use name or letters for your variables that describe them. It is easy to write software that works satisfactory. But it is very hard to write reliable, understandable and maintainable code. One important aspect is using good variable and function names. For instance, in the code below I changed the variables i and j for col and row_number.
I don't really get what you are trying to do, but I modified a little bit your code so you can maybe take some useful ideas.
Sub sum_columns()
'descriptive variable examples
Dim col As Long
Dim row_number As Long
Dim date_col As Long
Dim last_row2 As Long
date_col = 3
For col = 9 To 12
For row_number = 3 To 6
'this looks very complicated try to code it as simple as possible
'Cells(i, j).FormulaR1C1 = "=SUMIFS(R3C" & datecol & ":R" & Lastrow2 & "c" & datecol & ", R3C2:R" & Lastrow2 & "C2, R" & i & "C8"
'example
Cells(row_number, col).Formula = "=SUMIF(D" & row & ":D" & row + 3,">100)"
'another idea
Cells(row_number, col) = _
Application.WorksheetFunction.SumIf(Range("A1:A10"), "In", Range("B1:B10"))
Next row_number
date_col = date_col + 1
Next col
End Sub
Note
The code above is ONLY meant for explanation purposes (concepts, examples and ideas) NOT for executing it.
This question already has an answer here:
How to automatically input an array formula as string with more than 255 characters in length into an excel cell using VBA?
(1 answer)
Closed 2 years ago.
yesterday I posted about this problem because I didn't know an array had a limit of 255 characters. Today I've been trying for the last 9 hours to break it down as shown here:
Overcoming the 255 char. limit for formulaArray in Excel VBA and on google search for other posts doing exactly the same thing.
I followed the instructions about in order for the trick to work, you need to write complete formulas, but still haven't figured it out.
Dim TR As Double
Dim TC As Double
Dim Formula1 As String
Dim Formula2 As String
Dim Formula3 As String
Dim Rows2Copy As Integer
Dim PValue As String
Dim str As String
str = OpenBook.Sheets(1).Cells(2, 1).Value
PValue = Mid(str, 20, 2)
Rows2Copy = (PValue / 5) - 10
TR = ActiveWorkbook.Sheets(2).Cells(22 + Rows2Copy, 2).Value
TC = WorksheetFunction.Match("*" & "W" & Cells(2, 3) & "*", Worksheets(1).Range("5:5"), 0)
For j = 300 To TotalRows * 300 Step 300
With ActiveWorkbook.Sheets(2).Range("B24")
Formula1 = "=LOOKUP(2,1/('Raw Data'!R11C" & TC & ":R1048576C" & TC & "=VLOOKUP(INDEX('Raw Data'!R" & TR - j & "C1:R" & TR - j + 300 & "C1,MATCH(MIN(+FX2),+FX2,0)),'Raw Data'!R11C1:R1048576C131,+FX3,FALSE)),'Raw Data'!R11C1:R1048576C1)"
Formula2 = "ABS('Raw Data'!R" & TR - j & "C" & TC & ":R" & TR - j + 300 & "C" & TC & "-((R[1]C[2]-0.05)*R7C4))"
Formula3 = "MATCH(""*""&""W""&R2C3&""*"",'Raw Data'!R5,0)"
.FormulaArray = Formula1
.Replace "+FX2", Formula2, xlPart
.Replace "+FX3", Formula3, xlPart
End With
Next j
Sample
In the Picture, the Load case is extracted as well as the maximum force applied, the first thing is based on W Tested, it looks for the column containing that data, then returns the maximum value on "Applied Load" Column and finally returns the ID of that value. The applied load value represents 75.7%
The next step is based on a 300 upward row range from the starting position (in this case row 44834) find the closest match to 70% of the initial test and then return the value, then with 65% then 60% and so on until 10%. Everything else will populate with those values and create the intended charts. All I'm missing is this formula for it to work
Thank you! I really appreciate the help!
Maybe this doesn't help, but I hope it gives you some insight.
Excel charts work best when they are charting data from a worksheet. If you can define an array in VBA, you can easily dump that array into a sheet somewhere, then insert that range into the chart series formula. This eliminates the problem with array character limits, and makes it easier to debug the chart data.
I managed to solve it but thanks to everyone anyways:
TR = ActiveWorkbook.Sheets(2).Cells(22 + Rows2Copy, 2).Value
TC = WorksheetFunction.Match("*" & "W" & Cells(2, 3) & "*",
Worksheets(1).Range("5:5"), 0)
TCL = Split(Cells(1, TC).Address, "$")(1)
TotalRows = (PValue / 5) - 3
ActiveWorkbook.Sheets(2).Activate
Rows2Copy2 = Rows2Copy
For i = 0 To TotalRows Step 1
With ActiveWorkbook.Sheets(2).Cells(19 + Rows2Copy - i, 2)
'Split formula
Formula1 = "=LOOKUP(2,1/('Raw Data'!$" & TCL & TR - PRange & ":" & TCL & TR & "=VLOOKUP(INDEX('Raw Data'!A" & TR - PRange & ":A" & TR & ",MATCH(MIN(+FX2),+FX2,0)),'Raw Data'!$A" & TR - PRange & ":EA" & TR & ",+FX3,FALSE)),'Raw Data'!$A" & TR - PRange & ":A" & TR & ")"
Formula2 = "ABS('Raw Data'!" & TCL & TR - PRange & ":" & TCL & TR & "-((D" & 20 + Rows2Copy2 & "-0.05)*$D$7))"
Formula3 = "MATCH(""*""&""W""&$C$2&""*"",'Raw Data'!$5:$5,0)"
.FormulaArray = Formula1
.Replace "+FX2", Formula2, lookat:=xlPart
.Replace "+FX3", Formula3, lookat:=xlPart
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
End With
Rows2Copy2 = Rows2Copy2 - 1
Next i
I am completely new in VBA or programming. Right now I am developing a macro for a manufacturing site that inputs process data using Excel's User Forms. One of the things I want this macro to do is to automatically create run numbers for each process. The run number syntax we use is as follows:
V1.yy.mm.dd-1
V1.yy.mm.dd-2
V1.yy.mm.dd-3
Ex V1.20.04.29-1
The way I am trying to set up the run number creation is that when I select an item from a ComboBox the part number gets created into a TextBox to later be submitted into the corresponding database. I am not sure how to create a sequence after the Prefix = V1.yy.mm.dd-, I tried to use a CountIf application that would count the number of Prefixes with the same date in the spreadsheet for sequencing, but it seems the function does not work for partial matches. I tried to use the following but I can't get it to work. I am sure there are simpler ways to do this, can you give me a few suggestions? Thanks
This is the code I wrote so far:
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value <> "" Then
Dim Prefix As String
Dim mm, dd, yy As String
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("2- V1 Loading (2)")
Dim s As Long
s = 1 + sh.Application.Count(Application.Match(Prefix, Range("B:B"), 0))
mm = Format(Date, "mm")
dd = Format(Date, "dd")
yy = Format(Date, "yy")
Prefix = "V1." & yy & "." & mm & "." & dd & "-"
v1 = "V1." & yy & "." & mm & "." & dd & "-" & "" & s
Me.TextBox6.Value = v1
End If
Maybe something like this ?
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value <> "" Then
Set sh = ThisWorkbook.Sheets("2- V1 Loading (2)")
oDate = Format(Date, "yy.mm.dd")
oConst = "V1." & oDate & "-"
Range("B1:B10000").Copy Destination:=Range("zz1") 'copy all the item to helper column
Range("zz:zz").Replace What:=oConst, Replacement:="" 'get only the number from all the items with the current date
nextNum = Application.Max(Range("zz:zz")) + 1 'get the next number
MsgBox oConst & CStr(nextNum) 'this line only for checking
Range("zz:zz").ClearContents 'clear the helper column
Me.TextBox6.Value = oConst & CStr(nextNum)
End If
But this assuming that the item number in columns B is only at the same day.
If for example there is a forgotten data from any day before the current day, and this want to be inputted with that day and the next number, it need an input box or maybe a cell in sheet where the value is that day, then it will give the last number of that day.
Suppose the data in column B is something like below:
If the code is run today, it will show V1.20.04.30-4 as the next number. With the same data like above, if the code is run tomorrow, it will give V1.20.05.01-1.
To get the next number from yesterday (29 Apr 2020), the code need more line - which is to know on what day the code must get the next number.
Or this kind of line maybe is shorter:
oConst = "V1." & Format(Date, "yy.mm.dd") & "-"
nextNum = oConst & Application.WorksheetFunction.CountIf(Range("B:B"), "*" & oConst & "*") + 1
MsgBox nextNum
There are a few ways you could go about this but I'd say the easiest would be to put the incrementing run number in a separate cell somewhere on your worksheet (or another one if you want) to reference each time.
For example:
When the data is entered onto your 'database' sheet, write the run value to ThisWorkbook.Sheets("2- V1 Loading (2)").Range("AZ1").
Then in your code check that value like so:
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value <> "" Then
Dim Prefix As String
Dim mm, dd, yy As String
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("2- V1 Loading (2)")
Dim s As Long
s = 1 + sh.Range("AZ1").Value
mm = Format(Date, "mm")
dd = Format(Date, "dd")
yy = Format(Date, "yy")
Prefix = "V1." & yy & "." & mm & "." & dd & "-"
v1 = "V1." & yy & "." & mm & "." & dd & "-" & s
Me.TextBox6.Value = v1
Presuming that the reference numbers are written to column B of the 2- V1 Loading (2) tab then the next number must always be the one found at the bottom of the column + 1. If there is no number for that date than the new sequential number should be 1. The code below implements that method
Function NextRef() As String
' 016
Dim Fun As String
Dim Counter As Integer
Dim Rng As Range
Dim Fnd As Range
Dim Sp() As String
Fun = Format(Date, """V1.""yy.mm.dd")
With ThisWorkbook.Worksheets("2- V1 Loading (2)")
' start in row 2 (row 1 holding column captions)
Set Rng = .Range(.Cells(2, "B"), .Cells(.Rows.Count, "B").End(xlUp))
End With
If Rng.Row > 1 Then ' skip, if the column is empty
' finds the first occurrence of Ref from the bottom
Set Fnd = Rng.Find(What:=Fun, _
After:=Rng.Cells(1), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchDirection:=xlPrevious)
If Not Fnd Is Nothing Then
Sp = Split(Fnd.Value, "-")
If UBound(Sp) Then Counter = Val(Sp(1))
End If
End If
NextRef = Fun & -(Counter + 1)
End Function
You can use the function simply like ComboBox1.Value = NextRef. However when and how to call that line of code is a bit unclear in your design as published. Especially, it's not clear why you would want it in a ComboBox at all, given that the box might also contain other information. Your idea to use the Change event may not work as intended because that event occurs with every letter the user types. I have tested this:-
Private Sub ComboBox1_GotFocus()
' 016
With ComboBox1
If .Value = "" Then .Value = NextRef
End With
End Sub
The next reference number is inserted as soon as you click on the ComboBox. It works but it doesn't make sense. I think now that you have the function that does the work you will find a way to deploy it. Good luck.
I am currently working on a excel macro which generates Weekly data. I have to prepare multiple reports where my Week starting day is different e.g. if for one report my week start day is "Friday" whereas for other report the week start day is "Monday"
Right now, I am doing this in multiple steps:
First I am getting all data from source excel and adding a formula to get all records in a particular week. I have considered "Friday" as my first day of week.
I arranged the records in descending order and get the unique value for each AZ column. This way I got the last record from each week, which is what I was looking.
Code I am using for this is as follows:
Range("Data").AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=Range("$A$1:$A$2"), _
CopyToRange:=Range("$BB$4:$BD$4")
FilterDataLastRow = Cells.Find(What:="*", _
After:=Range("BA999999"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
' Sort data in descending order of date
' Range("WeeklyFilteredData").Sort Key1:=Range("$BB$4:$BB$999999"), Order1:=xlDescending, Header:=xlYes
Range("AW4:BE999999").Sort Key1:=Range("BC4:BC999999"), order1:=xlDescending, Header:=xlYes
' Assign Unique Key for each record row. We are using RowNum for same
Range("BA5:BA" & FilterDataLastRow).Formula = "=ROW(RC[-2])"
' Assign SearchKey to filter Out all the data belonging to same week
Range("AZ5:AZ" & FilterDataLastRow).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],15),""00""))"
' Get all data in User View
Range("A5:A" & FilterDataLastRow).Formula = "=VLOOKUP(RC[51],C[51]:C[55],2,FALSE)"
Range("B5:B" & FilterDataLastRow).Formula = "=VLOOKUP(RC[50],C[50]:C[54],3,FALSE)"
Range("C5:C" & FilterDataLastRow).Formula = "=VLOOKUP(RC[49],C[49]:C[53],4,FALSE)"
Range("E5:E" & FilterDataLastRow).Formula = "=VLOOKUP(RC[47],C[47]:C[51],5,FALSE)"
Cells.RemoveDuplicates Columns:=Array(1)
This was working perfectly fine till WEEKNUM 53. January 2020 started on Wednesday and this was considered a WEEKNUM "1" which is not correct for my report.
Currently I am getting my Output as shown below:
I need to modify my Code to skip data for 12/31/2019 (Highlighted in red) as this data will be calculated as part of week which is ending on 01/02/2020.
Please suggest a better way to update my code to enter code here
[Update: 07 January 2020] ANSWER
I figured out a way to achieve my end result. But I know there is still better way to do same thing and hence I am keeping this question open for better approach.
Here is what I did:
1. Retrieve MONTH, DAY and WEEKDAY from given date
Range("AW5:AW" & FilterDataLastRow).Formula = "=MONTH(RC[6])"
Range("AX5:AX" & FilterDataLastRow).Formula = "=DAY(RC[5])"
Range("AY5:AY" & FilterDataLastRow).Formula = "=WEEKDAY(RC[4],16)"
Now added a for loop. I tried to explain each of my step in comments inside code.
For i = 5 To FilterDataLastRow
' Check for records with Month = 1 And DAY is 1-6 and WEEKDAY < 6
If Range("AW" & i).Value = 1 And Range("AX" & i).Value < 7 Then
CurrYear = Year(Range("BC" & i).Value)
PrevYear = CurrYear - 1
PrevYearLastDay = "12/31/" & PrevYear
Range("AV" & i).Value = PrevYearLastDay
'Get the Day of Weel on 31st December of Previous Year
Range("AU" & i).Value = "=WEEKDAY(RC[1],16)"
'Calculate Number of Days remaining for new week to start
DaysRemForNewWeek = 8 - Range("AU" & i).Value
'Calculate Date of First Friday of Current Year
Range("AT" & i).Value = PrevYearLastDay + DaysRemForNewWeek
'Compare all the dates prior to first Friday and rollover WeekNum from last year for these dates
If Range("BC" & i).Value < Range("AT" & i).Value Then
Range("AZ" & i).Formula = "=(TEXT(RC[-4],""yyyy""))&(TEXT(WEEKNUM(RC[-4],16),""00""))"
Else
Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))"
End If
Else
Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))"
End If
Next i
What is your definition of a Week given a particular start day?
If it is the first full week of the year starting with that date, then you can derive it more easily from the VBA DatePart function, e.g
DatePart("ww", myDate, vbFriday, vbFirstFullWeek)
If you need to have this as a function or part of a formula on your worksheet, use it as a UDF instead of the worksheet WEEEKNUM function which is not as flexible. Or, better yet, construct the year/wknum string in VBA using the vba Format function and write that string to the worksheet.
For example:
Function yrWkNum(dt As Date) As String
yrWkNum = Year(dt) & Format(DatePart("ww", dt, vbFriday, vbFirstFullWeek), "00")
End Function
I figured out a way to achieve my end result. But I know there is still better way to do same thing and hence I am keeping this question open for better approach.
Here is what I did:
1. Retrieve MONTH, DAY and WEEKDAY from given date
Range("AW5:AW" & FilterDataLastRow).Formula = "=MONTH(RC[6])"
Range("AX5:AX" & FilterDataLastRow).Formula = "=DAY(RC[5])"
Range("AY5:AY" & FilterDataLastRow).Formula = "=WEEKDAY(RC[4],16)"
Now added a for loop. I tried to explain each of my step in comments inside code.
For i = 5 To FilterDataLastRow
' Check for records with Month = 1 And DAY is 1-6 and WEEKDAY < 6
If Range("AW" & i).Value = 1 And Range("AX" & i).Value < 7 Then
CurrYear = Year(Range("BC" & i).Value)
PrevYear = CurrYear - 1
PrevYearLastDay = "12/31/" & PrevYear
Range("AV" & i).Value = PrevYearLastDay
'Get the Day of Weel on 31st December of Previous Year
Range("AU" & i).Value = "=WEEKDAY(RC[1],16)"
'Calculate Number of Days remaining for new week to start
DaysRemForNewWeek = 8 - Range("AU" & i).Value
'Calculate Date of First Friday of Current Year
Range("AT" & i).Value = PrevYearLastDay + DaysRemForNewWeek
'Compare all the dates prior to first Friday and rollover WeekNum from last year for these dates
If Range("BC" & i).Value < Range("AT" & i).Value Then
Range("AZ" & i).Formula = "=(TEXT(RC[-4],""yyyy""))&(TEXT(WEEKNUM(RC[-4],16),""00""))"
Else
Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))"
End If
Else
Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))"
End If
Next i
I have to find the number of working days between two dates which should exclude weekends and National Holidays.
I am using function NETWORKDAYS in vba, this excludes weekends but I want to exclude Some National Holidays as well.
How to use this function NETWORKDAYS(startDate, endDate, [holidays]) for National holidays. It says it accepts [holidays] as a list. I have all the national holidays in an array. how can I use it with this function via VBA ??
Please find the code snippet.
Public Function dataFromInputSheetHolidayDates() As Variant
Dim holidayDates As Integer
Dim holidaydatesArray(20) As Variant
holidayDates = Sheets("InputSheet").Cells(Rows.Count, "D").End(xlUp).Row
For countDate = 0 To holidayDates - 1
holidaydatesArray(countDate) = Format(Sheets("InputSheet").Cells(countDate + 2, "D").Value, "DD-MMM-YY")
Next countDate
dataFromInputSheetHolidayDates = holidaydatesArray
End Function
holidayList = dataFromInputSheetHolidayDates()
Sheets("Estimation").Range("Z" & taskcounter).Formula = "=NETWORKDAYS(X" &
taskcounter & ",Y" & taskcounter &","& holidayList & ")"
Sheets("Estimation").Range("AB" & taskcounter).Formula = "=NETWORKDAYS(X" &
taskcounter & ",AA" & taskcounter &"," & holidayList & ")"
Change these 2 lines in your code:
Dim holidayDates As Long
holidaydatesArray(countDate) = Sheets("InputSheet").Cells(countDate + 2, "D")
In VBA Integer is up to 32767, which is not quite enough for dates. Furthermore, holidaydatesArray should have a numeric value and not some text format.
Pretty much similar problem as this one - workday holiday argument doesn't accept array
If you are trying to create a flexible formula through VBA, where the holidays are on different worksheet, try this solution:
Public Sub TestMe()
Dim holidayLists As Range
Set holidayLists = Worksheets(2).Range("D1:D10")
With Worksheets(1)
.Range("A1").Formula = "=NETWORKDAYS(B1, C1," & holidayLists.Parent.Name & "!" _
& holidayLists.Address & ")"
End With
End Sub
There the holidayLists.Parent.Name & "!" & holidayLists.Address would refer correctly to the worksheet's name of the holidays.