ACCESS VBA Unmatched Records Query Not Working When Concatenating - vba

I have been trying to run a query from MS ACCESS VBA. My query works well when I don't add concatenated fields. When I use a concatenated field like in the code below, it turns an empty result.
Is there any work around?
lstStudentName.RowSource = "SELECT [sdtName] & ' ' & [sdtFatherName] & ' ' & [sdtLastName] AS sdtFullName, sdtID FROM tbl_sdt_Info " & _
" LEFT join tbl_sdt_Rounds ON tbl_sdt_Info.sdtID = tbl_sdt_Rounds.sdtID " & _
" WHERE IS NULL(tbl_sdt_Rounds.sdtID)"

Issues with your SQL:
Incorrect use of IS NULL - should be either IsNull(tbl_sdt_Rounds.sdtID) or tbl_sdt_Rounds.sdtID IS NULL. The latter is preferable because it is SQL, IsNull() is a VBA function.
Since there are two sdtID fields, query shouldn't work without table prefix to specify field. I am surprised you get anything.
Although possibly not an issue as is, my preference would be to make sdtID the first field and set ColumnWidths as 0";1.0" and first column as BoundColumn. This will allow viewing and typing first letter of name but sdtID will be listbox value.
Never hurts to build and test query object and when it works, replicate SQL statement in VBA.
lstStudentName.RowSource = "SELECT tbl_sdt_Info.sdtID, sdtName & ' ' & sdtFatherName & ' ' & sdtLastName AS sdtFullName FROM tbl_sdt_Info " & _
"LEFT join tbl_sdt_Rounds ON tbl_sdt_Info.sdtID = tbl_sdt_Rounds.sdtID " & _
"WHERE tbl_sdt_Rounds.sdtID IS NULL;"

Related

Retrieve Data from SQL with input from table

I have a table in excel, with range : Sheets("Sheet1").Range("d4:d215"). These data are similar to PS.WELL in the server.
From that table, I want to retrieve data using this code (other SQL requisite has been loaded, this is the main code only):
strquery = "SELECT PS.WELL, PS.TYPE, PS.TOPSND " & _
"FROM ISYS.PS PS " & _
"WHERE PS.WELL = '" & Sheets("Sheet1").Range("D4:D215") "' AND (PS.TYPE = 'O' OR PS.TYPE = 'O_' OR PS.TYPE = 'GOW') " & _
"ORDER BY PS.WELL"
Unfortunately it didn't work. Can anyone help me how to write the code especially in the 'where' section?
You have to iterate through each item in the range and concatenate the results to a string variable so the contents look like this
'val1','val2','val3'
Then you have to adjust your query code to use the IN operator instead of equals operator. Let's say the string is concatenated to a variable called myrange.
"WHERE PS.WELL IN (" & myrange & ") AND ...
I have solved the problem. The key is to make 2 function of SQL:
to read and write each input
to count number of output per input (an input can have 0, 1, or more output).
then, just call using procedure

SQL Server Join Tables By Combining 2 Columns

This sounds ridiculously easy but I've tried so many different approaches. This query is just set up weird and I'm trying to JOIN it but there's not a common column I can do that with. There is, however, a LastFirst column (consists of LastName then FirstName) written in the context of DOE, JOHN. Then on the columns I'm trying to join that with it's just FirstName (John) and LastName (Doe).
I'm actually trying to select data from 4 tables that all are returning 1 row. These 2 tables can be joined:
SELECT
RIFQuery.*,
_Employee.EmployeeLastName + ', ' + _Employee.EmployeeFirstName AS EmployeeLastFirst,
_Employee.EmployeeTitle, _Employee.Phone As EmployeePhone,
_Employee.EmailAddress As EmployeeEmailAddress
FROM
RIFQuery
INNER JOIN
_Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE
RIFQuery.Autonumber = 1
This one has nothing to join with so I'll probably union it and null remaining columns:
SELECT *
FROM tblOrganization
This is the table that contains LastName and FirstName that I'm trying to join with RIFQuery.LastFirst:
SELECT
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM
_Clients
WHERE
_Clients.LASTNAME = left(RIFQuery.LastFirst, len(RIFQuery.LastFirst)-CHARINDEX(',', REVERSE(RIFQuery.LastFirst)))
AND _Clients.FIRSTNAME = ltrim(substring(RIFQuery.LastFirst, len(RIFQuery.LastFirst)-CHARINDEX(',', REVERSE(RIFQuery.LastFirst))+2, len(RIFQuery.LastFirst)))
In that WHERE statement the code will split the LastFirst column and get the row by searching their LastName and FirstName. I'm wondering if there's a way I can write that into a JOIN? Otherwise I can probably UNION and null remaining columns but it will look very ugly.
UPDATE
I tried 2 suggestions from here and both result in a syntax error. I forgot to mention that I'm executing this code inside Microsoft Access VBA and trying to retrieve a DAO.RecordSet. I had to remove some table names in the SELECT statement to get past a syntax error from there, so maybe I should update the question to reflect MS ACCESS and not SQL Server, although only the query is the only pure Access object and the rest are linked ODBC tables to SQL Server.
UPDATE
Just one of those issues where I can't sleep until it's fixed and will obsess until it is. If I take out all _Employee references (from SELECT and JOIN statements), it wants to work but errors about too few parameters. I just now know this is related to _Employee. Getting different results from applying parentheses and just hoping I'll get lucky and hit on it.
The error is caused by this line:
INNER JOIN [_Employee] ON [_Employee].[AutoNumber] = [RIFQuery].[CreatedBy]
I get this error:
"Syntax error (missing operator) in query expression".
As seen in this screenshot:
Here's my latest query I'm playing with, minus the parentheses:
str = "SELECT [RIFQuery].*, " & vbCrLf & _
" ([_Employee].[EmployeeLastName] & ', ' & [_Employee].[EmployeeFirstName]) AS [EmployeeLastFirst], " & vbCrLf & _
" [_Employee].[EmployeeTitle], " & vbCrLf & _
" [_Employee].[Phone] AS [EmployeePhone], " & vbCrLf & _
" [_Employee].[EmailAddress] AS [EmployeeEmailAddress], " & vbCrLf & _
" [_Clients].[Gender] AS [ClientGender], " & vbCrLf & _
" [_Clients].[DOB] AS [ClientDOB], " & vbCrLf & _
" [_Clients].[SSN] AS [ClientSSN] " & vbCrLf & _
"FROM [_Clients] " & vbCrLf & _
" INNER JOIN [RIFQuery] ON [RIFQuery].[LastFirst] = [_Clients].[LASTNAME] & ', ' & [_Clients].[FIRSTNAME] " & vbCrLf & _
" INNER JOIN [_Employee] ON [_Employee].[AutoNumber] = [RIFQuery].[CreatedBy] " & vbCrLf & _
"WHERE [RIFQuery].[Autonumber] = 1;"
For debugging purposes, if I remove those last 2 lines and the _Employee SELECT statements, it'll process the query without a problem. If anyone has any ideas just let me know.
I was focused on that RIFQuery JOIN statement being the culprit for the longest time but I've found that simply is not the issue any more. With that said, this thread has been essentially solved and I appreciate the help.
MS Access is using a slightly different syntax than SQL Server when it comes to using more than one JOIN. You could leave out the JOIN with the _Clients (making it a cross join) and move that condition to the WHERE clause, which would make the query look like this (and which would allow you to display the design window for the query without any problem)
SELECT RIFQuery.*,
EmployeeLastName + ', ' + EmployeeFirstName As EmployeeLastFirst,
EmployeeTitle, Phone As EmployeePhone, EmailAddress As EmployeeEmailAddress,
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM _Clients, RIFQuery INNER JOIN _Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE RIFQuery.LastFirst = _Clients.LASTNAME & ", " & _Clients.FIRSTNAME;
Instead of assembling the query string in VBA just for being able to change the parameter value, I suggest to save the following query as an Access object (maybe qryRIF):
PARAMETERS lgRIF Long;
SELECT RIFQuery.*,
EmployeeLastName + ', ' + EmployeeFirstName As EmployeeLastFirst,
EmployeeTitle, Phone As EmployeePhone, EmailAddress As EmployeeEmailAddress,
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM _Clients, RIFQuery INNER JOIN _Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE RIFQuery.LastFirst = _Clients.LASTNAME & ", " & _Clients.FIRSTNAME
AND RIFQuery.Autonumber = [lgRIF];
In your VBA code, you can use code like the following to grab the QueryDef object, assign the parameter value and open a recordset:
With CurrentDb.QueryDefs!qryRIF
!lgRIF = lgRIF
With .OpenRecordset()
' ... your code ...
.Close
End With
.Close
End With

Searching a table where the field doesnt exist - Access VBA

I am a data consultant who migrates data I am sent into our system. I have written code that compares the contents of my table against what has been put into oracle, as an extra test. The tables are a little convoluted due to how they relate to each other. But essentially here is my question:
When I look to match two field values and the field doesnt exist I get a parameter pop up box. I want to only run the code if the field exists.
I have tried many things, wrapping an if statement around it but I always get the parameter box, can anyone help there must be an easier way to do this!
If Not DoCmd.OpenQuery("SELECT TOP 1" & MatchValues!FieldName & " FROM " &
MatchValues!ORACLE_TABLE_NAME) Then
MsgBox "moomins"
' strSQL = "INSERT INTO 002_TableValueErrors(ORACLE_TABLE_NAME,TRANSFORM_TABLE_NAME,FIELD_NAME,ORACLE_FIELD_VALUE,TRANSFORM_FIELD_VALUE) "
' strSQL = strSQL & " VALUES (" & MatchValues!ORACLE_TABLE_NAME & "," & MatchValues!TRANSFORM_TABLE_NAME & "," & MatchValues!FieldName & ",'ORACLE: NOT FOUND','ORACLE: NOT FOUND')"
End If
If you deal with Oracle: Have you tried to check if the field exists by querying ALL_TAB_COLUMNS in Oracle?
"Select count(*) from ALL_TAB_COLUMNS where table_name = " & MatchValues!ORACLE_TABLE_NAME & " and COLUMN_NAME = " & MatchValues!FieldName
(Untestet cause currently I have no Oracle Instance available)

Get VBA to Evaluate Formula In String

I have a table that stores a string representing a formula that I would like to have either Access or VBA evaluate. A few example strings look like:
table.FirstName & ' ' & table.LastName
table.LastName & ', ' & table.FirstName
table.LastName & ', ' & table.FirstName & ' ' & LEFT(table.Middle,1)
Basically, I'm trying to change how different names can be viewed based on entity type, missing information, etc.
Is there any way to force either Access (in a query) or VBA (as part of a custom function) to return what the string is telling it as opposed to the literal value? From the examples above, I would expect:
table.FirstName table.LastName
table.LastName, table.FirstName
table.LastName, table.Firstname, t
Replace by itself won't work, as some of the formatting includes LEFT(table.Name,1) or other functions. I'm just hoping there is a simple way to force the string to be evaluated, rather than having to come up with a complex function.
I apologize if I haven't explained this well, I feel like my attempt to merge the database aspect with the string formatting aspect may not come across clearly. If you have questions please reply and I'll do my best to explain it better.
Thank you in advance.
How about the Microsoft Access Eval() function:
?Eval("3 + 1")
4
You could build an SQL string from your table formulas like:
SQL = "Select " & tblFormulas.FormulaField.Value & " From " & Split(tblFormulas.FormulaField.Value, ".")(0) & ";"
Not bullet-proof but a start ...
As you have a special table with formulas you can aim at queries and/or VBA.
For VBA you can store code for eval function to be run in form of several forms with same set of required fields(that is used in formulas):
in field VBAformula of your special table should resides such string me![LastName] & ', ' & me!FirstName & ' ' & LEFT(Me![Middle],1)
then in some function you could write:
formula = dlookup("VBAformula","SpecialTable","id=" & me![HowToViewID])
Me![ViewAs] = eval(formula)
For Queries you can store SQL formula to be used in UPDATE query, SQLformula with such string:
[LastName] & ", " & [FirstName] & " " & LEFT([Middle],1) then you can build and run SQL:
formula = dlookup("SQLformula","SpecialTable","id=" & me![HowToViewID])
currentdb.Execute "UPDATE [table with people] SET [ViewAs] = " & formula & " WHERE peopleID=" & Me![peopleID] & ";" , dbFailOnError
These are examples to show some variants, so there is no error handling or security.

SQL Access VBA UPDATE table with another table? Too Few Parameters

I am looking to update one of my tables with another table depending on a field condition. I am wondering what the correct way to do this is. I tried to do UPDATE statements with the 2 tables, but everytime it came out with this error: Too few Parameters, Expected 2
My goal:
If SOURCING field = O, I want Zip Code to be Origin Postal Code
If SOURCING field = D, I want Zip Code to be Dest Postal Code
So as of right now, I am simply doing a LEFT JOIN with a condition. Is this the best way to do it? Or should I have done this with the original INSERT statement somehow?
CurrentDb.Execute "UPDATE Processing" & _
" LEFT JOIN tblImport" & _
" ON Processing.[BATCH_NO] = tblImport.[BATCH_NO]" & _
" SET Processing.[Zip Code] = tblImport.[Origin Postal Code]" & _
" WHERE tblImport.[Sourcing] = O;"
CurrentDb.Execute "UPDATE Processing" & _
" LEFT JOIN tblImport" & _
" ON Processing.[BATCH_NO] = tblImport.[BATCH_NO]" & _
" SET Processing.[Zip Code] = tblImport.[Dest Postal Code]" & _
" WHERE tblImport.[Sourcing] = D;"
I have tried changing the WHERE statement since I am not sure if it should be in quotes, single quotes, not in quotes, etc... but I have come up empty there. Everything else looks correct to me.
Here's what I do, you might find this helpful; Set a variable equal to your SQL string, then CurrentDB.Execute the variable. Why is this helpful? Because you can break the code after the variable is set, and then copy the SQL into a new query and see what it's complaining about. :o)
Dim tmpUpdate as string
tmpUpdate = "UPDATE Processing" & _
" LEFT JOIN tblImport" & _
" ON Processing.[BATCH_NO] = tblImport.[BATCH_NO]" & _
" SET Processing.[Zip Code] = tblImport.[Origin Postal Code]" & _
" WHERE tblImport.[Sourcing] = O;"
CurrentDB.Execute tmpUpdate
Set a breakpoint on the "tmpUpdate =" line, and then run the code. When it hits the breakpoint, press F8 to step to the next line. In the Immediate window, type "?tmpUpdate" (without the quotes) and see what it thinks the variable is equal to. Then, go to the database, create a new query and go to the SQL of the query. Copy and paste the SQL from the Immediate window and try running the query. If it pukes, go to the Design view and see if you can see anything that doesn't look right.