Inner Join Excel recordset with Access recordset - sql

Is it possible to make an inner join between an excel spreadsheet and and access database table?
I tried many ways to make this possible but with no success.
This is my Visual Basic 6 code:
Dim DbTemp As Database
Dim ExcelDB As Database
DIm xlsRs As Recordset
Set DbTemp = OpenDatabase(App.Path + "\mydb.mdb")
Set ExcelDB = OpenDatabase(App.path + "\QueryExcelDATA.xls", False, True, "Excel 8.0;")
Set xlsRS = ExcelDB.OpenRecordset(query, dbOpenDynaset) ' query is a sql query I used to get some other results
Do Until xlsRs.EOF
Workspaces(0).BeginTrans
sql = "INSERT INTO Presenze(Enterprise, Emp_ID, mYear, mMonth, mDay, WorkHours) " _
& " SELECT Presenze.Emp_ID, '"+xlsRs("Entps")+"', '" + xlsRs("Yr") + "', '" + " _
& " xlsRs("Mnth") + "', '" + xlsRs("Dy") + "', '" + xlsRs("WH") + `"' " _
& " FROM [ExcelDATA$] INNER JOIN Presenze On [ExcelDATA$].[CardID] = Presenze.CardID"
DbTemp.Execute sql
Workspaces(0).CommitTrans
xlsRS.MoveNext
Loop
I want to get the data from [ExcelData$] spreadsheet and insert them to access Table "Presenze"
Can anyone help me?

The only realistic way to do this is to create an import table in your access DB and copy the data from Excel into it then join to this table. That way you don't have to recreate the join everytime the data in Excel changes.

Related

Access table and excel sheet join

I have to append latest access record to an excel sheet with headers from access table where a column in excel sheet(LAN) matches column (LAN) in access table. This is my code so far:
qry = "Select (Select Call_Date from Tel_List Where t.LAN=Tel_List.LAN And Ctrl=(Select Max(Ctrl) From Tel_List Where t.LAN=Tel_List.LAN)) From [Excel 12.0;HDR=Yes;Database=C:\Boda Boda Banja Ltd\Modules\Prototypes\UG RFIN UI 1.0.xlsm].[TEL_List$]t Inner Join Tel_List on t.LAN=Tel_List.LAN Where Ctrl=(Select Max(Ctrl) From Tel_List Where t.LAN=Tel_List.LAN)"
The code returns values but is not appended against the relevant rows. Below is the screen shot after retrieving previous call date from access table.
Is there a way to append the data against the relevant rows?
Try
Const WORKBOOK = "C:\Boda Boda Banja Ltd\Modules\Prototypes\UG RFIN UI 1.0.xlsm"
Const SQL = "SELECT e.LAN, Max(a.Call_Date) " & _
"FROM Tel_List AS a " & _
"INNER JOIN [Excel 12.0;HDR=Yes;Database=" & WORKBOOK & "].[TEL_List$] AS e " & _
"ON a.LAN = e.LAN " & _
"GROUP BY e.LAN;"

VB 6 application throwing error The server principal (username) unable to access the database production under the current security context

I am working with a legacy application that was written in vb 6. In the code there is an embedded sql query. I am trying to make a left join on another database. using the following select statement:
SQL = "select h.case_ref, t.t5_desc, h.narisno, h.valuation_ref, h.claimant, h.t5," & _
" h.claim_amount, h.claim_date , h.dateofentry, h.case_completed, l.project_short_name AS narisno_desc, h.case_type "
If blnFromCaseRefSelection = True Then
SQL = SQL & " from case_header h left join lut_t5 t on h.t5 = t.t5 left join" & _
" [production].[dbo].[xxx_01_project_attributes] l on h.nno = l.pin where h.case_ref = '" & cboCaseRef.Text & "'"
Else
SQL = SQL & " from lut_fileref f, case_header h left join lut_t5 t on h.t5 = t.t5" & _
" left join lut_nno n on h.nno = n.nno Where h.case_ref = f.case_ref" & _
" and f.ha_fileref = '" & xxoHAFileRef.Text & "'"
End If
error : The server principal (username) unable to access the database
production under the current security context
Any idea of how ui can solve this, my experience with VB 6 is basic

SQL for INSERT from SELECT with additional values

I'm not sure if this is possible but I'm trying the run the following SQL from a VBA application in ACCESS DB. I'd like to INSERT a record into 'outputTable' with most of the data coming from a record in 'stagingTable'. However, two fields need to come from a form and I cannot figure out how to include those values into the INSERT statement.
sql = "INSERT INTO " & outputTable ([Date],[Carrier],[Division],[Code],[Status],[Total])
SELECT [Division],[Code],[Status],Sum([Claim]) AS [SumOfClaim]
FROM " & stagingTable & "
GROUP BY [Division],[Code],[Status];"
On the outputTable, the [Date] and [Carrier] values are missing. These would come from user input on a form. Is there a way I could add these values into to SQL statement?
Thank you
The best solution is to create a parameterized query as shown here: https://stackoverflow.com/a/2317225/3820271
It would e.g. look like this:
Dim DB As Database
Dim QD As QueryDef
Dim S As String
Set DB = CurrentDb
S = "PARAMETERS parDate DateTime, parCarrier Text(255); " & _
"INSERT INTO " & outputTable & "([Date], [Carrier], [Division], [Code], [Status], [Total]) " & _
" SELECT [parDate], [parCarrier], [Division],[Code],[Status],Sum([Claim]) AS [SumOfClaim] " & _
" FROM " & stagingTable & _
" GROUP BY [Division],[Code],[Status];"
' Create a temporary query object
Set QD = DB.CreateQueryDef("", S)
' Set parameter values from your input form
QD.Parameters!parDate = Forms!myForm!myDateField
QD.Parameters!parCarrier = Forms!myForm!Carrier
' Run the query
QD.Execute
Set QD = Nothing

Issues with SQL Query

as may be quiet aparent, i have very little experience with SQL queries.
I'm having problems with the following Query that i'm generating within my Vb.net application
UPDATE Payments SET B1Code = '12345', ARInvoice = '54321', INV2Go = '00000' WHERE PatientID = '400' AND Product = 'Consultation' AND Catagory = 'Orthotics'
(i have created a test record in the database matching the above information)
Its being constructed with the following code in vb.net:
Dim query As String = "UPDATE Payments SET B1Code = '" & txtB1Code.Text & "', ARInvoice = '" & txtARInvoice.Text & "', INV2Go = '" & txtInv2GoCode.Text & "' WHERE PatientID = '" & Integer.Parse(txtID.Text) & "' AND Product = '" & txtProduct.Text & "' AND Catagory = '" & txtPatientType.Text & "'"
Then being passed the my execute query function like this:
DatabaseFunctions.ExecuteQuery(query)
and the function:
Public Shared Sub ExecuteQuery(ByVal SQL As String)
CheckConnection()
Dim cmd As New OdbcCommand(SQL, con)
cmd.ExecuteNonQuery()
End Sub
The function works perfectly, i've used it time and time again for creating/editing records using simple sql queries built in similar ways as above.. The problem is this particular query returns an error:
ERROR [07002ض] [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 1.
Maybe someone with more sql experience than me can see what i'm missing ?
Thanks
This error indicates, that one of the columsn you use in your query does not exist.
Check your query again: did you mean Catagory OR Category ?

VBA string length problem

I have an Access application where everytime a user enters the application, it makes a temp table for that user called 'their windows login name'_Temp. In one of my reports I need to query using that table, and I can't just make a query and set it as the recourdsource of the report, since the name of the table is always different.
What I tried then was to programatically set the recordset of the report by running the query and setting the form's recordset as the query's recordset. When I tried this, it kept giving me an error about the query.
I tried to debug, and I found that the string variable isn't able to contain the whole query at once. When I ran it with break points and added a watch for the string variable, it shows me that it cuts off the query somewhere in the middle.
I've experienced this problem before, but that was with an UPDATE query. Then, I just split it into two queries and ran both of them separately. This one is a SELECT query, and there's no way I can split it. Please help!
Thank you
Heres what I've tried doing:
ReturnUserName is a function in a module that returns just the login id of the user
Private Sub Report_Open(Cancel As Integer)
Dim strQuery As String
Dim user As String
user = ReturnUserName
strQuery = "SELECT " & user & "_Temp.EmpNumber, [FName] & ' ' & [LName] AS [Employee Name], " & _
"CourseName, DateCompleted, tblEmp_SuperAdmin.[Cost Centre] " & _
"FROM (tblCourse INNER JOIN (" & user & "_Temp INNER JOIN tblEmpCourses ON " & _
user & "_Temp.EmpNumber = EmpNo) ON tblCourse.CourseID = tblEmpCourses.CourseID) " & _
"INNER JOIN tblEmp_SuperAdmin ON " & user & "_Temp.EmpNumber = tblEmp_SuperAdmin.EmpNumber" & _
"WHERE (((" & user & "_Temp.EmpNumber) = [Forms]![Reports]![txtEmpID].[Text])) " & _
"ORDER BY CourseName;"
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Dim rsCmd As ADODB.Command
Set rsCmd = New ADODB.Command
rsCmd.ActiveConnection = CurrentProject.Connection
rsCmd.CommandText = strQuery
rs.Open rsCmd
Me.Recordset = rs
rs.Close
End Sub
This what strQuery contains when I add a breakpoint on rsCmd.CommandText = strQuery:
SELECT myusername_Temp.EmpNumber, [FName]
& ' ' & [LName] AS [Employee Name],
CourseName, DateCompleted,
tblEmp_SuperAdmin.[Cost Centre] FROM
(tblCourse INNER JOIN (myusername_Temp
INNER JOIN tblEmpCourses ON
myusername_Temp.EmpNumber = EmpNo) ON
tblCourse.CourseID=
(It's all one line, but I've written it like this because the underscores italicize the text)
And the error I get says Run Time Error: Join not Supported.
Not quite what I was hoping for, but guessing, for:
strQuery = "long query goes here"
Try:
strQuery = "some long query goes here "
strQuery = strQuery & "more query goes here "
BASED ON NEW INFORMATION:
strQuery = "SELECT " & user & "_Temp.EmpNumber, [FName] & ' ' & [LName] AS [Employee Name], " & _
"CourseName, DateCompleted, tblEmp_SuperAdmin.[Cost Centre] " & _
"FROM (tblCourse " & _
"INNER JOIN tblEmpCourses ON tblCourse.CourseID = tblEmpCourses.CourseID) " & _
"INNER JOIN (Temp INNER JOIN tblEmp_SuperAdmin " & _
"ON Temp.EmpNumber = tblEmp_SuperAdmin.EmpNumber) " & _
"ON Temp.EmpNumber = tblEmpCourses.EmpNo " & _
"WHERE " & user & "_Temp.EmpNumber = " & [Forms]![Reports]![txtEmpID] & _
" ORDER BY CourseName;"
Note that in VBA:
& [Forms]![Reports]![txtEmpID].[Text] &
That is, the reference to the form must go outside the quotes so you get the value.
NEW INFORMATION #2
Your best bet would be to add these tables to the Access query design window and create the joins that you want, then switch to SQL view and use the string generated for you. I do not believe that the string is too long, only that the SQL is incorrect. The SQL I posted above should work, but it may not be what you want.
You can programmatically create a querydef that fits the user. So, when your report is called, you
Delete LoginName_Query_Temp (CurrentDb.QueryDefs.Delete), if it already exists.
Create the querydef (CurrentDB.CreateQueryDef), using LoginName_Temp as the table name.
Set the RecordSource of your Report to LoginName_Query_Temp.
Open the report.
I don't see what purpose the table myusername_Temp serves here. Is that where the name fields are? If so, avoid the join entirely:
Dim lngEmpNumber As Long
Dim strName As String
Dim strSQL As String
lngEmpNumber = Forms!Reports!txtEmpID
strName = DLookup("[FName] & ' ' & [LName]", "myusername_Temp", "EmpNumber=" & lngEmpNumber
strSQL = "SELECT " & Chr(34) & strName & Chr(34) & " AS [Employee Name], " & _
"CourseName, DateCompleted, tblEmp_SuperAdmin.[Cost Centre] " & _
"FROM tblCourse " & _
"INNER JOIN tblEmpCourses " & _
"ON tblCourse.CourseID = tblEmpCourses.CourseID) " & _
"INNER JOIN tblEmp_SuperAdmin " & _
"ON tblEmp_SuperAdmin.EmpNumber = tblEmpCourses.EmpNo " & _
"WHERE tblEmp_SuperAdmin.EmpNumber = " & lngEmpNumber & _
" ORDER BY CourseName;"
Now, the parentheses may need to be changed in the join (I always do my equi-joins in the Access QBE and let it take care of the getting the order and parens correct!), and my assumptions about the purpose of the temp table may be wrong, but I don't see it being used for anything other than as an intermediate link between tables, so I guessed it must be there to provide the name fields.
If that's wrong, then I'm at a loss as to why the temp table needs to be there.
Also, in your second post you referred to the control on the form as:
Forms!Reports!txtEmpID.Text
...the .Text property of Access controls is accessible only when the control has the focus. You could use the .Value property, but since that's the default property of Access controls, you should just stop after the name of the control:
Forms!Reports!txtEmpID
...you'll see this is how I did it in my suggested code.
I find the idea of your name-based temp table to be highly problematic to begin with. Temp tables don't belong in a front end, and it's not clear to me that it is actually a temp table. If it's temp data, put it in a shared table and key the record(s) to the username. Then you don't have to worry about constructing the table name on the fly.