How to remove period in Middle Initial ms access - sql

I have two table that 1 table need to find a match on the other table.
Say I have table1 and Masterfiles table. Table1 has a name field the same with Masterfiles.
But table1 name field has different value because it has only middle initial while Masterfiles has middle name.
Now I want to get the other field value from Masterfiles called "Gender", since table1 has no value on gender field.
The table look like this:
Table1 Masterfiles
Name Gender Name Gender
Smith, John E. Smith, John Estaw M
Canard, Donald R Canard, Donald Reever M
Since I have a lot of records in table1 that need to get the value of gender field I need to do it programmatically.
Currently I have the following code:
Dim db As Database
Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
Set rs = db.OpenRecordset("Table1")
Do While Not rs.EOF
strSQL = "SELECT [Name], Gender FROM Masterfiles WHERE [Name] Like '%" & Me!txtName & "%'"
Set rs2 = db.OpenRecordset(strSQL)
If rs2.RecordCount > 0 Then
rs!Gender = rs2!Gender
End If
Loop
But this code will not get any result because some of the value of Name field in table1 has a period in the middle initial while other row has no period. Please refer to the sample data above. The middle initial of "Smith, John" has period while "Canard, Donald" has no period.
So how can I query Masterfiles and get the value of Gender field and put it in table1 gender field?

strSQL = "SELECT [Name], Gender FROM Masterfiles WHERE [Name] Like '%" & replace(Me!txtName,".","") & "%'"

You have the name in VB; it is best just to use VB to remove any . from the end of the name before searching:
Dim searchName as String
If Me!txtName.Substring(Me!txtName.Length - 1,1) = '.' Then
searchName = Me!txtName.Substring(0,Me!txtName.Length - 1)
Else
searchName = Me!txtName
End If
strSQL = "SELECT [Name] FROM Masterfiles WHERE [Name] Like '%" & searchName & "%'"
However, in the long term you should probably fix your design:
Give each person a numeric ID that is the same in all tables.
Split the name into first, middle, and last fields.
Use a single table to store all information that is unique to the person. Then link it to other tables using the ID.

Related

sql where statement with range: how to separate by a comma

I'm new to VBA and I'm trying to pull info from a range of cells that will be plugged into the "where" clause of a sql statement. Since it is a where clause, I need to separate the variables with a comma. For example, my code is:
Sub loop()
AB=2
BC=9
Set IDX = Sheets("Sheet2).Cells(AB,BC)
Dim cn as ADODB.Connection
Dim rs as ADODB.Recordset
cn.ConnectionString=PORRI;Trusted_Connection=Yes;APP=Microsoft Office 2010; DATABASE=LKMJ_intm"
cn.open
set rs= New ADODB.Recordset
rs.ActiveConnection=cn
rs.OPEN "SELECT DATE, ID, NAME, INFO FROM xxx WHERE ID in ('"& IDX &")"
r=1
Do While Not rs.EOF
Cells (r,1) = rs.Fields(0)
Cells (r,2) = rs.Fields(1)
Cells (r,3) = rs.Fields(2)
Cells (r,4) = rs.Fields(3)
Cells (r,5) = rs.Fields(4)
r=r+1
Loop
End Sub
Right now, I can't create a range that will work in the where statement without the comma.
Thanks!
Assuming this piece of code works per one id:
rs.OPEN "SELECT DATE, ID, NAME, INFO FROM xxx WHERE ID in ('"& IDX &")"
What you wish to do is make sure that IDX would be translated to a list of codes, for example (1,2,3) or ('a', 'b', 'c').
If the list of codes is a list of integers I highly recommend getting the list of codes like this
rs.OPEN "SELECT DATE, ID, NAME, INFO FROM xxx WHERE ID in ('"& IDX &"," & IDB & ")"
(whatever IDB is)
and if it's a list of strings and you need to put them inside single quotes parameters:
rs.OPEN "SELECT DATE, ID, NAME, INFO FROM xxx WHERE ID in ('"& IDX &"','" & IDB & "')"
This is all very confusing with the quotes and single quotes! Luckily the editor here is smart enough to tell me when I got the code wrong :)

Concatenating field data into string via Access SQL

Imagine the following table
ID | Name
----------
1 | Shaun
1 | Terrence
2 | Jessica
I need to concatenate the string data in Name based on ID
ID | Name
-----------
1 | Shaun, Terrence
2 | Jessica
I am using an access database. I was thinking I could do a pivot transform and try to concatenate those fields but the problem is its hard to dynamically loop through the total field count. Any ideas?
**Edit: Order does not matter, I just want to concatenate based on ID with , and space being the delimiter. I am calling this sql code using an ADO connection from excel vba.
This is a similar problem I had recently trying to pivot a two column table; MS Access convert and summarise two rows into columns with unique names
'Name' is a reserved word and 'ID' is usually a auto-index with unique numbers so I changed your columns to UserID and UserName respectively.
There are some problems with creating the answer in a single subquery so I ended up doing this:
Create a temporary table with an index:
SELECT t1.UserID, t1.UserName,
(SELECT COUNT(*) + 1
FROM Table1 t2
WHERE t1.UserID = t2.UserID and t2.UserName < t1.UserName) AS [Index]
INTO Table1_indexed
FROM Table1 AS t1;
create a temporary cross tab table:
TRANSFORM First(Table1_indexed.UserName) AS FirstOfUserName
SELECT Table1_indexed.UserID FROM Table1_indexed
GROUP BY Table1_indexed.UserID
PIVOT Table1_indexed.Index;
concatenate the name fields
SELECT Table1_crosstab.UserID, Table1_crosstab.[1], Table1_crosstab.[2],
IIf([1] Is Not Null,[1]) & IIf([2] Is Not Null,", " & [2]) AS ConcatenatedName
FROM Table1_crosstab;
If you have more than two name fields you could adjust the concatenate query to the maximum number you expect.
It might be possible to merge these steps into a single query but I've not yet found a way.
You can create a Visual Basic Function and call it from your query, e.g. something like this (assuming your table is called Names):
Public Function ListOfNames(id as Integer) As String
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("Select Name from Names where ID=" & id, DbOpenSnapshot)
ListOfNames = ""
If Not (rs.EOF and rs.BOF) Then
rs.MoveFirst
Do Until rs.EOF = True
If (Len(ListOfNames) > 0) Then
ListOfNames = ListOfNames & “, “
End If
ListOfNames = ListOfNames & rs!Name
rs.MoveNext
Loop
End If
rs.Close
End Function
Then you can for instance call the function from your query:
SELECT ID, ListOfNames([ID]) as Name From Names Group By ID

Prepopulating Access Form

I have a form that we use for data entry, to make it easier I would like to have some of the fields prepopulate based on the EmployeeID field, for example once I put in my employee id then the EmployeeName field would be Auto populate with John Doe, and Gender would be Male and EEOC would be White, etc. Is this at all possible to do? It would be based of the data in another table title EmpData.
In the AfterUpdate event of EmployeeID, you could put something like (untested code, so it needs to be tweaked a bit):
Dim db as DAO.Database
Dim rec as DAO.Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("Select * from EmpData where EmployeeID = " & Me.EmployeeID & "")
Me.EmployeeName = rec("EmployeeName")
Me.Gender = rec("Gender")
Me.EEOC = rec("EEOC")
etc...
Set rec = Nothing
Set db = Nothing
If EmployeeID is a Text field, it will need to be surrounded by single quotes in the "Set rec" line. Like this:
Set rec = db.OpenRecordset("Select * from EmpData where EmployeeID = '" & Me.EmployeeID & "'")
If you create a query that joins the two tables, then Access will do it all for you automatically. Then you should use that query as the DataSource for the form.
SELECT MyDataTable.*, EmpData.*
FROM MyDataTable LEFT JOIN EmpData
ON MyDataTable.EmployeeID = EmpData.EmployeeID;
Doing this, you might want to lock the columns coming from EmpData from being possible to edit.
In your form, you show the fields from the MyDataTable and the relevant fields from EmpData. Any fields in MyDataTable that should be filled in from EmpData should not be shown to the user.
I.e. you show the EmployeeName from EmpData and not from MyTableData.
In the AfterUpdate event on EmployeeID you copy the data from EmpData to MyTableData
Me.RecordSet!MyTableData.EmployeeName = Me.RecordSet!EmpData.EmployeeName

GUI using VBA in access. Recordset from query

Making GUI in Access with VBA (first time i saw it in this semester and it looks unusual for me). I got table Authors where i got columns author_id, last_name, first_name and table Books with columns author_id, book_name.
I got button on Form which on click should ask user to input author last name and then search and show all books of this author.
So I trying to find author id from Authors table and then from Books table show all books where author.author_id is equal to books.author_id.
I was thinking that i need to create temp query which contained author_id value and after that create record set with this query using SQLquery like "SELECT [Books].[book_name] AS [Bookname] FROM [Books] WHERE [Books].[author_id] = [test].[ID]" But i stucked here - I trying to just check if this thing working but it says there is an error 3061
Private Sub authorlist_Click()
Dim dbs As Database, authorsRS, booksRS As Recordset, queryStr, idbynameQuery, srchASurStr, strOutput, srId As String, qdf As QueryDef
Set dbs = CurrentDb()
srchASurStr = InputBox("Input author surname, please", , , 100, 100)
strQuery = "SELECT [Authors].[author_id] AS [ID] FROM [Authors] WHERE [Authors].[last_name] = " & srchASurStr & ""
Set authorsRS = dbs.OpenRecordset(strQuery, dbOpenSnapshot)
With dbs
Set qdf = .CreateQueryDef("test", strQuery)
DoCmd.OpenQuery "test"
.QueryDefs.Delete "test"
End With
End Sub
So could you help me please to understan what's wrong? And is there maybe more simple way to show all books of some author (maybe without using SQL querys)?
String values in an SQL statement need to be surrounded with single-quotes (') or double-quotes ("):
SELECT author_id FROM authors WHERE last_name = "Smith"
If written without the quotes:
SELECT author_id FROM authors WHERE last_name = Smith
Smith will be understood to be a field name and not a string value. So your code should look something like this:
'Chr returns a string from a character code. 34 is the code for "
strQuery = "SELECT author_id FROM authors WHERE last_name = " & Chr(34) & srchASurStr & Chr(34)
In VBA, you can escape double-quotes with a string by doubling them:
strQuery = "SELECT author_id FROM authors WHERE last_name = """ & srchASurStr & """"
SQL injection: Keep in mind that if the user inputs a string with " in it, there will probably be an error, as the resulting SQL statement has invalid syntax:
SELECT author_id FROM authors WHERE last_name = "Smi"th"
The right way to avoid this problem is to use parameters.
Some notes:
You can reference a form control within a query: [Forms]![FormName]![ControlName]. Thus, you can create a saved query that filters based on a form textbox, instead of using an inputbox.
Consider using a combobox to have the user select from a list, instead of having the user type free text. The combobox can have multiple columns, with the value of the combobox being the first column (author_id) and the displayed value being another expression (last_name or last_name & " " & first_name). If you set the ColumnWidths property to 0 (for the first column), the next column will be displayed
If you prefer to use a textbox, consider using the LIKE operator in your query, to display all authors whose last_name contains the user string:
SELECT author_id FROM authors WHERE last_name LIKE "%sm%"
will return Smith, Smythe, and Asmodeus.
I suggest you set up a form and subform. The form can contain author details and the subform can contain books by that author, you can further add a textbox that the user can fill in with part of the author name. You can then apply a filter to the main form to show all the authors with that name.
Me.Filter = "Author Like '*" & Me.Search & "*'"
Me.FilterOn = True
There are a number of variations on this, the user could select names from a combo or listbox. The form could be a continuous form with a filter / search in the header and so on.

MS access SELECT INTO in vba

I'm having some issues with some functionality of my application. There is a particular instance where I have an instance of a 'pending class' on a form for an administrator to review. The form is populated with students associated with this pending class. After their grades are finished, I have a button at the footer that will delete this class from my 'pending' table and add the grades to all of the students. This works.
However, I want to essentially copy this pending class, which just has the class name, date, and teacher to a completed class table before it's deleted from pending. Since no data about this class other than the primary key(class number) persists throughout this form, I can't populate the other fields(class name, date) of the row into my completed class table.
I am trying a "SELECT INTO" operation in VBA to get these values. It's going like this:
dim cname as String
dim classdate as Date
dim pid as integer
dim teacher as String
dim qry as String
pid = [Forms]![frmClasses]![txtID]
qry = "Select className INTO cname FROM tblPending WHERE tblPending.id = " & " ' " & pid & " ' " & ";"
db.execute qry
debug.print qry
debug.print cname
From here, I do the same operations for each other variable, build my INSERT query, and execute it. The problem is-- my select into's are not working. Debug.print shows that the local variables were never initialized from the SELECT INTO statement. Any thoughts?
First, having all classes in one table and just setting a "NotPending" or "Completed" column would be better.
Having two identical tables for classes and moving values from one into the other to indicate status changes is bad database design.
If you really need to do this by using two tables and copying rows, then you need an INSERT INTO query (and not SELECT INTO), as already mentioned by Remou in the comments, because SELECT INTO creates a new table (or overwrites an existing one with the same name, if already there).
The syntax for INSERT INTO looks like this:
INSERT INTO CompletedClassTable (ClassName, Teacher)
SELECT ClassName, Teacher FROM tblPending WHERE id = 123
And finally, you asked this in a comment:
So SELECT INTO is completely different in Access than Oracle? In Oracle and PL/SQL, you can select a row into a variable OR a table. In Access can you not select into a variable?
To load a row into a variable, you need to use a Recordset.
Example code to load your query into a Recordset and output the ClassName field:
Dim RS As DAO.Recordset
Set RS = CurrentDb.OpenRecordset("SELECT * FROM tblPending WHERE id = 123")
If Not RS.EOF Then
Debug.Print RS("classname")
End If
RS.Close
Set RS = Nothing
Seems you want to retrieve a text value, className, from tblPending where tblPending.id matches the value found in your text box, txtID, and store that text value in a string variable named cname.
If that interpretation is correct, you needn't bother with a query and recordset. Just use the DLookup Function to retrieve the value, similar to this untested code sample.
Dim cname As String
Dim pid As Integer
Dim strCriteria As String
pid = [Forms]![frmClasses]![txtID]
strCriteria = "id = " & pid
cname = Nz(DLookup("className", "tblPending", strCriteria), vbNullString)
Debug.Print "cname: '" & cname & "'"
Notes:
I assumed the data type of the id field in tblPending is numeric. If it is actually text data type, change strCriteria like this:
strCriteria = "id = '" & pid & "'"
DLookup() returns Null if no match found. Since we are assigning the function's return value to a string variable, I used Nz() to convert Null to an empty string. Alternatively, you could declare cname As Variant (so that it can accept a Null value) and get rid of Nz().