Trying to run a DELETE query using DAO in VBA - sql

Im using Access 2013 and Excel 2013. In terms of References, I am using Microsoft Office 15.0 Access database engine Object Library.
So I am trying to run a DELETE query in VBA. Here is what I have so far
Sub UpdatePartList()
Dim ws As DAO.Workspace
Dim dbs As DAO.Database
Dim rsTable As DAO.Recordset
Dim rsQuery As DAO.Recordset
Dim rsSql As DAO.Recordset
Set ws = DBEngine.Workspaces(0)
Set dbs = ws.OpenDatabase("P:\Distribution Purchasing\Kit Bids\Kit Parts Query.accdb")
'deletes previous part numbers
Sql = "DELETE * FROM [Kit Parts]"
Set rsSql = dbs.OpenRecordset(Sql, dbOpenDynaset)
When I run a SELECT query for the same table, it works just fine. But when I try to DELETE, I get this error.
" Run-time error '3219': Invalid operation. "

DAO's OpenRecordSet is not appropriate for Delete queries, which do not return any recordset object. Use the Execute method instead:
Change
Set rsSql = dbs.OpenRecordset(Sql, dbOpenDynaset)
to
dbs.Execute(Sql)
also there's no need for * in the Delete SQL statement. Although Access will accept it, other systems probably won't.

You can modify your SQL as #Rahul suggested, plus change your last line of code to:
dbs.Execute sql

Related

Change Recordset Type via VBA [duplicate]

This question already has an answer here:
Set Recordset Type of QueryDef via VBA
(1 answer)
Closed 11 months ago.
I have a MS-Access database, which includes several queries, which have the recordset type Dynaset. I want to change all Queries to the Recordset Type Snapshot (i.e. dbOpenSnapshot).
Following approach gives me the error message that dbOpenSnapshot is not a valid argument, which I took from here
Sub Properties()
Dim dbs As DAO.Database
Dim rsQuery As DAO.RecordSet
Set dbs = CurrentDb
Set rsQuery = dbs.OpenRecordset("Query1")
rsQuery.Properties("Type") = dbOpenSnapshot
End Sub
Thank you for any hints!
This is the syntax:
Set rsQuery = dbs.OpenRecordset("Query1", dbOpenSnapshot, dbReadOnly)
Database.OpenRecordset

MS Access VBA code

I am new to MS Access and would like to type EmployeeID in the text box 1 (text_in) and after the button is pressed the result query (one unique value e.g. employee first name taken from the table) is printed out in the text box2 (text_out).
So far have the following code:
Private Sub btn_get_data_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
'declaration of database on recordset objects
Dim strSQL As String
Dim a As String
a = text_in.Value
Set db = CurrentDb
Set rs = db.OpenRecordset("Employee")
strSQL = "SELECT Employee.FirstName FROM Employee WHERE Employee.EmployeeId=" & a
Set db = Nothing
Set rs = Nothing
End Sub
I have tried searching for a solution in many places but I cannot understand the structure that is used in MS access VBA to implement query from regular SQL language.
Guys, thank you very much! It took me one more hour to sucessfully implement both solutions into my database file. As I wrote I am completely new to Ms-access I am learning using some tutorials but my level is still low. Thank you very much once again.
Private Sub btn_get_data_Click()
on error goto errorCatch
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT Employee.FirstName FROM Employee WHERE Employee.EmployeeId=" & Me.text_in.Value & ";"
Set rs = db.OpenRecordset(strSql, DbOpenDynaset)
If rs.RecordCount > 0 Then
debug.print; rs!FirstName
Me.text_out.Value = rs!FirstName
End if
Cleanup:
Set db = Nothing
Set rs = Nothing
Exit Sub
errorCatch:
debug.print; err.Number
debug.print; Err.Description
GoTo Cleanup
End Sub
I cant tell what youre after is this. You need to be better at utilizing recordsets and how to use a string value as your sql statement.
You also didnt need to create a variable to store the textbox value in- you can use it directly in your sql statement.
Also it is very important to have good error handling as hanging recordset objects can be quite a pain in the ass.
EDIT - Ill expand on other ways to use string sql statements within VBA
DoCmd.RunSQl strSql
Or
DoCmd.Execute strSql
Both of these are great for UPDATE's or INSERT's.
Then, like Gustav pointed out, you have various D functions that are basically compact queries with some limitations. However, they often save you the trouble of having to do all the typing that is involved with opening,utlizing and closing records sets. Even though the D functions seem limited, I have often nested a few to get join results out of. Just a matter of imagination.
Look at this nifty site for function details -
https://www.techonthenet.com/access/functions/index.php
You don't need a query to do this. Just set the ControlSource of text2:
=DLookup("FirstName","Employee","EmployeeId=" & [text_in] & "")

VBA queries and cleaning up strings on exit

If I have a query that I have created using VBA:
dim SQL as string
dim rs as recordset
dim db as database
SQL = "SELECT ... FROM ..."
Set db = CurrentDb
Set rs = db.OpenRecordset(SQL, dbOpenDynaset)
At the end of my sub I would always do the following:
rs.close
set rs = nothing
My question is, do I need to SQL ="" or something of that like? I think my confusion originally came from the fact that I haven't used set SQL in my code.
and if I do clear these strings, then, is there a 'best' way?
Since you're not opening a connection to either CurrentDb or the SQL string, there's no need to close them. However, you are opening a recordset, so that should be closed. It wouldn't harm anything to set SQL = "", but it's not going to actually do anything constructive.
As far as a "best way", I think you've already got it. At the end of your sub, or before any code that might prematurely exit it, just put:
rs.close
set rs = nothing

How Do I Return Multiple Recordsets from SQL Stored Procedure in Access 2010

I’ve created a pass-through query in Access which executes a stored procedure that searches for a string across all tables in my SQL database. The stored procedure on the SQL server runs as expected, returning multiple Recordsets that contain the value of my search string. However, when I double-click on the pass-through query in Access, in Datasheet View I see the results of only one Recordset. Since it appears that Access is not designed to handle multiple result sets, then how do I use VBA in Access to accomplish this?
exec sqlsp_searchalltables #Tablenames='', #SearchStr='%motion%'
I'm not quite sure how you expected to "bind" your form to the multiple recordsets returned by the stored procedure, but as far as I know the only way to deal with SQL Server stored procedures that return multiple recordsets is to use ADODB.Recordset objects.
(Don't be misled by the "Recordset.NextRecordset Method (DAO)" article here. If you try that approach you will receive run-time error '3847': "ODBCDirect is no longer supported. Rewrite the code to use ADO instead of DAO.")
For example, I have a SQL Server stored procedure that returns two recordsets and I create a pass-through named [dbo_myMultiRsSp_1] to call it:
EXEC dbo.myMultiRsSp #id=1
If I open it in Datasheet View by double-clicking it I see the results of the first recordset.
If I want to process all of the recordsets in VBA I cannot use the pass-through query directly, but I can use its .Connect and .SQL properties as follows
Option Compare Database
Option Explicit
Sub MultiRsSpTest()
Dim cdb As DAO.Database
Dim con As ADODB.Connection, cmd As ADODB.Command
Dim r1 As ADODB.Recordset, r2 As ADODB.Recordset
Set cdb = CurrentDb
Set con = New ADODB.Connection
' connect directly to the SQL Server
' (by using the .Connect property of the pass-through query)
con.Open Mid(cdb.QueryDefs("dbo_myMultiRsSp_1").Connect, 5) ' omit "ODBC:" prefix
Set cmd = New ADODB.Command
cmd.ActiveConnection = con
cmd.CommandType = adCmdText
cmd.CommandText = cdb.QueryDefs("dbo_myMultiRsSp_1").SQL
Set r1 = cmd.Execute
Debug.Print
Debug.Print "First Recordset:"
Do Until r1.EOF
Debug.Print r1(0).Value
r1.MoveNext
Loop
Set r2 = r1.NextRecordset
Debug.Print
Debug.Print "Second Recordset:"
Do Until r2.EOF
Debug.Print r2(0).Value
r2.MoveNext
Loop
' r1.Close (happens implicitly)
Set r1 = Nothing
r2.Close
Set r2 = Nothing
Set cmd = Nothing
Set con = Nothing
Set cdb = Nothing
End Sub

Run-time error on appending linked table in MS Access

I have a database that links to an Excel spreadsheet. When adding the linked table manually, I have no problems (I just follow the little wizard and the table is created perfectly). I am trying to automate that using VBA:
Dim db as DAO.Database
Dim tdf as TableDef
Set db = CurrentDB
Set tdf = db.CreateTableDef("linked_table")
tdf.Connect = "Excel 8.0;HDR=YES;IMEX=2;DATABASE=" & Me.txtExcelFile ' references form field
db.TableDefs.Append tdf ' Here's where I get a run time error
Unfortunately I get run-time error 3264 on the last line and it says, "No field defined--cannot append TableDefs or Index." I'm not even sure why the last line is needed (it seems from the documentation I've found that it's to add the table to the TableDefs collection of the database). Any suggestions on resolving the error?
You are missing:
tdf.SourceTableName = "Sheet1$"
Or whatever range or sheet name you wish to use as the table.
So, in all, this works for me:
Dim db as DAO.Database
Dim tdf as TableDef
Set db = CurrentDB
Set tdf = db.CreateTableDef("linked_table")
tdf.SourceTableName = "Sheet1$"
tdf.Connect = "Excel 8.0;HDR=YES;IMEX=2;DATABASE=" & Me.txtExcelFile ' references form field
db.TableDefs.Append tdf
You can also link Excel using TransferSpreadsheet