3

I want to apply an SQL query to one Access table, from which it is retrieving data from a table in another Access file. I've looked around on this subject and can't seem to get solutions to work.

Based on this source http://support.microsoft.com/kb/113701, I came up with the following, but still have no luck.

sSQL = "UPDATE TableInCurrentDB 
SET [Field1InCurrentDB]= DAvg('Field1InExternalDB','[;database=C:\VB\ExternalDB.accdb].[TableInExternalDB]','Field2InExternalDB= & Year(Now()) & ') 
WHERE [Field2InCurrentDB]='1';"
DoCmd.RunSQL sSQL

I know that the error lies somewhere in the reference to the external DB, because the code works fine if the tables are in the same database. However, it's tough to tell exactly what's wrong because the error I get is 'Unknown'.

How can I modify this statement to update an Access table from another Access database's table?

6
  • This should be simper if you create a link to TableInExternalDB. Have you ruled out a linked table for some reason? Commented Nov 19, 2013 at 16:35
  • Thanks HansUp. Yeah I'd prefer not have a linked table although this does work. Do you know how I can write the connection directly in the SQL statement? Commented Nov 19, 2013 at 16:39
  • For a plain SQL statement, you could use FROM TableInExternalDB IN 'C:\VB\ExternalDB.accdb' However I don't know how to make that approach work as the Domain option for DAvg (or any other domain function). Commented Nov 19, 2013 at 16:43
  • You confirmed it works with a linked table. So I don't understand why you're opposed to using a linked table. If the location of the external db changes, you would need to update the link. But that is no more difficult than changing a hard-coded file path in a VBA DAvg statement ... assuming you could even get DAvg to work as you originally intended. Commented Nov 19, 2013 at 16:46
  • Yeah, it's tougher with the DAvg function. I also tried to modify the code so that it wouldn't need a domain function, but no luck on that front either. As for the linked table, there are many tables for which this function will retrieve data. The path isn't hard-coded. I just modified it to make the question clear. I guess the main reason I don't want to create links is to keep the DB looking as clean as possible. I know it's less convenient to code. Appreciate your help though. Commented Nov 19, 2013 at 16:47

2 Answers 2

4

You prefer not to use a link to the table in the external database, but that choice is a complication when you want to use DAvg. However, since you're doing this with VBA code, you can ditch DAvg and do what you need in 2 steps:

  1. First retrieve the average from the external table.
  2. Use that step #1 average in your UPDATE.

For step #1, test this as a new query in the Access query designer ...

SELECT Avg(Field1InExternalDB)
FROM TableInExternalDB IN 'C:\VB\ExternalDB.accdb'
WHERE Field2InExternalDB=Year(Date());

Assuming that query returns the correct value, adapt your VBA code to retrieve the same value.

Dim db As DAO.database
Dim strSelect As String
Dim varAvg As Variant
strSelect = "SELECT Avg(Field1InExternalDB)" & vbCrLf & _
    "FROM TableInExternalDB IN 'C:\VB\ExternalDB.accdb'" & vbCrLf & _
    "WHERE Field2InExternalDB=Year(Date());"
'Debug.Print strSelect
Set db = CurrentDb
varAvg = db.OpenRecordset(strSelect)(0)
Debug.Print Nz(varAvg, 0) ' see note

Note that query will return Null when no rows include Field2InExternalDB values which match the current year. That is why varAvg is declared as Variant. Later Nz(varAvg, 0) will give you zero instead of Null.

Then you can use a parameter query for your UPDATE and supply Nz(varAvg, 0) as the parameter value.

Dim qdf As DAO.QueryDef
Dim strUpdate As String
strUpdate = "UPDATE TableInCurrentDB" & vbCrLf & _
    "SET [Field1InCurrentDB]=[pAvg]" & vbCrLf & _
    "WHERE [Field2InCurrentDB]='1';"
'Debug.Print strUpdate
Set qdf = db.CreateQueryDef(vbNullString, strUpdate)
qdf.Parameters("pAvg") = Nz(varAvg, 0)
qdf.Execute dbFailOnError
Set qdf = Nothing
Set db = Nothing
Sign up to request clarification or add additional context in comments.

Comments

0

Could you not do this as a single step? Incorporate the output of the first SQL as the input to the "set" in the second?

In other words,bypass the first query and just do the second using this as the "strUpdate" string:

strUpdate = "UPDATE TableInCurrentDB" & vbCrLf & _
    "SET [Field1InCurrentDB]=" & vbCrLf & _
    "  (SELECT Val(Nz(Avg(Field1InExternalDB),0))" & vbCrLf & _
    "   FROM TableInExternalDB IN 'C:\VB\ExternalDB.accdb'" & vbCrLf & _
    "   WHERE Field2InExternalDB=Year(Date()) )" & vbCrLf & _
    "WHERE [Field2InCurrentDB]='1';"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.