First Published 13 Mar 2023

Boolean variables/fields can have two values, True / False, and may cause various issues in different versions of Access

This article explores some of the issues you may experience and ways of solving them



Problem 1

As part of my Automatic Form Resizing example application, I had 2 boolean variables in a SaveMonitorInfo procedure

The procedure is used to populate a table, tblMonitors

MonitorsTable
Here are the relevant sections of the original code:

Private Sub SaveMonitorInfo(ForMonitorID As String, bytNoMonitors As Byte)

'adds info to tblMonitors
Dim blnPrimary As Boolean, blnCurrent As Boolean

'more code here . . .

If GetMonitorInfo(CLng(ForMonitorID), MONITORINFOEX) = False Then Failed "GetMonitorInfo"

With MONITORINFOEX
If .dwFlags And MONITOR_PRIMARY Then
blnPrimary = True
Else
blnPrimary = False
End If
End With

'more code here . . .

'check which monitor is current
blnCurrent = GetXCursorPos >= lngLeft And GetXCursorPos <= lngRight And GetYCursorPos >= lngTop And GetYCursorPos <= lngBottom

'populate table
strSQL = "INSERT INTO tblMonitors ( MonitorID, PrimaryMonitor, [Left], [Top], [Right], Bottom, HRes, VRes, CurrentMonitor )" & _
" SELECT " & I & " AS MonitorID, " & blnPrimary & " AS PrimaryMonitor," & _
" " & lngLeft & " AS [Left], " & lngTop & " AS [Top], " & lngRight & " AS [Right], " & lngBottom & " AS Bottom," & _
" " & lngHRes & " AS HRes, " & lngVRes & " AS VRes, " & blnCurrent & " AS CurrentMonitor;"

CurrentDb.Execute strSQL, dbFailOnError

End Sub


The procedure works perfectly in English language versions of Office where the 2 variables blnPrimary and blnCurrent return True or False

However, that isn’t the case in other languages.
For example in Spanish, the code returns the Spanish for True (Verdadero) or False (Falso), neither of which are recognised by VBA.

As a result, the code fails with error 3061 ... Too few parameters.

Using -1/0 instead of True/False in the code does not help as the procedure will still return the unrecognized words.



Solutions

There are several ways of solving this problem:

1.   Replace the boolean variables with byte (or integer) number variables and get them to return 1 (for True) or 0 (for False). For example:

Private Sub SaveMonitorInfo(ForMonitorID As String, bytNoMonitors As Byte)
'adds info to tblMonitors
Dim bytPrimary As Byte, bytCurrent As Byte

'. . .

If GetMonitorInfo(CLng(ForMonitorID), MONITORINFOEX) = 0 Then Failed "GetMonitorInfo"

With MONITORINFOEX
If .dwFlags And MONITOR_PRIMARY Then
bytPrimary = 1 'True
Else
bytPrimary = 0 'False
End If
End With

'. . .

'check which monitor is current
bytCurrent = IIf(GetXCursorPos >= lngLeft And GetXCursorPos <= lngRight And GetYCursorPos >= lngTop And GetYCursorPos <= lngBottom, 1, 0)

'populate table
strSQL = "INSERT INTO tblMonitors ( MonitorID, PrimaryMonitor, [Left], [Top], [Right], Bottom, HRes, VRes, CurrentMonitor )" & _
" SELECT " & I & " AS MonitorID, " & bytPrimary & " AS PrimaryMonitor," & _
" " & lngLeft & " AS [Left], " & lngTop & " AS [Top], " & lngRight & " AS [Right], " & lngBottom & " AS Bottom," & _
" " & lngHRes & " AS HRes, " & lngVRes & " AS VRes, " & bytCurrent & " AS CurrentMonitor;"

CurrentDb.Execute strSQL, dbFailOnError

End Sub


      As VBA treats any non-zero value as True, these can then be used to populate the boolean fields in the table

2.   Change the boolean fields in the table to Short Text. Use string variables in the code to return "Yes" or "No" and use that to populate the table



Problem 2

I had a similar issue with my Access/Office365/Windows Version Check utility app a year or so ago.

In that case, the use of a boolean function to populate a table caused a similar issue for German language users.

The relevant parts of the problem code were:

Function CheckAccess365() As Boolean

'. . .

' check string value exists in registry
If GetStringValFromRegistry(HKEY_LOCAL_MACHINE, registryKey, KeyName) <> "" Then
CheckAccess365 = True
End If

End Function


Initially, I changed the code above to:

Function CheckAccess365() As Byte

'v2.54 - changed from Boolean to Byte to fix issue in German when used in PopulateComputerInfo

'. . .

' check string value exists in registry
If GetStringValFromRegistry(HKEY_LOCAL_MACHINE, registryKey, KeyName) <> "" Then
CheckAccess365 = True
End If

End Function


Subsequently, I completely rewrote the code using a text string as it suited my purposes better

Function CheckAccess365() As String

'v2.61 - changed to return string value
CheckAccess365 = "No"
If Nz(GetAccessProductNumber, "") = "365" And GetAccessVersion = "16.0" Then CheckAccess365 = "Yes"
End Function


Both methods work equally well


More Problems

There are other issues with the use of boolean variables and fields.

As already stated, in Access, the boolean datatype only has two possible values True/False (-1/0)
However in most other database programs including SQL Server, boolean datatypes have 3 possible values: True/False/Null

The lack of null values in Access boolean fields can cause a number of issues including

1.   Errors when SQL Server tables with null values in boolean fields are used as linked Access tables. See my article: Write Conflict Errors

2.   Outer join queries fail on Yes/No fields - see thia article on Allen Browne's website



Acknowledgements

Many thanks to Jacinto Trillo and Gunter Avenius for alerting me to these issues so I could fix my code.



Feedback

Please use the contact form below to let me know whether you found this article interesting/useful or if you have any questions/comments.

Please also consider making a donation towards the costs of maintaining this website. Thank you



Colin Riddington           Mendip Data Systems                 13 Mar 2023



Return to Access Blog Page




Return to Top