MS Access – Running Access on Linux/Ubuntu

Have you ever had a client throw you the nice curveball of wanting to run an MS Access database on a Linux OS? Well, there is a workable solution.

You can install Wine on most Linux distributions. You can check out their website at http://www.winehq.org/download. You can also check out their brief page regarding MS Access at http://appdb.winehq.org/objectManager.php?sClass=application&iId=12

Overall, this seems to be a very good option for older versions, and slightly less reliable for the newer version (2007) with no data regarding 2010 compatibility. Depending on you needs, this is definitely worth checking out and the price is right, it’s free (you have to love open-source)!

MS Access – VBA – Number of Weekdays Between Two Dates

Have you ever needed to calculate the number of weekdays (Monday through Friday) there were between two dates, that is exactly what the VBA function below does.

'---------------------------------------------------------------------------------------
' Procedure : CalcNoWeekDays
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Count the number of weekdays between two specified dates
' 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:
' ~~~~~~~~~~~~~~~~
' dtFirstDate   The first of 2 dates to count the number of weekdays between
' dtLastDate    The second of 2 dates to count the number of weekdays between
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' CalcNoWeekDays(#2010-10-6#,#2010-10-23#)      =23
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-Jul-09                 Initial Release
'---------------------------------------------------------------------------------------
Function CalcNoWeekDays(dtFirstDate As Date, dtLastDate As Date) As Integer
On Error GoTo Error_Handler
    Dim dtDay   As Date
    
    'Ensure that the dates provided are in the proper order
    If dtFirstDate > dtLastDate Then
        dtDate1 = dtLastDate
        dtDate2 = dtFirstDate
    Else
        dtDate1 = dtFirstDate
        dtDate2 = dtLastDate
    End If
    
    CalcNoWeekDays = 0 'Initialize our weekday counter variable
    
    For dtDay = dtFirstDate To dtLastDate
        iDayOfWeek = Weekday(dtDay)
        If iDayOfWeek <> vbSunday And iDayOfWeek <> vbSaturday Then
            CalcNoWeekDays = CalcNoWeekDays + 1
        End If
    Next dtDay

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: CalcNoWeekDays" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, _
           "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

MS Access – VBA – Disable Query Warning Messages

Once you start doing some VBA programming in your database you will at some point or another want to run/execute queries through VBA. However, you may not want your user’s to receive the action query confirmation prompts, such as:

MS Access Action Query Confirmation Prompt Message
MS Access Action Query Confirmation Prompt Message

Nothing could be easier. To disable all confirmation prompts simply use the following line of code

DoCmd.SetWarnings False 'Turn off warnings

Of course do not forget to turn them back on after running your code so that legitimate messages are displayed.

DoCmd.SetWarnings True  'Turn warnings back on

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

MS Access – VBA – Error Handling

The Basics

Before delving into actual programming functions and sub-routine, we must first establish what is an error handler.

An error handler is a bit of code which will do pre-defined actions whenever an error occurs. For instance, generate a message to the user or developer describing the nature of the error. For an error handler to be useful, it must provide a minimum of information in its message to the user.

Microsoft’s Error Handler

If ever you allow Microsoft to generate code block, say by converting a macro to VBA, and include their ‘error handler’ you will get something like:

Private Sub Command3_Click()
On Error GoTo Command3_Click_Err

    'The code will be here

Command3_Click_Exit:
    Exit Sub

Command3_Click_Err:
    MsgBox Error$
    Resume Command3_Click_Exit
End Sub

Sadly, this error handler is dismal! It will result in a message box displaying a description of the error, but nothing more. Below is an example of what you can expect from Microsoft’s error handler.

Microsoft Default Error Handler

In most cases, this simply isn’t enough information, certainly not for a developer, to properly isolate an issue to remedy it.

Continue reading

MS Access – VBA – Copy a File

Have you ever needed to make a copy of a file? Well, there are a number of ways that you can do it.

Built-in VBA FileCopy

I find that using the built-in FileCopy function to be the simplest and cleaness method. Below is a simple procedure around it that trap certain common errors.

'---------------------------------------------------------------------------------------
' Procedure : CopyFile
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Copy a file
'             Overwrites existing copy without prompting
'             Cannot copy locked files (currently in use)
' 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:
' ~~~~~~~~~~~~~~~~
' sSource - Path/Name of the file to be copied
' sDest - Path/Name for copying the file to
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' 1         2007-Apr-01             Initial Release
'---------------------------------------------------------------------------------------
Public Function CopyFile(sSource As String, sDest As String) As Boolean
On Error GoTo CopyFile_Error

    FileCopy sSource, sDest
    CopyFile = True
    Exit Function

CopyFile_Error:
    If Err.Number = 0 Then
    ElseIf Err.Number = 70 Then
        MsgBox "The file is currently in use and therfore is locked and cannot be copied at this" & _
               " time.  Please ensure that no one is using the file and try again.", vbOKOnly, _
               "File Currently in Use"
    ElseIf Err.Number = 53 Then
        MsgBox "The Source File '" & sSource & "' could not be found.  Please validate the" & _
               " location and name of the specifed Source File and try again", vbOKOnly, _
               "File Currently in Use"
    Else
        MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
               Err.Number & vbCrLf & "Error Source: CopyFile" & vbCrLf & _
               "Error Description: " & Err.Description, vbCritical, "An Error has Occurred!"
    End If
    Exit Function
End Function

All you have to do is copy it into a module and then call it as required. Enjoy!

Copying a File Using FSO

As an alternative, here is an example to copy a file using FSO.

'---------------------------------------------------------------------------------------
' Procedure : FSO_FileCopy
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Copy a file
'               Overwrites existing copy without prompting (you can change the varible
'               in the CopyFile method call)
' 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: Uses Late Binding, so none required
' Ref       : FSO - https://msdn.microsoft.com/en-us/library/ms127964(v=vs.110).aspx
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sSource - Path/Name of the file to be copied
' sDest - Path/Name for copying the file to
'
' Usage:
' ~~~~~~
' FSO_FileCopy("C:\TE.MP\Tab.le1.txt", "C:\TE.MP\Tab.le3.txt")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2018-06-16              Initial Release - Blog Help
'---------------------------------------------------------------------------------------
Public Function FSO_FileCopy(ByVal sSource As String, _
                             ByVal sDest As String) As Boolean
    On Error GoTo Error_Handler
    Dim oFSO                  As Object

    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Call oFSO.CopyFile(sSource, sDest, True)
    FSO_FileCopy = True

Error_Handler_Exit:
    On Error Resume Next
    If Not oFSO Is Nothing Then Set oFSO = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: FSO_FileCopy" & 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 – Rename a File

Ever simply needed to rename a file? Well, once again there are a multitude of ways to accomplish this within MS Access. I have seen numerous postings suggest using a scripting object and then copy the file while renaming the copied version. To me, if all you need is to rename the file, this is a uselessly complicated method. Instead, why not simply use the Name Statement? It can all be accomplished in one clean line of code!!!

Name "C:\OldFileName" AS "C:\NewFileName"

Actually, you can even use the Name command to move and rename a file simultaneously.

Name "C:\OldDir\OldFileName" AS "C:\NewDir\NewFileName"

As you can see this is another versatile command to be aware of.

VBA – Run/Execute A File

Ever needed to run, execute a file? It could be a *.bat, *.vbs, *.exe, … One common method is to use the shell function. However, we see quite often in the forums and newsgroups regarding issues with it not working and users not getting the synthax right because of spaces in the file paths, etc.

Below is, yet again, a very simple procedure which encapsulates the file to be run/executed with the necessary quotations so that you no longer have any headaches trying to get your Shell function operational. Simply copy the function to a module and call it as indicated below.

'---------------------------------------------------------------------------------------
' Procedure : RunFile
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Run/Execute files from vba (bat, vbs,…)
' 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:
' ~~~~~~~~~~~~~~~~
' strFile - full path including filename and extension
' strWndStyle - style of the window in which the program is to be run
'               value can be vbHide,vbNormalFocus,vbMinimizedFocus
'               vbMaximizedFocus,vbNormalNoFocus or vbMinimizedNoFocus
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' RunFile("c:\test.bat", vbNormalFocus)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-Feb-05             Initial Release
'---------------------------------------------------------------------------------------
Function RunFile(strFile As String, strWndStyle As String)
On Error GoTo Error_Handler

   Shell "cmd /k """ & strFile & """", strWndStyle

Error_Handler_Exit:
   On Error Resume Next
   Exit Function

Error_Handler:
   MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
   Err.Number & vbCrLf & "Error Source: RunFile" & vbCrLf & "Error Description: " & _
   Err.Description, vbCritical, "An Error has Occurred!"
   Resume Error_Handler_Exit
End Function

If however you are interested in opening a file, any type of file, then please refer to my MS Access VBA – Open a File post.

MS Access – VBA – Automatically Adjust User Input to Percentage Values

Have you ever created a control on a form to enter percentage values and had your users complain because they enter whole numbers which get automatically multiplied by 100. So if the user enters 3, it will actually give 300%.

No worries anymore! I created a very simple procedure which will automatically readjust values entered by your users. 3 will automatically be updated to 0.03, which give 3%.

'---------------------------------------------------------------------------------------
' Procedure : ajustPercentage
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Automatically adjust whole number to percentage values
' 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         2010-Sep-21                 Initial Release
'---------------------------------------------------------------------------------------
Function ajustPercentage(sValue As Variant) As Double
On Error GoTo Error_Handler

    If IsNumeric(sValue) = True Then            'Only treat numeric values
        If Right(sValue, 1) = "%" Then
            sValue = Left(sValue, Len(sValue) - 1)
            ajustPercentage = CDbl(sValue)
        End If
        
        If sValue > 1 Then
            sValue = sValue / 100
            ajustPercentage = sValue
        Else
            ajustPercentage = sValue
        End If
    Else                                        'Data passed is not of numeric type
        ajustPercentage = 0
    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: ajustPercentage" & vbCrLf & _
           "Error Description: " & Err.Description, vbCritical, _
           "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

The one thing to note regarding this procedure is that it is meant for controls/fields that you always expect a percentage value between 0% and 100%. If you expect percentage above 100% this procedure will not help you in that case and you will need to build a custom procedure for that situation.