vba access query with variables - vba

I get the runtime error 3141 which says the SELECT statement includes a reserved word or an argument name that is misspelled or missing, or the punctuation is incorrect. On user form click, I'm trying to use a loop where multiple fields within a query are defined using variable inputs. Where am I going wrong here?
Private Sub Calculate_Click()
Dim db As Database
Dim x As Integer
Dim y As Integer
Dim WPmonthly As String ' field name for monthly written premium
Dim UPRmonthly As String ' field name for monthly unearned premium
Dim EPmonthly As String ' field name for monthly earned premium
Dim runningDate As Date
Dim useDateLower As Date
Dim useDateUpper As Date
Dim qry As dao.QueryDef
Months = Me.YearsBack * 12 + Month(Me.ValDate)
If Me.Period = "monthly" Then
Set db = CurrentDb
Set qry = CurrentDb.CreateQueryDef("MyQuery")
Debug.Print qry.SQL ' shows the SQL from MyQuery
For x = 1 To Months
runningDate = Format(DateAdd("m", -x + 1, Me.ValDate), "mm yyyy")
useDateLower = runningDate
useDateUpper = Format(DateAdd("m", -x + 2, Me.ValDate), "mm yyyy")
WPmonthly = "WP M" & Month(runningDate) & " " & Year(runningDate)
EPmonthly = "EP M" & Month(runningDate) & " " & Year(runningDate)
UPRmonthly = "UPR M" & Month(runningDate) & " " & Year(runningDate)
qry.SQL = "SELECT IIf([tblEPdata]![IssueDate]>" & useDateLower & ",IIf([tblEPdata]![IssueDate]<" & useDateUpper & ",[tblEPdata]![GrossPremium])) AS " & WPmonthly & " FROM tblEPdata;"
Next
qry.Close
End If
end sub

by seing your query i think that is the format for Dates should be between '' and yyyymmdd or yyyy-mm-dd format and for the last ; in the query statement.
You have something like:
useDateLower = 01/05/2016
Excel understand it but SQL does not, so, you must inclose your dates with '' or ## and your query ends like:
... [tblEPdata]![IssueDate]> '' " & useDateLower & " '' ,IIf([tb...
and you can add an Alias to your table.
qry.SQL = "SELECT IIf([TBL].[IssueDate]> ''" & useDateLower & _
"'',IIf([TBL].[IssueDate]< ''" & useDateUpper & _
"'',[TBL].[GrossPremium])) AS " & WPmonthly & _
" FROM tblEPdata AS [TBL]"

The first thing I would change is this line:
qry.SQL = _
"SELECT IIf([IssueDate] > #" & useDateLower & "#," & _
"IIf([IssueDate] < #" & useDateUpper & "#," & _
"[GrossPremium])) AS [" & WPmonthly & "] FROM tblEPdata;"
Also need brackets around WPmonthly. I would also try changing using bangs instead of periods (Me!Period).

Related

VBA - Get all value in Array as subsequent strings

I have connected VBA & SQL Database in order to pull information.
I have written a script that returns exactly what I want but I would like to make it dynamical (Change years used etc.) and I am here running into problems.
I need to have a special line in my SQL Query which only has 1 thing that changes between the lines (Number of lines need to change and the Case when y.Date_Year = )
I get an Error message in the below code saying that there is a Type mismatch at the " & " sign right above my "period ()" array.
Sub test()
Dim SQLDB As ADODB.Connection
Dim sQuery As String
Dim info()
Dim Start_D As String
Dim End_D As String
Dim Numerator_Used As String
Dim Denominator_Used As String
Dim Number_Years As Integer
Dim period()
Numerator_Used = Range("Numerator")
Denominator_Used = Range("Denominator")
Start_D = Range("Start_Date")
End_D = Range("End_Date")
Range("A11:J100000").Cells.ClearContents
Number_Years = End_D - Start_D
ReDim period(Number_Years + 1)
For i = 0 To Number_Years
period(i + 1) = ",sum(case when y.date_year = " & Start_D + i & " then n." & Numerator_Used & " end) / sum(case when y.date_year = " & Start_D + i & " then s." & Denominator_Used & " end) as '" & Numerator_Used & "/" & Denominator_Used & " " & Start_D + i & "' & _ "
Next i
' Get Margin Expectation Changes
sQuery ="select m.date_month" & _
" m.date_month " & _
period() & _
" from " & Numerator_Used & " as n" & _
" inner join " & Denominator_Used & " as s on s.company_id = n.company_id" & _
" and s.date_month_id = n.date_month_id" & _
" and s.date_year_id = n.date_year_id" & _
" inner join date_year as y on y.date_year_id = n.date_year_id" & _
" inner join date_month as m on m.date_month_id = n.date_month_id" & _
" where y.date_year between " & Start_D & " and " & End_D & " " & _
" and n." & Numerator_Used & " <> 0" & _
" and s." & Denominator_Used & " <> 0" & _
" group by m.date_month;"
Set rs = Common.SQL_Read(SQLDB, sQuery)
ThisWorkbook.Worksheets("Sheet1").Range("A11").CopyFromRecordset rs
Set SQLDB = Common.SQL_Close(SQLDB)
End Sub
As i mentioned in the ocmment to the question, you can not explicity convert period() data into string as it is an array of variant data type (each undefined variable is treated as variant data type). You have to loop through the array data, i.e.:
For i = LBound(period()) To UBound(period())
sQuery = sQuery & period(i) & "...."
Next
'finally:
sQuery = "SELECT ... " & sQuery & " ...."
Change the code as i mentioned above and let me know if it works.

vba access getting exceeded system resources error

Running the code below on access 2013 I get a system resource error. My understanding is that the program can take more time but the system resource error does not make sense. My laptop has 8gb RAM and core i3. Is there a better way to do this? Values used:
me.yearsback= 1
me.valdate = 5/31/2016
me.period = "monthly"
UPDATE: Used 0.5M rows first, producing the system resource error. However, when I reduce the number of rows, it runs fine.
:
Option Compare Database
Private Sub Calculate_Click()
Dim db As Database
Dim rs As Recordset
Dim x As Integer
Dim y As Integer
Dim Months As Integer
Dim WPmonthly As String ' field name for monthly written premium
Dim UPRmonthly As String ' field name for monthly unearned premium
Dim EPmonthly As String ' field name for monthly earned premium
Dim runningDate As Date
Dim runningDate2 As Date
Dim useDateLower As Date
Dim useDateUpper As Date
Months = Me.YearsBack * 12 + Month(Me.ValDate)
If Me.Period = "monthly" Then
Set db = CurrentDb
For x = 1 To Months
runningDate = Format(DateAdd("m", -x + 1, Me.ValDate), "mm yyyy")
WPmonthly = "WP M" & Month(runningDate) & " " & Year(runningDate)
EPmonthly = "EP M" & Month(runningDate) & " " & Year(runningDate)
UPRmonthly = "UPR M" & Month(runningDate) & " " & Year(runningDate)
db.Execute "ALTER TABLE tblEPdata ADD COLUMN [" & WPmonthly & "] STRING;"
db.Execute "ALTER TABLE tblEPdata ADD COLUMN [" & EPmonthly & "] STRING;"
db.Execute "ALTER TABLE tblEPdata ADD COLUMN [" & UPRmonthly & "] STRING;"
If x = Months Then
runningDate = Format(DateAdd("m", -x, Me.ValDate), "mm yyyy")
UPRmonthly = "UPR M" & Month(runningDate) & " " & Year(runningDate)
db.Execute "ALTER TABLE tblEPdata ADD COLUMN [" & UPRmonthly & "] STRING;"
End If
Next
For y = 1 To Months
runningDate2 = Format(DateAdd("m", -y + 1, Me.ValDate), "mm yyyy")
useDateLower = runningDate2
useDateUpper = Format(DateAdd("m", -y + 2, Me.ValDate), "mm yyyy")
WPmonthly = "WP M" & Month(runningDate2) & " " & Year(runningDate2)
EPmonthly = "EP M" & Month(runningDate2) & " " & Year(runningDate2)
UPRmonthly = "UPR M" & Month(runningDate2) & " " & Year(runningDate2)
Set rs = db.OpenRecordset("tblEPdata", dbOpenDynaset, dbSeeChanges)
Do Until rs.EOF
'Written Premium Calculation
If rs!issueDate < useDateUpper And rs!issueDate >= useDateLower Then
rs.Edit
rs.Fields(WPmonthly) = rs!grossPremium
rs.Update
End If
'UPR Calculation
If rs!issueDate < Me.ValDate Then
If rs!expiryDate < useDateUpper Then
rs.Edit
rs.Fields(UPRmonthly) = 0
rs.Update
ElseIf rs!effectiveDate < useDateUpper Then
rs.Edit
rs.Fields(UPRmonthly) = (rs!expiryDate - useDateUpper + 1) / (rs!expiryDate - rs!effectiveDate + 1) * rs!grossPremium
rs.Update
ElseIf rs!effectiveDate >= useDateUpper Then
rs.Edit
rs.Fields(UPRmonthly) = rs!grossPremium
rs.Update
Else:
rs.Edit
rs.Fields(UPRmonthly) = rs!grossPremium
rs.Update
End If
End If
rs.MoveNext
Loop
rs.Close
Next
End If
db.Close
End Sub

access 2013 increasing quantity in a table field

Good day. I'm a little stumped about what is happening in my code. I have a userform which collects txtQntyRecd and cboSupplySource. I calculate the lookupValue. And it works just fine. It successfully places the txtQntyRecd in the correct tblWarehouseLocations.WQuantity location. The code is:
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = '" & Me.txtQntyRecd & "'" & _
"WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError
What I want to do is add the next quantity to the same location. I get weird results if I change the SET statement to the following:
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + '" & Me.txtQntyRecd & "'"
If I put 200 in the first statement, I get 200 in my WQuantity field. When I change to the second statement and I try to add 1 to the 200 I get a result of 211. If I add 1 again, the result is 223. Add 1 again, the result is 236.
Could someone explain what is happening and why the results aren't 201, 202 and 203? In the future I will need to subtract quantities from WQuantity as well.
Thanks
You're adding quotes around an integer and appending it as a string. Change it to:
".....
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & val(Me!txtQntyRecd) & "....
...."
I've changed the . to a ! as I think it's still a nice distinction between objects properties and controls, and used the val function as it converts the string number value to the integer value.
This is your query in full:
' When I use values from controls, I like to store them in vars
Dim quantityReceived As integer
quantityReceived = val(Me!txtQntyRecd)
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
I solved the problem. I created a SELECT query to get the present amount in WQuantity. Now quantityReceived = Me!txtQntyRecd + the present amount. With SET tblWarehouseLocations.WQuantity = " & quantityReceived it works fine. However, if just seems so cumbersome.
' lookupValue gives the index into the tblWarehouseLocations where WQuantity resides
Dim lookupValue As Integer
lookupValue = DLookup("[WLocation_ID]", "[tblWarehouseLocations]", "[Location_Name] = '" & Me.cboWLocation & "'")
'Define SQL Query
strSQL = "select tblWarehouseLocations.WQuantity FROM tblWarehouseLocations WHERE (((tblWarehouseLocations.WLocation_ID)= " & lookupValue & "))"
Set rs = db.OpenRecordset(strSQL)
If IsNull(rs!WQuantity) Then
dbvalue = 0
Else
dbvalue = rs!WQuantity
End If
Dim quantityReceived As Integer
quantityReceived = Val(Me!txtQntyRecd) + dbvalue
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError

Excel VBA Selecting Records from Access Database Not Pulling Correctly

I have a macro that pulls from an Access DB and writes the recordset to the spreadsheet based upon dates that are entered into a userform. However, if I enter in "3/2/2105" and "3/5/2015" it returns all the records from 3/2-3/5 and then 3/20-3/31. I cannot think of any reason why it would do this. If anybody could point me in the right direction/make suggestions it would be greatly appreciated.
Sub pullfrommsaccess()
queryform.Show
Dim conn As Object
Dim rs As Object
Dim AccessFile As String
Dim SQL As String
Dim startdate As String
Dim enddate As String
Dim i As Integer
Sheet2.Cells.Delete
Application.ScreenUpdating = False
AccessFile = ThisWorkbook.Path & "\" & "mdidatabase.accdb"
On Error Resume Next
Set conn = CreateObject("ADODB.connection")
If Err.Number <> 0 Then
MsgBox "Connection was not created!", vbCritical, "Connection Error"
Exit Sub
End If
On Error GoTo 0
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & AccessFile
If tblname = "Attainments" Then
If shift1 = "1" Then
SQL = "SELECT [Line],[Area],[Shift],[Attainment Percentage],[Date] FROM " & tblname & " WHERE Shift='1' and Date Between " & "'" & pastdate & "' " & "and" & " '" & currentdate & "'"
End If
If shift2 = "2" Then
SQL = "SELECT [Line],[Area],[Shift],[Attainment Percentage],[Date] FROM " & tblname & " WHERE Shift='2' and Date Between " & "'" & pastdate & "' " & "and" & " '" & currentdate & "'"
End If
If shift1 = "1" And shift2 = "2" Then
SQL = "SELECT [Line],[Area],[Shift],[Attainment Percentage],[Date] FROM " & tblname & " WHERE Date Between " & "'" & pastdate & "' " & "and" & " '" & currentdate & "'"
End If
End If
If tblname = "MDItable" Then
If shift1misses = "1" Then
SQL = "SELECT [Date],[Area],[Shift],[Line],[Quantity],[Issue] FROM " & tblname & " WHERE Shift='1' and Date Between " & "'" & pastdatemisses & "' " & "and" & " '" & currentdatemisses & "'"
End If
If shift2misses = "2" Then
SQL = "SELECT [Date],[Area],[Shift],[Line],[Quantity],[Issue] FROM " & tblname & " WHERE Shift='2' and Date Between " & "'" & pastdatemisses & "' " & "and" & " '" & currentdatemisses & "'"
End If
If shift1misses = "1" And shift2misses = "2" Then
SQL = "SELECT [Date],[Area],[Shift],[Line],[Quantity],[Issue] FROM " & tblname & " WHERE Date Between " & "'" & pastdatemisses & "' " & "and" & " '" & currentdatemisses & "'"
End If
End If
On Error Resume Next
Set rs = CreateObject("ADODB.Recordset")
If Err.Number <> 0 Then
Set rs = Nothing
Set conn = Nothing
MsgBox "Recordset was not created!", vbCritical, "Recordset Error"
Exit Sub
End If
On Error GoTo 0
rs.CursorLocation = 3
rs.CursorType = 1
rs.Open SQL, conn
If rs.EOF And rs.BOF Then
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
Application.ScreenUpdating = True
MsgBox "There are no records in the recordset!", vbCritical, "No Records"
Exit Sub
End If
For i = 0 To rs.Fields.Count - 1
Sheet2.Cells(1, i + 1) = rs.Fields(i).Name
Next i
'Copy From RecordSet to Excel and Reset
Sheet2.Range("A2").CopyFromRecordset rs
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
MsgBox "The records from " & pastdate & " and " & currentdate & " were successfully retrieved from the '" & tblname & "' table!", vbInformation, "Done"
End If
Call TrimALL
End Sub
You have a field named Date, try renaming that and reworking the code as in first instance that's a reserved word and is a bad idea for starters!
When working with dates, see Allen Browne's comments on the matter here for consistency;
http://allenbrowne.com/ser-36.html
You have your dates declared as string, but in your SQL query you're surrounding them with a ' not a #. It should read;
Date Between " & "#" & pastdate & "# " & "and" & " #" & currentdate & "#"
All of the above should sort you out, if not comment and I'll take a much closer look for you!

Export Excel Spread Sheet to Access Table with A Timestamp?

I currently use a set up like the one below.
Set AccessConn = CreateObject("ADODB.Connection")
sExcel = "[Excel 8.0;HDR=YES;IMEX=2;DATABASE=" & ThisWorkbook.FullName & "].[Sheet1$]"
AccessConn.Open "DSN=Foo", "", ""
sSQL = "Insert Into BarTable Select * FROM " + sExcel
AccessConn.Execute sSQL
Now if I wanted to add a now() column in the export is this possible? something like
Set AccessConn = CreateObject("ADODB.Connection")
sExcel = "[Excel 8.0;HDR=YES;IMEX=2;DATABASE=" & ThisWorkbook.FullName & "].[Sheet1$]"
AccessConn.Open "DSN=Foo", "", ""
sSQL = "Insert Into BarTable Select *,NOW() FROM " + sExcel
AccessConn.Execute sSQL
Where the last column in BarTable is a Date/Time column and I want to insert the current time into it?
to enter the date in SQL you may need to convert it into text - Access itself can handle 'Now()' but not sure if it can when being passed a SQL string. Something like the below should do it.
sSQL = "Insert Into BarTable Select *,#" & format(NOW(),"MM/DD/YYYY hh:mm:ss") & "# As DateTimeStamp FROM " + sExcel
In Access I have two functions that I use for getting the date or date and time stamp when building SQL strings, I haven't tested but they should translate into Excel VBA okay:
Function MakeSQLDateTime(pSourceDate As Variant) As String
Dim SQLDay As String, SQLMonth As String, SQLYear As String, SQLTime As String
SQLDay = Day(pSourceDate)
SQLMonth = Month(pSourceDate)
SQLYear = Right(Year(pSourceDate), 4)
SQLTime = Hour(pSourceDate) & ":" & Minute(pSourceDate) & ":" & Second(pSourceDate)
MakeSQLDateTime = "#" & SQLMonth & "/" & SQLDay & "/" & SQLYear & " " & SQLTime & "#"
End Function
Function MakeSQLDate(pSourceDate As Variant) As String
Dim SQLDay As String
Dim SQLMonth As String
Dim SQLYear As String
SQLDay = Day(pSourceDate)
SQLMonth = Month(pSourceDate)
SQLYear = Right(Year(pSourceDate), 4)
MakeSQLDate = "#" & SQLMonth & "/" & SQLDay & "/" & SQLYear & "#"
End Function
To use these to complete what you are trying:
sSQL = "Insert Into BarTable Select *," & makeSQLDateTime(Now()) & " As DateTimeStamp FROM " + sExcel