DSum function in vba - ms-access

I want to display sum of a column in a textbox when I hit a button. But it is giving me a compile error: "Wrong number of arguements or invalid property assignment"
The below code is implemented in vba.
Here is the code that I used:
Text19 = Nz(DSum("Total_Units", "6_Provincial_SUB", , "[BudgetYear] =" & [Combo5] & " And [Program_Name] ='" & Replace([Combo7], "'", "''") & "'"), 0)

DSum has three parameters. You have four. Drop the extra comma
Text19 = Nz(
DSum(
"Total_Units",
"6_Provincial_SUB", <==== Here I dropped a comma (,)
"[BudgetYear] =" & [Combo5] & " And [Program_Name] ='" &
Replace([Combo7], "'", "''") & "'"
),
0
)
When things like this happen, I try to find the problem by indenting the expression like above in order to find matching braces etc. Without line continuation character "_" this will not work of cause, but it gives you an idea of the structure of the expression.
I have these functions in my library. They help me in the creation of SQL strings
Public Function SqlStr(ByVal s As String) As String
'Input: s="" Returns: NULL
'Input: s="abc" Returns: 'abc'
'Input: s="x'y" Returns: 'x''y'
If s = "" Then
SqlStr = "NULL"
Else
SqlStr = "'" & Replace(s, "'", "''") & "'"
End If
End Function
Function Build(ByVal s As String, ParamArray args()) As String
'Build("FirstName = {0}, LastName = {1}","John","Doe") -->
'"FirstName = John, LastName = Doe".
'"\n" is expanded with vbCrLf.
Dim i As Long
s = Replace(s, "\n", vbCrLf)
For i = 0 To UBound(args)
s = Replace(s, "{" & i & "}", Nz(args(i)))
Next i
Build = s
End Function
By using them, your SQL would be constructed like this
sql = Build("[BudgetYear] = {0} AND [Program_Name] = {1}", _
Combo5, SqlStr(Combo7))

You have a comma too many after the domain parameter:
"6_Provincial_SUB", ,
That would make the space the criteria parameter, and the actual criteria an unknown fourth parameter.

Related

VBA returning a value and error information together

I am writing some VBA in MS Access, although the principle of my question would apply just as well to Excel or Word VBA. I have written a function GetStringParameterFromTable which returns a string value. It is possible that the function may result in a VBA-generated error, despite my best efforts to write it so that it does not. If an error happens, I don't want the code to crash, so I must use error handling. However, I don't want the code to display an error message and stop within the function if there is an error. I want the function to finish executing and return control to the calling procedure, and then I want the calling procedure to display the error message and tidy up, e.g. close open files. My question is: how does the calling procedure know that there has been an error in the function it called, and how does it get the error message?
I have thought of three ways of implementing this:
(1) Make GetStringParameterFromTable into a Sub, and pass it ParameterValue, ErrorFlag and ErrorMessage by reference.
(2) Keep GetStringParameterFromTable as a Function, define ErrorFlag and ErrorMessage as global variables and have the function alter ErrorFlag and ErrorMessage.
(3) Keep GetStringParameterFromTable as a Function and define a type with three components – ParameterValue, ErrorFlag and ErrorMessage – and make GetStringParameterFromTable return a value of the type I have defined.
I think that my requirement must be quite common, but I can’t find any examples of how it’s implemented. Does anyone have any views on which of my suggestions is the best way, or whether there is a better way that I haven’t thought of?
I have been contemplating the same thing since C#.net has implemented Tuples. I have implemented Tuples using VBA's type to create my tuples. What I have done is the following:
Public Type myTuple
Value as String 'Or whatever type your value needs to be
ErrCode as Long
ErrDesc as String
End Type
Public Function DoWork (ByRef mObject as MyClass) as myTuple
Dim retVal as myTuple
'Do whatever work
If Err.Number <> 0 then
retVal.Value = Nothing
retVal.ErrNumber = Err.Number
retVal.ErrDesc = Err.Description
Else
Set retVal.Value = Whatever Makes Sense
retVal.ErrNumber = 0
retVal.ErrDesc = VbNullString
End If
DoWork = retVal
End Function
I would like to be more specific, but you didn't provide a code example.
I am doing it like this and log the errors in a table:
' Lookups Replacements
'---------------------
Function DLook(Expression As String, Domain As String, Optional Criteria) As Variant
On Error GoTo Err_Handler
Dim strSQL As String
strSQL = "SELECT " & Expression & " FROM " & Domain 'DLookup
'DCount: strSQL = "SELECT COUNT(" & Expression & ") FROM " & Domain
'DMax: strSQL = "SELECT MAX(" & Expression & ") FROM " & Domain
'DMin: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DFirst: strSQL = "SELECT FIRST(" & Expression & ") FROM " & Domain
'DLast: strSQL = "SELECT LAST(" & Expression & ") FROM " & Domain
'DSum: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DAvg: strSQL = "SELECT AVG(" & Expression & ") FROM " & Domain
If Not IsMissing(Criteria) Then strSQL = strSQL & " WHERE " & Criteria
DLook = DBEngine(0)(0).OpenRecordset(strSQL, dbOpenForwardOnly)(0)
Exit Function
Err_Handler:
'Can be made as Error Sub as well
Dim ErrNumber as Integer
Dim ErrDescription as String
ErrNumber = Err.Number
ErrDescription = Err.Description
Err.Clear
On Error Resume Next
Dim strSQL as String
strSQL = "INSERT INTO tblErrorLog (ErrorNumber, ErrorDescription) VALUES (" & ErrNumber & ", '" & ErrDescription & "')"
Currentdb.Excecute strSQL, dbFailOnError
End Function
Called with:
If DLook("Column2", "Table1", "Column1 = " & ID) = 0 Then
'Do stuff
End If
If DLook("Column2", "Table1") = 0 Then
'Do other stuff
End If

Select from where contains

I have a database where i can add a full name of a person, and i am trying to implement a search function using a textBox and a button but i only want to search for the first or last name not necessarily entering the full name.
I tried using SELECT FROM WHERE CONTAINS like this:
OleDbCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM Table WHERE CONTAINS (column, '"+textBox.Text+"')";
But i keep getting this error:
Syntax error (missing operator) in query expression 'CONTAINS (column,'the text i tried to search')'.
I also tried changing the + to % or * or & but still it didn’t work.
Contains is not valid Access SQL. Use Like:
cmd.CommandText = "SELECT * FROM Table WHERE [YourNameField] Like '*" + textBox.Text + "*')";
Here is an example of a search such as you want:
Private Sub cmdFind_DisplayName_Click()
Dim dbs As Database, rstPatient As Recordset
Dim txtDisplayName, strQuote As String
strQuote = Chr$(34)
On Error GoTo ErrorHandler
Me.OrderBy = "DISPLAYNAME"
Me.OrderByOn = True
Set dbs = CurrentDb
Set rstPatient = Me.RecordsetClone
txtDisplayName = Trim(InputBox("Please Enter Patient Name ", "Patient Find By Name"))
txtDisplayName = UCase(txtDisplayName) & "*"
If IsNull(txtDisplayName) Then
MsgBox ("No Patient Name Entered - Please Enter a Valid Patient Name")
Else
rstPatient.FindFirst "[DISPLAYNAME] Like " & strQuote & txtDisplayName & strQuote
If Not (rstPatient.NoMatch) Then
Me.Bookmark = rstPatient.Bookmark
Me.Refresh
Else
MsgBox ("Patient Not Found - Please Enter a New Patient Name")
End If
End If
GoTo Exit_cmdFind_Click
ErrorHandler:
MsgBox LTrim(RTrim(Me.NAME)) + "." + "Patient Find By Display Name - " + "Error: " + AccessError(Err.Number)
Exit_cmdFind_Click:
rstPatient.Close
Set dbs = Nothing
Set rstPatient = Nothing
End Sub
Create 1 textbox (txtMain) and search command button(btnSearch) to execute SQL. Then add a listbox (listResult) to display results.
Private Sub btnSearch_Click()
Dim mainSQL As String
mainSQL = " SELECT YOUR_FIELD_NAME " & _
" FROM MasterReg " & _
" WHERE Left(,InStr(YOUR_FULL_NAME_FIELD,' ')-1) LIKE '" & me.txtMain & "*'" & _ ' Firstname Search
" OR RIGHT( YOUR_FULL_NAME_FIELD,Len( YOUR_FULL_NAME_FIELD )-InStr( YOUR_FULL_NAME_FIELD,' ')) LIKE '" & me.txtMain & "*'" 'Surname Search
Me.listResult.SetFocus
Me.listResult.RowSource = mainSQL
Me.listResult.Requery
End Sub

Creating a form to search for records based on multiple criteria

I am trying to create a form that allows you to return results based on multiple criteria.
I have FirstName field, LastName field, and State Field.
I also have an text boxes named searchFirst, searchLast, searchState where users can input criteria.
The search button will execute the following code once clicked.
Private Sub mySearchQuery_Click()
Dim filter As String
Dim rtFirstName As String
Dim rtLastName As String
Dim rtState As String
rtFirstName = Me.searchFirst.Value
rtLastName = Me.searchLast.Value
rtState = Me.searchState.Value
If Not IsNull(rtFirstName) Then
If Not IsNull(filter) Then filter = filter & " AND "
filter = filter & "(FirstName like""*" & rtFirstName & "*"")"
End If
If Not IsNull(rtLastName) Then
If Not IsNull(filter) Then filter = filter & " AND "
filter = filter & "(LastName like""*" & rtLastName & "*"")"
End If
If Not IsNull(rtState) Then
If Not IsNull(filter) Then filter = filter & " AND "
filter = filter & "(State LIKE""*" & rtState & "*"")"
End If
' Now re-construct the SQL query '
Dim sql As String
sql = "SELECT * FROM MainData"
If Not IsNull(filter) Then
sql = sql & " WHERE " & filter
End If
Me.RecordSource = sql
'SubForm.Form.RecordSource = sql
End Sub
I am getting the following error below.
Run-time error '3075': Syntax error (missing operator) in query
expression 'AND (FirstName like"*tracy*") AND (lastName like"*Smith*")
AND (State LIKE"*ga*")'.
I am not sure why AND was included at the beginning of the search query?
I am not sure why AND was included at the beginning of the search
query?
Since you have Dim filter As String, filter can never contain Null. That means these If conditions ... If Not IsNull(filter) ... will always be True.
Similarly, Not IsNull(rtFirstName), Not IsNull(rtLastName), and Not IsNull(rtState) will always be True.
The net result is the code adds another condition piece to your filter string regardless of whether or not the corresponding search text box contains anything, and each of those pieces is prefixed with " AND ".
With those points in mind, you could refactor your code to add a filter segment only when you have something in the corresponding search text box and decide when to include " AND ". However I find it simpler to include " AND " for each of them and then strip away the very first " AND " from filter before adding it to the WHERE clause.
Private Sub mySearchQuery_Click()
Dim strSelect As String
Dim strWhere As String
If Len(Trim(Me!searchFirst.Value) & vbNullString) > 0 Then
strWhere = strWhere & " AND FirstName Like ""*" & Me!searchFirst.Value & "*"""
End If
If Len(Trim(Me!searchLast.Value) & vbNullString) > 0 Then
strWhere = strWhere & " AND LastName Like ""*" & Me!searchLast.Value & "*"""
End If
If Len(Trim(Me!searchState.Value) & vbNullString) > 0 Then
strWhere = strWhere & " AND State Like ""*" & Me!searchState.Value & "*"""
End If
' Now re-construct the SQL query
strSelect = "SELECT * FROM MainData"
' only add WHERE clause if we have something in strWhere
If Len(strWhere) > 0 Then
' use Mid() to ignore leading " AND "
strSelect = strSelect & " WHERE " & Mid(strWhere, 6)
End If
Debug.Print strSelect ' <- inspect this in Immediate window; Ctrl+g will take you there
' enable one of these RecordSource lines after confirming Debug.Print shows you what you need
'Me.RecordSource = sql
'SubForm.Form.RecordSource = sql
End Sub

VBA Basic Function returning null

I have a very basic function that is to return symbols such as "=", ">","<",">=", and "<=" and it is only returning a null value. any Ideas?
Function Lookup_Symbol(search_Name As String) As String
Lookup_Symobl = DLookup("[Symbol]", "[Search_Names]", "[Search_Name]= '" & search_Name & "'")
End Function
when I do a Debug.print DLookup("[Symbol]", "[Search_Names]", "[Search_Name]= '" & search_Name & "'") it will return =
Because you have misspelled Lookup_Symbol in your function. It should be:
Function Lookup_Symbol(search_Name As String) As String
Lookup_Symbol = DLookup("[Symbol]", "[Search_Names]", "[Search_Name]= '" & search_Name & "'")
End Function
You would have been able to spot this much easier if you had Option Explicit at the top of the module; it would then have told you that the variable Lookup_Symobl is not defined.

Using User Defined Function output from VBA as an input in access query

I have created a function that provide the value based on user selection.I want to use the output of the fuinction in another query.
My function is :-
Public Function provisionvariable() As String
For Each sItem In Forms![Access Form].Provision.ItemsSelected
v_provision = "" & Forms![Access Form].Provision.Column(0, sItem) & ""
Provision = Provision & "" + v_provision + ","
'MsgBox Provision
Next
Provision = Left(Provision, Len(Provision) - 1)
provisionvariable = Provision
MsgBox provisionvariable
End Function
The output of the function is BBNI,FP
I want to use the output as where condition in access query
My query is
***SELECT DISTINCT quarter, provision, [currencycode]+'-not found in Master' AS Comment
FROM t_00_unearned_unincepted_alloc_basis AS inp
WHERE **provision in (provisionvariable()) AND**
NOT EXISTS
(SELECT 1
FROM t_01_le_currency_master key1
WHERE inp.[group_stat]=key1.[group_stat] AND
inp.le=key1.le AND
inp.[currencycode]=key1.[original_currency]);***
Now the problem is output of function is BBNI,FP but access takes it as single string i.e. 'BBNI,FP' in the query.
Is it possible to have it as two string ('bbni','FP') rather than 'BBNI,FP'
Any Suggestions Much Appreciated
Thanks
Try:
Provision = Provision & "'" & v_provision & "',"
And to ensure you aren't repeatedly appending to a module-level variable, you should also do a local
Dim Provision As String
Based on the following post, "a function cannot be used for IN () clauses" How to call VBA-function from inside sql-query?
So you need to build the SQL (which would include the 'In' list) then execute it. Since I have no idea if multi-user environment, or how you will use the query output, I would build the SQL, save as a QueryDef object, then do whatever you want.
The following is what the code to build the SQL could look like:
Dim strSQL As String
strSQL = "SELECT DISTINCT quarter, provision, [currencycode]+'-not found in Master' AS Comment " & _
"FROM t_00_unearned_unincepted_alloc_basis AS inp " & _
"WHERE provision In (" & ProvisionVariable() & ") AND " & _
. . . .
Debug.Print strSQL
The following is my version of your Function (note the single-quote delimiters are added):
Public Function ProvisionVariable() As String
Dim sItem As Variant
Dim v_provision As String
Dim provision As String
provision = ""
For Each sItem In Forms![Access Form].Provision.ItemsSelected
v_provision = "'" & Forms![Access Form].Provision.Column(0, sItem) & "'"
provision = provision & "" + v_provision + ","
Next sItem
provision = left(provision, Len(provision) - 1)
ProvisionVariable = provision
Debug.Print ProvisionVariable
End Function