Passing Parameter Value in Access Query using vba - vba

Our requirement -
We have few suppliers and we want to generate a monthly report of purchases from each supplier during the month and export to excel. I think the solution is to create a parameter query where I can pass the value of the supplier ID, Month and Year. The list of supplier keeps changing and is stored in a separate table.
So, basically, I should be able to sequentially read the supplier ID from that table and pass as a parameter to my query to generate the report for that supplier.
The closest solutions that I found for my requirement was on (which are similar in nature) -
Exporting Recordset to Spreadsheet
http://answers.microsoft.com/en-us/office/forum/office_2010-customize/filtering-a-query-used-by-docmdtransferspreadsheet/06d8a16c-cece-4f03-89dc-89d240436693
Why I think there could be a better solution -
In the suggested solution, we are creating multiple queries and deleting these. Conceptually, I feel there should be a way to create a parameter query and use the do while loop to sequentially pass the value of the parameter (DeptName in above example) to the query and export the results to excel.
I should be able to achieve this if I can use vba to pass value to a parameter query. And that is what I have not yet been able to figure out.
Update on 24-Feb -
Following is the code that I have written -
Private Sub Monthly_Supplier_Sales_Report_Click()
Dim strDirectoryPath As String
Dim DateFolderName As String
DateFolderName = Format$((DateSerial(year(Date), month(Date), 1) - 1), "YYYY MM")
strDirectoryPath = "C:\dropbox\Accounting\Sales Reports\" & DateFolderName
If Dir(strDirectoryPath, vbDirectory) = "" Then MkDir strDirectoryPath
Dim Filename As String
Dim strSQL1 As String
Dim strSQL2 As String
Dim DesignerCode As String
Dim month1 As String
Dim year1 As Integer
Dim Query1 As DAO.QueryDef
Dim query2 As DAO.QueryDef
Dim rsDesigner As DAO.Recordset
Set rsDesigner = CurrentDb.OpenRecordset("Designer Details Master")
Do While Not rsDesigner.EOF
DesignerCode = rsDesigner![Designer Code]
month1 = "Jan" 'right now hardcoded, will call this programatically
year1 = 2014 'right now hardcoded, will call this programatically
strSQL1 = "SELECT * FROM [Sales Report Generation Data] WHERE [designer code] = '" & DesignerCode & "' AND [Shipping Month]= '" & month1 & "' AND [Shipping Year]=" & year1
strSQL2 = "SELECT * FROM [Sales Report Generation - Monthwise Inventory Snapshot] WHERE [designer code] = '" & DesignerCode & "' AND [Snapshot Month]= '" & month1 & "' AND [Snapshot Year]= " & year1
Set Query1 = CurrentDb.CreateQueryDef(Name:="TempSalesQuery", SQLText:=strSQL1)
Set query2 = CurrentDb.CreateQueryDef(Name:="TempInventoryQuery", SQLText:=strSQL2)
Filename = strDirectoryPath & "\" & DesignerCode & Format$(Now(), " yyyy mm") & ".xls"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "TempSalesQuery", Filename, False, "Sales Report"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "TempInventoryQuery", Filename, False, "Inventory"
CurrentDb.QueryDefs.Delete "TempSalesQuery"
CurrentDb.QueryDefs.Delete "TempInventoryQuery"
rsDesigner.MoveNext
Loop
End Sub
Instead, The logic I want to apply is -
Do While Not
assign Value to Parameter 1 = rsDesigner![Designer Code]
assign Value to Parameter 2 = Month1
assign Value to Parameter 3 = Year1
Run the two Parameter queries, for which about three parameters are the input value and export to excel in respective sheets.
Loop
Just that I have not yet been able to figure out - how to achieve this.

Here is one solution. Note that I created Functions that the two queries will use.
Just create your two queries and save them (see sample SQL below), add your code to pick dates and everything should be fine.
Option Compare Database
Option Explicit
Dim fvShipMonth As String
Dim fvShipYear As Integer
Dim fvDesignerCode As String
Public Function fShipMonth() As String
fShipMonth = fvShipMonth
End Function
Public Function fShipYear() As Integer
fShipYear = fvShipYear
End Function
Public Function fDesignerCode() As String
fDesignerCode = fvDesignerCode
End Function
Private Sub Monthly_Supplier_Sales_Report_Click()
Dim Filename As String
Dim strSQL1 As String
Dim strSQL2 As String
Dim DesignerCode As String
Dim month1 As String
Dim year1 As Integer
Dim rsDesigner As DAO.Recordset
'SAMPLE SQL
'SELECT * FROM [Sales Report Generation Data] " & _
'WHERE [designer code] = '" & fDesignerCode() & "' AND [Shipping Month]= '" & fShipMonth() & "' AND [Shipping Year]=" & fShipYear()
fvShipMonth = "Jan"
fvShipYear = 2014
Set rsDesigner = CurrentDb.OpenRecordset("Designer Details Master")
Do While Not rsDesigner.EOF
fvDesignerCode = rsDesigner![Designer Code]
Filename = strDirectoryPath & "\" & DesignerCode & Format$(Now(), " yyyy mm") & ".xls"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "<your Query 1>", Filename, False, "Sales Report"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "<your Query 2>", Filename, False, "Inventory"
rsDesigner.MoveNext
Loop
rsDesigner.Close
Set rsDesigner = Nothing
End Sub

Open your database
Create a NEW module
Paste the following code
Place your cursor inside Function TEST_MY_CODE()
Press F5
Paste the results from the immediate window in your response.
Option Compare Database
Option Explicit
Dim fvShipMonth As String
Dim fvShipYear As Integer
Dim fvDesignerCode As String
Public Function fShipMonth() As String
fShipMonth = fvShipMonth
End Function
Public Function fShipYear() As Integer
fShipYear = fvShipYear
End Function
Public Function fDesignerCode() As String
fDesignerCode = fvDesignerCode
End Function
Function TEST_MY_CODE()
My_Click_EVENT ' Test the code I provided
End Function
Private Sub My_Click_EVENT()
Dim month1 As String
Dim year1 As Integer
fvShipMonth = "Jan"
fvShipYear = 2014
Debug.Print "**** START TEST ****"
Debug.Print "fvShipMonth = " & fvShipMonth
Debug.Print "fvShipYear = " & fvShipYear
Debug.Print "fShipMonth() = " & fShipMonth()
Debug.Print "fShipYear() = " & fShipYear()
Debug.Print "**** END TEST ****"
End Sub

Related

VBA ACCESS - SQL statement which Counting between 2 columns which are variables

I need a macro in VBA Access. I have a table with all dates of the years like columns (and also the dates are the names of the fields). I've made a form where the user selects two dates, and the macro would count all the data between these 2 columns.
For the example, I put two fixed dates. The problem is I need count between the 2 columns, and the columns can change depending the input of the user. The table is EVOLUTIVO_ASISTENCIA and the field can change depends the user selection. Ihe following code EVOLUTIVO_ASISTENCIA.[" & INICIO_MES_VAR1 & "] is the field "01-01-2023" of the EVOLUTIVO_ASISTENCIA table, but the syntax is wrong and does not function. Can anyone help me?
The code:
Private Sub BUSQUEDA()
Dim CONTEO As String
Dim VAR1 As String
Dim INICIO_MES_VAR1 As Date, TERMINOS_MES_VAR1 As Date
INICIO_MES_VAR1 = Format("01-01-2023", "dd-mm-yyyy")
TERMINOS_MES_VAR1 = Format("31-01-2023", "dd-mm-yyyy")
VAR1 = "VAR1"
CONTEO = "SELECT COUNT(*) FROM EVOLUTIVO_ASISTENCIA " & _
"WHERE EVOLUTIVO_ASISTENCIA.[NOMBRES]='" & VAR1 & "' " & _
** "BETWEEN EVOLUTIVO_ASISTENCIA.[" & INICIO_MES_VAR1 & "] AND EVOLUTIVO_ASISTENCIA.[" & TERMINOS_MES_VAR1 & "]"**
DoCmd.RunSQL CONTEO
End Sub
You don't run a select query, you open it as a recordset. So try:
Private Sub BUSQUEDA()
Dim Records As DAO.Recordset
Dim CONTEO As String
Dim VAR1 As String
Dim INICIO_MES_VAR1 As String
Dim TERMINOS_MES_VAR1 As String
Dim ASISTENCIA_CONTEO As Long
INICIO_MES_VAR1 = "01-01-2023"
TERMINOS_MES_VAR1 = "31-01-2023"
VAR1 = "VAR1"
CONTEO = "SELECT COUNT(*) FROM EVOLUTIVO_ASISTENCIA " & _
"WHERE EVOLUTIVO_ASISTENCIA.[NOMBRES]='" & VAR1 & "' " & _
"BETWEEN EVOLUTIVO_ASISTENCIA.[" & INICIO_MES_VAR1 & "] AND EVOLUTIVO_ASISTENCIA.[" & TERMINOS_MES_VAR1 & "]"
Set Records = CurrentDb.OpenRecordset(CONTEO)
' Read/list/print records.
' Retrieve the value of the first and only field of the first and only record.
ASISTENCIA_CONTEO = Records(0).Value
' Close when done.
Records.Close
End Sub

VBA SQL string saving short date as General date instead of short

I'm trying to do something basic:
Take 2 dates [startD] and [endD] from a accdb file.
Move them forward one month each
save the new dates as short dates in the respective record.
I'm doing this all by VBA
The issue is that it is showing the correct SQL String (if i do msgbox sql) however when it saves, it is saving as a general date with time and is the wrong value!
*Note: I'm in Australia so I have a format section to make sure the date saves correctly.
I have tried using DateValue() and Formatting the date too.
Dim frq As Integer
Dim wks As Integer
Dim CurAcc As Integer
Dim CurAccEnd As Date
Dim Days As Integer
Dim curaccvalue As Currency
Dim cardtype As Integer
Dim cardcharged As Integer
cardtype = 0
cardcharged = 0
CurAcc = Me.ID
curraccvalue = DLookup("Acccurvalue", "Accounts", "[ID] = " & CurAcc)
Curraccend = DLookup("Accend", "Accounts", "[ID] = " & CurAcc)
frq = DLookup("freqid", "Accounts", "[ID] = " & CurAcc)
wks = DLookup("freqvalue", "tblfrequency", "FrequencyID = " & frq)
Days = wks * 7
strsql = "UPDATE Accounts SET AccStart = " & Date & " , AccEND = " &
Curraccend + Days & " , AccCurValue = 0.00 WHERE ID = " & CurAcc
MsgBox strsql
DoCmd.RunSQL strsql
When implicitly converting a date to a string, your regional settings are used, but in a SQL string, a date must be in the American format.
To avoid this, I suggest to do the update in just one query:
Dim strSql As String
strSql = "UPDATE Accounts " & _
"INNER JOIN tblfrequency ON Accounts.freqid = tblfrequency.FrequencyID SET " & _
"AccStart = Date(), " & _
"AccEND = DateAdd(""w"", tblfrequency.freqvalue, Accounts.Accend), " & _
"AccCurValue = 0.00 WHERE ID = " & Me.ID
MsgBox strSql
DoCmd.RunSQL strSql

Access Split column data w semi-colon into normalize table structure

I have a table, which was pulled out of some XML data. I'm trying to do a cross reference, so I can line out a plan for organizing the data. This 1 table has a list of variables. Fields of different data types, computations, as well as dialogs. One of the columns has options. If the data type of the variable is a dialog, its options has a list of variables, separated by a semi-colon.
So the main table has a structure like so:
For the dialog records I need to look through their options column and insert records into a normalized table. For each field, in that column, I want to add a record with that dialog name, and the ID of the row in that table (I added a PK to the table). For instance, in the dialog record, Options column, there is a field in there called BusinessName TE. I need to search this main table for the PK ID of the row that has a variable name of the same. I need to put that record's ID with the name of the dialog, and insert both into a new table I set up. This will create a cross reference for me, so I can know which variables are being used by which dialogs.
I appreciate any help anyone can give. I see stuff about using a split function, arrays and looping through to get each value, but the examples I'm finding are for strings, not a column in a table.
Thanks!
Edit: Adding in the VBA code I'm working with. I attached it to a button on a form, just so I could click to run it.
Private Sub RunParse_Click()
Dim db As DAO.Database
Dim rs As Recordset
Set db = CurrentDb()
Dim sqlStr, insertSQL, arrayVal As String
Dim TestArray As Variant
Dim Options As String
Dim Dialog As String
Dim FieldName As Long
Dim i As Integer
sqlStr = "SELECT [MASTER Fields].Options,[MASTER Fields].[Variable Name] FROM [MASTER Fields] WHERE ((([MASTER Fields].[Variable Type])='dialog'));"
Set rs = db.OpenRecordset(sqlStr)
rs.MoveLast
rs.MoveFirst
Do While Not rs.EOF
Options = rs.Fields(0)
Dialog = rs.Fields(1)
If InStr(Options, ";") Then
TestArray = Split(Options, ";")
For i = 0 To UBound(TestArray) - LBound(TestArray) + 1
If TestArray(i) <> "" Then
arrayVal = TestArray(i)
FieldName = DLookup("ID", "MASTER Fields", "[Variable Name] = " & "'" & arrayVal & "'")
insertSQL = "INSERT INTO FieldTemplatesUse(FID, TemplateAK) " _
& "VALUES(""" & FieldName & """, """ & Dialog & """)"
DoCmd.RunSQL (insertSQL)
End If
Next i
End If
rs.MoveNext
Loop
End Sub
right now on the line that says
If TestArray(i) <> "" Then
creates an error ""
If anyone can help, I'd really appreciate it!
Another Edit:
Parfait figured out my issue. I'm posting the final code I am using, in case it helps someone else! p.s. I added a condition to check if the dlookup is successful, and trap failures in a failures table. That way I can check those out afterward.
Private Sub RunParse_Click()
Dim db As DAO.Database
Dim rs As Recordset
Set db = CurrentDb()
Dim sqlStr, insertSQL, arrayVal As String
Dim TestArray As Variant
Dim Options As String
Dim Dialog As String
Dim FieldName As Long
Dim i As Integer
sqlStr = "SELECT [Master Fields].Options,[Master Fields].[Variable Name] FROM [Master Fields] WHERE ((([Master Fields].[Variable Type])='dialog'));"
Set rs = db.OpenRecordset(sqlStr)
rs.MoveLast
rs.MoveFirst
Do While Not rs.EOF
Options = rs.Fields(0)
Dialog = rs.Fields(1)
If InStr(Options, ";") Then
TestArray = Split(Options, ";")
For i = 0 To UBound(TestArray) - LBound(TestArray)
If TestArray(i) <> "" Then
arrayVal = TestArray(i)
If Not (IsNull(DLookup("ID", "Master Fields", "[Variable Name] = " & "'" & arrayVal & "'"))) Then
FieldName = DLookup("ID", "Master Fields", "[Variable Name] = " & "'" & arrayVal & "'")
insertSQL = "INSERT INTO FieldTemplatesUse(FID, TemplateAK) " _
& "VALUES(""" & FieldName & """, """ & Dialog & """)"
DoCmd.RunSQL (insertSQL)
'MsgBox "Adding ID = " & FieldName & "for Dialog: " & Dialog & "Now"
Else
insertSQL = "INSERT INTO tblFieldsNotFound(Dialog, FieldNotFound) " _
& "VALUES(""" & Dialog & """, """ & arrayVal & """)"
DoCmd.RunSQL (insertSQL)
End If
End If
Next i
End If
rs.MoveNext
Loop
MsgBox "All Done!"
End Sub

Dlookup returns null when data exists

Hi I have been trying this for hours and it doesn't matter how much I search to try different options I cannot get the lookup for give a result that I am looking for. I am testing it using a date and work code that I know is in the table that I am referring to.
I am using the input box to provide the date and fixing the work code as 13 (Dispatch). The lookup should be returning the date in the table as the date input is in the table. My code is:
Sub Append_Dispatch()
Dim dbs As Object
Dim qdf As querydef
Dim InputDateString As String
Dim InputDate As Date
Dim RtnDate As String
Dim chkDate As Date
Dim WC As Long
Set dbs = CurrentDb
Set qdf = dbs.querydefs("Dispatch Append to Production Data")
WC = 13
InputDateString = InputBox("Please enter start date to import", "Date")
InputDate = DateValue(InputDateString)
RtnDate = DLookup("[Date of Action]", "Production Data", "[Date of Action]= #" & InputDate & "# AND [Work Code] = " & WC & "")
chkDate = DateValue(RtnDate)
If InputDate = chkDate Then
IB = MsgBox("This dispatch date has already been entered:" & vbCrLf & "Please check and use a date after " & Dte, vbOKOnly, "Date Error")
Exit Sub
End If
'qdf.Parameters("Dispatch Date").Value = InputDate
'qdf.Execute
'qdf.Close
'Set qdf = Nothing
'Set dbs = Nothing
End Sub
Also I cannot get the code to work after the end if to input the parameter and run the append query. But that is another issue.
Any ideas please.....

Pass-through query with user input as filter criteria - MS Access

I am currently have an USER INTERFACE (a Form) in Access which has two combo boxes referring to a specific date of a quarter. The form values are queried in from a pass through query from SQL SERVER 2008.
Is there any way in which I can write a pass through query which will use the form values in where condition.
For eg :
INSERT INTO TBL.ABC
SELECT * FROM TBL.DEF where [Date]=Formvalue
After all of the research and I even have gone through couple of questions posted in Stackoverflow, but couldnt find the answer. Is this even possible ??
The main motive behind doing this is to segregate the data into two different tables based on the input as a form of "FormValue" and then perform different operations based on the dates.
Please do let me kno if you need further information. Any help is much appreciated!!
Private Sub Command13_Click()
Dim St001, St002 As String
Dim conn As ADODB.Connection
Dim strPath As String
Dim strDate As String
Set conn = CurrentProject.Connection
strPath = "ServerName"
'conn.Open = "ODBC;DRIVER=SQL Server;SERVER=" & strpath & ";
' DATABASE=DB;UID=ABC;PWD=DEF;Trusted_Connection=No;"
'DoCmd.OpenQuery "003a Drop Curr_Qtr"
strDate = curQtr & ""
StrDate2 = prevQtr & ""
' If combo box is empty?
If strDate = "" Then
MsgBox "The Curr Qtr Date value is Empty, Please select the date"
ElseIf StrDate2 = "" Then
MsgBox "The Date Prev Qtr Date value is Empty, Please select the date"
Else
' Append values
DoCmd.OpenQuery "003a Drop Curr_Qtr"
'On Error Resume Next
St002 = "SELECT COLUMNS into TblB from TblA where ColA='" & strDate & "'
DoCmd.RunSQL St002
As scuh, all the tables that I am reffering to in the code are linked tables. I tried using the below format of the code as suggested in one of the form, but it is the same error that pops up all the time :
Dim St001, St002 As String
Dim conn As ADODB.Connection
Dim strPath As String
Dim strDate As String
Set conn = CurrentProject.Connection
strPath = "ServerName"
'conn.Open = "ODBC;DRIVER=SQL Server;SERVER=" & strpath & ";DATABASE=DBName;
' UID=Username;PWD=password;Trusted_Connection=No;"
'DoCmd.OpenQuery "003a Drop table"
strDate = curQtr & ""
StrDate2 = prevQtr & ""
' If combo box is empty?
If strDate = "" Then
MsgBox "The Curr Date value is Empty, Please select the date"
ElseIf StrDate2 = "" Then
MsgBox "The Prev Date value is Empty, Please select the date"
Else
' Append values
DoCmd.OpenQuery "003a truncate table"
'conn.Open = "ODBC;DRIVER=SQL Server;SERVER=" & strPath & ";DATABASE=009;
' UID=GM_SA;PWD=gmsa;Trusted_Connection=No;"
'On Error Resume Next
St002 = "Insert Into [Tabl B] ([Tabl B].[ColA]" & _
"Select [Tabl A].[Col A] from [tabl A].[Col A] where [Tabl A].[Col z]='" & strDate & "'"
strCon = "ODBC;DRIVER=SQL Server;SERVER=" & strPath & ";DATABASE=DBName;UID=UserName;" _
& "PWD=Password;Trusted_Connection=No"
Set wksp = DBEngine(0)
Set dabs = wksp.opendatabase("", False, False, strCon)
dabs.Execute St002, dbSQLpassThrough
End If
End Sub
Try the following, after making sure you have a reference to Microsoft ActiveX Data Objects 2.8 Library
Dim adoConn As ADODB.Connection
...
St002 = "Insert Into [Tabl B] ([ColA]) Select [Tabl A].[Col A] from [tabl A].[Col A] where [Tabl A].[Col z]='" & FORMAT(strDate,"yyyy-mm-dd") & "'"
strCon = "ODBC;DRIVER=SQL Server;SERVER=" & strPath & ";DATABASE=DBName;UID=UserName;PWD=Password;Trusted_Connection=No"
adoConn.Open(strCon)
adoConn.Execute St002
Using ADO instead of DAO is often a better option when passing queries directly to servers, it should completely bypass any possibility of errors similar to "RUNTIME ERROR 3024 - Could not find file 'H:\TableName.Mdb"
Also, if you need a value from a combo column other than the bound column, use Me.DateCombo.Column(1) or similar. Access uses 0-based indexes, so Me.DateCombo.Column(1) refers to the second column.