Liverpool Hope University College
International Business, Information, Technology and Enterprise School (IBITE)
Information and Communication Management Department (IM&C)
Part 1 - Database Applications Concepts
1. Database History
2. Database Choices
3. RDBMS Ingredients
4. Database Administration (1) – Backup and Recovery
5. Database Administration (2) – Security
6. Web Databases
7. Promoting and Distributing Database Applications.
8. Licensing and Copyright Issues in Database Development.
Part 2 – Database Implementation Using Microsoft Access
9. Intro to Access and the Friends
10.User Interface Design Principles
11.Programming Good Practice
12.Using ADO with Access
13.Using SQL in Access
15.Testing and Debugging
16.Locking Down Access Applications
18.Packaging and Deploying Access Applications
Note: The italic sections are pending approval.
Database Applications Concepts
- what you need to know about DBMS’s and database applications in general -
1. Database History
Database history is closely linked with the history of computers. As it happens with the
machines we use today for so many tasks, the database management systems used in the
beginning were far less complicated than what we are accustomed to today - SystemR, from
IBM, was initially tested on an “amazing” load of 8 megabytes of data! Databases were not
only smaller in those days, but also fundamentally different as structure. The first database
systems were based on the ‘Tree’ and ‘Hierarchical’ models, as opposed to the ‘Relational’
used by most of Database Management Systems (DMBS) today.
In 1970 a researcher with IBM, Tedd Codd, formulated, in a famous white paper, the premises
for a model of data storage which was to become the relational model. The only problem was
that Codd formulated the model in maths language, which made it not so obvious for the
beginning that it could be successfully used to build commercial database systems. And it was
not IBM that to first reaped the rewards of this advance in computing fields, but Honeywell
Information Systems, who hold the record for being the first company to bring a commercial
Relational Database Management System (RDBMS) to the market. Only after that IBM
released SystemR, a relational database management system, known latter as SQL/DS and
DB2 into our days. The same group of IBM researchers who designed SystemR also conceived
the SQL database query language, which was to become latter the industry standard for
interacting with databases.
Two more products worth mentioning here are Oracle, from Oracle Inc., which was the first
commercial database based on the SQL language, and Ingres, an academic effort from UCB –
University of California at Berkley, which has been the base for many commercial database
offerings, including Ingres from Relational Software, Postgres from Illustra (latter purchased
by Informix) and PostgreSQL, the most advanced open source database management system.
And thus, one of the most useful and used computing tools of all time, the relational database
management system, has come to being. Relational databases have dominated the market
throughout the ‘80s and ‘90s. In spite of their detractors and their known shortcomings in
storing and representing data for some specialist fields, they are still the most employed
database model in existence.
At the end of ‘80s, with the advent of object orientation paradigm to the world of
programming, the Object Oriented Database model has sprung to life. Some argue that it is
better suited for certain tasks than the relational model, but despite being around for over a
decade now and despite of being supported by several vendors who have release OODBMS’s,
it has never caught much momentum. There have also been those who tried to get the “best of
both worlds”, and came up with hybrid database systems – the Object Relational Database
Management Systems – ORDBMS in short.
2. Database Choices
Although not strictly a technical issue, knowledge about database vendors and their products is
certainly a must-know for any database programmer or administrator. The reasons are simple:
it won’t directly help you manage or build better the database, but it will help you in other
ways. It is difficult to make a career decision and choose to learn a certain database
management system, without knowing what other systems are available out there, who makes
them, and especially who uses them and for what purposes. Also, as a database administrator
and implementation programmer, it is often required to take business decisions and select a
certain database system, according to particular criteria such as available budget, capabilities,
reliability, target software or hardware platform and, not the least, personal previous
experience and knowledge about the chosen system. However, be aware that some of the
information presented here will become dated as new vendors join the markets and existing
products get updated, so always do your own research into independent reviews, feature lists,
peer enquiries etc.
The three largest database manufacturers – in respect of number of users and product literal
size – are Oracle, IBM and Microsoft. Their products – Oracle suite, IBM DB2 and Microsoft
SQL Server are essentially large database management systems, also called database servers,
with complex administration and design utilities, integrity checks, optimisation and tuning
facilities. They can implement distributed and parallel databases and complex replication set-
ups. They are suitable for large scale, powerful installations, capable of processing million of
transactions in a short interval of time. However, as the latest versions have gained extra
features, they have become rather large, requiring significant hardware resources, which makes
them less suitable for smaller set-ups. Oracle and DB2 run on Microsoft Windows and Unix
flavours – including Linux. Microsoft SQL server runs only on Microsoft Windows flavours.
In the Open Source world, two products hold the flagship – MySQL from AB Software in
Scandinavia, and PostgreSQL from The PostgreSQL Development Group. Both of them are
considerably less “hungry” in respect of hardware resources, which is a prime incentive for
deploying in small to medium enterprises (SME’s). Both of them are available free of charge,
and professional support can be purchased from specialist companies. MySQL is faster, but has
fewer features, and runs on Linux and Windows flavours. PostgreSQL runs only on Linux and
Unix flavours, it is just a bit slower, but notably richer in features such as triggers and integrity
Other products are: Microsoft Visual FoxPro, a smaller size database engine not so favoured
any more by Microsoft. Lotus Approach, a small size database engine similar to MS Access;
ColdFusion from Macromedia is targeted specifically at the web market for building web-
enabled databases; Interbase from Borland, which has a Open Source version called FireBird;
and FileMaker Pro, which is the most widespread relational database management system
available for Macintosh computers.
1. PostgreSQL database server (fully functional free download for Unix and Linux
flavours) – www.postgresql.org
2. MySQL database server (free fully functional software for Windows, Unix and Linux
flavours) – www.mysql.org
3. Oracle database server – www.oracle.com
4. IBM DB2 database server – www.ibm.com/software/data/db2
3. RDBMS Ingredients
Relational Database Management Systems (RDBMS) contain several distinct components with
well-defined roles. Firstly, there is the database server in the back-end and the database front-
end, or the user interface. The user interface is not really part of the database management
system, but we are going to discuss it here because it interacts closely with the database and,
most of the time, users wouldn’t get any real benefit from the database systems without it. It
can be a stand-alone application written in a programming language of choice, most frequently
Visual Basic, C++, Delphi and Microsoft Access (VBA). It can also be a web-page with some
programmatic and database connectivity abilities on its own, usually a programming language
is used on the server side to perform these roles, such as Perl, PHP, ASP or even C or C++ - in
case of CGI compliant programs. The scripts or binaries created with the above-mentioned
languages help establish connections to the database and generate dynamic web pages. The
front-end user interface can also be a Java applet embedded in a web page, or it can be
something less common, such as an electronic thermometer, humidity sensor or some other
device which collects some sort of data and uses the database to store it.
The Database Server
The database server, or the back-end as it is generically known, consists of the actual data
files, the database engine and utility tools. Many database servers store data in separate and
distinct files, one for each table, maybe one for each index defined, making it easier to execute
customised back-up scripts, just by copying the appropriate files. The core functionality of the
database server is concentrated in the database engine. Many times the database engine is
confused with the server itself, but normally the server contains some extra utility tools beside
the engine itself. The database engine is the actual piece of software responsible for scanning
data files, looking for and retrieving corresponding information, amending selected records and
deleting un-necessary ones. Like the engine of an automobile, it is the part of the system which
does most of the hard-work and is in motion most of the time.
Besides the data files and the database engine, database servers contain other utility programs.
They usually serve mainly design or administration purposes. The design utilities usually help
with creating and modifying the database structure, allowing for easy building of databases,
tables, columns and their data-types, triggers and relationships. Admin utilities help with the
day-to-day administration of the database server, and facilitate tasks such as backups, setting
up and tuning server parameters, creating and deleting users and user groups and opening
terminal connections to the server for executing command-line scripts.
Microsoft Access is a particular case regarding database systems structure. It bundles a small
scale database engine – the Microsoft Jet engine, a front-end programming environment –
Visual Basic for Applications (VBA), and some server utilities, such as the query designer, the
security and users manager and the table designer. Files created by Access, ending in the
“.mdb” extension contain the database data, the SQL queries, and the front end code – forms
and reports. It is probably this unique combination that gave Access the edge in the field of
small-scale, uncomplicated databases, implementable even by those with limited knowledge in
the field. However, Access is not really suitable for industrial strength, large-scale applications.
In between the database server and the front-end usually lies a database driver, bridge,
interface or API (Application Programming Interface), which facilitates communication of
commands between the programming language in the front-end and the database management
system in the back-end, and channels error messages and data back to the front-end.
Database Drivers, API’s, Bridges and Interfaces
In the early days of computer databases, writing an application capable of “talking” to a
database was a complex a time-consuming enterprise (some think it still is!). Normally the
programmer not only needed to know the language used for building the front-end user
interface, but also another language which was the one understood by the database
management system (DBMS) in the back-end. Almost each and every DBMS vendor
implemented a different version of their own database manipulation language. That is why, if a
front-end application had to be connected to a number of different DBMS’es, or the DMBS
had to be changed, than all parts of the application which were making calls to the database
had to be rewritten from scratch. Also, programmers had to learn a new language every time
they wanted to write any useful code dealing with a new database management system.
Database designers and administrators weren’t happy, programmers weren’t happy, and even
users, the bill payers, weren’t happy.
Even when SQL (the Structured Query Language) emerged as a standard, it was not enough.
Asking for some columns and rows from a table, appending and deleting data from a table, or
even manipulating the structure of the table is not enough in order to interact with a database
management system. First of all, in order to send any instructions to a DBMS, a connection has
to be made. This connection has to specify a certain database to be used (for systems capable
of hosting and managing more than one database). The connection has to be initiated for a
certain user, with a certain set of credentials, which will allow access to certain parts of the
system and deny access to others. Similarly, after work has been accomplished, the connection
has to be severed safely and graciously, making sure no un-completed transactions (updates,
deletes, inserts etc.) are left behind. These are just small examples of functionality unavailable
using plain vanilla SQL.
Thus Microsoft came forth with ODBC (Open Database Connectivity). ODBC is an API
(Application Programming Interface – a standard set of commands) which can be used to send
instructions to a wide variety of database management systems. The difference is that, although
the instructions are more or less the same in all cases, the ODBC drivers translates them into
instructions specific to each database management system, without the programmer needing to
know and understand these. Until recently ODBC was the de facto standard for database
connectivity on Microsoft Windows platforms (Win 95, 98, ME, NT etc.), but drivers are now
available for MacOS series of operating systems running on Apple computers and Unix
(including Linux) systems. In order to use ODBC, both the programming environment used to
build the front-end, and the DBMS in the back-end have to be ODBC compliant. Also, an
ODBC driver has to sit in the middle and translate ODBC commands in DBMS specific
commands (that is why the driver is specific to the database management system – i.e. ODBC
driver for Paradox, ODBC driver for MS SQL server, ODBC driver for PostgreSQL etc.)
Although it has solved many of our ancestors’ (in computer history terms) problems, ODBC
still has a low-level character. Microsoft later came up with OLEDB, which seems to be a
layer on top of ODBC, and which brings a higher-level perspective to things. Also, OLEDB is
capable of connecting to non-database data sources, such as spreadsheets and text files.
To add just another layer on top of everything, Microsoft brought DAO (Data Access Objects),
later renamed and revamped under the title of ADO (ActiveX Data Objects) which is hailed as
the ultimate in the matter of easy access to data sources of any kind. It is an object-oriented
API (Application Programming Interface) which allows manipulation of data in databases at
the other end through a common set of objects, such as connections, recordsets and fields.
ADO is now supported and implemented by a variety of programming environments such as
Microsoft Visual Basic, Microsoft Access, Microsoft Visual C++, Borland Delphi and Perl, so
it can be considered as a passport to the world of database programming. However, there are
still doubts regarding its efficiency and speed, even compared to its predecessor, DAO.
Bellow is an extract of ADO code from a VBA (Visual Basic for Applications) procedure.
Similar code would be used in VB, C++ or Delphi. The code opens a connection to the
‘tblClient’ table in the Microsoft Access database ‘GarnersCo.mdb’. The code is commented
throughout for readability, and it is merely an example of how ADO works.
‘ create object variables for the connection and the recordset
Dim cnnMyConnection as ADODB.Connection
‘ initialise the connection object
Set cnnDefaultConnection = New ADODB.Connection
‘ set the provider property of the connection, which is the DBMS driver to be used.
‘ In this case we are connecting to an MS Access database
cnnDefaultConnection.Provider = "Microsoft.Jet.OLEDB.4.0"
‘ open the connection specifying the database location,
‘ and the user name and password credentials (in this case both blank)
cnnDefaultConnection.Open "Data Source=C:GarnersCo.mdb;User ID=;Password=;"
With the advent of Java programming at the beginning of ‘90s, Sun decided to bring their own
database connectivity tool to the market, in the shape of JDBC – Java Database Connectivity.
Sun claims on their website that JDBC simplifies the task of working with databases. Like
ODBC, JDBC allows Java applets and Java stand-alone applications to connect to many
DBMS’s. Theoretically, even other programming environments could use the JDBC drivers to
connect to databases, but that depends on vendors building compatibility in their products. In
case a certain Database Management System does not have a JDBC driver, but does have the
ODBC driver, Sun had made available a JDBC-ODBC bridge, which enables translation
between the two standards.
1. Sun’s JDBC database interface: www.sun.com/products/jdbc
4. Database Administration (I): Backup and Recovery
All the great uses and advantages of database management systems can be wiped out in
seconds when the system fails. These can range from hardware failures, to software lock-ups
and network problems and can lead to data corruption or even disappearance of entire database
data. The higher the importance of the database for an organisation, the higher is the cost of
any partial or total system failure.
Database back-up and recovery procedures are never important as long as they work. But
comes the time when they are needed and found to fall short of their purpose, many people and
organisations have found out the hard way what it means not to have a back-up system in
Further more, traditionally the emphasis use to lay with the back-up, recovery being marginal
to the whole process. However, imagine how important the recovery time is for an organisation
whose databases processes “only” few thousand transactions per minute! What would be the
impact of few hours of downtime? Once a database expert said that “your back-up plans are as
good as your recovery procedure is!” – and it has never been more to the point.
When considering a back-up and recovery plan, it is important to consider as many variables as
possible, such as:
• What if only a part of the database gets corrupted?
• What if the whole database is corrupted?
• What if you need to reinstall the RDBMS as well, not only the data files?
• What if you need to reinstall the OS of the host computer system as well?
• What if you have a hardware failure? How long would it take to set-up a replacement
• Is it possible for a certain type of error or corruption to find its way in the database un-
observed, and by the time it is noticed, all available back-up copies to be affected as
Back-up and recovery plans and solutions are as varied as business needs are. A business with
a large database, which is central to its operations, will have a different back-up requirement
than a smaller organisation with a small database, which is not vital to its operations. When
choosing software, hardware and a methodology for backup, few factors have to be taken in
• Cost (almost always a priority)
• Back-up speed
• Recovery speed
• Back-up frequency
Cost. There will always be the perfect back-up solution out-there, but if its cost cannot be
justified against the benefits it delivers for the organisation, than it will be inadequate. This is
part of the larger business context in which the database designers and administrators work,
and, as organisations are looking more and more for business aware IT staff, understanding the
business sense of IT projects becomes more and more important.
Backup speed. This is the second item on the list, with a various degree of importance. As a
rule, the bigger the database and the higher the number of transactions performed on it, the
more important back-up speed is. If the back-up process lasts 10 hours and during this period
of time nobody can access the data, it will certainly be an inconvenience for the organisation.
Modern backup techniques allow backing up transactions as they are processed, or allow
concurrent work on the database while the backup it is executed, in order to deal with this
issue. Small organisations with databases sizing up to few tenth of megabytes shouldn’t be too
difficult to set-up, but a database ranging from few hundred megabytes to few hundred
gigabytes, where 24 x 7 access is required (such as in the case of banking, financial and on-line
store systems), things become much more complex and backup speed is an essential factor.
As stated previously, recovery speed is as important as back-up speed, especially for large
installations. The recovery speed will determine how long the system is down after a failure –
so the shorter, the better. Web connected systems and high-availability systems, with
permanent demand and high costs in case of failure tend to require fast recovery times, but
even a smaller installation won’t benefit if it takes one or more working days to restore the
database! Another thing to remember is that, in the larger context of an IT system, the recovery
duration does not only consist of the time necessary for copying lost data back to the affected
system, but it also might include re-installation of the database management system, of the
operating system, rebuilding configuration files, installation and configuration of hardware and
fixing anything that might possibly go wrong and prevent the database from being accessed by
Frequency of back-ups is another important issue. If back-ups are performed once per week,
than the demands on hardware space and human resources are less than if it has to be
performed four times a day! The more frequent backups have to occur, the larger the amount of
space is necessary to store enough of them. Also, the more often the backup occurs, the more
important is to automate all, or parts of it, or otherwise the database administrator might do
nothing else than backups. As with any computing systems, reliability of the whole backup
and recovery process is essential. All too many organisations have experienced system failures
only to realise that their backup system doesn’t work and never worked correctly, and they do
not have a valid backup as expected.
1.Storage Mountain – website specialising in backup and storage issues –
2.Backup on a Budget – Unix Review magazine article – good exploration of backup –
especially for smaller installations – http://www.unixreview.com/documents/urm0106i/
3.Detailed explanation of RAID – www.raid.edu
5. Database Administration (II): Security
As in the case of networks and systems security, security is often allocated a minor share of
focus and resources when it comes to designing and implementing a database software system.
In small companies, with a network unconnected to the Internet, and with a small number of
users who can be trusted, maybe security does not play such an important role – and even in
this case, it is a “maybe”. But this is less and less the case in modern database
implementations. More organisations than ever are using their databases to share selected data
across departments. More organisations are connecting their databases to the Internet, and, with
the advance of web services, more organisations share portions of data held in their databases
with suppliers and customers often over the Internet, through a myriad of different
technologies, such as Microsoft .NET, .NET extensions on top of other programming
languages such as C++ or Delphi, network intercommunication protocols such as Corba and
Soap, and obviously, not the least, XML.
With these radical changes in the technology and business areas, it is more important than ever
to assess correctly your database system security needs. This should start at the design phase,
because the system has to be planned with security in mind, and not add it as a quick-fix patch
in the end. When considering security implementation, there are numerous factors to consider,
but here are some of the most important:
a) Maximum costs of possible security breach – probably a decisive factor in designing
security measures. What is the maximum damage that a possible intruder could inflict on
the system? If the total costs of a security breach on the database system cannot amount to
more than one thousand pounds, would a five thousand pounds investment in security
implementation be justified? However, in most modern organisations assessing the real
cost of a security breach is a complex matter – how much does it really cost disrupting the
activity of several departments for few days? How much does personal privacy cost? If the
organisation is storing personal information about people outside its boundary, is it possible
that they will seek legal action if the information is stolen and misused? How much would
that really cost in financial term? What about the long term reputation damage and business
loss if things become public?
b) The human and social factor. Traditionally, database designers and implementers did not
pay much attention to the human and social aspects of the environment their systems is
performing in, but this is changing. One of the most known hackers of all times, Kevin
Mitnick, imprisoned in USA for extensive break-ins in numerous computer systems,
refused to reveal his techniques and the way he unlocked complex security systems, but did
point out that companies should concentrate more resources around their employees when
it comes to security, instead of buying expensive defence systems. Social engineering is a
well established topic in the computer security field, and it usually refers to employees of
an organisation unknowingly releasing sensitive information and helping outsiders gain
access to IT systems through their ignorance. That is why security implementation in any
IT installation, including database systems, should include training and awareness efforts
directed at the future users of the system.
c) The system boundary. It is important to carefully analyse the real boundary of the
database system you are about to implement. This aspect increases more and more in
importance as connectivity is the word of the day in the IT industry. LAN’s, WAN’s,
ethernet, token ring, ADSL, ISDN, proxy’s, firewalls, gateways, wireless networking – all
these technologies have been designed and are further developed to connect IT systems
further and further. Obviously the web connected databases have the largest system
boundary, with a potential user base of millions, if not hundred of millions of people – and
thus worth the highest investment in security. But probably more dangerous than the
obvious cases are the less obvious ones. You might have implemented your database
system strictly for an internal, presumably secure LAN network – but users might be using
wireless un-encrypted and unsecured connections from their laptops to access your
database – the compromising the entire setup. Another example might be that of a local
network with a poorly configured and protected connection to the Internet. The conclusion
is: carefully analyse the environment were the database is going to operate as a whole,
including the less obvious aspects. If necessary don’t hesitate to liase up with other IT
specialists, such as networks experts, operating systems experts, communication experts, to
determine what is the overall security status of the database you are going to implement.
• About.com - “Database Security Issues: Inference”
• University of Essen “Database Security” – course materials (www.wi-inf.uni-essen.de/
Database Implementation Using
1. Intro to Access and the Friends
The first thing that you need to know about Microsoft Access is that is not like any other
Database Management System. Actually, Access is not even a DBMS. At least not only a
DBMS. It is an integrated environment for developing, documenting and administering
database back-ends and database front-ends, or database applications. This is rather uncommon
in the word of databases, where the whole back-end matter was and is usually an entirely
separate issue from the front-end matters. Not with Access. This makes for a suitable tool for
beginners, ready to get a basic database system, including front-end user interface, ready in a
matter of, maybe hours.
However, as you can’t have them all, Access’s easiness of use comes at a price. The Jet
Database Engine, which comes with Access, has been initially designed as a ‘desktop
database engine’ (and still is one), suitable for use on a single, unconnected computer. With all
the later improvements and upgrade efforts from Microsoft, the Jet engine is still a small scale,
low user capacity database management system. It can handle only relatively small databases –
in industrial terms speaking, of course – and if more than ten users connect to an Access
database in the same time, performance will suffer considerably, as far as unacceptable for
day-to-day use. That is why any person who intends to work in the database field usually ends
up learning and moving to larger database management systems, such as DB2, Oracle, MySQL
or Sybase – but this is not a rule, of course. That is also why Microsoft has been pushing lately
vigorously for tighter integration between Access and Microsoft SQL Server, with the intention
of using Access as front-end and SQL Server as powerful and scalable back-end. Some of the
Access 2000 kits come actually with what is called ‘Microsoft Data Engine’, or MSDE, which
is nothing else but a scaled down, reduced version of Microsoft SQL Server, but definitely
more capable than Access’s Jet Engine.
One of the most important components of Access is the table. Tables show up under the tab
with the same name, and they are the actual back-end of the database system. They can be part
of the local Access database, or linked, residing in a different database, possibly on a remote
system. The remote database where linked tables reside doesn’t have to be Access. If fact it can
be Microsoft SQL Server, it can be Paradox, it ban be FoxPro, or a variety of other database
formats. Access comes with the necessary utilities for creating and modifying the table
structure, but it only woks for the internal, local tables, and not for the linked ones. To find out
the necessary steps for creating a table, please see the Access help. Columns in a table have a
data type. For details on data types, and how or when to use them, as well as other table
properties, please, again see the detailed description that comes with the help files.
One note on table design: Access provides a data-type for columns called ‘AutoNumber’.
Other Database Management Systems often provide data-type with similar functionality. Once
a column is set-up as ‘AutoNumber’, control over its content is taken over by Access. For each
new record, it will be filled automatically with a number one unit higher then the previous
record. This will provide with a ready-made, unique identifier for the records in the table, and
it seems like the perfect solution for insuring record uniqueness. Many database programmers
are tempted to think about it as a real blessing. But it is not. All it provides is just a unique
number for each record, but that is no guarantee that the rest of the information contained in
that record – the part provided by the user, is not a duplicate of an existing record. Thus, it only
provides with the illusion of uniqueness, and illusion is a dangerous thing, even in the world of
databases. Furthermore, experience has shown that information in most, if not all, business
systems, has already a way of being identified as unique for real life purposes, even before any
database implementation is considered. Experience has also proven that, if a business
information has no unique identifier in paper format, something is fundamentally missing from
the business model. A unique way of identifying data has to be conceived, even if a database is
to be implemented or not. Conclusion: stay away from ‘AutoNumber’ and the likes, because in
the long term they will bring more trouble than benefits. If you have no choice and need the
computer to generate unique identifiers for new pieces of information (records), generate them
yourself using programming in the front-end, to have full control over what is happening.
The next Access component is the query. Again, queries can be found under the tab with the
same name. They are nothing else but stored SQL statements, which can be executed against
the tables in the database, or used as record sources for forms, reports or other controls, just
like tables. But that is not what attracts so many people to queries. The shiny part is that
queries come with a drag-and-drop tool for quick and easy creation of SQL statements. For
beginners, un-initiated in the dark mysteries of SQL, it is certainly a recommended way of
getting things going. However (databases and programming are full of “however’s”), there is a
downside. Queries and ADO don’t really work together, and it doesn’t seem, in the light of
latest developments from Microsoft, that they ever will. Queries are somewhat cumbersome to
manipulate from VBA code, mainly through the DoCmd.RunSQL object method. But this will
only run action queries (UPDATE, DELETE etc.), with queries that return a recordset basically
impossible to run or use from VBA code. Also, in case of back-end migration to Microsoft
SQL server, or some other database server, which happens often when databases grow in size
and need to scale-up, queries will be useless. They use Jet SQL, the SQL flavour used by
Access with its Jet database engine. So they will have to be scrapped and all functionality
implemented from scratch. Lastly, they offer only a limited functionality through the drag-and-
drop interface, resulting in more complex SQL constructs impossible to implement without
manual coding. Conclusion: use them and loose them. As soon as you get comfortable enough
with SQL, use it directly in code. Or better yet, use them to generate the necessary SQL
statements, and then copy and paste in your VBA code – which will give the opportunity to
tinker with SQL and learn more about it in the process. And at last, but not the least, to get you
started with queries, Access help is your friend.
The form is in line for the next Access component. Although it occupies the third position in
this exposition, the form is very important indeed, and even worst, the most complex
component Access has to offer. That is because forms and modules together are the equivalent
of the front-end programming environment, for building graphical user interfaces to our
database. Forms and modules use Visual Basic for Applications, a twin brother of Visual Basic
if we may say so. There are lots of things to say about forms, and even more to learns, but they
wouldn’t all fit here. As usual, few tips here, and the rest can be found in the usual help files.
Forms have properties, and so do the graphical and non-graphical controls placed on them.
Most of the properties can be changed at design time, as well as run-time, using programming.
Forms and controls also have events, which can be used to trigger more actions. Because the
whole thing happens in a windowing environment, first thing to do when writing some code is
to decide which event will trigger it. There are a variety of events, to suit even the most exotic
scenarios, and it is always worth investigating the help documentation to find out exactly when
they are supposed to happened – in order to know when the code you write will happen.
Subforms are forms on their own, but in the same time of another kind, because they are
embedded, on included on the parent form – which is a normal form on its own. To create a
subform, create a normal form, and then drag-and-drop it on another form, which will become
the parent form – thus the subform will also be called child form. They can successfully be
used to build complex database interfaces. However – and you notice this becomes a favourite
word – few rules apply:
a. Subforms are mainly used for displaying recordsets different than the one on the main
form – essentially information drawn from two different tables or queries. If the parent
form and the subform are linked to the same table or query, than there is a good chance
that you have complicated things unnecessarily.
b. Usually use the main form for information to be modified/amended, and the subform for
information to be displayed only – or vice-versa. Don’t place information to be edited on
both of them. Access will allow you to do that, but this combination will create real
head-aches with data validation and checking, and with events generated by user trying
to enter or leave the subform after amending data.
c. Try to understand properly the difference between the container object on the main form
that holds the subform, and the subform itself. They are different and their properties are
different as well. Figure which one you need to reference in your code and when.
Forms also have a code section attached to them, where VBA programming accomplishes
necessary actions. The code sections is very similar to a code module (see bellow), but you can
place in it functions and subprocedures which are visible only from the form.
Modules are code/programming containers, but without forms attached to them. They behave
the same as code under forms, and they are usually used for storing public functions,
subroutines and variables, which are called from different locations in your project/application.
You can place public items on your forms as well, but that would make them difficult to locate
and troubleshoot. It is rather more practical to have a modules called “modPublicFunctions”
where you could store all public functions in your project.
The reports are part of the database front-end, and in essence have the same role as forms – to
display data. Only that reports are specifically designed for printing their content, so data
displayed on them cannot be modified by the user directly. Many times, when information has
to be displayed on-screen only, some programmers choose to use form, others reports. It is
really up to you, and it depends if in the future that information will have to be printed, in
which case the reports are the obvious choice. You can place on reports the same kind of
graphical controls as on the forms, such as text boxes, combo-boxes and list boxes.
Macros are just macros. They are a way of programming without actually doing any
programming. They offer a simplified interface for creating the equivalent of a function or
subroutine. However, they offer limited and inflexible functionality, and keep the developer
away from what is really happening in the application. With rare exceptions, it is
recommended that all coding is accomplished using modules and forms, and avoids macros.
2. User Interface Design Principles
Why user interface design principles? Is there such a topic in Access documentation? Well,
unfortunately there isn’t one. That is why this section is needed. Unfortunately again, even
software design books don’t have a section on user interface design, and those that have it tend
to contain high-level tips, such as “The interface should be easy to navigate”, or “The interface
should be user friendly”. All the above is definitely true, but few or no books tell you how to
do that. It is a bit like telling automobile design students that cars should be safe and
economical, but explaining to nothing to them about airbags or electronic fuel injection! In
other words, they would be left to reinvent the wheel (and all other mechanical components!),
so to speak.
That is about what happens most of the time with software engineering or database
programming students. The tendency is to drop controls on a form as and when needed, re-
shuffle them around when more space is needed, then create another form when things really
run out of … screen. Then the navigation problem occurs: soon we realise that the user must be
able to move somehow from a form to another, so two solutions come to mind:
a. Either place a bunch of buttons on one of the forms (usually the first one that was
created) which will open the other forms, or
b. Place ‘Next’ type of buttons on each form, thus creating a ‘chain’ of forms. The order is
not always important, usually corresponding to the one they were created.
Rarely somebody things of closing/hiding away the previous form when opening a new one,
thus we end up with a screen full of overlapping forms. In the case of the ‘chain’ model, many
times the user finds him/herself stuck at the last form, with no way of finding his/her way back,
and no other choice but closing the application and starting all over again. All the scenarios
above would be the equivalent of the ‘square wheel’ stage in the history of automobiles.
But enough with the criticism. The main conclusion stemming from the lines above is that, if
car designers don’t have to reinvent the engine to build decent automobiles, why would you
have to reinvent the user-interface design principles to build a decent user interface? And here
we go: the first in line is a high-level tip (notice, consistency!). Actually a very high-level one.
To accomplish good graphical user interfaces, you have to wear the user’s shoes. Before
drawing up anything on the paper, or writing any piece of code, stop for a moment and think
about your user experience. Think about happy moments and think about painful ones. Think
about good applications which were a pleasure to use, and think about dreadful ones, which
made you think of turning the monitor into a flying projectile. Think of what made you more
productive, and which features made application cumbersome to use and interact with. Most of
those reading these lines should have behind enough experience as a computer user to be able
to accomplish this step. This is your great chance to get even with the world of software – good
and bad! Make the most of it and build that piece of dream application!
All along the design process, and while coding the user interface, remember to put yourself in
user’s shoes. If you would open for the first time this or the other form, what would you be
looking for? If you would be searching for a certain piece of information, where would you
expect to find it in your application? Of course, computer users are not all a bunch of mass
produced identical characters, but it is well known that programmers who can emulate, or
guess the average user behaviour build the best applications.
And because one high-level tip is not enough, here it goes the second one: can’t create or make
something entirely original? No problem, so the vast majority of other programmers and
software engineers on this planet (and probably on other planets as well, just that we don’t
know it for a fact yet). Just learn from others’ work. Don’t misunderstand me. Copyright and
intellectual property theft are serious things. You are not supposed to get somebody else’s
application, put your name on it and sell it as yours. You can’t do that even with part of their
application. But you can certainly look at it and learn how it is done. Understand the
underlying principles and apply them to your application. Find database applications, such as
those coming with Access (Northwinds and Orders Database), or those distributed with sample
CD’s from other commercial software manufacturers. Compare, analyse, decide what is good
and what is not so good, and improve your design style.
The first thing to do when programming your database front-end is the application structure.
That can be represented as a navigation diagram, such as the one bellow:
Clients Clients List
Details Form Form
Usually arrows represent the sense of navigation: if you can go through in one direction only,
or go through and come back – in both directions. The navigation can have horizontal
branches, such as:
Clients Input Personal Personal
Form Details Form Details Form
These sections will end up looking similar to MS Windows wizards, with ‘Back’ and ‘Next’
buttons on each one of them. There might be few cases when they are suitable, but remember
a. Normally the information on them has to be connected in some way, otherwise it
doesn’t make much sense using them.
b. Too many of them will make for a tedious and frustrating experience. Three or four
should be just about enough, if you don’t want your software to feel like a maize
labyrinth – keep clicking ‘Next’ until you reach the ‘way out’!
c. Make sure you control very well what is happening when the user clicks the ‘Back’
button or tries to abort the whole thing all together – e.g. information on half of the
forms is saved, while the other half is lost.
Going back to the navigation diagram issue, it is good to start with it even if you will return
latter and change things as needed. Try to structure forms according to some logical pattern.
For example you might structure them by functionality:
New New New All All All
Client Invoice Employee Clients Invoices Employees
(list) (list) (list)
Section for creating new
records Section for viewing lists
of existing records
Rather more common is to group forms by entity – by their connection to a certain table in
New Amend List New Amend List New Amend List
Forms relating to Forms relating to
Forms relating to Invoices table Employees table
Whichever you choose, make sure it suits the end user needs and it makes sense to deploy.
Also, as usual, consistency is the key. Be consistent throughout your application.
An easy to follow model is:
a. From Main Menu form, which is the first one to open after application starts, go to
forms which contain list of records – e.g. list of all clients, list of all invoices etc. From
list forms, the user can either:
b. Select a record and open a details form to view or amend it, or,
c. Go to the same details form as above, but with empty fields, ready to create a new
d. Select a record and delete it, by pressing the delete button on the list form.
The above model is illustrated bellow. Notice that the list form contains all records, but with
limited information about each one of them (just 3-4 columns). They are all in read-only mode,
and cannot be modified directly on the list form. The details form contains fields for each piece
of information in the record (all columns in the underlying table). It is used for creating new
records, and modifying existing ones. Beside the ‘View’ and ‘New’ buttons on the list form,
you can see the ‘Delete’ button, which, when pressed, deletes the selected record from the list
to the left and from the database. The ‘Close’ button opens the menu form (where the user was
coming from in the first place) and closes the list form. Here it goes:
No Name Surname Tel.
Open details form with blank
fields for new record
6 Open details form with
7 selected record in it
11 Delete selected record from
12 New the list and database
16 Delete Close current form and return
17 to previous menu
This basic model can be applied successfully throughout the front-end software. It can be
modified and extended to cater for different user needs. For example, on the list form a list box
can be added for selecting an item to sort by. Or a text box for searching records by a value –
that is if the number of records in the database (implicitly in the list) is large.
Then there is the issue of buttons – how many buttons do we need on a form? A ‘Close’ button
would do? What if the user changed their mind and doesn’t want to save the changed? Maybe
an ‘OK’ and ‘Cancel’ buttons should do? What if the user spends a while on that form, and
wants to save changes without exiting the form? ‘Save’, ‘Undo’, ‘Close’? Again, there are no
hard rules, but here are the guidelines:
a. On forms which don’t save information to the back-end database, with the role of
displaying it only, or some other functionality - such as the list form above, a ‘Close’
button should do. There are no changes to be confirmed.
b. For small to medium input forms, where data is editable and linked to a table or query
in the database, such as the ‘details’ form above, ‘OK’ and ‘Cancel’ should do. Both
close the form when pressed, but one saves changes while the other discards them.
c. For large input forms, where the user might spend quite a while inputting or amending
information, a ‘Save’ and ‘Undo’ buttons are useful, so that the user can save and
discard changes without having to exit the form. Besides the two buttons above, a
‘Close’ buttons will be necessary to close the form. However, remember that a lot of
information on a form is not a desirable thing, so try to avoid large forms if you can.
This is another subject well discussed when it comes to user interfaces of any sort and kind.
That is why we are not going to give it much space here. Things go like this:
a. No more than three colours in your application. It is a business application, not an art
gallery, and people will likely stare at it for days.
b. The same goes for colour tones – look for mild, neutral ones, easy on the eye.
c. However, make sure that there is enough contrast for words and numbers to be easy to
d. Grey as background seems to be an established option, so unless you really want to go
other way, stick with it.
Mouse versus Keyboard
And then there is the eternal dispute between mouse and keyboard aficionados. Many
experienced or advanced computer users tend to prefer using keyboard more often than mouse,
because with a properly designed application, a considerable amount of time can be saved
using only the keyboard – and not having to move your hand between the two all the time. But
there are “the others”, who find it annoying to learn all those keyboard shortcuts and key
combinations. The answer to this dilemma lies with your users. Consult them closely, talk to
them and learn as much as possible about them. If they love their mouse, find! If they want
keyboard only, than that’s the way to go. If they are OK with both, but prefer as much
keyboard actions as possible, than make sure to provide enough hot key combinations in your
Usually, in case of mouse lovers, there isn’t much extra to do. But, if you deal with keyboard
guys, the story gets a bit longer:
a. First thing to do is to check and amend accordingly the tab order of ALL controls and
ALL forms. Also, be careful with which controls you leave out of your tab cycle.
Normally, these two operations should be performed anyway, because many users tend to
move between fields on a form using the TAB key on the keyboard, but in case of a
‘mouseless’ environment, pay extra attention to these steps.
b. Provide keyboard shortcuts for standard opperations, such as closing and opening forms,
saving and undoing changes – at least. Usually you accomplish this using the ‘On Key
Down’, ‘On Key Up’ and ‘On Key Press’ events of the form you are on. These will
happen every time a key from the keyboard is pressed - while the focus is on that form,
so the next step is to use your code to check which key(s) have been pressed. The Access
documentation contains an appropriate section for these events.
c. Use appropriately the ‘ALT+’ shortcuts, which you obtain for command buttons by
placing an ampersand (&) character before one of the letters on the button’s caption.
When you will press the ‘ALT’ key and that letter together, the button will be clicked like
you would have used the mouse to do it. An easy way to create shortcuts, specially for
saving records, undoing changes and closing forms. Two main advantages: (i) the
shortcut will be active and available only for the form where the button resides and (ii)
the shortcut will be easy to spot by new users since the letter preceded by the ampersand
character will appear automatically underlined.
Remember that there are environments where the mouse-less operation is a ‘must’, such as the
case of some call centre operators software. Even where it isn’t a must, it might make a real
difference for users, such as in accounting, billing, data input operators and typists.
Practical Demo: Introductory Menu Form
3. Programming Good Practice
When an Access database is created (as any other piece of software for that matter), a
programmer writes the code. If the database is a large database, and the company has enough
staff, it is likely that more than one programmer will work on the database project. After the
coding has finished or, in case of a larger project, after the coding has finished on one of the
modules, the programmer or programmers involved have to test and debug the application.
Again, if the project is a large one, and if the company is large enough to have specialised
software testers, than they will do the testing and will report back to programmers for
After the database application has been shipped and deployed at the client side, if any further
errors are detected, than the programmers are called in to debug them. If any amount of time
has passed since the database was first created, it is possible that the initial programmer or
programmers who made it don’t work for the company anymore, so another programmer or
programmers will be drafted in for the task. They will have to familiarise themselves with the
project and the code content, and only after that will they be able to do any useful work and
start chasing the errors. After another period of time, the client might ask for improvements or
additions to the database software – the developer company might decide to release a new,
upgraded version. Again, previous programmers or new ones have to understand the code base
in order to be able to improve or extend the application.
In other words, the moral of the story above is that, many times along the life of a software
application – and that includes database applications – new people get involved with the
project and the first thing they have to do is understand the existing code. Without
understanding the existing code, they won’t be able to extend it, they won’t be able to
troubleshoot errors, they won’t be able to fix them. Furthermore, even the programmer who
wrote the code initially many times needs to get re-acquainted with it. After few years and few
tenth of thousands of lines of code latter, most programmers won’t remember by heart what
and exactly how an application that they’ve made was supposed to do.
All the time spent by programmers reading and understanding the code adds to the final cost of
the project, and of the final software. And poorly written code can increase exponentially the
time necessary to understand it! And it is not just a matter of time and money, it is also about
intellectual effort and human patience. Programmers all too often find out how frustrating and
nerve wrecking is dealing with low quality code – as opposed to comfortable and satisfying
time spent working with clean, clear and neat code. That is why programming style and good
practice are essential skills needed all the way from the beginning. They will cut down costs
and stress, and increase productivity and work satisfaction.
This stems from the need to easily recognise and remember identifiers – such as variable
names and object names (forms, tables, controls etc.). The first rule when it comes to naming,
and programming style in general, is to be consistent. Whatever model you use for naming
your variables and objects, make sure you don’t change your mind and stop using it half way
through the project.
The recommended practice when writing code is to add a prefix, usually of three letters, in
front of identifier’s name, which denotes what they are – their type. For example:
curMyWage – will be a variable of type ‘Currency’
blnIsMale – will be a variable of type ‘Boolean’
frmInvoiceDetails – will be an object of type ‘Form’
There are few lists available with suggested prefixes, one of them on Microsoft’s web site, but
whichever you choose, make sure you use it through all your application.
The second recommendation, as you might have guessed already from examples above, is
using whole words when naming things. It makes names easier to understand, and specially
easier to remember when they need to be referenced again in code. An old style was to separate
words in an identifier with the ‘_’ character, like in “bln_server_is_up”, or “int_counter”; but
the recommended practice now is to start the name of the variable/object with a lower case
letter, and then use a capital letter for the first letter of every new word in the name, like in the
And one more thing: try to think of meaningful names for your identifiers – something related
to the information they are to store: ‘lngInvoiceNumber’ tells us more than ‘lngMyVar’.
Code alignment is specially useful for quickly spotting sections’ beginning and end. It is used
with mostly everything that has a beginning and an end. For the example the contents of a
function or subroutine , except its header and ending line, will be indented on tab from the left
edge. Thus, it’s easy to spot where everything starts and ends, like bellow:
Private MyFunction() as Long
The same rule applies for ‘For … next’, ‘If … Then’, ‘While … do’ and ‘Loop … Until’
statements. It goes like this:
While (a = b) do
For (I=0; I<10; I++)
… and so on …
Make sure you preserve the same indentation, where there is no other reason to change it. Pay
attention to nested statements, which will have two or more level’s of identation:
For (j=1; j<=8:j++)
If (x=z) Then
By keeping with these simple indentation rules, your code will be easy to read and nobody will
have problems identifying where things start and where things end. Specially in the case of
multiple nested statements, this can be a serious problem.
Comments inserted in code are a programmer’s great chance to fame. Short stories, novel
chapters, comic essays, personal diaries, all the lot goes in here! Going beyond the funny part,
there are known cases when programmers have inserted in their code, under the shape of
comments, things, at least to say unexpected, for such a place!
But beside final refuge for releasing supercharged imagination, code comments do serve a
practical and important role. They help those coming after you, and even yourself, understand
what the code is supposed to do and how. There are no hard rules when it comes to
commenting your code, but again, here as well is good to be consistent. Choose a certain style
for yourself and follow it throughout the application.
One common suggestion is to have a body of comment at the beginning of every function,
subroutine or class module (in case you decide to do object oriented programming in VBA), in
a standard format. It is suggested that this piece of comment explains what is the purpose of
the subroutine or function, what are the inputs it expects and/or accepts, and what are the
outputs (if any). Also, for class module, it is important to mention if they interact with other
classes or objects, by sending messages to them.
One important aspect to remember about this header comment is not to include in it details
about how you are going to accomplish the purpose. That is because, in case you decide to
make changes to the code latter, for optimisation or debugging purposes (and that is going to
happen more often than you might expect, at the beginning of an application as well as later in
its life – as you learn more tricks about the programming language or you get more ideas in
time about how to better accomplish something in your code), the header comment will quickly
become outdated. In the same time the purpose, inputs and outputs are less likely to change
Following the header comment, inside the actual body of the function, subroutine or class
module, it is up to you how much detail to provide. But usually, the more you explain what you
are trying to do, the better. Try to be clear and logical. Bellow is an example of an Access
subroutine commented for clarity. Comments have been italicised for clarity. And, by the way,
it is not supposed to be perfect!
'******************** Header Comment *********************
'Purpose: changes the colour of the labels’ bakground in the form depending
' on the type of record - invoice or credit note; it also changes
' the caption of the form
'Input: a string variable conveying if the form is an invoice
Private Function changeFace(strRecordType As String)
‘ make a temporary Access control object
Dim ctrTemp As Access.Control
‘ make the two colour codes constants, so that they can be replaced just here,#
‘ and not throughout the code
Const CIntColour1 As Long = 255 ‘ red
Const CIntColour2 As Long = 16711680 ‘ blue
‘ go through each control on the current form
For Each ctrTemp In Me.Controls
‘ if, according to naming conventions, the first three letters of the name are
‘ lbl, which means it is a label control
If Left(ctrTemp.Name, 3) = "lbl" Then
‘ check if the record opened is a credit note
If Trim(strRecordType) = "C" Then
‘ and change the background colour of the label to credit note colour
ctrTemp.BackColor = CIntColour1
‘ if is an invoice
ElseIf Trim(strRecordType) = "I" Then
‘ change the background colour of the label to invoice colour
ctrTemp.BackColor = CIntColour2
‘ go to next control on the form
‘ if the current record is an invoice
If Trim(strRecordType) = "I" Then
‘ change the caption of the form correspondingly
Me.Caption = "Invoice Details"
‘ but if it is a credit note
ElseIf Trim(strRecordType) = "C" Then
‘ change the caption accordingly
Me.Caption = "Credit Note Details"
Clear, Logical Programming
Nevertheless crucial, this topic is rather difficult to explain. And that is because it is not about
following hard and clear rules (even less than the previous sections), but it is more about
acquiring and maintaining a certain spirit while programming. It is more about something that
is developed in time, with experience, and with reading from books. An attitude of logical
abstraction, a pursuit of simplicity and clarity. One advantage of programming is that the same
thing can be accomplished in many ways, but that can also be one of its great pitfalls. There is
what is called sloppy, dirty programming, and there is what is called elegant, clean, light
programming. It is a matter of experience and years of practice of course, but even the longest
of journeys starts with one small step, so it is important to aim permanently for code that is
easy to understand, by you and by others. It is important to aim for code that is easy to modify
and extend when time comes and it is necessary.
Practical Demo: List Form with Delete button
4. Using ADO with Access
ADO stands for ActiveX Data Objects, and it is a technology created and promoted by
Microsoft for interacting with databases. If you are wondering, yeas, there are some other
technologies available for interacting with databases, most of them available before ADO was
even on the drawing boards and the company from Redmond. Among them is ODBC, OLEDB
and JDBC. One close relative of ADO is DAO, which it actually replaced, and it is still
available, though with diminishing functionality and usefulness in Access 2000. The two
technologies, DAO and ADO, with some exceptions, are rather similar in syntax and
functionality. If you ever worked with DAO before, moving on to ADO won’t be that difficult.
Actually, if it is to be honest, ADO is and improvement, or an upgrade of DAO, but it seems
that, for some (shall we say marketing) reasons, the name had to be changed in the process as
Another thing to get cleared up about ADO is where does it stay in relation to SQL. Many
people (including the author, at some point in time) wondered: “If we have SQL, which is a
language for talking to databases, why do we need things like ADO, DAO, ODBC etc. to
interact with databases? Do they all do the same job?” Well, not exactly. It’s true that ODBC,
OLEDB, JDBC, ADO and DAO do about the same job in between themselves – but not with
SQL. SQL might be suitable for what is was intended – as a query language, but that is not
enough for interacting with a relational database management system. Think about the fact
that, when writing your SQL query, there is no way to tell in which database do the table or
tables mentioned reside. Take for example the following example query – a simple one, really:
“UPDATE tblClients SET ClientAge = 25”
This SQL statement will set the ‘ClientAge’ column for all records in the ‘tblClients’ table to
the value ‘25’. But where can we find this table? Is it on the local computer? Is it on a remote
computer on the network? In what kind of database is it residing? Is it an Oracle database, is it
a Paradox one? How is our application to know all these pieces of information, how is it to find
the computer, how is it to know how to talk to that particular database management system?
Here is where things like ADO, DAO and the other friends step in – just pick one of them.
They are called Call Level Interfaces – in short CLI. They take care of establishing a
connection, finding the database on a remote system, tuning the connection parameters for
optimisation (such as the size of local cache and the refresh intervals), closing the connection
when it is not needed anymore, and so on. They are capable of accepting SQL statements from
our application and passing them along to the DBMS. They work together with SQL, not
instead of it and not against it.
But enough with generalities, lets see how you can use ADO with Access, and to what purpose.
Here are few examples of things you might want to use ADO for:
a. Find a certain row (record) in a table, and update/modify the value of one of its
b. Delete a row from a table using VBA/ADO code.
c. Check to see if a record in a table, according to certain supplied criteria, does exist.
d. Use values supplied by the user to add a new record to a table.
The main idea here is that you can manipulate data in your database using ADO, without
actually binding it, through the ‘RecordSource’ property, to a form. It usually happens that
ADO comes in most handy when you want to do operations on your data ‘behind the scenes’,
from the programming code, and not using data objects available on your form.
Let’s get first familiar with the objects available in ADO:
a. The Connection object is the first thing that you will need. Normally, in order to do
anything on a database, you need to create and open a connection in the first place.
Luckily, if you just want to work with the tables contained in or linked to your Access
application, you can use a default Access connection object as your connection, instead
of creating a brand new one. This default connection can be referenced and used using
the ‘CurrentProject.ActiveConnection’ format. For creating and opening a new
connection, please see Access documentation which has a detailed section on this topic.
The main thing to pay attention to is a connection string, which gets passed to the new
connection object in order to activate its ‘Open’ method, and which is different from
DBMS to another, and has to be formatted correctly if it is to work. Sometimes this can
b. The Recordset object is the rough equivalent of an Access table as far as ADO is
concerned, but in the same time it is not exactly a table. It is a collection of records
(recordset) – like a table, only that you can generate recordsets dynamically, based on
SQL queries, so the data in a recordset can be actually pulled on the fly from two or
more tables. The same, if a recordset is based on a SQL query, it might just contain
only some of the rows from a table, depending on the SQL statement content. In order
to use a recordset, you need to create the object, initialise it and open it first. Something
‘ create object
Dim rstExampleRecordset as ADODB.Recordset
‘ initialise it
Set rstExampleRecordset = New ADODB.Recordset
‘open it now
rstExampleRecordset.Open strSQL, CurrentProject.Connection, adOpenDynamic,
‘ close the recordset when done
‘ and release memory resources by killing the object
Set rstExampleRecordset = Nothing
‘ all done !
You might have noticed that we needed some pieces of information to pass as arguments to
the ‘Open’ method, in order to be able to open the recordset. One of them was the ‘strSQL’
string variable, which, in our case, is assumed to contain an SQL statement, but instead of
it we could have used the name of a table in database. Another essential piece of
information is the connection which the recordset will use to talk to the database. In our
case, this was the default connection that Access uses, and which we talked about just
earlier on. You will figure out the rest of the arguments when you read the recordset section
in Access documentation. There are some nice examples there, too. You might have
noticed that, after we are done with the recordset object, we are closing it and releasing the
memory resources allocated to it. Try to get used to performing these operations, because if
you don’t, you might encounter nasty memory leakage problems in your application, which
are usually difficult to trace and troubleshoot. The same applies to the command object
c. The Command object is used to run SQL statements against the database. Normally,
these would be SQL statements which do not return results, but rather act on the data in
your tables, such as ‘UPDATE’ and ‘DELETE’ type of statements. The Command object
needs an open connection object to run, just like the recordset object. See the Access help
on how to use this object and the required syntax.
Practical Demo: Detail Form integrated with previously developed List Form
5. Using SQL in Access
We have already touched on SQL several times along our Access journey, but it is the time
now to dig a bit deeper in its fruitful territory of “database conversation”. SQL might be often
called a “programming language”, but it definitely isn’t one – not in the sense of your average
programming language, like Java or Visual Basic. It was specifically designed to work fast on
datasets – information which is arranged in a table-like format, with columns and rows. It can
do miracles of tasks otherwise complex. It can embody truly powerful activities in few short
lines of code. The main purpose of this chapter is to reveal more of the ways you can use SQL
in Access. It is not a pure SQL story, but rather a story about how SQL can be convinced to
work hard for your application, using the tools provided by Access.
One of the first things to keep in mind is that although SQL is supposed to be a standardized
language, almost without exception, each vendor has implemented a slightly “customised”
flavour, for the “benefit of their clients”. So, although you will find most things where expect
them to be, some will be different. Check carefully the appropriate documentation for the
vendor you are working with, and make sure you are aware of differences and peculiarities in
their own version of SQL. Strangely enough, not even the same vendor is a guarantee for SQL
compatibility. Microsoft Access and Microsoft SQL server are both produced by the same
company, but they use two different flavours of SQL. Access uses what is called Jet SQL,
while SQL server supports another version called T-SQL – or Transact SQL. And things go
even further than this, If you are working with Access, it doesn’t necessarily mean that you are
going to be using just one version of SQL. Usually SQL has to be understood by the back-end,
so even if your front-end is make up of Access forms and reports, if the back-end is managed
by something else, like Paradox or MySQL, you might have to write in the SQL versions
understood by these Database Management Systems.
But, let’s continue our journey in the world of SQL. It is true that writing SQL in Access might
prove a bit more difficult than writing VBA code in Access. Ant that is not because SQL is
more complex than VBA, but because of the poor debugging and syntax checking available for
SQL. If you choose to write and test your statements using the query designer, in SQL view,
some level of syntax checking is available (obviously, that is in case you are writing Jet SQL).
But even this syntax checking is limited and primitive, with rather incomprehensible error
messages at time, or just code sections underlined and no error message at all. If you choose to
write your SQL straight in the VBA code (in your form modules), than syntax checking is non-
existent – SQL is treated like any other string between quotes. This makes it a bit difficult,
especially in the beginning, when things go awry and there is no clear indication of what
exactly is wrong.
The simplest way to use SQL in Access is as a record source for forms, sub forms, list boxes
and combo boxes. In case of forms and sub forms, if you want to display a particular record,
you can set the form’s Record Source property to an SQL statement. Something like this:
Forms!frmClientDetails.RecordSource = “SELECT * FROM tblClient WHERE ClientNumber=45”
We have just told Access to display a record from the “tblClient” table inside the
“frmClientDetails” form. This record can be identified by the fact that the “ClientNumber”
field should have the value ‘45’. You can accomplish the same thing using the filter property:
Forms!frmClientDetails.Filter = “ClientNumber=45”
Forms!frmClientDetails.FilterOn = True
Notice that you have to apply the filter you have just created – the second statement. Also,
keep in mind that in order for the above last example to work, the Record Source property of
the form should have been previously set to the “tblClient” table – during design time, or
during run-time, in code.
Also, a useful use for SQL is limiting the amount of data traffic between the front-end and the
back-end. Sure enough, considering that you have a combo-box or a list-box that displays only
two columns of a table, you can set its “Row Source” property to the table. But that would
mean that the entire table is pulled in the front-end, and after that the two columns are used.
While if you write an SQL statement instead, only the two columns are going to be retrieved
from the back-end:
lstClientList.RowSource = “SELECT ClientNumber, ClientName FROM tblClient”
Of course, you don’t have to do that in code, like above (unless you have a specific reason to
go this way), but you can rather do it at design time, in the property sheet of the list box.
You might have figured out by now that we have been dealing with “SELECT” queries. These
statements are the only ones to return results in the shape of a recordset when executed – and
their name comes from the first SQL key keyword in their content – “SELECT”. All the other
SQL statements either update/amend values in one or more columns of a table, either append
records at the end of a table, either delete records from a table – but don’t return back anything.
Well, almost anything – they might return an answer to let the user if things went through OK
– like an error-level message.
Let’s have a look at the “SELECT” statements. They have a first section, just after SELECT, in
which you specify which columns from table or tables that you are dealing with, want
displayed. Like this:
“SELECT CustomerName, CustomerSurname …”
This would assume that there is somewhere a table, holding customer data, and having at least
two columns with the same names as the two above … But it is possible that, when results are
displayed, you don’t want to see those cryptic column names, but something rather more
friendly. So you write:
“SELECT CustomerName AS ‘Customer Name’, CustomerSurname AS ‘Customer Surname’ …”
… and users will se those nice column headings when the query is executed. Also, notice that
the whole statement goes between double quotes, while the new names for columns go
between single quotes. You need single quotes for column names only if they contain spaces –
otherwise they don’t need the single quotes. But you definitely need single quotes every time
you deal with strings – such as:
“SELECT CustomerSurname & ‘, ’ & CustomersName AS Customer …”
Here we have exactly the same statement as above, with some modifications. The results will
contain one single column, called ‘Customer’ (notice, no need for single quotes in the SQL
statement, since ‘Customer’ doesn’t contain while spaces), containing customer’s surnames
and names, separated (or united, depending how you look at it) by a comma and a space. Like
So you’ve just learnt that, instead of placing simply column names after SELECT, you can also
place expressions, in which you modify the content of these columns on the fly, and only after
that display them. And because we have just mentioned earlier on that strings have to be
included between single quotes, it might be the right time to say also that number don’t have to
be included between anything, while date have to be preceded and followed by pound signs:
#4-Apr-1987# or #15/07/1012# or #5 October 2089#
That’s only so that the SQL parsing engine would figure quickly what kind of values does it
deal with. If the column names you are going to enumerate after “SELECT” keyword are from
different tables, than you might want to add the table name to tell Access which column is
from which table:
“SELECT tblCustomer.CustomerName, tblOrder.OrderNumber, tblOrder.OrderDate …”
In this example we are assuming that you want to pull together information from customers
and orders table. Placing the table name next to the column name, like above, is not
compulsory, but recommended. If you are absolutely sure that the two or more tables involved
don’t have columns with the same name in between them, then you can do without table name
prefixing. Otherwise keep it, if you don’t want to be in for unexpected results!
It is the time now to move to the second part of the SELECT statement. The part which starts
with the FROM keyword – or clause, as they are called in Access – and which lists the tables
that contain the columns enumerated in the first part. Besides listings the actual table names,
more importantly, the FROM section defines what is the relationship between them. And that
is because Access, the Jet engine or whichever other SQL engine you are using, needs to
understand how to piece together all those columns pulled from different tables – they need to
make sets of records together, somehow.
Here is our first, basic example, slightly extended:
“SELECT CustomerName, CustomerSurname FROM tblCustomer”
And Voila, we have a fully grown, stand alone SQL statement, ready to work for us. After the
FROM clause, you can have table names and query names. But remember that, if you are using
queries, they have to be “SELECT” queries, so that they return a table-looking like result when
they are executed. Let’s see a join now:
“SELECT CustomerNumber, OrderNumber, OrderDate FROM tblCustomer INNER JOIN
tblOrder ON tblCustomer.CustomerNumber=tblOrder.OrderCustomerNumber”
You can probably spot that I had the opportunity to specify the JOIN (relationship) type
between the two tables – INNER JOIN, LEFT JOIN, RIGHT JOIN and OUTER JOIN being
the available types. For an explanation of what they do and how to use them, see Access help
in the Jet SQL section. You can also see that I had to specify the primary and foreign key fields
in the two tables, which implement the actual relationship.
Practical Demo: Detail Form with subform suitable for Invoice/Order line editing
6. Access Objects
Sooner or later, if you work with Access, you will realise that most of the things available
come in the shape of objects. Tables can be considered objects, queries can be considered
objects, reports can be considered objects and forms can be considered objects. One of the
most obvious examples of object oriented programming in Access, and probably among the
first to be used is a reference of the kind:
Obvious example, where we tell Access to move focus to a combo box called
“cboClientType”, situated on the “frmClientDetails” form. It is actually quite a strange
situation, because the development environment in Access is built around Visual Basic for
Applications, which is a classic style, procedural language. But, probably because graphical
user interfaces (GUI) programming fits very well around the object oriented paradigm,
Microsoft seems to have added on top of everything all these objects. VBA is still a procedural
language, because we still write functions and subroutines, instead of class definitions, but
throughout the code we work with what is evidently Object Oriented programming. This can
be good and bad in the same time. Good because those not introduced to OO concepts before
can benefit from a “smooth” transition and a gradual acquaintance with this software
development methodology. But it can be also bad, with programmers writing code just because
they know it works, but without understanding the underlying principles.
And now, back to our sheep. Although Access programmers use code such as the example
above, not all of them understand the whole picture. Objects available in Access have slowly
increased in numbers during each upgrade cycle. They usually come grouped in collections – a
sort of an array, whose members are objects of the same type. An example of a collection is the
Forms collection. To reference one of the objects in the collection, you have three available
ways: two of them use the object’s name, one uses the index number (which is its ranking
order in the collection). To reference the “frmClientDetails” form from the example above, you
Forms(7) - assuming that it’s index in the Forms array is 7.
Using the index is usually not a good idea, since adding or removing objects from a collection
will likely affect the index number of individual objects – which will make your code obsolete
and incorrect. The safest thing to use is the object’s name. As you might have gathered, as a
general rule, you use the collection’s name first, then and indication to which member of the
collection you are interested in.
Besides the ‘Forms’ collection, there is also the Reports collection. These two are the most
referenced collections in Access – specially because they were available since early versions,
so many programmers know about them. To make things a bit clearer now, the ‘Forms’
collections refers to those forms which are opened at the moment in time the collection is used.
Every time you open a form in your project, a reference to it is added to the ‘Forms’ collection.
If no forms are opened, the ‘Forms’ collection is empty. The ‘Forms’ collection does not
contain all the forms in your project – not unless you happen to have them all open at a
particular moment in time. Even if you know the exact name of a form in your project, you are
not able to reference it using the ‘Forms’ collection, unless it will be open at the moment of
reference. For the same reasons, you cannot practically reference or work in code with
controls situated on a form, unless that form hasn’t been opened first. Similarly, the ‘Reports’
collection only contains the open reports in your project. The objects in these two collections
have a series of properties available – usually the same properties available through the
properties sheet in design view – and some of them can be modified in code, some others being
read-only. For the example the code bellow changes the caption of the ‘frmClientDetails’ form
– of course, assuming that somewhere earlier the form has been opened first:
Forms!frmClientDetails.Caption = “Client Details”
If the form is not opened before the above piece of code, Access simply returns an error –
something like object member cannot be found in the collection.
7. Testing and Debugging
Testing and debugging go usually hand-in-hand when it comes to software development. In
large software houses, the tester runs the application hard, trying all possible interaction
conditions, and any unusual or unexpected behaviour, from data corruption down to features
whose functionality doesn’t relate to specifications in the design documentation, get reported
back to programmers in the shape of a bug report. Then they have to perform one of the
seemingly least enjoyable and desirable tasks in software engineering: debugging – chasing the
errors and remedying their cause. Normally, the larger the company, the larger the project and
the more complicated the piece of software to be developed, the more formal and complex the
whole debugging process will be (or at least should be), with special and precise forms to fill in
for every step, delegation and specialisation of tasks and generally speaking outright headache!
– unless things are organised properly – in which case we are talking just about a mild
dizziness. Also, in case of a large installation, it is more likely to have specialist software
testing engineers – who have been purposefully trained for the undesirable task.
But not all is doom and gloom. In smaller companies, it is more likely that the programmer or
programmers who developed the software – or database application in our case – are going to
be the one or ones to perform testing and debugging as well. That can be better in a sense, as
they already know the software inside out, and have the opportunity to gain additional skills,
such as human-computer interaction knowledge, interface design and usability principles,
systematic software testing methodologies, systems integration and others. Another thing to
mention is that many times junior programmers are charged with testing and debugging. This
can result out of a mixture of unfortunate (for them) factors, such as being new on the job and
getting the least pleasurable task. Another often mentioned reason for giving testing and
debugging to new programmers is the belief that it is easier to criticise someone else’s work,
instead of doing it yourself, so when you don’t have enough skills to do programming, you
correct others’ code. And in the process it is possible that you will learn a few useful tricks, as
well as pick up on experienced programmers coding style, which, altogether, if you don’t give
up the job in the process, should improve your own skills and make a programmer out of you
in the end. Anyway that’s how the legend goes.
Whatever the circumstances, the essential skill needed for testing and debugging is patience.
Patience added to the ability of turning any problem into a opportunity and challenge makes for
a good start as software tester. The second thing needed as a tester is a systematic approach.
The main activity of a tester consists in trying out every single feature and functionality of the
application on the testing bench, and making sure it works the way it is supposed to . It is about
executing every possible action, trying every possible combination, covering every inch of
functionality. If the tester doesn’t do it, not matter how exotic the functionality is, one day, by
accident or deliberately, an user is going to try it, and if it doesn’t work or brakes the
application, at least one extra client is going to be unhappy with the product he or she has
purchased. And, as it usually happens, it is not just about one user, but they come in much
But, because applications today, no matter how small, are so complex and pack so many
features, covering each and every one of them can be a daunting task, if not an impossible one.