SQL query in vba by last month down to the second - sql

I have searched for a solution to my issue for quite some time, but cannot seem to find an answer that works. I have a table that contains influx of cases to the different lawyers based on date and casetype. Keep in mind that I'm a rookie when it comes to VBA and SQL
What I'm trying to do:
I need to sort the massive amount of cases into how many cases each lawyer gets based on dates, which in this case is recurring last month. Essentially I need to be able to press a button every month and then the data for the previous month is automatically retrieved and placed in an excel workbook. All of this has actually succeeded, except for the following problem
Problem:
Whenever I run the macro it doesn't retrieve the full amount. For instance, in February I know there were 159 new cases, but the formula only finds 155. Now I can get the correct result, by prompting an inputbox for a startdate and enddate and entering the format DD/MM/YY HH/MM/SS - But I would like to remove the inputbox part, so I don't have to type anything. The code should automatically take the last month in its enterity. For Feb. it would look like from 01/02/18 00:00:01 to 28/02/18 23:59:59
I assume the problem is because my current formula, doesn't extend all way and therefore excludes the hours, minutes and seconds - or something similar.
I am also pretty confident it can be fixed with the dateadd function, I just don't know how. How do you specify a Startdate and Enddate to include the entire month, down to the very first and last second?
Might be a very easy fix, but it's beyond me
Code:
Dim Startdate As Date
Dim Enddate As Date
Startdate = DateSerial(Year(Now), Month(Now) - 1, 1)
Enddate = DateSerial(Year(Now), Month(Now), 0)
Debug.Print Startdate, Enddate
Set rs = conn.Execute("Select [Jurist], [OpretDato], [Tilgang] From [dbo].[TilgangOgAfgangAfSagerTilgangIPeriodenView]" & _
"Where [OpretDato] Between '" & Startdate & "' And '" & Enddate & "' and (Jurist not in ('BF','MLT','NL') or Jurist is null)" & _
"Order by [Jurist] ASC ;")

Your four records are probably missing from the last day, because 2018-02-28 = 2018-02-28 00:00:00 = midnight at the beginning of February 28th.
Another problem with your formula: think what will happen in January 2019... Your formula (and others answers here) will return:
Year = 2019 Month = 0 Day = 1
Obviously, that won't work. You can't just "subtract 1 from the month" to consistently get a previous month.
Also, you shouldn't specify a end time of 23:59:59 and start time of 00:00:01, since you're skipping over 12 minutes a year ...as well as the month of December.
This is the correct way to handle "previous month" criteria:
EndDate = DateSerial(Year(Now), Month(Now), 1)
StartDate = DateSerial(Year(EndDate - 1), Month(EndDate - 1), 1)
and then your SQL criteria would be:
WHERE ([RecordDateTime] >= StartDate And [RecordDateTime] < EndDate)
Note that the = is NOT included in the second half of the criteria.
Your adjusted code:
Set rs = conn.Execute("Select [Jurist], [OpretDato], [Tilgang] " & _
"From [dbo].[TilgangOgAfgangAfSagerTilgangIPeriodenView]" & _
"Where [OpretDato] >= '" & Startdate & "' And [OpretDato] < '" & _
Enddate & "' and (Jurist not in ('BF','MLT','NL') or Jurist is null)" & _
"Order by [Jurist] ASC ;")

Alternatively, use DateAdd() which follows in line with #ashleedawg's point of using the strictly less, <, than on the current month for EndDate (consistent across any year/month). Additionally, below uses a ADO parameterization to separate SQL code from VBA data and not string interpolation (an industry best practice).
Dim StartDate As Date, EndDate As Date
Dim strSQL As String
EndDate = DateAdd("d", -Day(Date) + 1, Date)
StartDate = DateAdd("m", -1, EndDate)
Debug.Print StartDate, EndDate
' PREPARED STATEMENT
strSQL = "SELECT [Jurist], [OpretDato], [Tilgang] " & _
" FROM [dbo].[TilgangOgAfgangAfSagerTilgangIPeriodenView]" & _
" WHERE [OpretDato] >= ? AND [OpretDato] < ?" & _
" AND (Jurist NOT IN ('BF','MLT','NL') OR Jurist IS NULL)" & _
" ORDER BY [Jurist] ASC ;"
' COMMAND OBJECT (BINDING PARAMETERS)
With cmd
.ActiveConnection = conn ' CONNECTION OBJECT
.CommandText = strSQL
.CommandType = adCmdText
.Parameters.Append .CreateParameter("s_param", adDate, adParamInput, , StartDate)
.Parameters.Append .CreateParameter("e_param", adDate, adParamInput, , EndDate)
End With
' BIND TO RECORDSET
Set rst = cmd.Execute
...

Related

VBA Code for Filtering up through the current month

I have a sheet of work orders that have a column of complete by dates. I am trying to filter it down to show all orders with dates in the past going through to the end of the current month (EX: all past orders-End of July 2017).
The current code I'm am using works, but for some reason will not return 7/31/2017. It will return all prior date up to 7/30/2017. Can someone please help.
Sub Macro3()
Dim dtStart As Date
Dim dtFinal As Date
dtStart = CDate(Evaluate("DATE(YEAR(NOW()),-1,1)"))
dtFinal = CDate(Evaluate("EOMONTH(NOW(),0)"))
ActiveSheet.Range("$A$1:$N$709").AutoFilter 13, ">=" & dtStart, xlAnd, "<=" &
dtFinal, Operator:=xlFilterDynamic
End Sub
dtFinal is July 31, 2017 at 12:00am. You will want to make your final date August 1 and then change your filter from "<=" to "<".
You can use the WorksheetFunction.EoMonth function, and the DateSerial, and replace your Now with Date, since you don't need to mess with the hours.
Try the line below instead your entire code:
ActiveSheet.Range("A1:N709").AutoFilter 13, ">=" & DateSerial(Year(Date), -1, 1), _
xlAnd, "<=" & WorksheetFunction.EoMonth(Date, 0), _
Operator:=xlFilterDynamic

Find date, given WEEKNUM and WEEKDAY - VBA

I'm trying to find a way of finding a date value, given the WEEKNUM and WEEKDAY
For example
WEEKNUM = 9
WEEKDAY = 4 '(Wednesday)
I can use the below function to find the WEEKNUM from the date, but how can I go the other way around?
Function WEEKNUM(D As Date, FW As Integer) As Integer
WEEKNUM = CInt(Format(D, "ww", FW))
End Function
You could use a table on a hidden sheet, and just used Vlookup to find the correct date. EG
DATE WEEKDAY WEEK NO WEEKDAY + WEEK NO
01/03/2016 Tuesday Week 10 Tuesday 10
02/03/2016 Wednesday Week 10 Wednesday 10
In VBA, you could then look up the name of the sheet, which is the weekday, and got the week number from the filename of the workbook, then use vlookup to find the correct date.
weekNum = Mid(ThisWorkbook.Name, 6, 2)
searchStr = ActiveSheet.Name & " " & weekNum & " " & Format(Now(), "YYYY")
rowNo = Application.WorksheetFunction.Match(searchStr, Sheets("WEEKLIST").Range("D:D"), 0)
strSubject = Format(Sheets("WEEKLIST").Range("A" & rowNo).Value, "DD/MM")

Determine number of days between dates

How do I get the whole date difference in VBA?
I know that to get the year or the month or the day I do:
DateDiff("yyyy", Me.DateofBirth, Me.Year).
I want the whole difference. Not just the year, and the two columns that I have are Date of Birth and Year.
Dates are stored internally in VBA as doubles, with the integer portion as the number of days since 1/1/1900. To get the difference between two dates, you can just subtract them:
Dim dob As Date
dob = DateSerial(1990, 1, 1)
Dim difference As Date
difference = Now - dob
Debug.Print Year(difference) - 1900 & " years, " & _
Month(difference) & " months, " & _
Day(difference) & " days."
If you want the total number of days, you can just subtract them and use the numeric value of the underlying double:
Dim dob As Date
dob = DateSerial(1990, 1, 1)
Dim days As Long
days = Now - dob
Debug.Print days & " days."

Selecting rows from Access database by date search criteria in VB.NET form

I have a very simple problem. I have a couple of datepicker controls on my VB.NET form and users select "startDate" and "endDate", and all rows from the related table are displayed which have an orderDate between the user's selected start and end dates.
The following is the relevant code:
Private Sub generate_report_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles generate_report.Click
Try
Dim con As New OleDb.OleDbConnection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\KHMSDB.accdb"
con.Open()
Dim sql As String
Dim selected As String = ""
Dim ds As DataSet = New DataSet
Dim adapter As New OleDb.OleDbDataAdapter
sql = "SELECT OrderDate AS `Order Date and Time`, Items AS `Ordered Items` FROM Orders WHERE Format(Orders.OrderDate,'mm/dd/yyyy') >= #" + startDate.Value.Date + "# AND Format(Orders.OrderDate,'mm/dd/yyyy') <= #" + endDate.Value.Date + "#"
adapter.SelectCommand = New OleDb.OleDbCommand(sql, con)
adapter.Fill(ds)
gridReport.DataSource = ds.Tables(0)
Catch ex As Exception
MsgBox("Operation failed. " + ex.ToString)
End Try
If I save a new row in the database under today's date, and I leave the "start" and "end" dates both as the default date (i.e. today's date), it doesn't show the new row I just saved. The new row entered today only shows up if I move the "start date" up to the 30th of November. Then I add a new row with date 12th December. Again, it won't show up when I select the end date to be >= 12 December, it'll only show up when I move the start date up to 1st December. I decided to enter a row dated 21st November, and running the query with start and end date both on 21st November shows up that row. I then entered a new row in January 8th.. and now any combination of moving up startDate and or moving down endDate just doesn't display the January order. What's going on?? I've actually already tried this code out before in November and it worked perfectly fine!
What could be the issue with this is the string format. I'm not sure if Access will convert the string to a Date and then compare or convert the Date to a string and then compare. You can try this:
Format(Orders.OrderDate,'mm/dd/yyyy') >= Format(#" + startDate.Value.Date + "#,'mm/dd/yyyy')
Or you could always just use the date directly,
OrderDate >= #" + startDate.Value.Date + "#"
Edit:, to do my due diligence, you really should be doing the query like this
OrderDate >= #StartDate
Then add this code
adapter.Parameters.Add("#StartDate", startDate.Value.Date);
Using parameters is important for robust code and to avoid the dreaded SQL injection attack.

Datatable compute: filtering by date

I have a datatable with 2 columns: "amount" and "date"
I want to sum "amount" by month & year.
I am trying this:
_tAmount = myDT.Compute("sum(amount)", "date LIKE '%/" & i & "/" & _year & "'")
where:
var i equals a nº month ( 1 to 12)
var _year equals nº year (example:
2011)
But not displays any results....How I can do it? What is wrong?
I am working with the spanish format (example day/month/year). But I have tried with the english format (month/day/year) and no results too.
This is on VB.NET 2008.
I don't thing date works with LIJKE, why don't you use:
dim startdt as date = new date(_year, month, 1)
dim enddt as date = startdt.addmonth(1).adddays(-1)
_tAmount = myDT.Compute("sum(amount)", "date >= " & startdt & " AND date <= " & enddt)
This is out the top of my head, so check it yourself, but you should get the idea.
Also, I use mostly the # sign around the dates to force english notation, but you'll have to experiment yourself.