Archive for June, 2010

June 23rd, 2010

What happened to Microsoft’s Newgroups/Forum

Many, Many, Many people have been asking what happened to Microsoft’s Discussion groups that used to be found at http://www.microsoft.com/office/community/en-us/default.mspx.

Sadly, in their infinite (or is that finite) wisdom, Microsoft terminated those groups which had been around for decades and replace it with their ‘new’ and ‘improved’ forums found at http://social.answers.microsoft.com/Forums/en-US/group/Office.

 

Why the Dismay?

There are a number of reasons why I am discontent with this migration move.

  • One of the greatest problems is that they didn’t migrate, but rather shutdown and moved. Which means everything that was previously done, just disappeared over night. You can’t go and look up old posts….
  • If you are an MS Access forum user, then you’ll be disgusted with the simple fact that not only did we loose our categories (forms, queries, reports,…), but Access has been thrown into a common group with Visio and InfoPath… While Excel,… and others retained their own groups, Access has been simply tossed in with numerous other applications? If this is the importance that Microsoft places on its own software, then no wonder users are turning to alternate forums.
  • Another disappointing aspect of the new forum is simply that not all the functionalities actually work (Insert Code for instance). It seems like it was implemented before it was properly tested. Furthermore, months after flagging certain issues, nothing has been fixed!?
  • And then there are all the minor annoyances, such as:
    • If you are on a post and click on the reply button (when you aren’t signed in yet), sign in, you do not get returned to the post you were wanting to reply to… This worked in the old forum. Why in …. name couldn’t they make it work in the new ‘improved’ one!?
    • Sometimes, when you choose to edit a post, the post goes blank!? Your previous post content disappears.

There are many more reasons, but in reality there is no point going on as MS will not change a thing it does. That said, it is because of this that the vast majority of users have simply opted to migrate to alternative groups such as UtterAccess, Yahoo, …

MS’s reasoning, from what I understood, was they wanted to revive their groups, but in fact, from my experience, the numbers have been dropping since their ‘improvement’. The simple fact is that Microsoft chose to ignore the input of countless users, MVPS; the people that use and promote their software. To me it makes no sense! They have no one to blame but themselves for the decline in usage and migration to alternative forums.

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 23rd, 2010

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

As you can see, each application: Access, Excel, PowerPoint, Word as its own Trusted Locations and every entry has a parent key entitled ‘LocationX’, where X is an incremental number. From what I have read (not confirmed in any way) you can have 0 through 19 Trusted Location, so Location0, Location1, …, Location19. With this information in mind and a lot of web searching and vbscripting, I eventually managed to piece a script together and below is what it looks like.

'*******************************************************************************
' Purpose    :Setup the required trusted location
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' 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:	2010-06-23   Initial Release
'*******************************************************************************

	Const HKEY_CURRENT_USER = &H80000001
 
	Dim oRegistry	
	Dim sPath			'Path to set as a Trusted Location	
	Dim sDescription		'Description of the Trusted Location
	Dim bAllowSubFolders		'Enable subFolders as Trusted Locations
	Dim bAllowNetworkLocations 	'Enable Network Locations as Trusted
					'	Locations
	Dim bAlreadyExists
	Dim sParentKey
	Dim iLocCounter
	Dim arrChildKeys
	Dim sChildKey	
	Dim sValue
	Dim sNewKey
 
 
'Determine the location/path of the user's MyDocuments folder
'*******************************************************************************
	Set oRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
	sPath = "TheFullPathOfYourTrustedLocation" 	'ie: c:\databases\
	sDescription = "YourTrustedLocationDescriptionGoesHere"
	bAllowSubFolders = True
	bAlreadyExists = False
 
	sParentKey = "Software\Microsoft\Office\12.0\Access\Security\Trusted Locations"
'	sParentKey = "Software\Microsoft\Office\12.0\Excel\Security\Trusted Locations"
'	sParentKey = "Software\Microsoft\Office\12.0\PowerPoint\Security\Trusted Locations"
'	sParentKey = "Software\Microsoft\Office\12.0\Word\Security\Trusted Locations"
	iLocCounter = 0
	oRegistry.EnumKey HKEY_CURRENT_USER, sParentKey, arrChildKeys
	For Each sChildKey in arrChildKeys
		oRegistry.GetStringValue HKEY_CURRENT_USER, sParentKey & "\" & sChildKey, "Description", sValue
 		If sValue = sDescription Then bAlreadyExists = True
 
		If CInt(Mid(sChildKey, 9)) > iLocCounter Then
        		iLocCounter = CInt(Mid(sChildKey, 9))
	        End If
	Next
 
'Uncomment the following 4 linesif your wish to enable network locations as Trusted
'	Locations
'	bAllowNetworkLocations = True
'	If bAllowNetworkLocations Then
'    		oRegistry.SetDWORDValue HKEY_CURRENT_USER, sParentKey, "AllowNetworkLocations", 1
'	End If

	If bAlreadyExists = False Then
		sNewKey = sParentKey & "\Location" & CStr(iLocCounter + 1)
 
		oRegistry.CreateKey HKEY_CURRENT_USER, sNewKey
		oRegistry.SetStringValue HKEY_CURRENT_USER, sNewKey, "Path", sPath
		oRegistry.SetStringValue HKEY_CURRENT_USER, sNewKey, "Description", sDescription
 
		If bAllowSubFolders Then
			oRegistry.SetDWORDValue HKEY_CURRENT_USER, sNewKey, "AllowSubFolders", 1
		End If
	End if

As usual when dealing with code off the net, and especially with registry coding, use it at your own risk! I assume no liability whatsoever. I am simply sharing information on what worked for me in the hopes it might help someone else.

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

VBA – Converting Between Decimal and Binary

Quite some time ago I had a particular need to convert Decimal to Binary and vice versa. It took a little digging but eventually came across this little gem and thought it was worth posting for others to use.

'Decimal To Binary
' =================
' Source: http://groups.google.ca/group/comp.lang.visual.basic/browse_thread/thread/28affecddaca98b4/979c5e918fad7e63
' Author: Randy Birch (MVP Visual Basic)
' NOTE: You can limit the size of the returned
'              answer by specifying the number of bits
Function Dec2Bin(ByVal DecimalIn As Variant, _
              Optional NumberOfBits As Variant) As String
    Dec2Bin = ""
    DecimalIn = Int(CDec(DecimalIn))
    Do While DecimalIn <> 0
        Dec2Bin = Format$(DecimalIn - 2 * Int(DecimalIn / 2)) & Dec2Bin
        DecimalIn = Int(DecimalIn / 2)
    Loop
    If Not IsMissing(NumberOfBits) Then
       If Len(Dec2Bin) > NumberOfBits Then
          Dec2Bin = "Error - Number exceeds specified bit size"
       Else
          Dec2Bin = Right$(String$(NumberOfBits, _
                    "0") & Dec2Bin, NumberOfBits)
       End If
    End If
End Function
 
'Binary To Decimal
' =================
Function Bin2Dec(BinaryString As String) As Variant
    Dim X As Integer
    For X = 0 To Len(BinaryString) - 1
        Bin2Dec = CDec(Bin2Dec) + Val(Mid(BinaryString, _
                  Len(BinaryString) - X, 1)) * 2 ^ X
    Next
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – DoCmd.TransferSpreadsheet Error 3190 – Too many fields

A quick word of caution regarding the Error code 3190 that may occur when using the DoCmd.TransferSpreadsheet Method to export data. I previously had been using a procedure to export my data without any problems, then I went to use it again and kept getting this error. I mean I only had 12 columns in my query, so what the …?! After doing some testing I ended up determining that it had nothing to do with the field count, but rather with the fact that the file already existed. Basically, the DoCmd.TransferSpreadsheet Method was unable to overwrite the existing file and raised this most useless error!

So beware that Error 3190 – Too many fields can also mean cannot overwrite the existing export file. The fix is extremely easy, simply check for the file and if it does exist then delete it using the Kill statement prior to running the DoCmd.TransferSpreadsheet Method.

Hopefully this will avoid someone some headaches trying to resolve a field error where there never was one to begin with!!!

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

VBA – Using Regular Expressions (RegEx)

One of the most powerful features of some other languages is their ability to utilize Regular Expressions for finding patterns… Sadly however, vba does not have the ability to use them, well at least not naitively! Suprisingly enough, it really is not very complicated to be able to integrate RegEx with one of your procedure by simply creating a vbscript object. The basic idea goes something like:

Set oRegEx = CreateObject("vbscript.regexp")
oRegEx.Pattern = "YourRegEx Goes Here"
bResult = oRegEx.Test(YourStringToTestTheRegExWith)

A great source of RegEx for various purposes can be found at http://regexlib.com/ (click on the button ‘Browse Expressions’). Start by looking there before wasting your time trying to reinvent the RegEx wheel. You’re not the first to need to validate a string, number, …, chances are a RegEx exists that you can simply copy.

And there you go, now you can integrate the power of Regular Expressions in all of your Databases, Spreadsheets, Documents and more! Simple as can be!!!

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – FileName of the Current Database

VBA – Determine the FileName of the Current DatabaseTo determine the filename of the current database, simply use the following line of code:

Application.CurrentProject.Name

It will return a string value like: ‘Access_Solution_Center.mdb’

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – Path of the Current Database

If all you wish is to determine the path of the current database, simply use the following line of code:

Application.CurrentProject.Path

It will return a string value like: ‘D:\MS Access\References’

Pay particular attention to the fact that it does not include the closing slash in the string it returns. So if you are going to use it in your code, remember to concatenate it with a closing slash by simply doing somthing like:

Application.CurrentProject.Path & "\"

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – Path and FileName of the Current Database

Simply use the following line of code to get the full path and filename of the current database.

Application.CurrentDb.Name

It will return a string value like: ‘D:\MS Access\References\Access_Solution_Center.mdb’

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access – Phone Number Format

Although one can easily use an input mask to format value, including phone numbers. It became necessary for me to be able to do the same type of formating but directly through vba. Below is a simple routine, but hopefully it will help you.

This procedure becomes very useful whe you need to deal with phone numbers from varying regions. If you only will ever deal with a preset phone number format then I recommend using the input mask. However, if you will need to accomodate and format all sorts of international phone number formats the procedure is the way to go and you can easily add new format to it by simply adding new Case statement clauses.

'---------------------------------------------------------------------------------------
' Procedure : FormPhone
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Format a string into a formated phone number
' 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:
' ~~~~~~~~~~~~~~~~
' sPhone    : a raw phone number string (ie:5555555)
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' FormPhone("5555555")      -->>    555-5555
' FormPhone("5555555555")   -->>    (555)555-5555
' FormPhone("55555555555")  -->>    5(555)555-5555
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2009-Feb-13             Initial Release
' 2         2010-Jan-26             Expanded code to format 10 and 11 char phone no.
'---------------------------------------------------------------------------------------
Function FormPhone(sPhone As String) As String
On Error GoTo Error_Handler
    Dim sIni        As String
    Dim sArea       As String
    Dim sPNumber    As String
    Dim isPhoneLen  As Integer
 
    'Make sure we actually have a value to process
    If sPhone = "" Or IsNull(sPhone) Then
        sPhone = ""
        Exit Function
    End If
 
    sPhone = Trim(sPhone)    'Remove any leading or trailing white spaces
    isPhoneLen = Len(sPhone) 'Determine the length of the raw tel no.
    Select Case isPhoneLen
        Case 7  '555-5555
            FormPhone = Left(sPhone, 3) & "-" & Right(sPhone, Len(sPhone) - 3)
        Case 10 '(555)555-5555
            sArea = "(" & Left(sPhone, 3) & ") "
            sPNumber = Right(sPhone, Len(sPhone) - 3)
            FormPhone = sArea & Left(sPNumber, 3) & "-" & _
                        Right(sPNumber, Len(sPNumber) - 3)
        Case 11 '5(555)555-5555
            sIni = Left(sPhone, 1)
            sArea = "(" & Left(Right(sPhone, Len(sPhone) - 1), 3) & ") "
            sPNumber = Right(sPhone, Len(sPhone) - 4)
            FormPhone = sIni & sArea & Left(sPNumber, 3) & _
                        "-" & Right(sPNumber, Len(sPNumber) - 3)
        Case Else
            FormPhone = sPhone
    End Select
 
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: FormPhone" & _
           vbCrLf & "Error Description: " & Err.Description, vbCritical, _
           "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

 

Updated 2011-04-14

Below you will find another approach to formatting phone numbers.

Function StripAllChars(strString As String) As String
'Return only numeric values from a string
    Dim lngCtr      As Long
    Dim intChar     As Integer
 
    For lngCtr = 1 To Len(strString)
        intChar = Asc(Mid(strString, lngCtr, 1))
        If intChar >= 48 And intChar <= 57 Then
            StripAllChars = StripAllChars & Chr(intChar)
        End If
    Next lngCtr
End Function
 
Function FormatPhone(strIn As String) As Variant
On Error Resume Next
 
    strIn = StripAllChars(strIn)
 
    If InStr(1, strIn, "@") >= 1 Then
        FormatPhone = strIn
        Exit Function
    End If
 
    Select Case Len(strIn & vbNullString)
        Case 0
            FormatPhone = Null
        Case 7
            FormatPhone = Format(strIn, "@@@-@@@@")
        Case 10
            FormatPhone = Format(strIn, "(@@@) @@@-@@@@")
        Case 11
            FormatPhone = Format(strIn, "@ (@@@) @@@-@@@@")
        Case Else
            FormatPhone = strIn
    End Select
End Function

Both methods work. That said, the second one is much easier to keep adding to and probably run faster too since it does not call upon other procedures (Left(), Right(), Mid(), …) in it’s formatting process. Although with today’s computers you couldn’t tell the difference anyways.

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – Determine the First Day of the Week

Have you ever needed to determine the Sunday or Monday of a week. The following procedure will determine the date of the beginning of the week based on a given date within the week.

'---------------------------------------------------------------------------------------
' Procedure : GetFirstofWeek
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Determine the date of the first day of the week for a given date
' 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:
' ~~~~~~~~~~~~~~~~
' dtDate    : Date to find the start of the week of
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' GetFirstofWeek(#10/2/2009#)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2009-Nov-16                 Initial Release
'---------------------------------------------------------------------------------------
Function GetFirstofWeek(dtDate As Date)
On Error GoTo Error_Handler
    'GetFirstofWeek = DateAdd("d", dtDate, -(Weekday(dtDate)) + 1) 'Returns the Sunday
    GetFirstofWeek = DateAdd("d", dtDate, -(Weekday(dtDate)) + 2) 'Returns the Monday

Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: GetFirstofWeek" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Exit Function
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – Generate a Random String

The following procedure can be used to generate a random string of specified length by the user. Furthermore, the procedure allows the user to specify whether to include: numeric, uppercase and/or lowercase characters in the generated string. It requires no reference libraries and should work in any VBA application (MS Word, MS Excel, MS Access, …).

'---------------------------------------------------------------------------------------
' Procedure : GenRandomStr
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Generate a random string (alpha, numeric or alphanumeric)
' 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:
' ~~~~~~~~~~~~~~~~
' iNoChars      - No of characters the random string should be in length
' bNumeric      - Should the random string include Numeric characters
' bUpperAlpha   - Should the random string include Uppercase Alphabet characters
' bLowerAlpha   - Should the random string include Lowercase Alphabet characters
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' GenRandomStr(12, True, False, True)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2009-Nov-11                 Initial Release
'---------------------------------------------------------------------------------------
Function GenRandomStr(iNoChars As Integer, bNumeric As Boolean, _
                      bUpperAlpha As Boolean, bLowerAlpha As Boolean)
On Error GoTo Error_Handler
    Dim AllowedChars() As Variant
    Dim iEleCounter     As Integer
    Dim i               As Integer
    Dim iRndChar        As Integer
 
    'Initialize our array otherwise it throws an error
    ReDim Preserve AllowedChars(0)
    AllowedChars(0) = ""
 
    Randomize
 
    'Numeric
    '48-57
    If bNumeric = True Then
        For i = 48 To 57
            iEleCounter = UBound(AllowedChars)
            ReDim Preserve AllowedChars(iEleCounter + 1)
            AllowedChars(iEleCounter + 1) = i
        Next i
    End If
 
    'Uppercase alphabet
    '65-90
    If bUpperAlpha = True Then
        For i = 65 To 90
            ReDim Preserve AllowedChars(UBound(AllowedChars) + 1)
            iEleCounter = UBound(AllowedChars)
            AllowedChars(iEleCounter) = i
        Next i
    End If
 
    'Lowercase alphabet
    '97-122
    If bLowerAlpha = True Then
        For i = 97 To 122
            ReDim Preserve AllowedChars(UBound(AllowedChars) + 1)
            iEleCounter = UBound(AllowedChars)
            AllowedChars(iEleCounter) = i
        Next i
    End If
 
    iNoAllowedChars = UBound(AllowedChars)
    For i = 1 To iNoChars
        iRndChar = Int((iNoAllowedChars * Rnd) + 1)
        GenRandomStr = GenRandomStr & Chr(AllowedChars(iRndChar))
    Next i
 
Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: GenRandomStr" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Exit Function
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

MS Access VBA – Run or Execute a File

Have you ever needed to run a *.bat, *.vbs, *.exe, … file from within a database. It actually is quite simple using the Shell command. To simplify matters, and in response to a forum question, I created this simply function to do so. The beauty is that is will take care of adding the required quotes around long file name formats…

'---------------------------------------------------------------------------------------
' 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 Occured!"
    Resume Error_Handler_Exit
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 22nd, 2010

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 complexe 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

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 12th, 2010

MS Access VBA – Open a File

It can be very useful at times to store the paths of files within a database such as word document, excel spreadsheets, etc. Most often it is then necessary to provide the user a method of opening these files without needing to personally navigating to each file themselves. The following line of code will open the given file in the default application associated with it.

Application.FollowHyperlink Method

Application.FollowHyperlink "FullPath&FileName"Example:
 
Application.FollowHyperlink "C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Sunset.jpg"

You can use the Application.FollowHyperlink can also be used to open a folder (not just files)

This technique has always worked very well for me. That said, certain updates, have caused new security warning message to now appear rather than simply open the file. As such, you may wish to use Allen Browne’s GoHyperlink() function instead as it eliminates these messages and make for a more seamless approach.

 

Custom Procedure Method

Another very good alternative is to use the ExecuteFile sub courtesy of Graham Seach (Access MVP). A nice feature is that not only can you open the file, but you can also choose to print the file and control the appearance of the windowstyle of the given application.

'Source: http://www.pacificdb.com.au/MVP/Code/ExeFile.htm
Public Const SW_HIDE = 0
Public Const SW_MINIMIZE = 6
Public Const SW_RESTORE = 9
Public Const SW_SHOW = 5
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_SHOWNOACTIVATE = 4
Public Const SW_SHOWNORMAL = 1
 
Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
    (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long
 
Public Sub ExecuteFile(sFileName As String, sAction As String)
    Dim vReturn As Long
    'sAction can be either "Open" or "Print".
    
    If ShellExecute(Access.hWndAccessApp, sAction, sFileName, vbNullString, "", SW_SHOWNORMAL) < 33 Then
        DoCmd.Beep
        MsgBox "File not found."
    End If
End Sub

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 12th, 2010

MS Access – Listing of Database Objects

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 values 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

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 12th, 2010

MS Access VBA – List Of Security Groups a User Belongs To

The following function will return a listing of all of the Security Group the current user belongs to.

Function fncUserGroups() As String
On Error GoTo Error_Handler
' Created and provided by Dirk Goldgar (MS Access MVP)
' NOTE: Requires a reference to the DAO Object Library.
' PURPOSE: Returns a comma-separated list of the security groups of which
'          the current user is a member.

    Dim ws          As DAO.Workspace
    Dim grp         As DAO.Group
    Dim strGroups   As String
 
    Set ws = DBEngine.Workspaces(0)
 
    For Each grp In ws.Users(CurrentUser).Groups
        strGroups = strGroups & ", " & grp.Name
    Next grp
 
    fncUserGroups = Mid(strGroups, 3)
 
Error_Handler_Exit:
    On Error Resume Next
    Set ws = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: NoYrs" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 12th, 2010

MS Access VBA – Looping through records

One very frequent ‘action’ that programmers need to do is to loop through records. This could be a Table or Query … The basic concept is illustrated below using DAO. Although this can be done using ADO as well, I use DAO as it is native to Access and thus most efficient.

Sub LoopRecExample()
On Error GoTo Error_Handler
    Dim db              As DAO.Database
    Dim rs              As DAO.Recordset
    Dim iCount      As Integer
 
    Set db = CurrentDb()
    Set rs = db.OpenRecordset("TableName") 'open the recordset for use (table, Query, SQL Statement)
    
    With rs
        If .RecordCount <> 0 Then 'Ensure that there are actually records to work with
            'The next 2 line will determine the number of returned records
            rs.MoveLast 'This is required otherwise you may not get the right count
            iCount = rs.RecordCount 'Determine the number of returned records
            
            Do While Not .BOF
                'Do something with the recordset/Your Code Goes Here
                .MovePrevious
            Loop
        End If
    End With
 
    rs.Close 'Close the recordset

Error_Handler_Exit:
    On Error Resume Next
    'Cleanup after ourselves
    Set rs = 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: LoopRecExample" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Sub

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 12th, 2010

MS Access VBA – SendObject to Multiple Recipients

A common question regarding the SendObject Method is how can I specify multiple recipients for the To, CC, BCC variables. It is actually very easy to do! It is the same as that when you create a message manually using you e-mail software (such as Outlook, Outlook Express, Thunderbird, etc.). You need only separate the each e-mail recipient by a semi-colon.

Example:

DoCmd.SendObject acSendNoObject,,,"recipient1@somewhere.com;recipient2@somewhere.com",,,"YourSubject","YourEmailMessage"

And this applies to any of the e-mail recipient lists (To, CC or BCC).

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 12th, 2010

MS Access VBA – Not In List Event

The ‘Not In List Event’ occurs whenever a user tries to enter a vaule into a combobox that is not part of the existing list of choices. Below is a typical example of a ‘Not In List Event’ that will allow the user to add their new value to the exisitng list of choices for further use in the future, assuming you are using an underlying table as the list source.

Private Sub YourCboName_NotInList(NewData As String, Response As Integer)
'Requires that a reference to the Microsoft DAO 3.6 Object Library
On Error GoTo Error_Handler
    Dim rst As DAO.Recordset
 
    If MsgBox(NewData & "... not in list, add it?", vbOKCancel, "MessageBoxTitle") = vbOK Then
        Set rst = CurrentDb.OpenRecordset("TableName") 'Table to add the new value to
        With rst
            .AddNew
            .Fields("TableColumnName") = NewData 'Name of the table field to add the new value to
            .Update
        End With
        Response = acDataErrAdded
    Else
        Response = acDataErrContinue
    End If
 
Error_Handler_Exit:
    On Error Resume Next
    rst.Close
    Set rst = Nothing
    Exit Sub
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: YourCboName_NotInList" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Sub

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 11th, 2010

MS Access – Creating PDFs

MS Access 2003 (or earlier)

I will review 2 techniques for producing PDFs of Access Reports

The first, and the one I am most familiar with, is to install a PDF virtual printer. There are numerous PDF creation software programs on the market and depending on your exact need some are more appropriate than others. This said, for general use, the following 3 programs work well and are free.

CuteWriter – Works well.
pdfcreator – Works well
pdf995 – Works well but you get a popup every time you use it. You can buy and unlocked version for 10$ (without the popup).

Then you can simply print to the PDF printer to convert any document (Word, Excel, Access, etc.) into a PDF. To learn how-to control your printers from code take a look at VBA Change Printer code from Albert D. Kallal’s website.

As I mentioned before, the programs listed above are for basic use. If you need to implement security and/or modify PDFs then I would recommend you get a professional PDF software. There is no denying that Acrobat is very good at what it does.

The second method is to utilize Stephen Lebans Report to PDF. The benefit to this solution is that you do not need to install a printer driver. So you can easily distribute this solution without requiring the end-user to perform any installation which they may not have the rights to do in the first place. Furthermore, since Stephen has distributed it in an ‘open source’ format, one can easily customize it as required by their unique needs.

For more information, take a look at Creating PDF files from within Microsoft Access from Tony Toews’ website.

 

For Access 2007

Microsoft finally saw that there was a need for PDF generation and developed an add-in, “2007 Microsoft Office Add-in: Microsoft Save as PDF or XPS”, for the entire Office Suite. So you can now simply download it, install it and print to it like a normal printer. You can download the add-in at:

http://www.microsoft.com/downloads/details.aspx?familyid=4D951911-3E7E-4AE6-B059-A2E79ED87041&displaylang=en

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 10th, 2010

MS Access VBA – Check if a Report is Open

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

'---------------------------------------------------------------------------------------
' Procedure : IsRptOpen
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Determine whether a report is open or not
' 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 report to check if it is open or not
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' IsRptOpen("Report1")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-May-26                 Initial Release
'---------------------------------------------------------------------------------------
Function IsRptOpen(sRptName As String) As Boolean
On Error GoTo Error_Handler
 
    If Application.CurrentProject.AllReports(sRptName).IsLoaded = True Then
        IsRptOpen = True
    Else
        IsRptOpen = False
    End If
 
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: IsRptOpen" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 10th, 2010

MS Access VBA – Determine if a Report Exists

The following procedure can be used to determine if a specified report exists in the current database.

'---------------------------------------------------------------------------------------
' Procedure : DoesRptExist
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Determine if the specified report exists or not in the current 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:
' ~~~~~~~~~~~~~~~~
' sReportName : Name of the report to check the existance of
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' DoesRptExist("Report1")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-Feb-02             Initial Release
'---------------------------------------------------------------------------------------
Function DoesRptExist(sReportName As String) As Boolean
   Dim rpt  As Object
 
On Error GoTo Error_Handler
   'Initialize our variable
   DoesRptExist = False
 
   Set rpt = CurrentProject.AllReports(sReportName)
 
   DoesRptExist = True  'If we made it to here without triggering an error
                        'the report exists

Error_Handler_Exit:
   On Error Resume Next
   Set rpt = Nothing
   Exit Function
 
Error_Handler:
   If Err.Number = 2467 Then
      'If we are here it is because the report could not be found
   Else
      MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
      Err.Number & vbCrLf & "Error Source: DoesRptExist" & vbCrLf & "Error Description: " & _
      Err.Description, vbCritical, "An Error has Occured!"
   End If
   Resume Error_Handler_Exit
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 10th, 2010

MS Access VBA – Count the Number of Open Reports

'---------------------------------------------------------------------------------------
' Procedure : CountOpenRpts
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Returns a count of the number of loaded reports (preview or design)
' 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.
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2009-Oct-30                 Initial Release
' 2         2009-Oct-31                 Switched from AllReports to Reports collection
'---------------------------------------------------------------------------------------
Function CountOpenRpts()
On Error GoTo Error_Handler
 
    CountOpenRpts = Application.Reports.Count
 
Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: CountOpenRpts" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Exit Function
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 10th, 2010

MS Access VBA – List Currently Open Reports

'---------------------------------------------------------------------------------------
' Procedure : ListOpenRpts
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Returns a list of all the loaded reports (preview or design)
'             separated by ; (ie: Report1;Report2;Report3)
' 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.
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2009-Oct-30                 Initial Release
' 2         2009-Oct-31                 Switched from AllReports to Reports collection
'---------------------------------------------------------------------------------------
Function ListOpenRpts()
On Error GoTo Error_Handler
 
    Dim DbR     As Report
    Dim DbO     As Object
    Dim Rpts    As Variant
 
    Set DbO = Application.Reports
 
    For Each DbR In DbO    'Loop all the reports
            Rpts = Rpts & ";" & DbR.Name
    Next DbR
 
    If Len(Rpts) > 0 Then
        Rpts = Right(Rpts, Len(Rpts) - 1)   'Truncate initial ;
    End If
 
    ListOpenRpts = Rpts
 
Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: ListOpenRpts" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Exit Function
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print
June 10th, 2010

MS Access VBA – List the Reports within a Database

'---------------------------------------------------------------------------------------
' Procedure : ListDbRpts
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Returns a ';' separated string containing the names of all the reports
'             within the database (use Split() to convert the string to an array)
' 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         2007-Nov                 Initial Release
'---------------------------------------------------------------------------------------
Function ListDbRpts() As String
On Error GoTo Error_Handler
 
    Dim DbO     As AccessObject
    Dim DbP     As Object
    Dim Rpts    As String
 
    Set DbP = Application.CurrentProject
 
    For Each DbO In DbP.AllReports
        Rpts = Rpts & ";" & DbO.Name
    Next DbO
    Rpts = Right(Rpts, Len(Rpts) - 1) 'Truncate initial ;
   
    ListDbRpts = Rpts
 
Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: ListDbRpts" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Exit Function
End Function

Share and Enjoy

  • Google Plus
  • Facebook
  • LinkedIn
  • Twitter
  • Email
  • Print