Archive for ‘MS Access’

June 10th, 2011

MS Access – VBA – Delete all Linked Tables

Ever needed to delete the linked tables out of your database. Sadly Access does not allow one to make multiple selection of Access object to perform batch actions on, such as delete. So if you have quite a few tables to delete it can be frustrating and a waste of time. This is why I create the very simply procedure found below.

'---------------------------------------------------------------------------------------
' Procedure : DeleteAttachedTbls
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Deletes all the linked tables from the active database.  It only removes
'             the links and does not actually delete the tables from the back-end
'             database.
' 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).
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2011-Jun-10                 Initial Release
'---------------------------------------------------------------------------------------
Function DeleteAttachedTbls()
On Error GoTo Error_Handler
    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
 
    DoCmd.SetWarnings False
    Set db = CurrentDb()
    For Each tdf In db.TableDefs
        If (tdf.Attributes And dbAttachedTable) = dbAttachedTable Then
            DoCmd.DeleteObject acTable, tdf.Name
        End If
    Next
 
Error_Handler_Exit:
    DoCmd.SetWarnings True
    Set tdf = Nothing
    Set db = Nothing
    Exit Function
Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: DeleteAttachedTbls" & vbCrLf & _
           "Error Description: " & Err.Description, _
           vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function
June 8th, 2011

VBA – Extract the File Name from a Complete File Path and Name

You can use the following procedure to extract the path from a full file name. You supply the file address, complete file path and file name (ie: “C:\Documents and Settings\User\Desktop\Details.txt”) and it will return the file name (ie: “Details.txt”)

'---------------------------------------------------------------------------------------
' Procedure : GetFileName
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Return the filename from a path\filename input
' 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:
' ~~~~~~~~~~~~~~~~
' sFile - string of a path and filename (ie: "c:\temp\test.xls")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2008-Feb-06                 Initial Release
'---------------------------------------------------------------------------------------
Function GetFileName(sFile As String)
On Error GoTo Err_Handler
 
    GetFileName = Right(sFile, Len(sFile) - InStrRev(sFile, "\"))
 
Exit_Err_Handler:
    Exit Function
 
Err_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: GetFileName" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
    GoTo Exit_Err_Handler
End Function

June 7th, 2011

VBA – Extract the Path from a Complete File Path and Name

You can use the following procedure to extract the path from a full file name. You supply the file address, complete file path and file name (ie: “C:\Documents and Settings\User\Desktop\Details.txt”) and it will return the path (ie: “C:\Documents and Settings\User\Desktop\”)

'---------------------------------------------------------------------------------------
' Procedure : GetFilePath
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Return the path from a path\filename input
' 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:
' ~~~~~~~~~~~~~~~~
' sFile - string of a path and filename (ie: "c:\temp\test.xls")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2008-Feb-06                 Initial Release
'---------------------------------------------------------------------------------------
Function GetFilePath(sFile As String)
On Error GoTo Err_Handler
 
    GetFilePath = Left(sFile, InStrRev(sFile, "\"))
 
Exit_Err_Handler:
    Exit Function
 
Err_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: GetFilePath" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
    GoTo Exit_Err_Handler
End Function

June 6th, 2011

VBA – Append Text to a Text File

Ever simply wanted to append data into an existing text file? The procedure below does exactly that. Simply supply the full path and file name of the text file to append to, and supply the string to append and voila!

'---------------------------------------------------------------------------------------
' Procedure : AppendTxt
' DateTime  : 2007-Mar-06 10:14
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Output Data to an external file (*.txt or other format)
'             ***Do not forget about access' DoCmd.OutputTo Method for
'             exporting objects (queries, report,...)***
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile - name of the file that the text is to be output to including the full path
' sText - text to be output to the file
'---------------------------------------------------------------------------------------
Function AppendTxt(sFile As String, sText As String)
On Error GoTo Err_Handler
    Dim FileNumber As Integer
 
    FileNumber = FreeFile                   ' Get unused file number
    Open sFile For Append As #FileNumber    ' Connect to the file
    Print #FileNumber, sText                ' Append our string
    Close #FileNumber                       ' Close the file

Exit_Err_Handler:
    Exit Function
 
Err_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: AppendTxt" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
    GoTo Exit_Err_Handler
End Function

June 5th, 2011

VBA – Determine if a File Exists or Not

Here is another simple procedure that allows one to verify/check if a file exists or not.

'---------------------------------------------------------------------------------------
' Procedure : FileExist
' DateTime  : 2007-Mar-06 13:51
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Test for the existance of a file; Returns True/False
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strFile - name of the file to be tested for including full path
'---------------------------------------------------------------------------------------
Function FileExist(strFile As String) As Boolean
On Error GoTo Err_Handler
 
    FileExist = False
    If Len(Dir(strFile)) > 0 Then
        FileExist = True
    End If
 
Exit_Err_Handler:
    Exit Function
 
Err_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: FileExist" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
    GoTo Exit_Err_Handler
End Function

June 4th, 2011

VBA – VBE Enumerate Modules, Procedures and Line Count

It still amazes me how Microsoft can develop these complexe applications but seems to overlook some simple functions that they should included within them to aid developers… But then, as demonstrated with the release of Office 2007 and 2010, Microsoft is not interested in the developer, they are only interested in the end-user’s opinion. Not productivity (that went down, about 30-40% drop in efficiency, the tubes with their change of format)! So all that matters is looks, the feel – very superficial (rant over)!!!

This will be the first in a series of procedure that I will be posting in the coming months in which I hope to demonstrate how you can use the ‘Microsoft Visual Basic for Application Extensibility’ library in conjuntion with the power of VBA to learn more, control more, manipulate more the VBE.

In this first post, I simply wanted to create a simple procedure that would give me a breakdown of my Access project. I wanted to return a listing of procedure per module with a line count. As you can see, the ‘Microsoft Visual Basic for Application Extensibility’ enable us to perform this task with ease with little code. Heck, half of the code below is to write to the generated text file!

'---------------------------------------------------------------------------------------
' Procedure : GetVBEDeatils
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Goes throught the VBE and creates a text file which give a brief listing
'             of the procedures within each module and a line count for each
' 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).
' Requirements: reference to the Microsoft Visual Basic for Application Extensibility
'               library.
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2011-June-04            Initial Release
'---------------------------------------------------------------------------------------
Function GetVBEDeatils()
    Dim vbProj          As VBProject
    Dim vbComp          As VBComponent
    Dim vbMod           As CodeModule
    Dim sProcName       As String
    Dim pk              As vbext_ProcKind
    Dim FileNumber      As Integer
    Dim strFile         As String
    Const vbNormalFocus = 1
 
    'Where do youwant the text file created
    strFile = "C:\VBEDetails.txt"
    If Len(Dir(strFile)) > 0 Then Kill strFile
    FileNumber = FreeFile                           'Get unused file number.
    Open strFile For Append As #FileNumber          'Create file name.
        
    For Each vbProj In Application.VBE.VBProjects   'Loop through each project
        Print #FileNumber, vbProj.Name
        For Each vbComp In vbProj.VBComponents      'Loop through each module
            Set vbMod = vbComp.CodeModule
            Print #FileNumber, "   " & vbComp.Name & " :: " & vbMod.CountOfLines & " total lines"
            Print #FileNumber, "   " & String(80, "*")
            iCounter = 1
            Do While iCounter < vbMod.CountOfLines  'Loop through each procedure
                sProcName = vbMod.ProcOfLine(iCounter, pk)
                If sProcName <> "" Then
                    Print #FileNumber, "      " & sProcName & " :: " & vbMod.ProcCountLines(sProcName, pk) & " lines"
                    iCounter = iCounter + vbMod.ProcCountLines(sProcName, pk)
                Else
                    iCounter = iCounter + 1
                End If
            Loop
            Print #FileNumber, ""
        Next vbComp
    Next vbProj
 
    Close #FileNumber                               'Close file.
    Set vbMod = Nothing
 
    'Open the generated text file
    Shell "cmd /c """ & strFile & """", vbNormalFocus
End Function

May 26th, 2011

MS Access – VBA – Set Report to Use Default Printer

It is easy during development to inadvertantly change the page setup setting of a report (or reports) to use a local printer. Once deployed your database will throw an error message nagging the user to switch from the one specified to his default printer. Why not avoid this issue altogether?! I created a very simply procedure that simply go through the report collection and ensure that all the report are set to use the default printer. I then call this procedure (along with turn off SubDataSheets, deactivate AllowZeroLength property, etc.) in my deploy procedure I run before deploying any database to my users.

'---------------------------------------------------------------------------------------
' Procedure : RptPrntSetDef
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Ensure that all the report apge setups are set to use the Default Printer
' 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).
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2011-05-23              Initial Release
'---------------------------------------------------------------------------------------
Sub RptPrntSetDef()
    On Error GoTo Error_Handler
    Dim db               As DAO.Database
    Dim DbP              As Object
    Dim DbO              As AccessObject
 
    Set db = CurrentDb
    DoCmd.SetWarnings False
    Debug.Print "RptPrntSetDef Begin"
    Debug.Print "================================================================================"
    'Check Reports
    Set DbP = application.CurrentProject
    For Each DbO In DbP.AllReports
        DoCmd.OpenReport DbO.Name, acDesign
        If Reports(DbO.Name).Report.UseDefaultPrinter = False Then
            Debug.Print "Editing Report '" & DbO.Name & "'"
            Reports(DbO.Name).Report.UseDefaultPrinter = True
            DoCmd.Close acReport, DbO.Name, acSaveYes
        Else
            DoCmd.Close acReport, DbO.Name, acSaveNo
        End If
    Next DbO
    Debug.Print "================================================================================"
    Debug.Print "RptPrntSetDef End"
 
Error_Handler_Exit:
    On Error Resume Next
    DoCmd.SetWarnings True
    Set DbO = Nothing
    Set DbP = Nothing
    Set db = Nothing
    Exit Sub
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: RptPrntSetDef" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Sub

May 25th, 2011

MS Access – VBA – Hide Object Pane

Here is a simple bit of code that permits you to hide the MS Access’ main object browser, to stop nosy users from accessing tables, queries, etc…

DoCmd.SelectObject acTable, , True
DoCmd.RunCommand acCmdWindowHide

In conjunction with the code to determine whether the user is running the runtime or full version of Access (see MS Access – Determine if Runtime or Full Version
) you could insert a section of code such as:

If SysCmd(acSysCmdRuntime) = False Then
    DoCmd.SelectObject acTable, , True
    DoCmd.RunCommand acCmdWindowHide
End If

This would also be a good place to enable any custom command bars/ribbons and/or disable any built-in command bars/ribbons…

May 3rd, 2011

MS Access – Mandatory Fields, Mandatory Entries

Here is a common question: “How can I make a field mandatory to my users?”

Well, as always, there are different techniques that can be employed. I will breifly covert 2: using Table Field Properties and using Form Events.

 

Table Setup

The easiest method is to merely set the table’s Required field property to Yes.

That said, this approach does present limitations. Mainly the fact that the message returned to the user references the Field Name (see the example below) and not its’ Caption or Description or Form Control Name, so the message in fact ends up confusing most users! This is why, using form event can come in handy.

The field ‘YourFieldName’ cannot contain a Null value because the Required property for this field is set to True. Enter a value in this field.

 

Form Event

Happily, we can add a lot more functionality and user-friendliness to our form by using its’ BeforeUpdate event to perform our validation. By inserting a little VBA code, for instance, something along the lines of:

Private Sub Form_BeforeUpdate(Cancel As Integer)
    If IsNull(Me.[YourControlName]) Then
        Cancel = True
        MsgBox "You must enter a value for 'YourControlNameOrYourDescription'. Please make a valid entry or press ESC to Cancel"
        'You could set the focus on the specific control if your wish, change the background color, ...
    End If
End Sub

As you can see, both are easy to implement, but the second method offers much more control and you can explain to your users in plain English to problem. Furthermore, you could also perform more advance data validation to not only ensure they have made an entry, but that it meet the require format…

April 30th, 2011

MS Access – JET SHOWPLAN

I came across an article about optimizing queries using a hidden JET tool call SHOWPLAN which basically generates a showplan.out file (which is merely a text file) which elaborates the method used by Access to execute the query. With this information it is possible to perform optimizations, determine which fields require indexing…

I’m not going to rewrite the article, if the subject interests you, then simply look at the source article.

That said, I did want to try and add a little more information for anyone trying to get this to work using Windows 7 (possibly Windows Vista – untested). To be able to use ShowPlan one must create a registry entry to enable it. In the original atricle, they indicate that the base registry key is found at:

\\HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\JET\4.0\Engines

this may be the case for Windows XP, but if you are using Windows 7 (and I suspect Vista as well) you will not find this key. Instead look for:

\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines

April 11th, 2011

MS Access – VBA – Append/Insert Record into Another External Database

So how can one take data from one database and insert it into another database?

There are 2 methods that come to mind and both are quick and easy to implement.

 

Specifying the Database to Append to in Your SQL Statement

The first method is to modify your query to include the external database as a reference. A basic Insert query would look something along the lines of:

INSERT INTO TableName ( Field1, Field2, ...)
VALUES ( Value1, Value2, ...);

but did you know you can also include, as part of your SQL statement, the database to append the data into?! So we could easily modify the SQL statement like:

INSERT INTO TableName ( Field1, Field2, ...) In 'FullPathAndDbNameWithExtension'
VALUES ( Value1, Value2, ...);

Here’s a concrete example:

INSERT INTO Temp1( FirstName, LastName) In 'C:\Databases\Clients.mdb' 
VALUES ( "Don", "Hilman");

 

Using Linked Tables

Another approach is to merely create a linked table to your secondary database and then run a normal append query on your linked table!

Either way, as you can clearly see for yourself, it is not a hard thing to insert data into a table contained within another external database!

April 8th, 2011

MS Access – VBA – Determine Where a Field Is Used

I recently had to make a minor change to a poorly designed, but large database and had to determine where certain fields were being used so I could go make the necessary changes. In this case, I had to review hundreds of MS Access objects, so a manual approach was just not acceptable. As such, I created a VBA to let the computer do the checking for me and report back. Below is the fruits of my labor.

'---------------------------------------------------------------------------------------
' Procedure : FindFieldUsedWhere
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Locate where a field is used within queries, forms and reports
' 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:
' ~~~~~~~~~~~~~~~~
' sFieldName    : Field Name to search for in the various Access objects
'
' Usage:
' ~~~~~~
' FindFieldUsedWhere("Type A")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2011-04-08                 Initial Release
'---------------------------------------------------------------------------------------
Function FindFieldUsedWhere(sFieldName As String)
On Error GoTo Error_Handler
    Dim db               As DAO.Database
    Dim qdf              As DAO.QueryDef
    Dim sSQL             As String
    Dim ctl              As Control
    Dim frm              As AccessObject
    Dim DbO              As AccessObject
    Dim DbP              As Object
 
    Set db = CurrentDb
    Debug.Print "FindFieldUsedWhere Begin"
    Debug.Print "Searching for '" & sFieldName & "'"
    Debug.Print "================================================================================"
 
    'Check Queries
    For Each qdf In db.QueryDefs
        'qdf.Name    'The current query's name
        'qdf.SQL     'The current query's SQL statement
        sSQL = qdf.SQL
        If InStr(sSQL, sFieldName) Then
            'The Query is a Make Table Query and has our TableName we are looking for
            Debug.Print "Query: " & qdf.Name
        End If
    Next
 
    'Check Forms
    For Each frm In CurrentProject.AllForms
        DoCmd.OpenForm frm.Name, acDesign
        If InStr(Forms(frm.Name).RecordSource, sFieldName) Then
            'The Query is a Make Table Query and has our TableName we are looking for
            Debug.Print "Form: " & frm.Name
        End If
        'Loop throught the Form Controls
        For Each ctl In Forms(frm.Name).Form.Controls
            Select Case ctl.ControlType
                Case acComboBox
                    If Len(ctl.Tag) > 0 Then
                        If InStr(ctl.Tag, sFieldName) Then
                            'The Query is a Make Table Query and has our TableName we are looking for
                            Debug.Print "Form: " & frm.Name & " :: Control: " & ctl.Name
                        End If
                        If InStr(ctl.ControlSource, sFieldName) Then
                            'The Query is a Make Table Query and has our TableName we are looking for
                            Debug.Print "Form: " & frm.Name & " :: Control: " & ctl.Name
                        End If
                    End If
                Case acTextBox, acCheckBox
                    If InStr(ctl.ControlSource, sFieldName) Then
                        'The Query is a Make Table Query and has our TableName we are looking for
                        Debug.Print "Form: " & frm.Name & " :: Control: " & ctl.Name
                    End If
            End Select
        Next ctl
        DoCmd.Close acForm, frm.Name, acSaveNo
    Next frm
 
    'Check Reports
    Set DbP = Application.CurrentProject
    For Each DbO In DbP.AllReports
        DoCmd.OpenReport DbO.Name, acDesign
        If InStr(Reports(DbO.Name).RecordSource, sFieldName) Then
            'The Query is a Make Table Query and has our TableName we are looking for
            Debug.Print "Report: " & DbO.Name
        End If
        'Loop throught the Report Controls
        For Each ctl In Reports(DbO.Name).Report.Controls
            Select Case ctl.ControlType
                Case acComboBox
                    If Len(ctl.Tag) > 0 Then
                        If InStr(ctl.Tag, sFieldName) Then
                            'The Query is a Make Table Query and has our TableName we are looking for
                            Debug.Print "Report: " & DbO.Name & " :: Control: " & ctl.Name
                        End If
                        If InStr(ctl.ControlSource, sFieldName) Then
                            'The Query is a Make Table Query and has our TableName we are looking for
                            Debug.Print "Report: " & DbO.Name & " :: Control: " & ctl.Name
                        End If
                    End If
                Case acTextBox, acCheckBox
                    If InStr(ctl.ControlSource, sFieldName) Then
                        'The Query is a Make Table Query and has our TableName we are looking for
                        Debug.Print "Report: " & DbO.Name & " :: Control: " & ctl.Name
                    End If
            End Select
        Next ctl
        DoCmd.Close acReport, DbO.Name, acSaveNo
    Next DbO
 
    Debug.Print "================================================================================"
    Debug.Print "FindFieldUsedWhere End"
 
Error_Handler_Exit:
    On Error Resume Next
    Set qdf = Nothing
    Set db = Nothing
    Set ctl = Nothing
    Set frm = Nothing
    Set DbP = Nothing
    Set DbO = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: FindFieldUsedWhere" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, "An Error has Occured
    Resume Error_Handler_Exit
End Function

This is my first draft and I haven’t looked at optimizing my code. It was more about getting results than developing a procedure to be reused often. Hopefully it can help someone else in the same boat as I found myself! Simply execute the procedure and it will return a listing of what Access objects use the specified field in the immediate window of the VBE console.

April 7th, 2011

MS Access – VBA – Relink Back-End Tables

In any well developed MS Access database it becomes necessary to automate the relinking of the back-end database tables. There are any number of existing resources that you can very rapidly implement.

Below are a few useful link to get you going:

In complexe database setups, it may become necessary to relink your database to multiple back-ends. I started out writting my own code to do this and then came accross nice sample from David Fenton Associates:

Hopefully these links will save you some time searching the net.

March 13th, 2011

FMS Total Visual SourceBook Review

FMSTotal Visual SourceBook

What I wouldn’t have given to be aware of this add-in when I was starting out as a developer! Seriously, this add-in would have saved me hundreds, if not thousands, of hours searching online, posting to forums, to find out how to code what I needed to do. Beyond which, it provides the user with a standardized set of procedures, instead of trying to piece together countless routines found here and there as you search online.

Just yesterday, I needed a particular routine and instead of searching online, as I always have done until now, I opened the TVSB, performed a quick search, exported the appropriate code into my module and was back at work in a matter of 1-2 minutes, if that!

 

So what did I think of the TVSB?

Cons:

  • I wish it could be somehow directly integrated within the VBE as done with certain other add-ins rather than a separate popup application. Have some type of integrated toolbar with a drop down category/procedures/… select the procedure and BAM there is. AND, I’m not saying it is hard to export the procedures from the SourceBook the way it is currently setup. That said, even though it would be nice, I myself am not sure how it could be accomplished.
  • My other issue is that their code uses Early biding which I try to avoid normally as it can causes reference issues. So their code is a nice starting point, but I would convert most of the classes, procedures,… into late binding for my own purposes. Over the course of several years, I have learnt that Late Binding avoids reference issues and this outways (in my opinion) any performance benefits Early Binding presents. At the end of the day, each developer has their own opinion and experience with regards to this aspect of programming, so feel free to make up your mind on this aspect yourself. To learn a little bit more about the pros and cons of Early Binding vs. Late Binding take a look at Early vs. Late Binding
    from the Word MVP site, it is a short overview of the issue.

 

Pros:

  • Easy to install
  • Can be integrated to work in a team environment (untested)
  • Easy to navigate and work with
  • It is very intuitive
  • Came with a user manual! Just this to me put this application above most others!!! Although, in this case, a manual is not necessary.
  • The code itself, is well categorized so you can find things quite easily just by noising around.
  • Effective search tool enable one to quickly search through the repository.
  • Extendable. You can add your own code (procedures, modules, …) to the repository so you can build upon what is already there.
  • Good export utility (export directly into your module, to a file, …)
  • Customizable – You can configure the Error Handler and other elements to suit your programming methodologies.

Put simply, the FMS Total Visual SourceBook (TVSB) is a simple to use, powerful work tool that can easily accelerate the development process of any developer and give you a leg up on your competition.

March 9th, 2011

MS Access – Report – Change a Report’s RecordSource

The following procedure can be used to change the RecordSource of a Report.

'---------------------------------------------------------------------------------------
' Procedure : RedefRptSQL
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Redefine an existing report's recordsource
'             Requires opening the form in design mode to make the changes
' 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:
' ~~~~~~~~~~~~~~~~
' sRptName    ~ Name of the Query to redefine the SQL statement of
' sSQL        ~ SQL Statement to be used to refine the query with
'
' Usage:
' ~~~~~~
' RedefRptSQL "Report1", "SELECT * FROM tbl_Contacts ORDER BY LastName;"
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2009-07-13                 Initial Release
'---------------------------------------------------------------------------------------
Function RedefRptSQL(sRptName As String, sSQL As String)
On Error GoTo Error_Handler
    Dim Rpt     As Report
 
    DoCmd.OpenReport sRptName, acViewDesign, , , acHidden 'Open in design view so we can
                                                          'make our changes
    Set Rpt = Application.Reports(sRptName)
    Rpt.RecordSource = sSQL                               'Change the RecordSource
    DoCmd.Close acReport, sRptName, acSaveYes             'Save our changes

Error_Handler_Exit:
    On Error Resume Next
    Set Rpt = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occured." & vbCrLf & vbCrLf & _
            "     Error Number: " & Err.Number & vbCrLf & _
            "     Error Source: RedefRptSQL" & vbCrLf & _
            "     Error Description: " & Err.Description, _
            vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

February 15th, 2011

MS Access – VBA – Minimize/Maximize Access Application

Here is another common question, how can I control the Application window itself? Well that depends on what exactly you wish to do. So things are easy to do and other require APIs, etc.

 

Minimize/Maximize and Restore the MS Access Application Window

One can very easily control the Application Window state with one simple command, the often overlooked DoCmd.RunCommand!

DoCmd.RunCommand acCmdAppMinimize 'Minimize the MS Access Application
DoCmd.RunCommand acCmdAppMaximize 'Maximize the MS Access Application
DoCmd.RunCommand acCmdAppRestore 'Restore the MS Access Application

 

Completely Hide the MS Access Application Window

Once again, a not so uncommon question. Now implementing it requires a little more programming than merely minimizing or maximizing the application window, but it can be done! Now if you Google the subject you will find any number of code samples. That said, before I ‘waste‘ my time searching for anything relating to MS Access I always go and check The Access Web where you will find a ready to use API entitled Manipulate Access Window to do exactly this.

January 17th, 2011

MS Access – VBA – The Save Operation Failed

I was recently working on a database of mine which has been in production for over 4 years now and all of a sudden it started giving me the error: “The Save Operation Failed”. Nothing like a nice obscur error message from the VBA/VBE!!!

I tried the normal approaches: Compact and repair, Decompile/Recompile, … None worked for me.

I took a look at Microsoft’s Knowledge Base and found an article, ACC97: Error “The Save operation failed” When Saving a Module, for Access 97 (as a lot of the information can be used in furture version, I read it over). Sadly, the article is pretty much useless.

In the end, the solution, for me, was to start a new database and import all of the database objects (File -> Get External Data -> Import) from the database giving me the error message. Setup the startup properties… and everything was in working order again!

I hope this helps someone else in the same perdicament!

January 6th, 2011

MS Access – VBE – Plug-Ins, Add-Ons, Etc

One thing any good worker will tell you is that you must have the right tools to do the job. Computer programming, MS Access database development, is no exception to this rule! I thought I’d list a few add-ins, plug-ins, etc. that I have come across, or heard of. This is an unbiased listing and I have no link to any of the vendors, nor have I even used all of them. I am simply trying to regroup them to help you find them, and you can judge their usefullness on your own. In a future post, I will examine the 2 or 3 that I use myself and find very useful.

Free Ones
MZ-Tools
Smart Indenter
V-Tools

Ones you have to pay for
Find and Replace (30 day evaluation then you have to register/pay)
FMS Inc. Tools — FMS offers a multitude of various tools worth reviewing, including: Total Visual Source Book and Total Access Admin

 

A Few More Untested Add-ins (Update 2011-Mar-09)

Various utilies by Bill Mosca (Access MVP)
ACCESS Dependency Checker
http://www.4tops.com/query_tree.htm
http://www.4tops.com/ms_access_vba.htm
Compare Em – Compare 2 database to identify the differences and generate the necessary code to make the updates.

December 9th, 2010

MS Access – VBA – Determine if a Module Exists

Sometimes it can be handy to be able to identify whether or not a module is in a database or not. One way to check is to loop through the AllModules collection to see if it is there or not. Below is a sample procedure that demonstrates how you can check for the existance of a VBA module within your database.

 

Determine whether a Module Exists using the AllModules Collection

'---------------------------------------------------------------------------------------
' Procedure : ModuleExist
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Determine if a module exists within the database
' 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:
' ~~~~~~~~~~~~~~~~
' sModuleName - Name of the module you are searching for
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' ModuleExist("Module2")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2008-Aug-13                 Initial Release
'---------------------------------------------------------------------------------------
Function ModuleExist(sModuleName As String) As Boolean
On Error GoTo Error_Handler
Dim mdl                   As Object
    ModuleExist = False 'Initialize our variable
    'Loop trhough all the modules in the database
    For Each mdl In CurrentProject.AllModules
        If mdl.Name = sModuleName Then
            ModuleExist = True
            Exit For 'No point continuing if found
        End If
    Next
 
Error_Handler_Exit:
    On Error Resume Next
    Set mdl = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: ModuleExist" & vbCrLf & _
           "Error Description: " & Err.Description, _
           vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

December 6th, 2010

VBA – Validate Email Address

One option is to systematically check for the various dos and don’t using a series of if statements such as that in the function below:

Public Function isValidEmail(inEmailAddress As String) As Boolean 
' Author: Unknown

If (Len(inEmailAddress) = 0) Then 
    MsgBox "Please enter your email address." 
    isValidEmail = False 
    Exit Function 
End If 
If (InStr(1, inEmailAddress, "@") = 0) Then 
    MsgBox "The '@' is missing from your e-mail address." 
    isValidEmail = False 
    Exit Function 
End If 
If (InStr(1, inEmailAddress, ".") = 0) Then 
    MsgBox "The '.' is missing from your e-mail address." 
    isValidEmail = False 
    Exit Function 
End If 
 
If (InStr(inEmailAddress, "@.") > 0) Then 
    MsgBox "There is nothing between '@' and '.'" 
    isValidEmail = False 
    Exit Function 
End If 
 
If ((InStr(inEmailAddress, ".")) = ((Len(inEmailAddress)))) Then 
    MsgBox "There has to be something after the '.'" 
    isValidEmail = False 
    Exit Function 
End If 
 
If ((Len(inEmailAddress)) < (InStr(inEmailAddress, ".") + 2)) Then 
    MsgBox "There should be two letters after the '.'" 
    isValidEmail = False 
    Exit Function 
End If 
 
If (InStr(1, inEmailAddress, "@") = 1) Then 
    MsgBox "You have to have something before the '@'" 
    isValidEmail = False 
    Exit Function 
End If 
 
isValidEmail = True 
End Function

A Second better approach, like with many web programming languages, is to use regular expressions to validate certain type of strings. Now Access’ VBA does not allow RegEx persey, but you can very easily access such functionality by adding 2 simple lines of code. You then end up with a total of a three lines of code to validate almost any string, including an e-mail address. For all the details, and a link to where you can get a multitude of the RegEx so you don’t have to reinvent the wheel simply check out my post VBA – Using Regular Expressions (RegEx)

December 5th, 2010

MS Access – VBA – Loop Through All The Controls on a Form

Below is come sample VBA which illustrates how one can easily loop through all the controls within a form to identify and work with them.

Dim ctl As Control
For Each ctl In Me.Controls
    ctl.Name 'Get the name of the control
    ctl.Value 'Get or set the value of the control
    ctl.Visible = False 'Control the visibility of the control
Next ctl

Now how can this be put to good use? Well one use for such code would be to setup a Select All, or Select None button for a series of check boxes on a form. Below is what the code could look like for each command button:

'Select All
Dim ctl As Control
For Each ctl In Me.Controls
    If ctl.ControlType = acCheckBox Then
        If ctl.Value <> True Then
            ctl.Value = True
        End If
    End If
Next ctl
 
'Select None
Dim ctl As Control
For Each ctl In Me.Controls
    If ctl.ControlType = acCheckBox Then
        If ctl.Value <> False Then
            ctl.Value = False
        End If
    End If
Next ctl

Lastly, you could easily adapt the general form specific code and transform it into a generic procedure to which you will supply the form name to loop through the control, rather than working with the current form, you could do something along the lines of:

Function YourProcedureName(ControlName As String, frm As Access.Form)
    Dim ctl As Access.Control
    For Each ctl In frm.Controls
 
 
    Next ctl
End Function

November 23rd, 2010

MS Access Sample – Clocks and Timers

This database demonstrates how to insert a clock in your forms to display the current time as well as a demonstration of how to create a timer used to determine the amount of time which a form has been open for.

Download the sample database: MS Access Clocks and Timers Sample Database

November 22nd, 2010

MS Access Sample – Working with Dates

This database demonstrates some of the most common ways to work with dates. It demonstrates how to extract only a part of a date (year, month or day), how to display a date in different formats (ISO, American,…), how to determine the number of days, weeks between 2 dates, etc.

Download the sample database: MS Access Working with Dates Sample Database

November 20th, 2010

MS Access Sample – Working with Images

This database example show the proper way to work with images within a database (which is not to embed them into the database).

Download the sample database: MS Access Images Sample Database

November 19th, 2010

MS Access Sample – Change Password

If you are using user-level security (ULS), the following is a simple demonstration of a form that can be added to any database to permit the user the ability to change their password. Useful when you create an mde or disable the standard toolbars for increased security but still want to give the user the ability to rotate their own password.

Download the sample database: User-Level Security Change of Password Form Demonstration