Files
libreoffice/wizards/source/access2base/Utils.xba
Jean-Pierre Ledure 0bb042d442 Access2Base : Reference to documentation added in every module
+ workaround for setPosSize issue (LO 4.1)
+ "Sidebar" argument for RunCommand
+ Trace dialog layout revisit for cleaner display in Linux

Change-Id: I0d5c4da5681ab1649d062a7133d507163163343e
Reviewed-on: https://gerrit.libreoffice.org/6449
Reviewed-by: Lionel Elie Mamane <lionel@mamane.lu>
Tested-by: Lionel Elie Mamane <lionel@mamane.lu>
2013-10-28 07:38:33 +00:00

652 lines
28 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Utils" script:language="StarBasic">REM =======================================================================================================================
REM === The Access2Base library is a part of the LibreOffice project. ===
REM === Full documentation is available on http://www.access2base.com ===
REM =======================================================================================================================
Option Explicit
Global _A2B_ As Variant
REM -----------------------------------------------------------------------------------------------------------------------
REM --- PRIVATE FUNCTIONS ---
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _AddNumeric(ByVal Optional pvTypes As Variant) As Variant
&apos;Return on top of argument the list of all numeric types
&apos;Facilitates the entry of the list of allowed types in _CheckArgument calls
Dim i As Integer, vNewList() As Variant, vNumeric() As Variant, iSize As Integer
If IsMissing(pvTypes) Then
vNewList = Array()
ElseIf IsArray(pvTypes) Then
vNewList = pvTypes
Else
vNewList = Array(pvTypes)
End If
vNumeric = Array(vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbBigint, vbDecimal)
iSize = UBound(vNewlist)
ReDim Preserve vNewList(iSize + UBound(vNumeric) + 1)
For i = 0 To UBound(vNumeric)
vNewList(iSize + i + 1) = vNumeric(i)
Next i
_AddNumeric = vNewList
End Function &apos; _AddNumeric V0.8.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _BitShift(piValue As Integer, piConstant As Integer) As Boolean
_BitShift = False
If piValue = 0 Then Exit Function
Select Case piConstant
Case 1
Select Case piValue
Case 1, 3, 5, 7, 9, 11, 13, 15: _BitShift = True
Case Else
End Select
Case 2
Select Case piValue
Case 2, 3, 6, 7, 10, 11, 14, 15: _BitShift = True
Case Else
End Select
Case 4
Select Case piValue
Case 4, 5, 6, 7, 12, 13, 14, 15: _BitShift = True
Case Else
End Select
Case 8
Select Case piValue
Case 8, 9, 10, 11, 12, 13, 14, 15: _BitShift = True
Case Else
End Select
End Select
End Function &apos; BitShift
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _CalledSub() As String
_CalledSub = Iif(_A2B_.CalledSub = &quot;&quot;, &quot;&quot;, _GetLabel(&quot;CALLTO&quot;) &amp; &quot; &apos;&quot; &amp; _A2B_.CalledSub &amp; &quot;&apos;&quot;)
End Function &apos; CalledSub V0.8.9
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _CheckArgument(pvItem As Variant _
, ByVal piArgNr As Integer _
, Byval pvType As Variant _
, ByVal Optional pvValid As Variant _
, ByVal Optional pvError As Boolean _
) As Variant
&apos; Called by public functions to check the validity of their arguments
&apos; pvItem Argument to be checked
&apos; piArgNr Argument sequence number
&apos; pvType Single value or array of allowed variable types
&apos; If of string type must contain one or more valid pseudo-object types
&apos; pvValid Single value or array of allowed values - comparison for strings is case-insensitive
&apos; pvError If True (default), error handling in this routine. False in _setProperty methods in class modules.
_CheckArgument = False
Dim iVarType As Integer
If IsArray(pvType) Then iVarType = VarType(pvType(LBound(pvType))) Else iVarType = VarType(pvType)
If iVarType = vbString Then &apos; pvType is a pseudo-type string
_CheckArgument = Utils._IsPseudo(pvItem, pvType)
Else
If IsMissing(pvValid) Then _CheckArgument = Utils._IsScalar(pvItem, pvType) Else _CheckArgument = Utils._IsScalar(pvItem, pvType, pvValid)
End If
If VarType(pvItem) = vbCurrency Or VarType(pvItem) = vbDecimal Or VarType(pvItem) = vbBigint Then pvItem = CDbl(pvItem)
Exit_Function:
If Not _CheckArgument Then
If IsMissing(pvError) Then pvError = True
If pvError Then
TraceError(TRACEFATAL, ERRWRONGARGUMENT, Utils._CalledSub(), 0, 1, Array(piArgNr, pvItem))
End If
End If
Exit Function
End Function &apos; CheckArgument V0.9.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _CStr(pvArg As Variant, ByVal Optional pbShort As Boolean) As String
&apos; Convert pvArg into a readable string (truncated if too long and pbShort = True or missing)
Dim sArg As String, sObject As String, oArg As Object, sLength As String
Const cstLength = 50
If IsArray(pvArg) Then
sArg = &quot;[ARRAY]&quot;
Else
Select Case VarType(pvArg)
Case vbEmpty : sArg = &quot;[EMPTY]&quot;
Case vbNull : sArg = &quot;[NULL]&quot;
Case vbObject
If IsNull(pvArg) Then
sArg = &quot;[NULL]&quot;
Else
sObject = Utils._ImplementationName(pvArg)
If Utils._IsPseudo(pvArg, Array(OBJDATABASE, OBJCOLLECTION, OBJPROPERTY, OBJFORM, OBJSUBFORM, OBJCONTROL, OBJOPTIONGROUP _
, OBJEVENT, OBJFIELD, OBJTABLEDEF, OBJQUERYDEF, OBJRECORDSET _
)) Then
Set oArg = pvArg &apos; To avoid &quot;Object variable not set&quot; error message
sArg = &quot;[&quot; &amp; oArg._Type &amp; &quot;] &quot; &amp; oArg._Name
ElseIf sObject &lt;&gt; &quot;&quot; Then
sArg = &quot;[&quot; &amp; sObject &amp; &quot;]&quot;
Else
sArg = &quot;[OBJECT]&quot;
End If
End If
Case vbVariant : sArg = &quot;[VARIANT]&quot;
Case vbString : sArg = pvArg
Case vbBoolean : sArg = Iif(pvArg, &quot;TRUE&quot;, &quot;FALSE&quot;)
Case Else : sArg = CStr(pvArg)
End Select
End If
If IsMissing(pbShort) Then pbShort = True
If pbShort And Len(sArg) &gt; cstLength Then
sLength = &quot;(&quot; &amp; Len(sArg) &amp; &quot;)&quot;
sArg = Left(sArg, cstLength - 5 - Len(slength)) &amp; &quot; ... &quot; &amp; sLength
End If
_CStr = sArg
End Function &apos; CStr V0.9.5
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _DecimalPoint() As String
&apos;Return locale decimal point
_DecimalPoint = Mid(Format(0, &quot;0.0&quot;), 2, 1)
End Function
REM -----------------------------------------------------------------------------------------------------------------------
Private Function _ExtensionLocation() As String
&apos; Return the URL pointing to the location where OO installed the Access2Base extension
&apos; Adapted from http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/Location_of_Installed_Extensions
Dim oPip As Object, sLocation As String
Set oPip = GetDefaultContext.getByName(&quot;/singletons/com.sun.star.deployment.PackageInformationProvider&quot;)
_ExtensionLocation = oPip.getPackageLocation(&quot;Access2Base&quot;)
End Function &apos; ExtensionLocation
REM -----------------------------------------------------------------------------------------------------------------------
Private Function _getResultSetColumnValue(poResultSet As Object, Byval piColIndex As Integer) As Variant
REM Modified from Roberto Benitez&apos;s BaseTools
REM get the data for the column specified by ColIndex
REM get type name from metadata
Dim vValue As Variant, sType As String, vDateTime As Variant
sType = poResultSet.MetaData.getColumnTypeName(piColIndex)
Select Case sType
Case &quot;ARRAY&quot;: vValue = poResultSet.getArray(piColIndex)
Case &quot;BLOB&quot;: vValue = poResultSet.getBlob(piColIndex)
Case &quot;BIT&quot;, &quot;BOOLEAN&quot;: vValue = poResultSet.getBoolean(piColIndex)
Case &quot;BYTE&quot;: vValue = poResultSet.getByte(piColIndex)
Case &quot;BYTES&quot;: vValue = poResultSet.getBytes(piColIndex)
Case &quot;CLOB&quot;: vValue = poResultSet.getClob(piColIndex)
Case &quot;DATE&quot;: vDateTime = poResultSet.getDate(piColIndex)
vValue = DateSerial(CInt(vDateTime.Year), CInt(vDateTime.Month), CInt(vDateTime.Day))
Case &quot;DOUBLE&quot;, &quot;REAL&quot;: vValue = poResultSet.getDouble(piColIndex)
Case &quot;FLOAT&quot;: vValue = poResultSet.getFloat(piColIndex)
Case &quot;INTEGER&quot;, &quot;SMALLINT&quot;: vValue = poResultSet.getInt(piColIndex)
Case &quot;LONG&quot;, &quot;BIGINT&quot;: vValue = poResultSet.getLong(piColIndex)
Case &quot;DECIMAL&quot;, &quot;NUMERIC&quot;: vValue = poResultSet.getDouble(piColIndex)
Case &quot;NULL&quot;: vValue = poResultSet.getNull(piColIndex)
Case &quot;OBJECT&quot;: vValue = poResultSet.getObject(piColIndex)
Case &quot;REF&quot;: vValue = poResultSet.getRef(piColIndex)
Case &quot;SHORT&quot;, &quot;TINYINT&quot;: vValue = poResultSet.getShort(piColIndex)
Case &quot;CHAR&quot;, &quot;VARCHAR&quot;, &quot;LONGVARCHAR&quot;: vValue = poResultSet.getString(piColIndex)
Case &quot;TIME&quot;: vDateTime = poResultSet.getTime(piColIndex)
vValue = TimeSerial(vDateTime.Hours, vDateTime.Minutes, vDateTime.Seconds)&apos;, vDateTime.HundredthSeconds)
Case &quot;TIMESTAMP&quot;: vDateTime = poResultSet.getTimeStamp(piColIndex)
vValue = DateSerial(CInt(vDateTime.Year), CInt(vDateTime.Month), CInt(vDateTime.Day)) _
+ TimeSerial(vDateTime.Hours, vDateTime.Minutes, vDateTime.Seconds)&apos;, vDateTime.HundredthSeconds)
Case Else
vValue = poResultSet.getString(piColIndex) &apos;GIVE STRING A TRY
If IsNumeric(vValue) Then vValue = Val(vValue) &apos;Required when type = &quot;&quot;, sometimes numeric fields are returned as strings (query/MSAccess)
End Select
_getResultSetColumnValue = vValue
End Function &apos; getResultSetColumnValue V 0.9.5
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _FinalProperty(psShortcut As String) As String
&apos; Return the final property of a shortcut
Const cstEXCLAMATION = &quot;!&quot;
Const cstDOT = &quot;.&quot;
Dim iCurrentIndex As Integer, vCurrentObject As Variant, sCurrentProperty As String
Dim sComponents() As String, sSubComponents() As String
_FinalProperty = &quot;&quot;
sComponents = Split(Trim(psShortcut), cstEXCLAMATION)
If UBound(sComponents) = 0 Then Exit Function
sSubComponents = Split(sComponents(UBound(sComponents)), cstDOT)
Select Case UBound(sSubComponents)
Case 1
_FinalProperty = sSubComponents(1)
Case Else
Exit Function
End Select
End Function &apos; FinalProperty
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _GetProductName(ByVal Optional psFlag As String) as String
&apos;Return OO product (&quot;PRODUCT&quot;) and version numbers (&quot;VERSION&quot;)
&apos;Derived from Tools library
Dim oProdNameAccess as Object
Dim sVersion as String
Dim sProdName as String
If IsMissing(psFlag) Then psFlag = &quot;ALL&quot;
oProdNameAccess = _GetRegistryKeyContent(&quot;org.openoffice.Setup/Product&quot;)
sProdName = oProdNameAccess.getByName(&quot;ooName&quot;)
sVersion = oProdNameAccess.getByName(&quot;ooSetupVersionAboutBox&quot;)
Select Case psFlag
Case &quot;ALL&quot; : _GetProductName = sProdName &amp; &quot; &quot; &amp; sVersion
Case &quot;PRODUCT&quot; : _GetProductName = sProdName
Case &quot;VERSION&quot; : _GetProductName = sVersion
End Select
End Function &apos; GetProductName V1.0.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _GetRegistryKeyContent(sKeyName as string, Optional bforUpdate as Boolean) As Variant
&apos;Implement ConfigurationProvider service
&apos;Derived from Tools library
Dim oConfigProvider as Object
Dim aNodePath(0) as new com.sun.star.beans.PropertyValue
oConfigProvider = createUnoService(&quot;com.sun.star.configuration.ConfigurationProvider&quot;)
aNodePath(0).Name = &quot;nodepath&quot;
aNodePath(0).Value = sKeyName
If IsMissing(bForUpdate) Then bForUpdate = False
If bForUpdate Then
_GetRegistryKeyContent() = oConfigProvider.createInstanceWithArguments(&quot;com.sun.star.configuration.ConfigurationUpdateAccess&quot;, aNodePath())
Else
_GetRegistryKeyContent() = oConfigProvider.createInstanceWithArguments(&quot;com.sun.star.configuration.ConfigurationAccess&quot;, aNodePath())
End If
End Function &apos; GetRegistryKeyContent V0.8.5
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _getUNOTypeName(pvObject As Variant) As String
&apos; Return the symbolic name of the pvObject (UNO-object) type
&apos; Code-snippet from XRAY
Dim oService As Object, vClass as Variant
_getUNOTypeName = &quot;&quot;
On Local Error Resume Next
oService = CreateUnoService(&quot;com.sun.star.reflection.CoreReflection&quot;)
vClass = oService.getType(pvObject)
If vClass.TypeClass = com.sun.star.uno.TypeClass.STRUCT Then
_getUNOTypeName = vClass.Name
End If
oService.Dispose()
End Function &apos; getUNOTypeName
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _hasUNOMethod(pvObject As Variant, psMethod As String) As Boolean
&apos; Return true if pvObject has the (UNO) method psMethod
&apos; Code-snippet found in Bernard Marcelly&apos;s XRAY
Dim vInspect as Variant
_hasUNOMethod = False
On Local Error Resume Next
If IsNull(_A2B_.Introspection) Then _A2B_.Introspection = CreateUnoService(&quot;com.sun.star.beans.Introspection&quot;)
vInspect = _A2B_.Introspection.Inspect(pvObject)
_hasUNOMethod = vInspect.hasMethod(psMethod, com.sun.star.beans.MethodConcept.ALL)
End Function &apos; hasUNOMethod V0.8.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _hasUNOProperty(pvObject As Variant, psProperty As String) As Boolean
&apos; Return true if pvObject has the (UNO) property psProperty
&apos; Code-snippet found in Bernard Marcelly&apos;s XRAY
Dim vInspect as Variant
_hasUNOProperty = False
On Local Error Resume Next
If IsNull(_A2B_.Introspection) Then _A2B_.Introspection = CreateUnoService(&quot;com.sun.star.beans.Introspection&quot;)
vInspect = _A2B_.Introspection.Inspect(pvObject)
_hasUNOProperty = vInspect.hasProperty(psProperty, com.sun.star.beans.PropertyConcept.ALL)
End Function &apos; hasUNOProperty V0.8.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _ImplementationName(pvObject As Variant) As String
&apos; Use getImplementationName method or _getUNOTypeName function
Dim sObjectType As String
On Local Error Resume Next
sObjectType = pvObject.getImplementationName()
If sObjectType = &quot;&quot; Then sObjectType = _getUNOTypeName(pvObject)
_ImplementationName = sObjectType
End Function &apos; ImplementationName
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _InList(ByVal pvItem As Variant, pvList As Variant, ByVal Optional pvReturnValue As Variant, Optional ByVal pbBinarySearch As Boolean) As Variant
&apos; Return True if pvItem is present in the pvList array (case insensitive comparison)
&apos; Return the value in pvList if pvReturnValue = True
Dim i As Integer, bFound As Boolean, iListVarType As Integer, iItemVarType As Integer
Dim iTop As Integer, iBottom As Integer, iFound As Integer
iItemVarType = VarType(pvItem)
If iItemVarType = vbNull Or IsNull(pvList) Then
_InList = False
ElseIf Not IsArray(pvList) Then
_InList = ( pvItem = pvList )
ElseIf UBound(pvList) &lt; LBound(pvList) Then &apos; Array not initialized
_InList = False
Else
bFound = False
_InList = False
iListVarType = VarType(pvList(LBound(pvList)))
If iListVarType = iItemVarType _
Or ( (iListVarType = vbInteger Or iListVarType = vbLong Or iListVarType = vbSingle Or iListVarType = vbDouble _
Or iListVarType = vbCurrency Or iListVarType = vbBigint Or iListVarType = vbDecimal) _
And (iItemVarType = vbInteger Or iItemVarType = vbLong Or iItemVarType = vbSingle Or iItemVarType = vbDouble _
Or iItemVarType = vbCurrency Or iItemVarType = vbBigint Or iItemVarType = vbDecimal) _
) Then
If IsMissing(pbBinarySearch) Then pbBinarySearch = False
If Not pbBinarySearch Then &apos; Linear search
For i = LBound(pvList) To UBound(pvList)
If iItemVarType = vbString Then bFound = ( pvList(i) &lt;&gt; &quot;&quot; And UCase(pvItem) = UCase(pvList(i)) ) Else bFound = ( pvItem = pvList(i) )
If bFound Then
iFound = i
Exit For
End If
Next i
Else &apos; Binary search =&gt; array must be sorted
iTop = UBound(pvList)
iBottom = lBound(pvList)
Do
iFound = (iTop + iBottom) / 2
If ( iItemVarType = vbString And UCase(pvItem) &gt; UCase(pvList(iFound)) ) Or ( iItemVarType &lt;&gt; vbString And pvItem &gt; pvList(iFound) ) Then
iBottom = iFound + 1
Else
iTop = iFound - 1
End If
If iItemVarType = vbString Then bFound = ( pvList(i) &lt;&gt; &quot;&quot; And UCase(pvItem) = UCase(pvList(iFound)) ) Else bFound = ( pvItem = pvList(iFound) )
Loop Until ( bFound ) Or ( iBottom &gt; iTop )
End If
If bFound Then
If IsMissing(pvReturnValue) Then _InList = True Else _InList = pvList(iFound)
End If
End If
End If
Exit Function
End Function &apos; InList V0.9.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _InspectPropertyType(poObject As Object, psProperty As String) As String
&apos;Return type of property EVEN WHEN EMPTY ! (Used in date and time controls)
Dim oInspect1 As Object, oInspect2 As Object, oInspect3 As Object
&apos; On Local Error Resume Next
_InspectPropertyType = &quot;&quot;
Set oInspect1 = CreateUnoService(&quot;com.sun.star.script.Invocation&quot;)
Set oInspect2 = oInspect1.createInstanceWithArguments(Array(poObject)).IntroSpection
If Not IsNull(oInspect2) Then
Set oInspect3 = oInspect2.getProperty(psProperty, com.sun.star.beans.PropertyConcept.ALL)
If Not IsNull(oInspect3) Then _InspectPropertyType = oInspect3.Type.Name
End If
Set oInspect1 = Nothing : Set oInspect2 = Nothing : Set oInspect3 = Nothing
End Function &apos; InspectPropertyType V1.0.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _IsPseudo(pvObject As Variant, ByVal pvType As Variant) As Boolean
&apos; Test pvObject: does it exist ?
&apos; is the _Type item = one of the proposed pvTypes ?
&apos; does the pseudo-object refer to an existing object (e.g. does the form really exist in the db) ?
Dim bIsPseudo As Boolean, bPseudoExists As Boolean, vObject As Variant
If _ErrorHandler() Then On Local Error Goto Exit_False
_IsPseudo = False
bIsPseudo = False
vObject = pvObject &apos; To avoid &quot;Object variable not set&quot; error message
Select Case True
Case IsEmpty(vObject)
Case IsNull(vObject)
Case VarType(vObject) &lt;&gt; vbObject
Case Else
With vObject
Select Case True
Case IsEmpty(._Type)
Case IsNull(._Type)
Case ._Type = &quot;&quot;
Case Else
bIsPseudo = _InList(._Type, pvType)
If Not bIsPseudo Then &apos; If primary type did not succeed, give the subtype a chance
If ._Type = OBJCONTROL Then bIsPseudo = _InList(._SubType, pvType)
End If
End Select
End With
End Select
If Not bIsPseudo Then Goto Exit_Function
Dim oDatabase As Variant, oForms As Variant
bPseudoExists = False
With vObject
Select Case ._Type
Case OBJFORM
If ._Name &lt;&gt; &quot;&quot; Then &apos; Check validity of form name
Set oDatabase = _CurrentDb
If oDatabase._Standalone Then
bPseudoExists = True
Else
Set oForms = oDatabase.Document.getFormDocuments()
bPseudoExists = ( oForms.HasByName(._Name) )
End If
End If
Case OBJDATABASE
If ._Standalone Then bPseudoExists = True Else bPseudoExists = .Document.CurrentController.IsConnected
Case OBJDIALOG
If ._Name &lt;&gt; &quot;&quot; Then &apos; Check validity of dialog name
Set oDatabase = _CurrentDb
bPseudoExists = ( oDatabase._hasDialog(._Name) )
End If
Case OBJCOLLECTION
bPseudoExists = True
Case OBJCONTROL
If Not IsNull(.ControlModel) And ._Name &lt;&gt; &quot;&quot; Then &apos; Check validity of control
Set oForms = .ControlModel.Parent
bPseudoExists = ( oForms.hasByName(._Name) )
End If
Case OBJSUBFORM
If Not IsNull(.DatabaseForm) And ._Name &lt;&gt; &quot;&quot; Then &apos; Check validity of subform
If .DatabaseForm.ImplementationName = &quot;com.sun.star.comp.forms.ODatabaseForm&quot; Then
Set oForms = .DatabaseForm.Parent
bPseudoExists = ( oForms.hasByName(._Name) )
End If
End If
Case OBJOPTIONGROUP
bPseudoExists = ( .Count &gt; 0 )
Case OBJEVENT
bPseudoExists = ( Not IsNull(._EventSource) )
Case OBJPROPERTY
bPseudoExists = ( ._Name &lt;&gt; &quot;&quot; )
Case OBJTABLEDEF
bPseudoExists = ( ._Name &lt;&gt; &quot;&quot; And Not IsNull(.Table) )
Case OBJQUERYDEF
bPseudoExists = ( ._Name &lt;&gt; &quot;&quot; And Not IsNull(.Query) )
Case OBJRECORDSET
bPseudoExists = ( Not IsNull(.RowSet) )
Case OBJFIELD
bPseudoExists = ( ._Name &lt;&gt; &quot;&quot; And Not IsNull(.Column) )
Case Else
End Select
End With
_IsPseudo = ( bIsPseudo And bPseudoExists )
Exit_Function:
Exit Function
Exit_False:
_IsPseudo = False
Goto Exit_Function
End Function &apos; IsPseudo V0.9.1
REM -----------------------------------------------------------------------------------------------------------------------
Private Function _IsScalar(ByVal pvArg As Variant, Byval pvType As Variant, ByVal Optional pvValid As Variant) As Boolean
&apos; Check type of pvArg and value in allowed pvValid list
_IsScalar = False
If IsArray(pvType) Then
If Not _InList(VarType(pvArg), pvType) Then Exit Function
ElseIf VarType(pvArg) &lt;&gt; pvType Then
If pvType = vbBoolean And VarType(pvArg) = vbLong Then
If pvArg &lt; -1 And pvArg &gt; 0 Then Exit Function &apos; Special boolean processing because the Not function returns a Long
Else
Exit Function
End If
End If
If Not IsMissing(pvValid) Then
If Not _InList(pvArg, pvValid) Then Exit Function
End If
_IsScalar = True
Exit_Function:
Exit Function
End Function &apos; IsScalar V0.7.5
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _PCase(ByVal psString As String) As String
&apos; Return the proper case representation of argument
Dim vSubStrings() As Variant, i As Integer, iLen As Integer
vSubStrings = Split(psString, &quot; &quot;)
For i = 0 To UBound(vSubStrings)
iLen = Len(vSubStrings(i))
If iLen &gt; 1 Then
vSubStrings(i) = UCase(Left(vSubStrings(i), 1)) &amp; LCase(Right(vSubStrings(i), iLen - 1))
ElseIf iLen = 1 Then
vSubStrings(i) = UCase(vSubStrings(i))
End If
Next i
_PCase = Join(vSubStrings, &quot; &quot;)
End Function &apos; PCase V0.9.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _ReplaceSquareBrackets(ByVal psSql As String) As String
&apos; Returns psSql after substitution of [] by quote character
&apos; [] square brackets in quoted strings not affected
Dim sQuote As String &apos;RDBMS specific quote character
Dim vSubStrings() As Variant, i As Integer
sQuote = CurrentDb.MetaData.IdentifierQuoteString
If sQuote = &quot; &quot; Then &apos; What&apos;s the string used to quote SQL identifiers? This returns a space &quot; &quot; if identifier quoting is not supported.
_QuoteString = psSql
Exit Function
End If
vSubStrings() = Split(psSql, sQuote)
For i = 0 To UBound(vSubStrings)
If (i Mod 2) = 0 Then &apos; Only even substrings are parsed for square brackets
vSubStrings(i) = Join(Split(vSubStrings(i), &quot;[&quot;), sQuote)
vSubStrings(i) = Join(Split(vSubStrings(i), &quot;]&quot;), sQuote)
End If
Next i
_ReplaceSquareBrackets = Join(vSubStrings, sQuote)
End Function &apos; ReplaceSquareBrackets V0.7.5
REM -----------------------------------------------------------------------------------------------------------------------
Public Sub _ResetCalledSub(ByVal psSub As String) As String
&apos; Called in bottom of each public function. _A2B_.CalledSub variable is used for error handling
&apos; Used to trace routine in/outs and to clarify error messages
If _A2B_.CalledSub = psSub Then _A2B_.CalledSub = &quot;&quot;
If _A2B_.MinimalTraceLevel = 1 Then TraceLog(TRACEDEBUG, _GetLabel(&quot;Exiting&quot;) &amp; &quot; &quot; &amp; psSub &amp; &quot; ...&quot;, False)
End Sub &apos; ResetCalledSub
REM -----------------------------------------------------------------------------------------------------------------------
Public Sub _SetCalledSub(ByVal psSub As String) As String
&apos; Called in top of each public function.
&apos; Used to trace routine in/outs and to clarify error messages
If _A2B_.CalledSub = &quot;&quot; Then _A2B_.CalledSub = psSub
If _A2B_.MinimalTraceLevel = 1 Then TraceLog(TRACEDEBUG, _GetLabel(&quot;Entering&quot;) &amp; &quot; &quot; &amp; psSub &amp; &quot; ...&quot;, False)
End Sub &apos; SetCalledSub
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _Surround(ByVal psName As String) As String
&apos; Return [Name] if Name contains spaces
Const cstSquareOpen = &quot;[&quot;
Const cstSquareClose = &quot;]&quot;
If InStr(psName, &quot; &quot;) &gt; 0 Then
_Surround = cstSquareOpen &amp; psName &amp; cstSquareClose
Else
_Surround = psName
End If
End Function &apos; Surround
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _Trim(ByVal psString As String) As String
&apos; Remove leading and trailing spaces, remove surrounding square brackets
Const cstSquareOpen = &quot;[&quot;
Const cstSquareClose = &quot;]&quot;
Dim sTrim As String
sTrim = Trim(psString)
_Trim = sTrim
If Len(sTrim) &lt;= 2 Then Exit Function
If Left(sTrim, 1) = cstSquareOpen Then
If Right(sTrim, 1) = cstSquareClose Then
_Trim = Mid(sTrim, 2, Len(sTrim) - 2)
End If
End If
End Function &apos; Trim V0.9.0
REM -----------------------------------------------------------------------------------------------------------------------
Public Function _TrimArray(pvArray As Variant) As Variant
&apos; Remove empty strings from strings array
Dim sTrim As String, vTrim() As Variant, i As Integer, j As Integer, iCount As Integer
vTrim = Null
If Not IsArray(pvArray) Then
If Len(Trim(pvArray)) &gt; 0 Then vTrim = Array(pvArray) Else vTrim = Array()
ElseIf UBound(pvArray) &lt; LBound(pvArray) Then &apos; Array empty
vTrim = Array()
Else
iCount = 0
For i = LBound(pvArray) To UBound(pvArray)
If Len(Trim(pvArray(i))) = 0 Then iCount = iCount + 1
Next i
If iCount = 0 Then
vTrim() = pvArray()
ElseIf iCount = UBound(pvArray) - LBound(pvArray) + 1 Then &apos; Array empty or all blanks
vTrim() = Array()
Else
ReDim vTrim(LBound(pvArray) To UBound(pvArray) - iCount)
j = 0
For i = LBound(pvArray) To UBound(pvArray)
If Len(Trim(pvArray(i))) &gt; 0 Then
vTrim(j) = pvArray(i)
j = j + 1
End If
Next i
End If
End If
_TrimArray() = vTrim()
End Function &apos; TrimArray V0.9.0
</script:module>