building a search form in Access 2010 - ms-access

I am trying to make search customer form for access 2010.
I like to have an option group based on a query search. I made a search query looking for first name or last name. two textboxes are also present on the form to fill up the query inputs (1st and last name)
I need option group so that I can select the resulted name for booking purposes.
In the past I have made an indirect way of doing this using subform and a checkbox.
Then loading both results on a subform and checkbox (requery) so the user only has to select on the checkbox. But this time I want the options to be the query result itself! Please help.

Here is a simple example that uses a List Box:
Table: Clients
ID - AutoNumber
LastName - Text(255)
FirstName - Text(255)
Email - Text(255)
Test data:
ID LastName FirstName Email
-- ---------- -------------- ------------------
1 Thompson Gord gord#example.com
2 Loblaw Bob bob#example.com
3 Kingsley Hank hank#example.com
4 Thompson Hunter S. hunter#example.com
5 Squarepants Spongebob ss#example.com
6 O'Rourke P. J. pj#example.com
7 Aldrin Edwin "Buzz" buzz#example.com
Form layout:
VBA module for this form:
Option Compare Database
Option Explicit
Private Sub Form_Load()
Me.lstSearchResults.RowSource = ""
End Sub
Private Sub btnSearch_Click()
Me.lstSearchResults.SetFocus
Me.lstSearchResults.Value = Null
Me.lstSearchResults.RowSource = _
"SELECT ID, LastName, FirstName FROM Clients " & _
"WHERE LastName LIKE ""*" & DQ(Me.txtSearchLastName.Value) & _
"*"" AND FirstName LIKE ""*" & DQ(Me.txtSearchFirstName.Value) & "*"""
End Sub
Private Function DQ(s As Variant) As String
' double-up double quotes for SQL
DQ = Replace(Nz(s, ""), """", """""", 1, -1, vbBinaryCompare)
End Function
Private Sub btnLookupEmail_Click()
If IsNull(Me.lstSearchResults.Value) Then
Me.txtEmail.Value = ""
Else
Me.txtEmail.Value = DLookup("Email", "Clients", "ID=" & Me.lstSearchResults.Value)
End If
End Sub
When the form is first opened, everything is empty.
Typing "thompson" (without the quotes) and clicking btnSearch populates the List Box with clients WHERE LastName LIKE "*thompson*". (If you look at the code you'll see that it will also match on FirstName if you supply one.)
Select one of the items in the List Box and click btnLookupEmail and the email address is displayed in the Text Box below.

Related

MS Access query for have in only one field all value repeted [duplicate]

I have created a database that has these tables:
Student list
Student booklet numbers
Student needs
Teacher Information
In the Student Needs Table I have information entered similar to this:
Student ID Column, Last Name, First Name, Reading Special Need
123456 Mouse Mickey Dictionary
123456 Mouse Mickey Extra Time
123456 Mouse Mickey Small group
123456 Mouse Mickey Type Answer Choices
654321 Duck Daffy Dictionary
654321 Duck Daffy Thesaurus
654321 Duck Daffy Small Group
I need this to be pulled similar to this:
Student ID Column, Last Name, First Name, Reading Special Need
123456 Mouse Mickey Dictionary, Extra time, Small group, type answer choices
654321 Duck Daffy Dictionary, Thesaurus, Small Group
I used the concatrelated function in my report control source and it works to put all of the needs together, but because my query has the student listed multiple times, it is listing the student multiple times on the report. Like this:
Student ID Column, Last Name, First Name, Reading Special Need
123456 Mouse Mickey Dictionary, Extra time, Small group, type answer choices
123456 Mouse Mickey Dictionary, Extra time, Small group, type answer choices
123456 Mouse Mickey Dictionary, Extra time, Small group, type answer choices
123456 Mouse Mickey Dictionary, Extra time, Small group, type answer choices
654321 Duck Daffy Dictionary, Thesaurus, Small Group
654321 Duck Daffy Dictionary, Thesaurus, Small Group
654321 Duck Daffy Dictionary, Thesaurus, Small Group
I have tried all that I can think of to fix this - to the point of exporting the report and deleting duplicates - but then the export cuts off at 255 characters- so that doesn't work. Surely I am missing something that would be relatively easy- but I can't figure it out!
Use my DJoin function and a query like this:
SELECT
[Student Needs].[Student ID],
[Student Needs].[Last Name],
[Student Needs].[First Name],
DJoin("[Reading Special Need]","[Student Needs]","[Student ID] = " & [Student ID] & "",", ") AS [Reading Special Needs]
FROM
[Student Needs]
GROUP BY
[Student Needs].[Student ID],
[Student Needs].[Last Name],
[Student Needs].[First Name];
Output:
I created a module called "Get List From Table Field" and in it I have the following code:
Public Function GetList(sTable As String, sField As String, Optional sWhere As String, Optional sDelimiter As String, Optional UniqueValues As Boolean) As String
' compiles all the data from a single field in a table and returns them in a string.
' has options for providing a sql crieria, a delimiter, and if unique values should be returned
Dim rs As Recordset
Dim sList As String
Dim sChar As String
If sDelimiter = "" Then
sChar = ","
Else
sChar = sDelimiter
End If
Set rs = CurrentDb.OpenRecordset("Select " & IIf(UniqueValues, "Distinct ", "") & sField & " From " & sTable & IIf(sWhere <> "", " Where " & sWhere, ""))
Do While Not rs.EOF
sList = sList & sChar & rs.Fields(sField)
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
sList = Mid(sList, 2) & sChar
GetList = sList
End Function
In your select query, you can try:
SELECT [Student ID], [Last Name], [First Name],
GetList("[Student Needs]","[Reading Special Need]","[Student ID] = " & [Student ID]) AS [Reading Special Needs]
FROM [Student Needs]
GROUP BY [Student ID], [Last Name], [First Name];
I also recommend that you use underscores or CamelCase instead of spaces on all your table and field names. That way you can avoid using brackets in your statements. It's a better programming habit to get into. For instance:
Underscore SELECT Student_ID, Last_Name, First_Name FROM Student_Needs
CamelCase SELECT StudentID, LastName, FirstName FROM StudentNeeds

DoCmd.FindRecord isn't finding the record in Access VBA code

I am not sure if there is another post like this but i think my question is a little different.
I am currently designing a database to track employee training given by employer. My current error I find is adding an employee by using a bound form (frmAddEmployee) to my employees table (tblEmployees).
What I have at the moment that works is VBA code that shows a notification when you enter a value into a textbox for the employee number and it finds a duplicate record in the table. The VBA will also show the record in the same form that corresponds with the value you have entered when you clear the notification.
Here's the code I use for the txtEmpNumber after update:
Private Sub txtEmpNumber_AfterUpdate()
Dim EmpNum As String
Dim stLinkCriteria As String
Dim EmpNr As Integer
'Assign the entered employee number to a variable
EmpNum = Me.txtEmpNumber.Value
stLinkCriteria = "[EmpNumber] = " & "'" & EmpNum & "'"
If Me.txtEmpNumber = DLookup("[EmpNumber]", "tblEmployees", stLinkCriteria) Then
MsgBox "This employee number, " & EmpNum & ", has already been entered in database." _
& vbCr & vbCr & "Please check the number.", vbExclamation, "Duplicate information"
Me.Undo
'show the record of matched employee number from the employees table
EmpNr = DLookup("[EmpID]", "tblEmployees", stLinkCriteria)
Me.DataEntry = False
DoCmd.FindRecord EmpNum, , , , , acCurrent
Me.cmdSave.Enabled = False
Me.cmdNew.Enabled = True
Else
Me.txtIDNumber.Enabled = True
End If
End Sub
The notification shows there is a duplicate value, for example 1234 and shows the record in the table for 1234 but when I try a different value like 5678 then it shows the value again for 1234 and not 5678.
Any ideas how to fix this problem?
I think the problem you are having is that this command:
DoCmd.FindRecord EmpNum, , , , , acCurrent
...searches in the current field. But if there isn't a current field (because the form doesn't have the focus), or if the current field is some other field (such as ID), the "find" won't find a match, and the record you're looking at won't change.
The simplest fix would be to change your code to this:
DoCmd.FindRecord EmpNum, , , , , acAll
That will search for the value of EmpNum in ALL the fields.
But, if there's a chance that the value for EmpNum might also appear in other fields than txtEmpNumber (for example, if someone has EmpNum = 12 and someone else is ID = 12), this will eventually start "finding" the wrong record.
So I think the best thing to do would be to make sure your current field is txtEmpNumber before you execute the FindRecord.
Me.txtEmpNumber.SetFocus
DoCmd.FindRecord EmpNum, , , , , acCurrent
That will ensure it only looks in txtEmpNumber when it's trying to find the record.

Filtering Data using record sets

Hello everyone I am at a dilemma I am trying to find possible multiple accounts made by the same person by comparing the records, my main problem is how do you compare the current row value to the next value? By this I mean like this MI(i)=MI(i+1) "MI" is the field that I am targeting and i represents the current row, so what this is suppose to do is compare the current value to the next value. But it does not seem to work in vba is it done a diffferent way? To filter should I use rs.Filter or should I use Me.Filter because I want the filtered table to show up in my splitform.
Current Example Table that I am working with:
Number MI First Name Last Name DOB
15241543 123456789 James Matheson 2/25/1980
15241543 123456789 Jams Matheson 2/25/1980
12345679 124512451 Monroe Matheson 3/25/1980
12345679 124512451 Monro Matheson 3/25/1980
54789654 152415241 Dilan Pumley 4/23/1970
54789658 154215246 Michael Lan 1/30/1989
Final table that should appear is this:
Number MI First Name Last Name DOB
15241543 123456789 James Matheson 2/25/1980
15241543 123456789 Jams Matheson 2/25/1980
12345679 124512451 Monroe Matheson 3/25/1980
12345679 124512451 Monro Matheson 3/25/1980
Private Sub buttonSort_Click()
Dim i As Integer
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("deleteYo")
For i = 0 To rs.RecordCount - 1
'Comapred the current DOB cell value to the next DOB cell value and some other conditions are set such as Current First Name does not equal the next First Name value
If DOB(i) = DOB(i + 1) And [First Name](i) <> [First Name](i + 1) Or [Last Name](i) <> [Last Name](i + 1) And Number(i) = Number(i + 1) Or MI(i) = MI(i + 1) Then
'Filters the current value if the conditon is passed
Me.Filter = "[First Name]" & [First Name](i).Value & "'"
'Filter the next value also to append the filtered values so that they will not be overwritten.
Me.Filter = Me.Filter & "[First Name]" & [First Name](i + 1).Value & "'"
Else
End If
rs.MoveNext
Next i
Me.FilterOn = True
rs.Close
Set rs = Nothing
db.Close
End Sub
Please Note I have tried using a query with SQl statement for this which does not work properly perhaps because this data is practically millions of records and also because the UI is in the form and when the filtered values are applied I would like them to show up at the table at the bottom of the split form.
You can try using a corelated subquery.
SELECT t.ID, t.[First Name], t.[LastName], t.MI
FROM YourTable AS t
LEFT JOIN
(SELECT t2.id, t2.[First Name], t2.[Last Name], t2.MI
FROM YourTable AS t2) AS temp
ON t.MI = temp.MI
WHERE t.[First Name] != t2.[First Name]
OR
t.[Last Name] != t2.[Last Name];
This is going to compare each field with the same MI value and retrieve records where the first and last names are not similar.
You can adjust the fields to better fit your table schema.

VB.NET -> Combobox random index

I have a question regarding comboboxes in VB.net 2010.
In my database I have 4 fields: e.g.:
idDetails | DetailsShortCode | Details_Explain | DetailsSortOrder
{autonum}1| DOA | Death on Arrival| 5
{autonum}2| NDI | No Display | 10
{autonum}3| QQA | In Research | 4
etc..
These values I pull out of the dbase (mySQL) and insert into a CheckedListBox.
I display the values as DetailsShortCode & " - " & Details_explain.
I use a [for loop] to create index numbers, because the sort order is based on the Details Sort order. Which means that VB.net gets 'fed' with the results in the following order:
idDetails | DetailsShortCode | Details_Explain | DetailsSortOrder
3 | QQA | " ... " | 4
1 | DOA | "...." | 5
2 | NDI | " ... " | 10
If i put this in the listbox, the error I shall receive is '3 is an incorrect value for 'index'"
Due to the fact that VB.net expects that the CheckedListBox (and also ComboBox) index always is in a sequential order, as in 0,1,2,3,4..etc..
The problem is the fact that orders in the database can change, items can change, and I have a field in another table containing a comma separated list of the details selected (e.g. 1;10;14;12;)
This means that 1 always must be the item with PrimaryKey 1, and that the displayed item on that index must always be the same...
so what I need, is to know how I can use the Primary Key as an Index Number, and let VB.Net not throw an error when the Index is in a random order.., or give the items a hidden value (like in HTML and PHP), in which I can just use the [for loop] indexes..
This is the code I use to insert items to the Details CheckedListBox
Function LoadComboBoxes(ByVal CB As String)
Dim SQLtext = ""
Select Case CB
Case "Details"
SQLtext = "Select " & _
"idDetails, " & _
"DetailsCode, " & _
"DetailsExplain, " & _
"DetailsSortOrder " & _
"FROM Details order by DetailsSortOrder"
Dim i = -1
Dim dr As MySqlDataReader
Dim cmd As New MySqlCommand(SQLtext, dbconn)
connect()
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
CLBDetails.Items.Clear()
While dr.Read
i += 1
CLBDetails.Items.Insert(i, .GetString(1) & " - " & dr.GetString(2))
End While
end select
end function
The easiest way might be to use a DataGridView which should have all the functionality of the CheckedComboBox plus the ability to keep the data intact as column data and allow you to reference the ID column as an ID Column rather than an ID aliased as an Index.
Depending on what a CheckedComboBox is (there are lots of these around) and what it inherits from, you should be able to store objects there:
Class DisplayItem
Friend ID as Long
DetailsShortCode As String
Details_Explain As String
DetailsSortOrder As String
Public Function overrides ToString As String
' depending on the CheckedComboBox add column seperators?
return DetailsShortCode & Details_Explain & DetailsSortOrder
End Function
End Class
Adding an object such as this to the control lets you retain the PK ref:
ccb.Items(N).ID
While the ToString function lets you format the output as desired. Further, you could create a List(Of DisplayItem) or BindingList(Of DisplayItem) and drive the CheckedComboBox by binding the datasource to the List. A DGV is still easier...

combobox rowsource based on forms record source (distinct) field

I have a form record source set to a elaborate SQL select statement. That is working fine. If it helps to know, the form layout is Tabular. Here is an example of the data:
order carrier billto employee
1 smgd horm chrnic
2 axxm sele chrnic
3 smgd horm redned
4 mcta cron greand
5 mcta cron greand
Its basically unbilled order entries. I want a combo box to show distinct employee names (chrnic, redned, greand) based on the current records showing. I will be coding it to filter the form. Seems simple, but I am having trouble
Things I have tried:
Tried setting rowsource to me.recordsource, but get an
It appears that I would need to parse & edit that string
I copied the complex query & put as combo box record source & that worked to filter the form, so I know that filter logic is correct. I just want it to be dynamic so we only have to change SQL statement in one place if needed
"I have a form record source set to a elaborate SQL select statement."
Save that query as a named QueryDef. I will pretend you chose qryRecordSource as the name.
"I want a combo box to show distinct employee names ... based on the current records"
For the combo box row source use ...
SELECT DISTINCT employee
FROM qryRecordSource
ORDER BY 1;
And then to filter the form based on the combo selection, add a command button, cmdApplyFilter, and use this in its click event procedure ...
Me.Filter = "[employee] = '" & Me.YourComboName.Value & "'"
Me.FilterOn = True
If the employee names can include an apostrophe, use this for the Filter expression ...
Me.Filter = "[employee] = '" & _
Replace(Me.YourComboName.Value, "'", "''") & "'"
If you want to include a combo row to clear the filter, use a UNION query as the combo row source ...
SELECT "*** ALL ***" AS employee
FROM Dual
UNION
SELECT employee
FROM qryRecordSource
ORDER BY 1;
... where Dual is any table or query which returns just one row. Then in the command button click event you can do ...
If Me.YourComboName.Value = "*** ALL ***" Or _
IsNull(Me.YourComboName.Value) Then
Me.Filter = vbNullString
Me.FilterOn = False
Else
Me.Filter = "[employee] = '" & Me.YourComboName.Value & "'"
Me.FilterOn = True
End If
And actually you wouldn't even need the command button. You could set the Filter from the combo's AfterUpdate event.