I have an Access Application. It opens on a search form and the user selects the criteria, hits "Search" and it displays list of records that meets their criteria. The user then clicks on a record, and it displays the information about that record. All of this works great, but I am trying to add a "Count" feature, that will display a textbox showing the number of times that user is in the database.
But my textbox only ever displays "1".
In my textbox: I have the following:
=Count([Requester_UserName])
Because a Requester can have many entries in the database, I want to show a count of how many entries they have on this form, although the form only displays information about the one specific record, so this specific user might have 15 entries. How do I get this form to show "15" in that textbox?
Any help is appreciated.
Don't count (no pun intended) on the .Count method. It's unreliable for various scenarios. Use a SQL statement instead. Here's a multipurpose method:
'------------------------------------------------------------------------------
'Purpose : Retrieve number of records
'
'Prereq. : ADO 2.x
'Parameter: cn - Initialized ADODB.Connection object
' sTable - Table name
' sField - DB column name used for COUNT. This is ideally a integer column
' sFilter - SQL WHERE clause
'Returns : # of records
'Note : -
'------------------------------------------------------------------------------
Public Function SQLCount(ByVal cn As ADODB.Connection, ByVal sTable As String, Optional ByVal sField As String = "*", _
Optional ByVal sFilter As String = vbNullString) As Long
Dim rs As ADODB.RecordSet
Dim lRecCount As Long
Dim sSQL As String
sSQL = "SELECT COUNT([" & sField & _
"]) AS RecCount FROM [" & sTable & "]"
If Len(sFilter) Then
sSQL = sSQL & " WHERE " & sFilter
End If
sSQL = sSQL & ";"
Set rs = New ADODB.RecordSet
rs.Open sSQL, cn
If Not (rs.BOF And rs.EOF) Then
lRecCount = rs.Fields("RecCount").Value
End If
rs.Close
Set rs = Nothing
SQLCount = lRecCount
End Function
'==============================================================================
Assuming the ADODB table name is MyTable, ID is a integer column in that table and you want to know how many records with 'Miami' are stored in the field named City, you call it like
Debug.Print SQLCount(cn, "MyTable", "ID", "City = 'Miami")
Related
I'm attempting to setup a query that will show how many of each ship is owned and who owns it displaying each "Call Sign" who owns the ship in comma delimited format.
The table being used for the query is called "Members" and I'm using a Count function on the "Current Ships Owned" field in the query to get count totals.
The Base query is the following:
I used VBA to build the following module:
Public Function QueryFieldAsSeparatedString(ByVal fieldName As String, _
ByVal tableOrQueryName As String, _
Optional ByVal criteria As String = "", _
Optional ByVal sortBy As String = "", _
Optional ByVal delimiter As String = ", " _
) As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim sql As String
Dim whereCondition As String
Dim sortExpression As String
Dim retVal As String
Set db = CurrentDb
If Len(criteria) > 0 Then
whereCondition = " WHERE " & criteria
End If
If Len(sortBy) > 0 Then
sortExpression = " ORDER BY " & sortBy
End If
sql = "SELECT " & fieldName & " FROM " & "Members" & whereCondition & sortExpression
Set rs = db.OpenRecordset(sql, dbOpenForwardOnly, dbReadOnly)
Do Until rs.EOF
If Not IsNull(rs.Fields(0).Value) Then
retVal = retVal & Nz(rs.Fields(0).Value, "") & delimiter
End If
rs.MoveNext
Loop
retVal = Left(retVal, Len(retVal) - Len(delimiter))
QueryFieldAsSeparatedString = retVal
rs.Close
Set rs = Nothing
Set db = Nothing
End Function
I then added the field with the owners by adding the following expression to my query:
Owners: QueryFieldAsSeparatedString("[Call Sign]","Members",Count([Members]![Current Ships Owned])>=1)
But it comes back with the error "Your query does not include the specified expression 'Owners' as part of an aggregate function". Changing it from expression to group by gives an error "reserved error (-3087);"
If I remove the Count from the expression it runs but gives me all members rather than the members that own the ships.
Any help or push in the right direction would be greatly appreciated. I'm not sure what I'm missing but I think some fresh eyes on the issue may help.
Thank you!!
-Deke
Note that you have basically replicated http://allenbrowne.com/func-concat.html
The criteria parameter is the problem. It expects a string, but you pass an expression.
And even if Access silently converts it, WHERE Count([field]) >= 1 is not valid in the WHERE clause, that would only work in a HAVING clause.
But what you actually need there is a criterium that collects all Members records that belong to the current query record.
See the usage example on Allen Browne's page, and the documentation of the strWhere parameter.
I wrote the below vba function aiming to return a SQL record set into a cell. I get #Value error when I use this function. It should get two arguments, namely two cells, and simply return Yes or No. I checked the SQL query and it works fine when written as a subroutine. So pardon for replacing some sql commands with *
Public Function TrRe(No1 As String, No2 As String) As ADODB.Recordset
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim SourceText As String
Set cn = New ADODB.Connection
cn.ConnectionString = _
"Provider=MSOLEDBSQL;Server=****;Database=*****;Integrated Security=SSPI"
cn.Open
Set rs = New ADODB.Recordset
SourceText = " SELECT " & _
" CASE " & _
" WHEN ***** LIKE 'TEST%' OR *****=1 THEN 'Yes' " & _
" ELSE 'No " & _
" END " & _
" FROM *** "
" WHERE ****=" & No1 & _
" AND ****=" & No2
rs.ActiveConnection = cn
rs.Source = SourceText
rs.CursorType = adOpenForwardOnly
rs.LockType = adLockReadOnly
rs.Open
Set TrRe= rs
rs.Close
cn.Close
Set cn = Nothing
End Function
I would appreciate your comments/helps.
Update: a) The query always returns a 1x1 recordset and this is Yes or No.
b) The code should be written as a Function since I want to let the user to choose the inputs.
AS #Rory stated, you can't write a recordset into a cell. A RecordSet is an object, containing all kind of information, eg the field names and -types, the state, the connection, somehow the information about the current row that was read and so on. You can't (and you don't want to) write all that into a cell.
Your sql statement will return one row with exactly one field (containing either the string yes or no). In that case, you can simply write (note that this statement is without Set)
TrRe = rs(0)
That is a shortcut, fetching the first field of the current row. Current row is the first row, assuming that the sql statement was executed successfully and returns at least one row. To move to the next row, you would use rs.MoveNext. To check if there are any more rows, use If rs.EOF Then.
If you issue an sql that returns more than that, there are two handy commands:
(1) To write the complete data that was returned into Excel, use Range.CopyFromRecordset
ThisWorkbook.Sheets(1).Range("A2").CopyFromRecordset rs
(2) To read all data into a 2-dimensional array use RecordSet.GetRows
Dim data as Variant
data = rs.GetRows
dim row as long, col as long
For row = 0 To UBound(data, 2) ' Index for rows = 2
For col = 0 to UBound(data, 1) ' Index for fields (columns) = 1
... (do your stuff here)
next col
Next row
I have an issue with square brackets inside the name of column I am trying to access.
name of column: [KPI] Standard Delivery Capability SO [<0/0]
this is my code:
Dim rs As New ADODB.Recordset
Dim query As String
Dim WhatToSelect as String
query = "Select " & WhatToSelect & " From" & sourceSheet & ".[Sheet1$]"
rs.Open query, connection
rs.MoveFirst
i = rs.Fields(rs.Fields(0).name).Value
basicly I am trying to find variable, which would be in "WhatToSelect" variable
I have tried:
WhatToSelect = "avg([[KPI] Standard Delivery Capability SO [<0/0]])"
WhatToSelect = "avg(`[KPI] Standard Delivery Capability SO [<0/0]`)"
nothing has worked so far. (it works with every other column, with no [ ] in)
Coudn't find any documentation about that, so I did some experiments. I created a small table containing one column with exact your column name, executed a Select * from [Sheet1$] and had a look to the column name within the returned recordset. Turned out that the brackets where replaced by parenthesis:
Dim conn As ADODB.Connection, rs As ADODB.Recordset
Set conn = New ADODB.Connection
Dim connString As String
connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.Name & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=YES;"""
conn.Open connString
Set rs = conn.Execute("Select * from [Sheet1$]")
Dim i As Integer
For i = 0 To rs.Fields.Count
Debug.Print rs.Fields(i).Name
Next
>> (KPI) Standard Delivery Capability SO (<0/0)
To query this field, you need to (a) enclose the field name with brackets and (b) replace the brackets within the field name with parenthesis:
dim fieldname as String, sql as String
fieldName = "[(KPI) Standard Delivery Capability SO (<0/0)]"
' Use field in result set:
sql = "Select " & fieldname & " from [Sheet1$]"
Set rs = conn.Execute(sql)
' Use field in Where-Clause:
sql = "Select * from [Sheet1$] where " & fieldname & " > 100"
Set rs = conn.Execute(sql)
In your case, where you want to execute a aggregate function on that field, you need to specify
WhatToSelect = "avg([(KPI) Standard Delivery Capability SO (<0/0)])"
I have one table in my MS Access data base named COA_Map. I also have a form with a multi-select list box. When the values are selected, vba turns them into a string and updates a text box with the string. I want to use the textbox string as a variable in a query.
This is my query:SELECT * FROM COA_Map WHERE (COA_Map.ASL IN ( [Forms]![Multi-Select Search]![TextASL].Text ) );
This returns empty results. When I copy and paste the text box values into the query like this:
SELECT * FROM COA_Map WHERE (COA_Map.ASL IN ( 2.1,2.3,2.4 ) );
I get the expected results. I tried [Forms]![Multi-Select Search]![TextASL].Value and [Forms]![Multi-Select Search]![TextASL] but that gives an error "This expression is typed incorrectly, or it is too complex"
I also tried using "OR" clause instead of "IN". I changed the VBA to return this string:
to build this query: SELECT * FROM COA_Map WHERE COA_Map.ASL = [Forms]![Multi-Select Search]![TextASL] ;
This returns the same empty results. When I paste the textbox values into the query like this: SELECT * FROM COA_Map WHERE COA_Map.ASL = 2.1 OR COA_Map.ASL = 2.2 OR COA_Map.ASL = 2.3 ;
, I get expected results.
When only one value is selected in either version of the query, I get expected results.
I can't figure out why the the query will not return results when reading from the text box with multiple values selected.
Here is a generic example to get you going in the right direction.
Private Sub cmdOK_Click()
' Declare variables
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
' Get the database and stored query
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryMultiSelect")
' Loop through the selected items in the list box and build a text string
For Each varItem In Me!lstRegions.ItemsSelected
strCriteria = strCriteria & ",'" & Me!lstRegions.ItemData(varItem) & "'"
Next varItem
' Check that user selected something
If Len(strCriteria) = 0 Then
MsgBox "You did not select anything from the list" _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
' Remove the leading comma from the string
strCriteria = Right(strCriteria, Len(strCriteria) - 1)
' Build the new SQL statement incorporating the string
strSQL = "SELECT * FROM tblData " & _
"WHERE tblData.Region IN(" & strCriteria & ");"
' Apply the new SQL statement to the query
qdf.SQL = strSQL
' Open the query
DoCmd.OpenQuery "qryMultiSelect"
' Empty the memory
Set db = Nothing
Set qdf = Nothing
End Sub
I have a column with vendor name in an Access table which updates every day (from blank to name) with respect to delivery number (unique).
Every day I want to extract the data from SAP and update the records whose vendor name got updated in System.
I need a SQL query which will match the delivery numbers in Access and Excel workbook and according from Excel work it will capture name of vendor and update Access database.
I have written code that can update only one name at a time, but I want to update everything in one go.
Sub Update()
Sheets("Carrier Updated").Select
'Initialize all variables
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim stDB As String, stSQL As String, stProvider As String
Dim X As Variant
X = Range("A2").Value
Dim Y As Variant
Y = Range("B2").Value
stDB = "C:\Users\yemdema\OneDrive - Ecolab\Desktop\Drive - A\Delivery Creation\DB Backup\Test_1.accdb"
stProvider = "Microsoft.ACE.OLEDB.12.0"
'Opening connection to database
With cn
.ConnectionString = stDB
.Provider = stProvider
.Open
End With
'SQL Statement of what I want from the database
stSQL = "UPDATE Delivery_Creation set [Carrier Updated Later] = '" & Y & "' where[Delivery] = '" & X & "'"
Set rs = cn.Execute(stSQL)
MsgBox ("Carrier has been updated")
'Looping through the records I pulled and inserting the data into the comboBox
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
As you probably have different values for X and Y for each pair of values found in the worksheet, you can either update one set (as you do now), or collect these in a (temporary) table and call an update query using that table. No big difference, though.
Or you could "reverse" the process, using Access to link the range in the worksheet as a linked table, and then run an update query using that table.