Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsFormsForms ProgrammingQueriesModules / DAO / VBAReports / PrintingMacrosDatabase DesignSecurityConversionImporting / LinkingSQL Server / ADPMultiuser / NetworkingReplicationSetup / ConfigurationDeveloper ToolkitsActiveX ControlsNew UsersGeneral 1General 2
Access DirectoryToolsTutorialsUser Groups
Related Topics
SQL ServerOther DB ProductsMS OfficeMore Topics ...

MS Access Forum / Modules / DAO / VBA / May 2006

Tip: Looking for answers? Try searching our database.

VBA and SQL - some help for a novice

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jim Jones - 22 May 2006 14:34 GMT
I am curently using a number of macros each of which runs a large number of
queries.  I am told that this is not good practice, and that I should write
VBA code which executes the SQL code for each of the queries in turn.  So,
the VBA would do the same job as the macro, but in a single piece of code.  I
see myself designing the query in the Query Window, then pasting the
corresponding SQL code at the appropriate place in the VBA.  

Can anyone suggest how a VBA novice like me could start experimenting with
SQL in VBA code.  Perhaps, someone could show me how to write some VBA code
which does the same job as a very simple macro (say, one which calls two
queries).

I hope this makes sense

Jim Jones
Botswana
FBxiii - 22 May 2006 15:11 GMT
Its a bit of a large subject for one post, but you are on the right lines
with copying/pasting the SQL.

There are different methods depending on the type of queries you are
running.  This example is for an 'Action' query:

The code needed for an action query would be:  (Free-typed so may not work
at first)

Dim db as Database
dim strSql as String

Set db = Currentdb()

strSQL = "SELECT Name, Address INTO Details FROM tblCustomers;"

db.Execute strSQL

To use a query as a recordset:

Dim db as Database
Dim rs as Recordset
Dim strSQL As String

Set db = Currentdb()
Set rs = db.Openrecordset("SELECT Name, Address FROM tblCustomers;")

Do Until rs.EOF

  ' Loop through the recordset
  Msgbox rs("Name") & " - " & rs("Address")

  rs.MoveNext

Loop

That is the basics.  It gets a bit more complex when the SQL is longer and
if you want to use Parameters or reference forms, etc....

Good Luck!

Steve.

> I am curently using a number of macros each of which runs a large number of
> queries.  I am told that this is not good practice, and that I should write
[quoted text clipped - 12 lines]
> Jim Jones
> Botswana
Jim Jones - 22 May 2006 15:34 GMT
Dear FBxiii - It's good to know that I am on the right lines!

The code you provided is just the kind of start I needed - many thanks indeed!

Jim Jones

> Its a bit of a large subject for one post, but you are on the right lines
> with copying/pasting the SQL.
[quoted text clipped - 55 lines]
> > Jim Jones
> > Botswana
Allen Browne - 22 May 2006 15:26 GMT
Jim, this is a big question. Hopefully you are willing to spend some time
learning this, because it *really* makes a monster difference to what you
can do with a database.

At the most basic level, the VBA is:
   DoCmd.OpenQuery "Query1"
If Query1 is a SELECT query, this shows the query to the user. If it is an
Action query (Delete, Update, or Make Table), it executes the query.

For an Action query, it is probably better to use:
   DoCmd.RunSQL "Query1"

These queries ask for user confirmation before the action. If you wish to
avoid that:
   DoCmd.SetWarnings False
before the query, and:
   DoCmd.SetWarnings True
afterwards.

To run 2 queries, without confirmation, the code would be:
   DoCmd.SetWarnings False
   DoCmd.RunSQL "Query1"
   DoCmd.RunSQL "Query2"
   DoCmd.SetWarnings True

These approaches are essentially the same as the macro. You are using VBA,
but you have not gained any benefit. A major problem with turning off
SetWarnings is that you get no message if the action query failed. For
example, if you were deleting records from a table so you could use it
again, you have no idea whether all records were actually deleted, or if
someone was using them and some were not deleted at all. And you have no
idea how many records were deleted.

A better approach in VBA is to Execute the query:
   dbEngine(0)(0).Execute "Query1", dbFailOnError
With this approach, you do not need to turn SetWarnings off. But if the
query does not complete successfully, it triggers a trappable error. Your
VBA code can now handle the error and exit gracefully instead of ignorantly
continuing with the assumption that the data is ready to use. If the idea of
error handling is new, see:
   http://allenbrowne.com/ser-23a.html

After an Execute, you can see how many records were deleted/appended/updated
via the RecordsAffected property:
   dbEngine(0)(0).Execute "Query1", dbFailOnError
   MsgBox dbEngine(0)(0).RecordsAffected & " record(s)."

But the Execute also has a limitation that RunSQL does not. If your query
has a parameter or refers to a text box on a form like this:
   [Forms].[Form1]![Text0]
the Expression Service (ES) in Access will interpret the reference and the
query will run. The Execute cannot do that, so you need to build up the SQL
statement in your code, concatenating the value from the form into the SQL
string. Example:
   Dim strSql As String
   strSql = "DELETE FROM Table1 WHERE ClientID = " & _
       Forms!Form1!Text0 & ";"
   Debug.Print strSql
   dbEngine(0)(0).Execute strSql, dbFailOnError

The Debug.Print line above is optional. It dumps the SQL string to the
Immediate Window. After running the code, you can open the Immediate Window
(Ctrl+G) to see the statement that executed. If there is a problem with the
SQL statement, the execute will fail, but you will be able to see what it
tried to execute, which empowers you to get it right.

When you concatenate values into a SQL string like that, you need delimiters
around the values. For dates, the delimiter is #, e.g.:
   strSql = "DELETE FROM Table1 WHERE EntryDate = #" & _
       Forms!Form1!Text0 & "#;"
For Text type fields, the delimiter is the double-quote. Trouble with that
is that VBA is already using quotes to delimit the string. The convention is
to double-them up when they are embedded in a string. So, if you want:
   This string has a "word" in quotes
you code:
   "This string has a ""word"" in quotes"

It looks a bit odd when the string ends with this word, since you get 3
quotes together:
   "This string has a ""word"""
but that's the kind of thing you generally get:
   strSql = "DELETE FROM Table1 WHERE City = """ & _
       Forms!Form1!Text0 & """;"

So, you will certainly mock up a query using any sample critiera values,
switch it to SQL View, and copy the statement to use in your code. But you
still need to concatenate your variables into the string.

These SQL statements can be quite long, so you probably want to break them
into multiple lines like the Query window does as well. Effectively this is:
   strSql = "SELECT * FROM Table1 " & "WHERE ID = 99;"
Use the underscore as the line continuation charcacter:
   strSql = "SELECT * FROM Table1 " & _
   "WHERE ID = 99;"

There's more power beyond that as well, such as wrapping multiple statements
in a transaction so you roll the whole thing back unless it all completes
successfully. There's more info on that here:
   http://allenbrowne.com/ser-37.html

But I fear we have already given you indigestion.

Signature

Allen Browne - Microsoft MVP.  Perth, Western Australia.
Tips for Access users - http://allenbrowne.com/tips.html
Reply to group, rather than allenbrowne at mvps dot org.

>I am curently using a number of macros each of which runs a large number of
> queries.  I am told that this is not good practice, and that I should
[quoted text clipped - 15 lines]
> Jim Jones
> Botswana
Jim Jones - 22 May 2006 17:00 GMT
Dear Allen

Many thanks for providing such a detailed answer, and thanks for confirming
that the approach is worth persuing - it's obviously something which is worth
spending time on.

So, here goes ........

Thanks again

Jim Jones

> Jim, this is a big question. Hopefully you are willing to spend some time
> learning this, because it *really* makes a monster difference to what you
[quoted text clipped - 117 lines]
> > Jim Jones
> > Botswana
RD - 24 May 2006 00:23 GMT
>I am curently using a number of macros each of which runs a large number of
>queries.  I am told that this is not good practice, and that I should write
[quoted text clipped - 12 lines]
>Jim Jones
>Botswana

Take a look at this:
http://www.mvps.org/access/queries/qry0014.htm

HTH,
RD
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.