I need a little help with resolving a VBA code for an school assignment.
Dim i As Long
Dim LastStudent As Long
Records.Sheets("Student").Activate
LastStudent = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LastStudent
If (DateDiff("d", Date, Attendance_rng.Range("I" & i).Value) > 80) Then
.Range("K15").Value = WorksheetFunction.CountIfs(Attendance_rng.Range("A:A"), RollNo, Attendance_rng.Range("D:D"), "ACTIVE")
End If
Next
I tried to execute the above code snippet. I don't see any errors but I don't get any data output either.
I want to count the number of days (Today's date - date in column I for each student), if that value is > 80 then record the day count in cell K15 for each student(Roll Number) from column A where the G Column data is "Active".
Note:
Column I has the Weekly recorded attendance dates
Related
I have a for loop that iterates through each sheet in my workbook. Each sheet is identical for most purposes. I am making an overview sheet in my workbook to express the results from the data in the other sheets(the ones that are identical).
There are 11 vehicles, each with their own sheet that has data from a test from each day. On any given day there can be no tests, or all the way to 30,000 tests. The header of each column in row 47 states the date in a "06/01/2021 ... 06/30/2021" format. The data from each iteration of the test will be pasted in the column of the correct date starting at row 49.
So what my overview page needs to display is the data from the previous day. In one cell on my overview there is a formula for obtaining just the number of the day of the month like 20 or 1 etc. Using this number, the number of the day is the same as the column index that the previous day's data will be in conveniently. So in my for loop I want to have a table that has the name of each sheet in column B, in column C I want to display the total number of tests done in that day(not the sum of all the data), in column D I need the number of tests with a result of 0, in column E I need the number of tests that have a result above the upper tolerance, and in column F I need the number of tests that have a result below the lower tolerance minus the result in column D.
I've been playing with the Application.WorksheetFunction.Count and CountIf functions but I keep getting 0 for every single cell. I made two arrays for the upper and lower tolerance values which are type Longs called UTol and LTol respectively. TabList is a public array that has each of the sheet names for the vehicles stored as strings. finddate is an integer that reads in Today's day number which is yesterday's column index. I've included a picture of the table in question and my for loop code:
finddate = Worksheets("Overview").Range("A18").Value
For TabNRow = 1 To 11
startcol = 3
Worksheets(TabList(TabNRow)).Activate
Debug.Print (TabList(TabNRow))
'Total number of tests done that day
Worksheets("Overview").Cells(startrow, startcol).Value = Application.WorksheetFunction.Count(Range(Cells(49, finddate), Cells(30000, finddate)))
startcol = 4
'Total number of 0 results, this used to get the number of 0's from each sheet but that row has since been deleted
Worksheets("Overview").Cells(startrow, startcol).Value = Worksheets(TabList(TabNRow)).Cells(48, finddate).Value
startcol = 5
'Total number of results above tolerance
Worksheets("Overview").Cells(startrow, startcol).Value = Application.WorksheetFunction.CountIf(Range(Cells(49, finddate), Cells(30000, finddate)), ">" & UTol(TabNRow))
startcol = 6
'Total number of results below tolerance
Worksheets("Overview").Cells(startrow, startcol).Value = Application.WorksheetFunction.CountIf(Range(Cells(49, finddate), Cells(30000, finddate)), "<" & LTol(TabNRow))
startrow = startrow + 1
Next TabNRow
```
No need to select/activate sheets when referencing them. See: How to avoid using Select in Excel VBA
Something like this should work:
Dim wsOv As Worksheet, wsData As Worksheet, rngData As Range
Set wsOv = ThisWorkbook.Worksheets("Overview")
finddate = wsOv.Range("A18").Value
For TabNRow = 1 To 11
Set wsData = ThisWorkbook.Worksheets(TabList(TabNRow))
Set rngData = wsData.Range(wsData.Cells(49, finddate), _
wsData.Cells(Rows.Count, finddate).End(xlUp))
Debug.Print wsData.Name, rngData.Address 'edited
With wsOv.Rows(2 + TabNRow)
.Columns("C").Value = Application.Count(rngData)
.Columns("D").Value = Application.CountIf(rngData, 0)
.Columns("E").Value = Application.CountIf(rngData, ">" & UTol(TabNRow))
.Columns("F").Value = Application.CountIf(rngData, "<" & LTol(TabNRow)) _
- .Columns("D").Value
End With
Next TabNRow
I am trying to build a VBA code where I am given 2 dates to be used as a date range. Using this date range, I am trying to compare it to a date in every row within a table. If the table date is within the date range, I want to retrieve a specific value also within the table.
Example:
Date Range:
02/01/2021 - 07/01/2021
The colors are in Column A and the dates are in column B
Red - 03/08/2021
Orange - 09/01/2021
For this example, I need it to return "Red"
Yes there is...
If you try it, remember to first set the correct values on the CONFIG sections of the code.
Sub RetrieveValue()
Dim start_date, end_date As Date
Dim dates_col, db_start_row, db_end_row As Integer
Dim counter, values_col, retrieve_values_col As Integer
'CONFIG THIS BEFORE YOU RUN THE MACRO
'--------------------------
retrieve_values_col = 4 'column number where you want to retrieve the values
values_col = 2 'column where all the values are
dates_col = 3 'in what column are the dates?
db_start_row = 3 'in what row does the data start?
start_date = Date - 4 'set the date interval
end_date = Date + 3 'DATE is a function that returns todays date
'--------------------------
db_end_row = Cells(Rows.Count, dates_col).End(xlUp).Row
For counter = db_start_row To db_end_row
If Cells(counter, dates_col) >= _
start_date And Cells(counter, dates_col) <= end_date Then
Cells(counter, retrieve_values_col) = Cells(counter, values_col)
End If
Next counter
End Sub
The dates must be set like in the following picture for the macro to work.
I am making a function that will search through a range and find the oldest date (the oldest date is in last row with data). My range is structured as following and I won't be able to change this structure:
Year Month Day
yyyy mm dd
So the year month and day are seperated in three different columns.
My code is as following:
Function OLDEST(yearrng As Range) As Variant
Dim lastrow As Long
Dim year, month, day As String
lastrow = Range(yearrng).SpecialCells(xlCellTypeBlanks).Row
year = Range("I" & lastrow).value
month = year.Offset(0, 1).value
day = year.Offset(0, 2).value
OLDEST = year & month & day
End Function
The yearrng is the same range which the years are displayed.
The problem is that this function is not working and is returning "value error"...
I hope you understood my question.
Thanks!
For a non-volatile worksheet function, you can try:
=DATE(LOOKUP(2,1/(LEN($I:$I)>0),I:I),LOOKUP(2,1/(LEN($I:$I)>0),J:J),LOOKUP(2,1/(LEN($I:$I)>0),K:K))
where I is the column to test for which is the "bottom" row, and I, J, and K are the columns with the relevant date parts.
Im currently creating a template for our report. And I would like to do some automation.
I have a source sheet which I call "KPISource" (Data source is in sharepoint, thus this is a table). And in the first column I would like to get data which has has the current Month and the previous month.
Basically, If it is current month, it will then put the data in the "August" column. And If the date is previous month, then it will also put the data in the "July".
In my source sheet, the columns are Date, Tickets Solved (productivity), YTD, Ticket Reopen Rate(quality), Aging <5 days (Quality), YTD (Aging <5 days) Aging > 5 days (Quality), YTD (Aging >5 days), Customer Satisfaction, YTD (Customer Satisfaction)
Currently here is my code, but no output is appearing. This is the code that I'm trying if the there is a previous date in column 1 (KPISource), then it will have the value in KPI.Cells(6, 4).Value (Tickets Solved "July").
Sub OperationalKPI()
Dim KPI As Worksheet
Set KPI = Sheets("OperationalKPI")
Dim KPISource As Worksheet
Set KPISource = Sheets("KPISource")
mPrevious = Format(DateAdd("m", -1, Date), "mmmm")
mCurrent = Format(Date, "mmmm")
lastrow = KPISource.Cells(Rows.Count, 1).End(xlUp).Row
For x = 2 To lastrow
If mPrevious = KPISource.Cells(x, 1) Then
KPI.Cells(6, 4).Value = KPISource.Cells(x, 2).Value
End If
Next x
End Sub
The problem, based upon your feedback, is in the line
If mPrevious = KPISource.Cells(x, 1) Then
mPrevious is a string containing the name of the month, eg "July", however KPISource.Cells(x, 1) contains a date so the two are never going to be equal.
Change the line to:
If mPrevious = Format(KPISource.Cells(x, 1),"mmmm") Then
This will make both items strings with the name of the month in them and the If should find the matches.
I have a puzzle I've been trying to solve for ages now, but it's quite simply beyond me.
I have a spreadsheet with 3 columns. Column A is instructor ID numbers, Column B is their course Start date and Column C is their course end date. There are multiple courses for each instructor ID.
I'm basically trying to answer the question, what is the maximum number of courses this instructor is teaching at any given time.
Essentially, I need to find, for each ID number, the number of maximum, concurrent, overlapping date ranges.
The trouble is, while I know how to find overlapping date ranges, I don't know how to count the number of concurrent courses.
Eg.
Instructor 115 has the following date ranges listed:
9/10/13 / 11/04/13
9/17/13 / 11/11/13
11/05/13 / 12/30/13
11/12/13 / 1/20/14
While the 11/05/13 course overlaps with both the 9/17/13 course and the 11/12/13 course, they do not overlap with each other... so this instructor is only teaching a maximum of 2 courses at any time.
Is there a way to write a function that will return the highest number of concurrent overlapping date ranges for each ID?
Edit not form OP to transfer details from a comment:
I can solve this geometrically, but I don't know how to do that in a VBA function (I'm still very new to programming). If I were to solve this outside of code, I would create a table for each ID making a column for every day. I'd then create a row for each date range, marking a 1 in each column that range overlaps with. then I’d sum the total overlaps for each day. Then I’d use a simple MAX function to return the highest number of consecutive overlaps. Is there a way to do this inside of a function without having Excel physically draw out these tables?
Using VBA, assuming Column A contains your start dates, and column B contains your end dates, and assuming your data starts in row 1 and there are no blank rows in your data, the below sub will do what you outlined in your comment:
Sub getMaxConcurrent()
'get minimum date (startDate)
Dim startDateRange
Set startDateRange = Range("A1", Range("A1").End(xlDown))
Dim startDate As Date
startDate = WorksheetFunction.Min(startDateRange)
'get maximum date (endDate)
Dim endDateRange
Set endDateRange = Range("B1", Range("B1").End(xlDown))
Dim endDate As Date
endDate = WorksheetFunction.Max(endDateRange)
'get date range (dateInterval)
Dim dateInterval As Integer
dateInterval = DateDiff("d", startDate, endDate)
'Create daily table header
Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Dim x As Integer
For x = 0 To dateInterval
Dim dateVal As Date
dateVal = DateAdd("d", startDate, x)
Cells(1, 3 + x).Value = dateVal
Next
'Fill in daily table
Dim y As Integer
y = 2
Dim startDateValue As Date
startDateValue = Cells(y, 1).Value
Do Until IsEmpty(Cells(y, 1).Value)
For x = 3 To dateInterval + 3
If (Cells(y, 1).Value <= Cells(1, x).Value) Then
If (Cells(y, 2).Value >= Cells(1, x).Value) Then
Cells(y, x).Value = 1
Else
Cells(y, x).Value = 0
End If
Else
Cells(y, x).Value = 0
End If
Next
y = y + 1
Loop
'sum up each day
For x = 3 To dateInterval + 3
Cells(y, x).Value = WorksheetFunction.Sum(Range(Cells(2, x).Address & ":" & Cells(y - 1, x).Address))
Next
MsgBox ("Max concurrent courses: " & WorksheetFunction.Max(Range(Cells(y, 3).Address & ":" & Cells(y, x).Address)))
End Sub
If you have data down to row 1000 then this "array formula" will give the maximum number of concurrent courses for an Instructor ID in E2
=MAX(COUNTIFS(A:A,E2,B:B,"<="&B$2:C$1000,C:C,">="&B$2:C$1000))
confirmed with CTRL+SHIFT+ENTER
Let's assume there is only one instructor and you have start and end dates in A1:B4.
Copy A1:A4 to A7:A10, copy B1:b4 to A11:a14 (right under it). Select A7:A14, hit Sort (on data tab) and "remove duplicates". You have a list unique list of dates in ascending order. Let's assume there were no duplicates (as in your example), your of date is same A7:a14. Select it copy, and paste spacial with transpose to C5.
At this point You have start and end dates in A1:B4 and list of uniqe dates in C5:J5. Put formula =IF(AND($A1<=C$5,C$5<=$B1),1,0) in C1 and copy it to C1:J4.
put formula =SUM(C1:C4) in C6 and copy it to C6:J6.
Maximum number in C6:j6 is your maximum concurrent courses for this instructor