Access VBA Get Quarter From Month Number - vba

I am stuck in trying to find the quarter of year number from the month number i.e. i have month number 2 which should be quarter number 1, how do i do this in Access VBA or an access query?
Thanks in advance.

You can use this function:
Public Function Quarter(ByVal MonthNumber As Long) As Long
If (MonthNumber < 1) Or (MonthNumber > 12) Then
Call Err.Raise(6) ' Value out of Bounds '
End If
Let Quarter = (MonthNumber - 1) \ 3 + 1
End Function

In Excel VBA I like using Choose as sometimes I need to get the financial quarter rather than the calendar quarter.
calendar_quarter = Choose(Month(Date), 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4)
' if financial year starts in April - this will get the financial quarter from the current date
financial_quarter = Choose(Month(Date), 4, 4, 4, 1, 1, 1, 2, 2, 2, 3, 3, 3)

One liner for Excel:
=INT((MonthNo-1)/3 +1)
for SQL
floor(([MonthNo]-1)/3) +1

Related

Iterate through a list of dates with a known interval and create list with inverse dates in vb.net?

I'm trying to use a list of dates/times with a known interval of 10 minutes to create a list of all inverse times. I need to block off calendar times that are not available; but i only know what calendar times are available to start. My list of available slots needs to populate a calendar by blocking off all of the time that the user is not available. Each of the available appointments from my endpoint is a 10 minute interval.
Input Data Set:
6/7/19 - 8:00
6/7/19 - 8:20
6/7/19 - 9:30
6/7/19 - 10:10
6/7/19 - 11:20
With the known 10 minute interval, this means 8:00 - 8:10 is available, and should not be in my resulting list. I also block from day start 00:00 until first opening, and from last appointment, until end of day.
Expected Output:
6/7/19 - 0:00,8:00
6/7/19 - 8:10,8:20
6/7/19 - 8:30,9:30
6/7/19 - 9:40,10:10
6/7/19 - 10:20,11:20
6/7/19 - 11:30,24:59
My current code:
'// Setup some test data
Dim DateList As New List(Of DateTime)
DateList.Add(New DateTime(2019, 6, 7, 8, 0, 0))
DateList.Add(New DateTime(2019, 6, 7, 8, 20, 0))
DateList.Add(New DateTime(2019, 6, 7, 9, 30, 0))
DateList.Add(New DateTime(2019, 6, 7, 10, 10, 0))
DateList.Add(New DateTime(2019, 6, 7, 11, 20, 0))
Dim DateTemplate As New List(Of Tuple(Of DateTime, DateTime))
'// Calculate starting offset
DateTemplate.Add(Tuple.Create(New DateTime(2019, 6, 7, 0, 0, 0), DateList.First.AddMinutes(0)))
'// Loop through items
For idx = 0 To (DateList.Count - 2)
DateTemplate.Add(Tuple.Create(DateList(idx).AddMinutes(10), DateList(idx + 1).AddMinutes(0)))
Next
'// Calculate ending offset
DateTemplate.Add(Tuple.Create(DateList.Last.AddMinutes(10), New DateTime(2019, 6, 7, 23, 59, 0)))
For Each i In DateTemplate '// Show to console to debug
Console.WriteLine(i.Item1.ToString & " - " & i.Item2.ToString)
Next
If you split your day up in 10 minute intervals you know that there will be 144 slots (60 minutes / 10 intervals * 24 hours). With that being said, the way that I would tackle this problem would be to create a Dictionary where the key would represent the Date and the value would be a String array.
The values in the String array would be an Empty string to represent an open time slot or populated to represent an existing appointment.
You could then calculate the Date and Time by getting the outer Dictionary's key and the time by multiplying the index of the String in relation to the array by 10.
Take a look at this example:
Dim DateTemplate As New Dictionary(Of Date, String())
For Each existingAppointment As DateTime In DateList
If Not DateTemplate.ContainsKey(existingAppointment.Date) Then
DateTemplate.Add(existingAppointment.Date, Enumerable.Range(1, 144).Select(function(i) String.Empty).ToArray())
End If
DateTemplate(existingAppointment.Date)(existingAppointment.TimeOfDay.TotalMinutes \ 10) = "Apointment Booked"
Next
Live Demo: https://dotnetfiddle.net/FygG54

SQL converting number of days to weeks

I have a SQL table with a column that says number of days, and contains entries like 23, 26, 45, etc...
I am trying to convert each entry to a "week number". In essence, what I mean is that if my day entry is between 0 and 6, then, this is Week 1, if it is 7 and 13, then this is Week 2, 14 and 20, week 3, etc... Is there an "efficient" way to do this in SQL?
Thanks.
Thomas.
You need just the standard divide function. It ignores the remainder:
SELECT (Days / 7) + 1
You can try this and no need to add +1;
SELECT (Days / 7.00)

SSRS parameter default to most recent 1st April

I have a requirement for an SSRS parameter that will be for a start date of the most 1st April, so today it will report from 1/4/2015 with 10 weeks data, but after the 1/4/16 it will default to 1/4/16.
Can anyone help with this please?
I can find most recent month, or current month etc, but this one is a little tricky. Thankyou.
I am using SQL Server 2012 and Visual Studio 2010
You could use the following expression:
=IIF(Today() >= DateSerial(Year(Today()), 4, 1), DateSerial(Year(Today()), 4, 1), DateSerial(Year(Today()) - 1, 4, 1))
The idea is to check if the 1st of April of the current year has been reached (Today() >= DateSerial(Year(Today()), 4, 1)).
If yes, take the 1st of April of the current year: DateSerial(Year(Today()), 4, 1)
If no, take the 1st of April of the previous year: DateSerial(Year(Today()) - 1, 4, 1)

Excel year-week combination calculation

I am currently making an excel model where the date is an important aspect of it. However as the information comes from a different source it is sometimes structured in such a way that it is not realistic.
I have a problem with the calculation of the year and week combination when adding weeks or subtracting them.
The start data looks like this:
yyyyww (example: 201525, year 2015 week 25)
Now if I want to add for example 3 weeks, I can just do that by adding 3, results is 201528. However when it comes to 201552 (and sometimes yyyy53) it is more difficult as I need to calculate to 2016.
The same goes for when calculating back in the time, towards 2014 or lower. Does anyone know or have a solution for this? Maybe in VBA? or a formula trick?
a formula to add 1 to your week number format looks like this:
=YEAR(DATE(LEFT(A2, 4), 1, 1) + MID(A2, 5, 2) * 7) * 100 +
WEEKNUM(DATE(LEFT(A2, 4), 1, 1) + MID(A2, 5, 2) * 7)
it will create a sequence of week numbers that includes: 201452 => 201453 => 201502
LEFT(A2, 4) and MID(A2, 5, 2) extract the year and week components
date(year, 1, 1) + (week - 1) * 7 converts that to an actual Excel Date value, e.g. 201502 => 2015-01-08
date(year, 1, 1) + week * 7 will create a date that is 1 week after the "current" date
year(date) * 100 + weeknum(date) converts that date back to yyyyww format

Issues with updating a SQL table using a CASE statement

I'm fairly new to SQL and still trying to get my head around a few concepts...
I have created a simple table and i'm trying to update one of the columns in the table using a CASE statement. I understand why the statment won't work but i'm confused as to how to fix it....
This is my code:
CREATE TABLE q5
(
UserID INT,
Month INT,
Score INT
)
INSERT INTO q5(UserID, Month, Score)
VALUES (1,1,10), (1,2,5), (1,1,6), (2,8,6), (3,1,9), (3,4,11), (3,6,9), (4,9,10), (5,1,2);
UPDATE q5
SET
Month = CASE WHEN Month IN (1, 2, 3) THEN 'First Quarter'
WHEN Month IN (4, 5, 6) THEN 'Second Quarter'
WHEN Month IN (7, 8, 9) THEN 'Third Quarter'
ELSE 'Fourth Quarter'
END
I'm getting this error:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'First Quarter' to data type int.
Month is defined as an int, yet you are trying to update the table and set Month to a varchar, like 'First Quarter'. You can either change Month to store a varchar, and then modify your insert statement and WHEN Month IN pieces, or add an additional column that can store the quarter.
The query below shows the second option (adding an additional column).
CREATE TABLE q5
(
UserID INT,
Month INT,
Score INT,
Quarter varchar(20)
)
INSERT INTO q5(UserID, Month, Score)
VALUES (1,1,10), (1,2,5), (1,1,6), (2,8,6), (3,1,9), (3,4,11), (3,6,9), (4,9,10), (5,1,2);
UPDATE q5
SET
Quarter = CASE WHEN Month IN (1, 2, 3) THEN 'First Quarter'
WHEN Month IN (4, 5, 6) THEN 'Second Quarter'
WHEN Month IN (7, 8, 9) THEN 'Third Quarter'
ELSE 'Fourth Quarter'
END
Depending on how this is being utilized, you might be better off adding a View which would calculate the Quarter. This way, you wouldn't have to maintain that additional column, which is entirely dependant on the Month column.
Your column MONTH can only store data of type INT. What you've got now is similar to the following procedural code:
int month = 2;
if (month == 1 || month == 2 || month == 3)
{
month = "First Quarter"; // compiler error
}
As you can see, that conditionally executed line is fairly nonsensical, since month is of type int.
You're probably looking to add another column, say Quarter.
ALTER TABLE q5 ADD Quarter NVARCHAR(100)
UPDATE q5
SET
Quarter = CASE WHEN Month IN (1, 2, 3) THEN 'First Quarter'
WHEN Month IN (4, 5, 6) THEN 'Second Quarter'
WHEN Month IN (7, 8, 9) THEN 'Third Quarter'
ELSE 'Fourth Quarter'
END
Although realistically, listing the value names should be done by the UI. Best practice would be to use a computed column or separate VIEW that has a Quarter INT column. This code would add a computed column with the appropriate datatype.
ALTER TABLE q5 ADD
Quarter AS CASE WHEN Month IN (1, 2, 3) THEN 1
WHEN Month IN (4, 5, 6) THEN 2
WHEN Month IN (7, 8, 9) THEN 3
ELSE 4
END