Tag Archives: MS Access

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

VBScript – Create/Set Trusted Location Using VBScript

I looked high and low and had an impossible time, when I needed it, to locate an example, or explanation, of how I could create a Trusted Location for Access, Excel, Word,… using a simple vbscript.

If you manually make an entry in the Trusted Locations and then inspect your registry, you’ll see something similar to the following image (in this case for MS Access, but the same principal applies to almost all MS Office applications)

MS Office Trusted Location Registry Keys

Continue reading

MS Access – Calculate the Age

If you have ever needed to calculate the age between two dates, then the function below is for you. Often people mistakenly believe that the age calculation can simply be accomplished using the DateDiff() function, but this is not the case and a slightly more complex function is required to do the job.

To merely calculate the age of an individual in years, you can simply use the DateDiff().

=DateDiff("yyyy", [DOB], Date()) - IIF(Format([DOB], "mmdd") > Format(Date(), "mmdd"), 1, 0)

However, if you would like a little more detail (Years, Months, Days) you can use a function such as the one presented below.

Function fAge(dteStart As Variant, dteEnd As Variant) As Variant
'*******************************************
'Purpose:   Accurately return the difference
'           between two dates, expressed as
'           years.months.days
'Coded by:  raskew (from MS Access forum)
'Inputs:    From debug (immediate) window
'           1) ? fAge(#12/1/1950#, #8/31/2006#) 'Calculate btw 2 specific dates
'           2) ? fAge(#12/30/2005#, Date()) ' Calculate as of today's date
'*******************************************
Dim intHold   As Integer
Dim dayhold   As Integer

   'correctly return number of whole months difference
   'the (Day(dteEnd) < Day(dteStart)) is a Boolean statement
   'that returns -1 if true, 0 if false
   intHold = DateDiff("m", dteStart, dteEnd) + (Day(dteEnd) < Day(dteStart))

   'correctly return number of days difference
   If Day(dteEnd) < Day(dteStart) Then
      dayhold = DateDiff("d", dteStart, DateSerial(Year(dteStart), Month(dteStart) + 1, 0)) + Day(dteEnd)
   Else
      dayhold = Day(dteEnd) - Day(dteStart)
   End If

   fAge = LTrim(Str(intHold \ 12)) & " years " & LTrim(Str(intHold Mod 12)) & " months " & LTrim(Str(dayhold)) & " days"

End Function

MS Access VBA – Determine if a Form is Open

The following simple little procedure can be used to check if a given form is already open.

'---------------------------------------------------------------------------------------
' Procedure : IsFrmOpen
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Determine whether a form is open or not
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFrmName  : Name of the form to check if it is open or not
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' IsFrmOpen("Form1")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-05-26              Initial Release
' 2         2018-02-10              Minor code simplification (per Søren M. Petersen)
'                                   Updated Error Handling
'                                   Updated Copyright
'---------------------------------------------------------------------------------------
Function IsFrmOpen(sFrmName As String) As Boolean
    On Error GoTo Error_Handler

    IsFrmOpen =Application.CurrentProject.AllForms(sFrmName).IsLoaded

Error_Handler_Exit:
    On Error Resume Next
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: IsFrmOpen" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

How To Use It

Below is a very simple routine which checks to see if form ‘frm_Contacts’ is currently open, and if it is, then we requery it. This type of code would be used if you use a pop-up form to add new records, edit data to ensure that another form reflects those changes.

If IsFrmOpen("frm_Contacts") = True Then
    Forms(frm_Contacts).Form.Requery
End If

The Problem and The Solution

The issue with the above is that the .IsLoaded property cannot distinguish between a form being opened in design mode vs. normal visualization modes (Form View, Datasheet View, Layout View, …) so it can be inexact depending on the required usage. All the .IsLoaded property checks is whether the form is Loaded, not in which view mode it is running. As such, I prefer to use a function such as the one below that only return True when the object is open to visualization, not design. Furthermore, the following is more versatile as it can handle both Forms, Queries, Reports or Tables.

'---------------------------------------------------------------------------------------
' Procedure : IsObjectOpen
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Check if an object (Form or Report) is open or not
'               .IsLoaded is not reliable since it can't distinguish design view!
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: None required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sObjectName : Name of the Object (Form, Query, Report or Table) to check and see
'                   if it is open
' lObjectType : Type of Object: acForm -> Forms
'                               acQuery -> Queries
'                               acReport -> Reports
'                               acTable -> Tables
'
' Usage:
' ~~~~~~
' ?IsObjectOpen("Form1", acForm)
' ?IsObjectOpen("Query1", acQuery)
' ?IsObjectOpen("Report1", acReport)
' ?IsObjectOpen("Table1", acTable)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-05-26              Initial Release
' 2         2018-10-06              Updated Copyright and Error Handling
'---------------------------------------------------------------------------------------
Public Function IsObjectOpen(ByVal sObjectName As String, _
                             lObjectType As acObjectType) As Boolean
    On Error GoTo Error_Handler

    '0=Closed, 1=Open, 2=Open and Dirty, 3=Open on a New Record
    If SysCmd(acSysCmdGetObjectState, lObjectType, sObjectName) <> 0 Then
        Select Case lObjectType
            Case acForm
                '0=Design View, 1=Form View, 2= Datasheet View, 7=Layout View
                If Forms(sObjectName).CurrentView <> 0 Then
                    IsObjectOpen = True
                End If
            Case acQuery
                If CurrentData.AllQueries(sObjectName).CurrentView <> 0 Then
                    IsObjectOpen = True
                End If
            Case acReport
                '0=Design View, 5=Print Preview, 6=Report View, 7=Layout View
                If Reports(sObjectName).CurrentView <> 0 Then
                    IsObjectOpen = True
                End If
            Case acTable
                If CurrentData.AllTables(sObjectName).CurrentView <> 0 Then
                    IsObjectOpen = True
                End If
        End Select
    End If

Error_Handler_Exit:
    On Error Resume Next
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: IsObjectOpen" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

MS Access – Calendar/Date Picker Control

A very common issue with any documents, not only access databases, is how data is entered by the users, most notably date entries. To ensure proper data entry it is very useful to give your users simple graphical tools and eliminate keyboard entry. To this aim, the following are a few excellent date pickers that can very easily be incorporated into any of your database applications.

Allen Browne’s Popup Calendar a very basic calendar easy to setup and use. This is a form based calendar.
Stephen Lebans Calendar a more advanced calendar (more options – can view 12 months at a time!) equally easy to setup and use. This is an API based calendar.
Arvin Meyer’s Calendar another basic form based calendar which is easy to implement in any database.
CyberCow’s Time Pieces another nice set of tools (calendar/date picker, time picker, …).
Peter Hibbs’ Pop-up Calendar another great alternative which allows for date, or, date and time picking.

It is also very important to note that whenever possible you should always avoid the use of ActiveX controls as they can lead to reference and versioning issues. The calendars listed above will not suffer from such issues.

Also, if you have develop an mdb application working in 2007 and have taken advantage of the pop-calendar included in Access 2007. If you wish you database to be backwards compatible then you must implement your own calendar, as earlier version do not have this functionality!  That said, MS’ pop-up date picker is very primitive!  That is why I still believe you are much better off using an alternate calendar control with more options and giving you full control over its’ functionality, but that is up to you!

Since originally writing this post, I have create a new one with a few screenshots of each that you may prefer to review, so feel free to check out my article:

MS Access VBA – List of Database Queries

The following VBA Function can be used to produce a list of all the queries within a given MS Access database.

'---------------------------------------------------------------------------------------
' Procedure : ListDbQrys
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Returns a ';' separated string containing the names of all the queries
'             within the database (use Split() to convert the string to an array)
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: None required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sDelim    : optional delimiter to used when building the list of queries.  If omitted
'               will default to using ';'.
'
' Usage:
' ~~~~~~
' ? ListDbQrys
' ? ListDbQrys("~")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2007-Nov-??             Initial Release
' 2         2018-09-27              Updated Copyright
'                                   Updated Error Handler
'                                   Minor code update
'                                   Added optional sDelim input variable
'---------------------------------------------------------------------------------------
Function ListDbQrys(Optional sDelim As String = ";") As String
    On Error GoTo Error_Handler
    Dim oDbO                  As Access.AccessObject
    Dim oDbCD                 As Object
    Dim sQrys                 As String

    Set oDbCD = Application.CurrentData

    For Each oDbO In oDbCD.AllQueries
        sQrys = sQrys & sDelim & oDbO.Name
    Next oDbO
    If sQrys <> "" Then
        sQrys = Mid(sQrys, 2)    'Truncate initial ;
    End If

    ListDbQrys = sQrys

Error_Handler_Exit:
    If Not oDbO Is Nothing Then Set oDbO = Nothing
    If Not oDbCD Is Nothing Then Set oDbCD = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: ListDbQrys" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

MS Access VBA – Delete a Table

There are 3 approaches that come to mind for deleting a table in Microsoft Access:

DoCmd DeleteObject Method

DoCmd.DeleteObject acTable, "YourTableName"

SQL DROP Statement

Dim db As DAO.Database
Set db = CurrentDb
db.Execute "DROP TABLE YourTableName;", dbFailOnError

TableDefs Delete Method

Dim db As DAO.Database
Set db = CurrentDb
db.TableDefs.Delete "YourTableName"
RefreshDatabaseWindow

RefreshDatabaseWindow does as its name implies and will update the navigation pane’s table listing to reflect the deletion. If you omit this command the table will remain in the listing until you reopen that database.

Relationships!
Do keep in mind you can’t delete tables involved in relationships. You must first delete their relationships prior to attempting to delete the table itself. For that be sure to check out

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 Forums and Discussion Groups

Microsoft Access Forums and Discussion Groups

Below is a collection of Microsoft Access forums and discussion groups that I’ve personally found helpful or that others have recommended to me over the years. The entries are listed alphabetically; this order doesn’t imply any ranking or preference.

These sites allow you to post questions and receive real-time help from other users and developers.
 
Continue reading