Category Archives: MS Access General Information

MS Access – Make Tables Read-Only

Now here is an interesting question!

My first reaction to such a question is why? Since proper database design implicitly prohibits the users from ever directly accessing the database tables, this should never truly be an issue for any developer. But then again, as I have learnt of the course of the years, there are so many exceptional cases…

 

A Few Solutions to Make a Table Read-Only

  • If you are using an mdb format, then you could simply implement User-Level Security (ULS) and simply apply the proper permissions to make your desired tables read-only to your users.
  • A more general solution, and one that would also work in all versions of MS Access, would be to migrate the tables you wish to be in Read-Only mode, into a second back-end file and then set the file attributes to Read-Only. Then link the tables to your front-end.

MS Access – Trig Functions

Have you ever needed to use trig functions in your database?

You may have noticed that although MS Access does offer basic trig functions:

  • Sin
  • Cos
  • Tan
  • Arctangent (atn)

it does not offer any of the advance, ‘Derived Math Functions’, such as:

  • Secant
  • Cosecant
  • Cotangent
  • Inverse Sine
  • Hyperbolic Sine
  • Inverse Hyperbolic Sine

As a developer you have one of two options:

  • Create, or find, a function to replicate these functions
  • Utilize Excel’s trig functions from within you database

 

Create, or find, a function to replicate these functions

If you simply lookup the term ‘Derived Math Functions’ in the VBE’s help file you will find all the necessary information to build your own custom functions. That said, why not simply benefit from the fact that others before you have already done this work for you and simply perform a quick Google search to locate and existing module with these functions. For instance:

 

Utilize Excel’s trig functions from within you database

If you know that the database will be utilized on a computer that also has Excel installed on it, why not simply use it’s powerful library of trig function! Nothing could be easier to do. Simply use a procedure such as the one presented below

'---------------------------------------------------------------------------------------
' Procedure : Atanh
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Calculate the Inverse Hyperbolic Tangent by using Excel's built-in
'             function
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' x                 Value in Rads
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' Atanh(-0.9)       Gives -1.4722...
' Atanh(0)          Gives 0
'---------------------------------------------------------------------------------------
Function Atanh(x As Double) As Double
'This procedure requires a reference be set to the Microsoft Excel xx.x Library
On Error GoTo Error_Handler
    Dim oXls    As Excel.Application
     
    Set oXls = New Excel.Application
    Atanh = oXls.WorksheetFunction.Atanh(x)
     
Error_Handler_Exit:
    On Error Resume Next
    oXls.Quit
    Set oXls = Nothing
    Exit Function
    
Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: YourModuleName/ListDbTables" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, _
           "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

Launch/Open an MS Access Database Using a VBScript – Part 2

In my previous post launch-open-an-ms-access-database-using-a-vbscript I went over the basic concept of using a VBScript to launch a database.

In this post I would like to demonstrate the true power of VBScript for this type of application.

Say, you are a developer within a structured company network environment and you want to standardize the front-end setup on your users computers without having to sit down at each of their computers, one by one. Well, VBScript to the rescue!

The script below may seem scary, but really isn’t. It start by determining the user’s My Documents location. This is where I have chosen to place the Front-End application of the database. You could always alter this aspect, but it has served me very well in numerous routines. Once it has determine the location it determines the location of the VBScript itself (which will be installed with the Master copy of the Front-end). As such, it copies the Master copy to the user’s My Documents. Then it determines the location of the msaccess.exe required to launch the database and then finally launches it!

Once again, I do hope this helps someone out there as I found it hard to come across this information several years ago when I needed it.

'*******************************************************************************
'Date:		2008-05-27
'Author:	Daniel Pineault / CARDA Consultants Inc.
'Purpose:	This script should be located on a network share in the same
'		directory as the Front-End which it will automatically copy
'		to each user's MyDoc\Subfolder\ and then launch
'		Give your users a link to this script and it will do the rest
'Copyright:	You are free to use the following code as you please so long as
'		this header remains unaltered.
'Revision:	2008-05-27   Initial Release
'*******************************************************************************

	Const MY_DOCUMENTS = &H5&
	Const PROGRAM_FILES = &H26&

	Dim objShell
	Dim objFolder
	Dim objFolderItem
	Dim objNetwork
	Dim objFSO
	Dim objShellDb
	Dim DelFoldr
	Dim sMyDocPath
	Dim sProgPath
	Dim sVBSPath
	Dim sAccPath
	Dim sFrontEnd
	Dim sFolder
	Dim sSec
	Dim sUser
	Dim sPath
	Dim sComTxt


	'Specify the Fullpath and filename of the database to launch
	sFrontEnd = "test.mdb"	'Database name to open
	sFolder = "Databases"		'MyDoc subfolder where the
						'front-end will be copied to
	'If your database is secured by an mdw file specify it below, otherwise
	'leave its value blank
	sSec = "Security.mdw"


'Determine the location/path of the user's MyDocuments folder
'*******************************************************************************
	Set objShell = CreateObject("Shell.Application")
	Set objFolder = objShell.Namespace(MY_DOCUMENTS)
	Set objFolderItem = objFolder.Self
	sMyDocPath = objFolderItem.Path		'My Documents path
	sPath = sMyDocPath & "\" & sFolder & "\"'Path to front-end
	Set objFolder = objShell.Namespace(PROGRAM_FILES)
	Set objFolderItem = objFolder.Self
	sProgPath = objFolderItem.Path		'Program Files Path

'Determine path of this VBScript
'*******************************************************************************
	sVBSPath = Left(WScript.ScriptFullName,(Len(WScript.ScriptFullName) _
		     - (Len(WScript.ScriptName) + 1)))

	'Ensure lastest version of front-end is installed
	Set objNetwork = CreateObject("Wscript.Network")
	sUser = objNetwork.UserName			'User's network username
	Set objFSO = CreateObject("Scripting.FileSystemObject")

'Copy a network version of the Front-end to the MyDocs/SubFolder
'*******************************************************************************
	'Create application folder if it does not already exist
	If objFSO.FolderExists(sPath) = False then
		Set objFolderCreate = objFSO.CreateFolder(sPath)
	End If
	'Delete the existing copy to ensure we have a fresh copy
	If objFSO.FileExists(sPath & sFrontEnd) then
    		'Delete the file to copy a new fresh copy
    		Set DelFile = objFSO.GetFile(sPath & sFrontEnd)
    		DelFile.Delete
		Do While objFSO.FileExists(sPath & sFrontEnd) = True
			WScript.Sleep 100
		Loop
  	End if
	'Copy a fresh copy of the FE
	objFSO.CopyFile sVBSPath & "\" & sFrontEnd, sPath & _
                  	sFrontEnd, OverWriteExisting
	Do While objFSO.FileExists(sPath & sFrontEnd) = False
		WScript.Sleep 100
	Loop

'Determine the location of the MS Access executable
'*******************************************************************************
'	Set objShellDb = CreateObject("WScript.Shell")
'	'Determine in which folder the Access executable is located
'	If objFSO.FileExists(sProgPath &_
'                     	     "\Microsoft Office\OFFICE11\msaccess.exe") Then
'		sAccPath = sProgPath & "\Microsoft Office\OFFICE11"
'	Elseif objFSO.FileExists(sProgPath &_
'                                 "\Microsoft Office\OFFICE10\msaccess.exe") Then
'  		sAccPath = sProgPath & "\Microsoft Office\OFFICE10"
'	Elseif objFSO.FileExists(sProgPath &_
'                                 "\Microsoft Office\OFFICE\msaccess.exe") Then
'  		sAccPath = sProgPath & "\Microsoft Office\OFFICE"
'	End if
	sAppEXE = "MSACCESS.EXE"
	sRegKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" & sAppEXE & "\Path"
	sAccPath = objShellDb .RegRead(sRegKey)


'Launch database
'*******************************************************************************
	'Build the command to launch the database
	sComTxt = chr(34) & sAccPath & "msaccess.exe" & chr(34) &_
		  " " & chr(34) & sPath & sFrontEnd & chr(34)
	if isNull(sSec)=False AND sSec<>"" Then
		sComTxt = sComTxt & " /wrkgrp " & chr(34) & sVBSPath &_
			  "\" & sSec & chr(34)
		if isNull(sUser)=False AND sUser<>"" Then
			sComTxt = sComTxt & " /user " & sUser
		End if
	End if

	objShellDb.Run sComTxt 'Launch the database

Launch/Open an MS Access Database Using a VBScript

Have you ever tried to make a shortcut to launch/open an MS Access database and had an error returned because the Target string was too long? Or do you simply need more control/flexibility from your launching routine. In that case, a VBScript is the ideal way to go. Below is the most basic format that the VBScript can take. Simply alter the Script Variables, Save and execute!

I have made the following as flexible as possible so it can open simple database files, as well as security enabled database. It is simply a question of assigning values to the Script Variables or not.

I truly hope this helps you out!

'*******************************************************************************
'Date:		2008-05-27
'Author:	Daniel Pineault / CARDA Consultants Inc.
'		http://www.cardaconsultants.com
'Copyright:	You are free to use the following code as you please so long as
'		this header remains unaltered.
'Purpose:	Launch the specified access database
'Revision:	2008-05-27   Initial Release
'*******************************************************************************

	Dim sAcc
	Dim sFrontEnd
	Dim sSec
	Dim sUser
	Dim objShellDb
	Dim sComTxt

'Script Configuration Variable
'*******************************************************************************
	'Specify the Fullpath and filename of the msaccess executable
	sAcc = "C:\Program Files\Microsoft Office\OFFICE11\msaccess.exe"
	'Specify the Fullpath and filename of the database to launch
	sFrontEnd = "D:\Main\My Documents\TestDb.mdb"
	'If your database is secured by an mdw file specify it below, otherwise
	'leave its value blank
	sSec = "C:\Databases\Security.mdw"
	'If your database is secured by an mdw file and you want to specify the
	'username to use specify it below, otherwise leave its value blank
	sUser = ""


'*******************************************************************************
'*******************************************************************************
'You should not need to edit anything below this point
'*******************************************************************************
'*******************************************************************************


'Launch database
'*******************************************************************************
	Set objShellDb = CreateObject("WScript.Shell")
	'Build the command to launch the database
	sComTxt = chr(34) & sAcc & chr(34) &_
		  " " & chr(34) & sFrontEnd & chr(34) 
	if isNull(sSec)=False AND sSec<>"" Then
		sComTxt = sComTxt & " /wrkgrp " & chr(34) & sSec & chr(34)
	End if
	if isNull(sUser)=False AND sUser<>"" Then
		sComTxt = sComTxt & " /user " & sUser
	End if
	objShellDb.Run sComTxt 'Launch the database

MS Access – Splitting and Deploying Your Database

Splitting and Deploying Your Database

So you’ve developed a database and now you are finally ready to deploy it to your users! There are a couple things to consider to simplify your life as much as possible.

 

Split Your Database

Split? Yes, if you have not done so, and you are setting up a network or multi-user database, it is time to split your database. This is a simple process by which the tables are placed into one database (called the Back-End) and the remaining database objects (queries, form, report, code) are placed into another database (called the Front-End). The Back-End is then placed on the office server and a copy of the Front-End is given to each user and setup on their PC. DO NOT allow your users to all connect using the same Front-End file, they should each have their own copy on their machine.

Continue reading

MS Access – Multiple Criteria DLookup

A common question in many a newsgroup/forum is how can I perform a DLookup with more than one criteria? Well, the fact of the matter is that the Criteria permits you to specify as many criterion as you please.

For instance, lets say we have a contact table named ‘tbl_contacts’ and we want to retrieve the Telephone Number (field TelNo) for Daniel (Field FirstName) Pineault (field LastName), then the code would look something like:

DLookup("[TelNo]", "tbl_contacts", "[FirstName]='Daniel' AND [LastName]='Pineault'")

Now let’s push this example a little further. Let’s assume instead of wanting to hard code the individual’s name, we want to pull the value from form controls. So let assume we have a form name ‘frm_contacts’ with controls named ‘txt_FirstName’ and ‘txt_LastName’, in that case the code would look something like:

DLookup("[TelNo]", "tbl_contacts", "[FirstName]='" & Forms![frm_contacts].Form.[txt_FirstName] & "' AND [LastName]='" & Forms![frm_contacts].Form.[txt_LastName] & "'")

Special Note

One important thing to properly grasp when building a criteria is how and if they need to be surrounded by any special characters.

  • Date values need to be surrounded by #Your Date Value#
    • “[DateField]=#10/17/2009#”
  • Text values need to be surrounded by ‘Your Text Value’
    • “[TextField]=’Daniel'”
  • Numeric values do not need to be surrounded by anything
    • “[NumericField]=200”

MS Access – Listing of Database Objects (Tables, Queries, Forms, Reports, …)

It can be useful to have a listing of all the objects in the database. For instance, a listing of all the table or queries… This can easily be achieved using a query which uses as its source a hidden system table named ‘MSysObjects’.

The basic query SQL statment is as follows:

SELECT MsysObjects.Name AS [List Of Tables]
FROM MsysObjects
WHERE (((MsysObjects.Name Not Like "~*") And (MsysObjects.Name Not Like "MSys*")) 
	AND (MsysObjects.Type=1))
ORDER BY MsysObjects.Name;

You need only change the value of the (MsysObjects.Type)=1 part of the query expression to change what listing is returned. Below are the various common values of interest that can be used to return the various objects available in Access:

Object Type Value
Tables (Local) 1
Tables (Linked using ODBC) 4
Tables (Linked) 6
Queries 5
Forms -32768
Reports -32764
Macros -32766
Modules -32761

 
Continue reading

Documenting Your Database, Creating a Database Help File

Creating support documentation:

There a couple options for providing support documentation for a database that you have developed:

  1. External documentation (Word document, HTML file,…)
  2. Help file and associated to various areas throughout your database
  3. Creating an Access Report within your database

Developing support documentation for your database is a enormous subject to cover and there are entire sites devoted to this exact subject. Below are a collection of what I consider to be some of the best :

Do note that many of the links provided above are through the Web Archive as the direct links are all gone now. Many such tools no longer exist and Microsoft has simply done away with much of their older knowledge base articles.

Personally, this day in age, I think creating an HTML based help system is the way to go and can even be directly integrated into a database form via a WebBrowser control, if so desired.  My fallback would be PDF.

Why Use Microsoft Access

The following was taken from a discussion group and I believe is a very good explanation of a few reasons why Microsoft Access remains such a dominant tool, even 30+ years after its introduction to the marketplace.

Access is really an application development environment. It includes not one but *two* database engines: JET, the database engine in .mdb files, and (with the newer versions) MSDE, which is simply SQL/Server.

An Access application can link to any ODBC compatible database server – Access/JET databases, SQL/Server, MySQL, Oracle, DB/2, Visual FoxPro, dBase, take your pick (they all have their own advantages and disadvantages). SQL/Server, MySQL, and Oracle are all very capable database engines – but, by themselves, they don’t have tools for building user interfaces (forms and reports). You can use Visual Basic, C++, etc. to do so, or pay for expensive tools to frontend them- but Access is inexpensive and has a very capable form and report design feature.John W. Vinson MVP

Microsoft Access is an “all-in-one” tool, whereas the other database engines require additional, specialized skills to make the “complete” package. Access provides easy access to the database engine (Jet for Access 2003 and earlier, ACE for Access 2007) for data storage and data integrity. Access also provides fairly easy connectivity to other database engines for data storage, data integrity and security. Access provides automated tools (wizards) to build the presentation layer, or “front end” (data entry forms, reports for data displays, custom coding in modules, et cetera). An expert in Access can be expected to know how to use (and can teach you how to use) all of these tools in Access.

The other database engines may or may not provide similar tools besides the data storage feature. MySQL provides only data storage. It doesn’t have tools to build the front end. Oracle provides many additional reporting tools and presentation tools in addition to data storage, but these are so highly specialized that it usually takes a minimum of two or three Oracle professionals to build an application and manage the data. Microsoft SQL Server now has additional reporting tools and custom coding (T-SQL, CLR, and GUI managers) available, but again, these are so highly specialized that it usually takes a minimum of two or three SQL Server professionals to build an application and manage the data.

Access can handle additional complexity as your skills grow, and then allow you to migrate the back end to an even more complex database engine without having to start over from scratch when your organization’s needs increase and your workforce expands.

Managing the other database engines compared to managing Jet is more complex by an order of magnitude. Oracle is even more complex than the others, so increase the complexity by another order of magnitude. Unless you plan to get formal training, don’t expect to “jump in” and just “wing it” with Oracle. With the other database engines you can “jump in” without formal training, but expect to make so many mistakes that you shouldn’t plan to use real data until you have at least six months to two years of experience, so formal training is also a good idea.Gunny

Depending on the version, bells, and whistles, Oracle is about $40,000 for one license. So if you don’t already have Oracle, there’s a steep cost there.

One person who can do both DBA and Developer duties in Oracle will be very expensive as extensive skills are needed. Add to that the extra time it takes to get an Oracle app up and running.

I’m an Oracle DBA by day and develop Access apps by night. All things being equal, I probably can bring in an Access database for about one-fifth the price of a similar Oracle app in half the time. Of course the Oracle app can easily handle hundreds, not dozens, of users plus Oracle databases don’t have a corruption problem. If one does corrupt, there’s multiple ways to recover the data or not even let the user’s know that there was a problem.Jerry Whittle

MS Access Database Templates

A great way to learn how-to develop your own database is to look at pre-made databases.  As such, below is a listing of database templates from various sources.

Microsoft

 

UtterAccess

 

MVPs.  Many MVPs have a slew of samples on their site, so they usually are a great place to look

 

Warning
Be careful which databases you use/base your work off of.  Sadly, not all databases, even those coming from Microsoft, are designed properly.  So you still need to ensure you follow development Best Practices to ensure a successful outcome!

If you know of other, non-commercial template (ie: free with no strings attached) please let me know so I can add them to the list.