MS Access - Execute SQL statement receives error - sql

I get an error:
"Object doesn't support this property or method"
...when I try to run this code:
Dim db As DAO.Database
Dim mySQL As String
Set db = currentdb
mySQL = "SELECT tbl1.pID, tbl1.sID, tbl1.Type, tbl1.Description, tbl1.Amount, tbl1.Delete, tbl1.Approve, tbl2.sName FROM tbl2 INNER JOIN tbl1 ON tbl2.sID = tbl1.sID WHERE pID = " & Forms.frmEdit1.cboP & " And Delete = False;"
db.Execute mySQL, dbFailOnError
Set db = Nothing
It seems like the error is somewhere in the last line (that's where it fails when I use the immediate window) I also tried the single quotes around 'False'.
EDIT: Recordsource that worked
SELECT tbl1.[pID],
tbl1.[sID],
[tbl1].Type,
[tbl1].Description,
[tbl1].Amount,
[tbl1].Delete,
tbl1.Approve,
tbl2.sName
FROM tbl2 INNER JOIN tbl1 ON tbl2.sID = tbl1.sID
WHERE pID = Forms![frmEdit1].cboP
And [Delete] = False;

Logically, sending a SELECT statement to Execute is saying, 'select values according to this criteria but don't let me know the results', which doesn't make much sense. Populating an unbound subform needs to be done manually - that's what makes it 'unbound':
Sub LoadByID(Optional ByVal ID)
Dim RS As DAO.Recordset, SQL As String
If IsMissing(ID) Then ID = Forms!frmEdit1.cboP
SQL = " SELECT tbl1.sID, tbl1.Type, tbl1.Description, " + _
" tbl1.Amount, tbl1.Delete, tbl1.Approve, tbl2.sName " + _
" FROM tbl2 INNER JOIN tbl1 ON tbl2.sID = tbl1.sID " + _
" WHERE pID = " & ID & " And [Delete] = False;"
Set RS = CurrentDb.OpenRecordset(SQL)
' Assuming no match is an error; if it isn't, rewrite accordingly
If RS.EOF Then Err.Raise 999, "LoadByID", "Er, no selection..."
txtID.Value = RS!ID
txtDescription.Value = RS!Description
' and so on...
End Sub
I've allowed specifying the ID not through the combo box to make the method easier to test. Also, note that if the form is supposed to allow editing, then you will need more code to then save any changed values.
Edit
The above was assuming only one return record. If more than one, loop like this:
Sub LoadByID(Optional ByVal ID)
Dim RS As DAO.Recordset, SQL As String
If IsMissing(ID) Then ID = Forms!frmEdit1.cboP
SQL = " SELECT tbl1.sID, tbl1.Type, tbl1.Description, " + _
" tbl1.Amount, tbl1.Delete, tbl1.Approve, tbl2.sName " + _
" FROM tbl2 INNER JOIN tbl1 ON tbl2.sID = tbl1.sID " + _
" WHERE pID = " & ID & " And [Delete] = False;"
Set RS = CurrentDb.OpenRecordset(SQL)
' add code to clear current display here...
While Not RS.EOF
' add code to load the individual values here...
RS.MoveNext
Wend
End Sub

Related

Executing a SQL query from vba results with nothing

Cheers,
I am trying to send a simple SQL query, but I get no results in my recordset as if it simply was not executed.
Just after, I am executing a different query, which results correctly.
When running the same query from SMSS, do brings up the desired results.
Following is the code:
If CheckLogsFromRestartDay = True Then
'This line does NOT seem to work. Nothing is changed in the Recordset
Set objMyRecordset = objMyConn.Execute( _
" SELECT top 1 cast(tValue AS date) AS RestartDate " & _
" FROM settings (nolock) WHERE tkey = 'EngineStartTime' ")
'This line DOES provide an answer correctly
Set objMyRecordset = objMyConn.Execute( _
" SELECT * FROM " & LogTable & " (nolock) where Webpage like 'Engines%'" & _
" ORDER BY id desc")
sTodayMMDD = objMyRecordset!RestartDate
Else
sTodayMMDD = Format(Date, "yyyy-mm-dd")
End If

SQL on VBA: Compilation error, a function or variable was expected

I have the code below but it isnt working. It gives me the error: Compilation error, a function or variable was expected.
I guess the error is on the Database.Execute method, but I didnt come with a solution yet.
Sub ChavesMontante()
Dim dbschaves As Database
Dim rschaves As DAO.Recordset
Dim tipodechave As String
Dim SQLCMD As String
Dim chave As String
Set dbschaves = CurrentDb
chave = "BED20777"
SQLCMD =
"(SELECT us.instalacao, ch.bloco, us.tipounidade " & _
"FROM (SELECT useccionadora, bloco " & _
"FROM sgdprd.redeprimaria rp " & _
"WHERE rp.useccionadora IS NOT NULL " & _
"CONNECT BY rp.nox = PRIOR rp.fontex AND rp.noy = PRIOR rp.fontey " & _
"START WITH rp.useccionadora = '" & chave & "' ) ch " & _
"INNER JOIN sgdprd.useccionadora us ON ch.useccionadora= us.instalacao) "
Debug.Print SQLCMD
Set rschaves = dbschaves.Execute(SQLCMD)
End Sub
Execute is used for action SQL statements (UPDATE, DELETE, INSERT), not to set a Recordset object.
Try the following changes:
Dim dbschaves As DAO.Database
...
Set rschaves = dbschaves.OpenRecordset(SQLCMD)
Also, remove the outer parens enclosing the entire SQL statement. I have never seen CONNECT BY PRIOR START WITH. Does the query open in Access?

Where with And Clause SQL, Access-VBA

Hi Everyone, Another Installment of WTF am I missing?
When I run this code I get a missing operator run-time Error, see attached photo.
I can't seem to figure it out. This string is used to open a recordset that will populate a form.
Private Sub BtnUseSelection_Click()
Dim CompSQL As String
CompSQL = "SELECT T1Company.LegalName, T2AddressType.AddressType, T1Addresses.City" & _
" FROM T2AddressType INNER JOIN (T1Addresses INNER JOIN (T1Company INNER JOIN T3Company_Addresses ON T1Company.CompanyID = T3Company_Addresses.CompanyID) ON T1Addresses.AddressID = T3Company_Addresses.AddressID)" & _
" ON T2AddressType.AddressTypeID = T1Addresses.AddressType" & _
" WHERE T1Company.LegalName = " & Me.LstboxCompanies.Column(0) & " And T2AddressType.AddressType = " & Me.LstboxCompanies.Column(1) & " And T1Addresses.City = " & Me.LstboxCompanies.Column(2)
Set db = CurrentDb
Set RSCompany = db.OpenRecordset(CompSQL, dbOpenSnapshot, dbSeeChanges)
Not quite sure what I am missing, any help would be greatly appreciated.
Consider parameterizing query to avoid any need for quote enclosure or string concatenation.
SQL (save below as a saved Access query, more efficient than VBA string query as database engine saves best execution plan)
PARAMETERS [LegalNameParam] Text(255), [AddressTypeParam] Text(255),
[CityParam] Text(255);
SELECT T1Company.LegalName, T2AddressType.AddressType, T1Addresses.City
FROM T2AddressType
INNER JOIN (T1Addresses INNER JOIN (T1Company
INNER JOIN T3Company_Addresses
ON T1Company.CompanyID = T3Company_Addresses.CompanyID)
ON T1Addresses.AddressID = T3Company_Addresses.AddressID)
ON T2AddressType.AddressTypeID = T1Addresses.AddressType
WHERE T1Company.LegalName = [LegalNameParam]
AND T2AddressType.AddressType = [AddressTypeParam]
AND T1Addresses.City = [CityParam]
VBA (call the above query and bind values to named parameters)
Dim db As Database, RSCompany As Recordset, qdef As QueryDef
Dim CompSQL As String
Set db = CurrentDb
Set qdef = db.QueryDefs("myStoredQuery")
qdef!LegalNameParam = Me.LstboxCompanies.Column(0)
qdef!AddressTypeParam = Me.LstboxCompanies.Column(1)
qdef!CityParam = Me.LstboxCompanies.Column(2)
Set RSCompany = qdef.OpenRecordset(dbOpenSnapshot, dbSeeChanges)
It seems you've missed the ' ' around your string literals.
instead of
... WHERE T1Company.LegalName = " & Me.LstboxCompanies.Column(0) & " ...
use:
... WHERE T1Company.LegalName = '" & Me.LstboxCompanies.Column(0) & "' ...
You also need to escape your strings to avoid corruption of the command (or sql injections). Look here and here for some info.

Export nested tables to new back end

I have an Access back end database with 7 nested, related tables: Clients, Projects, Project Goals, Goal Impediments, Impediment Causes, Possible Solutions and Required Actions or Resources. Each client may have multiple Projects. Each Project may have multiple records in Goals to Actions.
I want to export one Client Project with its nested tables into an empty back end with exactly the same structure, so the Client, supplied with front and back end, can review the information and make changes. If the client has made changes, I want to import the changes back into the master database, replacing the existing data.
Clients has the usual personal information. Projects has eight fields including a linked ID to Clients. Each Table from Goals to Actions has an Auto numbered primary key, an ID field linked to the primary key of table above, a 100 character short description, a long field for Notes, a number for priority or weighted importance and a Yes/No field for Resolved or Completed. Each may have between 1 and 10 records. There are 94 records in the sample record set I am working with.
It is easy enough to extract the Project and its related data from the database with a query; but I am having trouble coming up with the most efficient way to insert it into the empty back end. I started a few subroutines under an Export button to transfer the data table by table, so I could handle the changed relationships caused by the renumbered the primary keys; but I would like to do the entire process in one fell swoop, if possible. I created a huge back end file with one flawed attempt at a While NOT rsSource.EOF – Wend routine. Any suggestions gratefully received.
******************************** Code **********************************
Private Sub Command316_Click()
' SelectedClient and SelectedProject are Public Integer variables
' To be used in For...Next loops
Dim i, iNumRecs, intGoal, intImped, intCause, intSolution, intAction As Integer
Dim SQLstr As String
'Open source database
Dim dbSource As Database
Set dbSource = CurrentDb
'Open dest database
Dim dbDestination As Database
Set dbDestination = DAO.OpenDatabase("C:\Prosolve\Temp\Prosolve_BE.accdb")
' Select Project to be transferred
' Might be easier to work with if everything NOT selected at once
SQLstr = "SELECT Clients.ClientID, Clients.ContactFirstName, Clients.ContactLastName, Clients.Address, Clients.City, Clients.StateOrProvince, Clients.PostalCode, "
SQLstr = SQLstr + "Clients.Country, Clients.EmailAddress, Clients.CompanyName, Clients.PhoneNumber, Clients.CellNumber, Clients.BillingRate, Clients.TaxPayable, Clients.Discount, "
SQLstr = SQLstr + "Projects.ProjectID, Projects.ClientID, Projects.ProjectName, Projects.ProjectOwner, Projects.ProjectDescription, Projects.EmployeeID, Projects.Priority, Projects.TotalBilled, "
SQLstr = SQLstr + "Goals.GoalID, Goals.ProjectID, Goals.Goal, Goals.Notes, Goals.Owners, Goals.Gpriority, "
SQLstr = SQLstr + "Impediments.ImpedID, Impediments.IgoalID, Impediments.Impediment, Impediments.Notes, Impediments.Iweight, Impediments.Resolved, "
SQLstr = SQLstr + "Causes.CauseID, Causes.cimpedID, Causes.cause, Causes.Notes, Causes.cweight, Causes.resolved, "
SQLstr = SQLstr + "Solutions.SolutionID, Solutions.ScauseID, Solutions.Solution, Solutions.Notes, Solutions.Sweight, Solutions.Implemented, "
SQLstr = SQLstr + "Actions.ActionID, Actions.AsolutionID, Actions.Action, Actions.Notes, Actions.Priority, Actions.Completed "
SQLstr = SQLstr + "FROM ((Clients INNER JOIN Projects ON Clients.ClientID = Projects.ClientID) "
SQLstr = SQLstr + "INNER JOIN ((Goals INNER JOIN Impediments ON Goals.GoalID = Impediments.IgoalID) "
SQLstr = SQLstr + "INNER JOIN (Causes INNER JOIN Solutions ON Causes.causeID = Solutions.ScauseID) "
SQLstr = SQLstr + "ON Impediments.ImpedID = Causes.cimpedID) ON Projects.ProjectID = Goals.ProjectID) "
SQLstr = SQLstr + "INNER JOIN Actions ON Solutions.SolutionID = Actions.AsolutionID "
SQLstr = SQLstr + "WHERE Clients.ClientID = " & SelectedClient & " AND Projects.ProjectID = " & SelectedProject & " ;"
'Open source recordset
Dim rsSource As Recordset
Set rsSource = dbSource.OpenRecordset(SQLstr, dbOpenDynaset)
'Open dest recordset
Dim rsDestination As Recordset
Set rsDestination = dbDestination.OpenRecordset("Clients", dbOpenDynaset)
'Loop through source recordset
'While Not rsSource.EOF
'Look for record in dest recordset
rsDestination.FindFirst "ContactFirstName = '" & rsSource.Fields("ContactFirstName") & "'"
'& " AND ContactLastName = " & rsSource.Fields("ContactLastName") & ""
'If not found, copy record
'Works okay
If rsDestination.NoMatch Then
rsDestination.AddNew
rsDestination.Fields("ContactFirstName") = rsSource.Fields("ContactFirstName")
rsDestination.Fields("ContactLastName") = rsSource.Fields("ContactLastName")
rsDestination.Fields("Address") = rsSource.Fields("Address")
rsDestination.Fields("City") = rsSource.Fields("City")
rsDestination.Fields("StateOrProvince") = rsSource.Fields("StateOrProvince")
rsDestination.Fields("PostalCode") = rsSource.Fields("PostalCode")
rsDestination.Fields("Country") = rsSource.Fields("Country")
rsDestination.Fields("EmailAddress") = rsSource.Fields("EmailAddress")
rsDestination.Fields("CompanyName") = rsSource.Fields("CompanyName")
rsDestination.Fields("PhoneNumber") = rsSource.Fields("PhoneNumber")
rsDestination.Fields("CellNumber") = rsSource.Fields("CellNumber")
rsDestination.Fields("BillingRate") = rsSource.Fields("BillingRate")
rsDestination.Fields("TaxPayable") = rsSource.Fields("TaxPayable")
rsDestination.Fields("Discount") = rsSource.Fields("Discount")
rsDestination.Update
Else
MsgBox "Record alreasy exists"
End If
'Works okay
Set rsDestination = dbDestination.OpenRecordset("Projects", dbOpenDynaset)
rsDestination.FindFirst "ClientID = 1"
If rsDestination.NoMatch Then
rsDestination.AddNew
rsDestination.Fields("ClientID") = 1
rsDestination.Fields("ProjectName") = rsSource.Fields("ProjectName")
rsDestination.Fields("ProjectOwner") = rsSource.Fields("ProjectOwner")
rsDestination.Fields("ProjectDescription") = rsSource.Fields("ProjectDescription")
rsDestination.Fields("EmployeeID") = rsSource.Fields("EmployeeID")
rsDestination.Fields("Priority") = rsSource.Fields("Projects.Priority")
rsDestination.Fields("TotalBilled") = rsSource.Fields("TotalBilled")
rsDestination.Update
Else
MsgBox "Record alreasy exists"
End If
' Try to find number of Goals for a For ... Next procedure
' Not counting Goals in Query. Will cause problems later when 2 or more client have same ProjectID
iNumRecs = DCount("ProjectID", "Goals", "ProjectID = " & SelectedProject & "")
'Here we need to copy all goals for projectID = 1 from 1 to number of goals'
' Once this is done successfully the process can be repeated for tables below it
'Loop through source recordset
'Currently copies 6 x first goal. rsSource.Movenext not working.
Set rsDestination = dbDestination.OpenRecordset("Goals", dbOpenDynaset)
rsDestination.FindFirst "ProjectID = " & SelectedProject & ""
If rsDestination.NoMatch Then
For i = 1 To iNumRecs
rsDestination.AddNew
rsDestination.Fields("ProjectID") = SelectedProject
rsDestination.Fields("Goal") = rsSource.Fields("Goal")
rsDestination.Fields("Notes") = rsSource.Fields("Goals.Notes")
rsDestination.Fields("Owners") = rsSource.Fields("Owners")
rsDestination.Fields("Gpriority") = rsSource.Fields("Gpriority")
rsDestination.Update
rsSource.MoveNext
Next
Else
MsgBox "Record alreasy exists"
End If
MsgBox "Procedure successfully completed to this point"
End Sub
******************************** End Code **********************************
You are constructing a giant source recordset with a join of all tables. So this recordset will have a large number of records (94 in your example), but the various tables you are exporting have less records.
This works when you know you only have to insert a single record into the target recordset (Clients, Projects), but it won't work if there is a variable number of records.
With Goals, you limit their number with the DCount and the For loop, but you simply get the first 6 records of the giant source. Because of the joins, this will usually be 6 times the same goal.
You should create a separate source recordset for all tables, each with a WHERE clause on client/project. Then you can copy all records from source to destination.
A much easier method would be:
Run INSERT statements for all tables directly into the target DB.
INSERT INTO [Goals] IN 'C:\Prosolve\Temp\Prosolve_BE.accdb'
SELECT *
FROM Goals
WHERE Goals.ProjectID = 1;
Note that this works also for AutoNumber columns.
And note that the hard part is still ahead of you: importing the changed data won't be so easy. How hard depends on whether the client can only change existing data, or can also add/delete records.

SQL Error Access 2010 VBA Update Command

I need help figuring out an error in my SQL statement. I have been trying several things, but nothing seems to work?
This is the error message I receive
Run-time error '3075':
Syntax error (missing operator) in query expression '([description] = Manufacturing and Delivery Schedule AND [pr_num] = 83)'.
This is my code:
Private Sub Command6_Click()
' ===================================================
' Receives the selected item in the combo box
' ===================================================
' Open the Database connection
Dim data_base As Database
Set data_base = CurrentDb
' Grab description and pr number from the form
Dim desc As string
dim pr_number as long
desc = Combo4.Value
pr_number = Text8.Value
' Build the query
Dim query As String
query = "UPDATE VDR_Table " & _
"SET [received] = [p1] " & _
"WHERE ([description] = " & desc & _
" AND [pr_num] = " & pr_number & ");"
Dim rec_set As DAO.Recordset
Set rec_set = data_base.OpenRecordset(query)
' Build the QueryDef
Set qd = data_base.CreateQueryDef("")
qd.SQL = query
' Execute query
qd.Parameters("p1").Value = true
qd.Execute
' Close nad null record set
rec_set.close
set rec_set = nothing
' Close the connection to the database
data_base.Close
' Prompt the user success
MsgBox "Item has been received"
End Sub
Thanks in advance for any help!
You need to enclose the description field value you are setting in quotes since it is a string field. It should look like this:
' Build the query
Dim query As String
query = "UPDATE VDR_Table " & _
"SET [received] = [p1] " & _
"WHERE ([description] = '" & desc & _
"' AND [pr_num] = " & pr_number & ");"
Removed the links below since they don't matter in this case.
Also, I would recommend using parameters instead of string concatenations to avoid SQL injections. Here's an example of using parameters with VBA - http://support.microsoft.com/kb/181734 - and here is some reasoning on why to use parameterized sql - http://www.codinghorror.com/blog/2005/04/give-me-parameterized-sql-or-give-me-death.html.