How to count and output rows in Access VBA [duplicate] - vba

I am using DCount to help display an error message if the data signals an error. I have it working with one criteria where a number is equal to another number. Now I wanted to add another criteria in there where another field, ReturnDate (this field is Text not Date/Time) is equal to a hyphen (-).
I'm just not really sure how to format it. I have this:
If DCount("*", "CrewTable", "KitNumber=" & _
Me.AssignKit.Value And "ReturnDate=" & _
"-") > 0 Then
Cancel = True
MsgBox "Kit is already assigned!"
AssignKit = ""
AssignKit.SetFocus
Else
...
The error pops up with a 'Type Mistmatch' and the debugger highlights the whole statment from 'If -> Then' and has an error pointing to the line with the hyphen in the quotes.

If DCount("*", "CrewTable", "ReturnDate='-' AND KitNumber=" & _
Me.AssignKit.Value) > 0 Then

It's easier to troubleshoot DCount errors when you store its Criteria option in a string variable.
Dim strCriteria As String
strCriteria = "ReturnDate='-' AND KitNumber=" & Me.AssignKit.Value
Debug.Print strCriteria
If DCount("*", "CrewTable", strCriteria) > 0 Then
If you had used this approach, Access would have alerted you to the fact that the original code which built the Criteria string was invalid. That should make it clearer that the problem wasn't due to the If condition, and it wasn't exactly a DCount problem either ... it was a problem with string concatenation.

Me.AssignKit.Value & " And ReturnDate=" & _

Related

Trying to Find Duplicate Records in Access Error

I am making a databse for a sports club,
When filling out a form, they input the facility ID, start time, end-time and date.
What I am trying to do is when they enter the end time box, the function scans through the entries on the 'Bookings' Table where all the data from this form is stored, to see if the facility is booked out at this time. ( For dtermining if it is booked out at a certain time, if the start time or the end time on table is between what is filled in on the form, an error is thrown
The code is shown below:
Private Sub EndNon_AfterUpdate()
Dim criteria As String
criteria = _
"Non-PlayingFacilityID= " & Me.NonPlayID.Value & " " & _
"Date(Non-PlayingFacility)= " & Me.DateNon.Value & _
" " & "AND [StartTime(Non-PlayingFacility)] Between Me.StartNon.Value And Me.EndNon.Value OR [EndTime(Non-PlayingFacility)] Between Me.StartNon.Value And Me.EndNon.Value "
If DCount("*", "Bookings", criteria) > 0 Then
MsgBox "Unfortunately, this facility is booked at this time"
Me.Undo
End If
End Sub
Syntax error is thrown when I run this, not sure why.
Any help would be much appreciated
It probably highlights this invalid syntax:
"Date(Non-PlayingFacility)= " & Me.DateNon.Value & _
Perhaps you mean:
"DateValue([Non-PlayingFacility])= " & Format(Me!DateNon.Value, "\#yyyy\/mm\/dd\#") & _
The remaining date comparisons need to be concatenated and formatted similarly.
Addendum - given the obscure field name:
"[Date(Non-PlayingFacility)]= " & Format(Me!DateNon.Value, "\#yyyy\/mm\/dd\#") & _
The format is needed to create a valid string expression in SQL for the date value. This is independent of a format applied for display.

Is there a better looping mechanism for this code that won't throw a code analysis warning?

I recently upgraded to VB.NET 2019 and have been going through code analysis to clean everything up in a database program to what MS considers "best practice". This bit of code and a couple just like it I'm having a issue with. The analysis says "Value assigned to 'x' is never used" which is true but I'm not sure of a better way of writing it. Long story short a user can select multiple items in a gridview then run a report and the query is built based on that using or statements. It runs through what is selected and adds to the query. If only one item is selected it just does the selected one (x=0) and if more are selected its adding a OR then the info. Code is cleaned up for simplicity:
Dim x As Integer = 0
For x = 0 To myGridView.SelectedRowsCount - 1
If x = 0 Then
mySQL += "{" & myQuery & ".CompanyID} =" & CInt(myGridView.SelectedRows(x))
Else
mySQL += " OR {" & myQuery & ".CompanyID} =" & CInt(myGridView.SelectedRows(x))
End If
Next
Is there a better way to do this so it doesn't throw that error?
You would be better off using a conditional statement as well as SQL's IN operator. Basically you'd check if myGridView.SelectedRowsCount equals 0, if so then you'd display an error. Then you'd have an ElseIf that checks if myGridView.SelectedRowsCount equals 1, if so then you'd use the equals operator. Finally you'd have an Else statement that joins the values using a comma as the glue.
Take a look at this example:
If myGridView.SelectedRowsCount = 0 Then
MessageBox.Show("There are no rows selected. Please select one or more rows.", "Error", MessageBoxButtons.Ok, MessageBoxIcon.Error)
ElseIf myGridView.SelectedRowsCount = 1 Then
mySQL &= "{" & myQuery & ".CompanyID} = " myGridView.SelectedRows(0)
Else
mySQL &= "{" & myQuery & ".CompanyID} IN (" & String.Join(", ", myGridView.SelectedRows) & ")"
End If
Please keep in mind that this is pseudo-code and you may need to make adjustments, in particular I don't know if SelectedRows or SelectedRows(0) returns a String array/literal.
P.S. You may want to consider using a parameterized query. It would not be difficult to implement one using the same concept that I'm using above.
Your actual warning might be because you initialize the integer but then use it in the For loop. Just initialize it in the For loop.
' Remove this line: Dim x As Integer = 0
For x As Integer = 0 To myGridView.SelectedRowsCount - 1
' ...
Next

VBA CountIFS With Multiple Criteria

I have a VBA procedure that scans a worksheet and produces counts where cell C is not equal to certain colors, but column I is set to one value. This is the procedure:
FormulaR1C1 = "=COUNTIFS(Sheet1!C[-2],RC[-2],Sheet1!C,""<>Red"",
Sheet1!C,""<>Blue"",Sheet1!C,""<>Green"",Sheet1!C,""<>Black"",
Sheet1!C,""<>Purple"",Sheet1!C,""<>White"",
Sheet1!C[6],""Temp"")"
Conditions have changed and I need to add in another criteria for count condition so I thought it would be a quick fix of adding in a comma and the criteria to the end like this
FormulaR1C1 = "=COUNTIFS(Sheet1!C[-2],RC[-2],Sheet1!C,""<>Red"",
Sheet1!C,""<>Blue"",Sheet1!C,""<>Green"",Sheet1!C,""<>Black"",
Sheet1!C,""<>Purple"",Sheet1!C,""<>White"",
Sheet1!C[6],""Temp"",Sheet1!C[6],""Perm"")"
However - now this always returns 0. What is the correct way to add in a secondary condition in VBA to a CountIFS()
EDIT
That second parameter I want to add, should be an "OR" condition as well, so Sheet1!C[6] = Temp OR Perm
EDIT 2
I tried to edit my syntax like this
FormulaR1C1 = "=COUNTIFS(Sheet1!C[-2],RC[-2],Sheet1!C,""<>Red"",
Sheet1!C,""<>Blue"",Sheet1!C,""<>Green"",Sheet1!C,""<>Black"",
Sheet1!C,""<>Purple"",Sheet1!C,""<>White"",
Sheet1!C[6],""Temp"")"
+
"COUNTIFS(Sheet1!C[-2],RC[-2],Sheet1!C,""<>Red"",
Sheet1!C,""<>Blue"",Sheet1!C,""<>Green"",Sheet1!C,""<>Black"",
Sheet1!C,""<>Purple"",Sheet1!C,""<>White"",
Sheet1!C[6],""Perm"")"
but this gives me an error of
application defiend or object defined error
Dim f
f = "=COUNTIFS(Sheet1!C[-2],RC[-2],Sheet1!C,'<>Red'," & _
"Sheet1!C,'<>Blue',Sheet1!C,'<>Green',Sheet1!C,'<>Black'," & _
"Sheet1!C,'<>Purple',Sheet1!C,'<>White'," & _
"Sheet1!C[6],'Temp') + COUNTIFS(Sheet1!C[-2],RC[-2],Sheet1!C,'<>Red'," & _
"Sheet1!C,'<>Blue',Sheet1!C,'<>Green',Sheet1!C,'<>Black'," & _
"Sheet1!C,'<>Purple',Sheet1!C,'<>White',Sheet1!C[6],'Perm')"
FormulaR1C1 = Replace(f, "'", """")

Using Dlookup with multiple criteria in a form

I have a Form where I enter in my part number and part rev. I am trying to write some VBA so if I click a button on the form, it will search the query, which holds all the history of all the parts, for a part number as well as part rev match. Once it finds a matching part number and part rev, it autofills some information into the form for me.
Right now I have it returning data for a matching part number, but it gives the first data found, regardless of part rev, i.e. returns values that match another part number but different rev.
Sub FindPartNumber_Click()
DoCmd.OpenQuery "SavedQuotesQuery" 'runs query to find any matching part numbers
'confirms if part previously exists
If IsNull(DLookup("PartNumber", "SavedQuotesQuery", "'[PartNumber]=" & Me.PartNumber _
& " AND [PartRev]=" & Me.PartRev & "'")) Then
MsgBox "Part does not previously exist. Please manually enter its characteristics", _
vbOK 'and alerts user
DoCmd.Close 'close query
Exit Sub
End If
[PartName] = DLookup("PartName", "SavedQuotesQuery", "PartNumber='" & Me.PartNumber _
& "'")
[Length] = DLookup("Length", "SavedQuotesQuery", "PartNumber='" & Me.PartNumber & _
" And PartRev = " & Me.PartRev & "'")
DoCmd.Close 'close query
End Sub
Am I just struggling with the syntax of the two match criteria or is there something else going on here?
There are a lot of problems here. First off, the DoCmd.OpenQuery and DoCmd.Close are not doing what you seem to expect. Read up on the help file to learn how they should be used, but for our purposes it's enough for me to just say you do not need them here.
The problem you are having is that you are only providing half of your criteria in the PartName DLookup call. So instead of returning the PartName with matching PartNumber and PartRev, you are telling Access to return the PartName of the first record it finds with a matching PartNumber. Which one it returns is not actually defined if there is more than one match.
Try the following instead:
Sub FindPartNumber_Click()
Dim MyPartName As Variant, Criteria As String
Criteria = "PartNumber=""" & Me.PartNumber & """ AND " & _
"PartRev= """ & Me.PartRev & """"
'confirms if part previously exists
MyPartName = DLookup("PartName", "SavedQuotesQuery", Criteria)
If IsNull(MyPartName) Then
MsgBox "Part does not previously exist. Please manually enter its characteristics", vbOK 'and alerts user
Else
[PartName] = MyPartName
[Length] = DLookup("Length", "SavedQuotesQuery", Criteria)
End If
End Sub

How do I reference a value from a list box in Column(0) on click?

I have a list box that is populated based on a previous filter (a text box). This means there is no predefined number of items in the listbox so using the index is impossible.
What I am looking for is a way of selecting the value of column(0), as there are 3 columns in my list box, of the selected line that is clicked.
Private Sub listSource_Click()
Dim strSource As String
strSource = "SELECT [Product Code],[Stock Level],[Description] FROM [products/stock] " & _
"WHERE Mid([Product Code],1,5) = " & Me.listSource.Column(0).Value & ";"
Me.listResult.RowSource = strSource
Me.listResult = vbNullString
End Sub
What I think I need is just the small piece of code that is supposed to be where "Me.listSource.Column(0).Value" is.
Thanks in advance,
Bob P
I reckon you want:
strSource = "SELECT [Product Code],[Stock Level],[Description] " & _
"FROM [products/stock] " & _
"WHERE Mid([Product Code],1,5) = '" & Me.listSource & "';"
Note the single quotes before and after Me.listSource.
Me.listresult gives the bound column
you then have to append .Column(0),.Column(1) ... for other columns.
to find out which one of the list you need to be looking at, .ItemsSelected.Count will tell you how many are selected (1 for a simple list box), and .ItemsSelected(0) for the index to the first item selected, so, the complete line for the first column of the first selected line would be:
Me.listSource.ItemData(Me.ListSource.ItemsSelected(0))
You should be able to use Me.ListSource.Column(0) to get the value of the first column of the selected row.
Also see: Retrieve column values of the selected row of a multicolumn Access listbox