Excel 97 Enum

G

Guest

I have a module that accesses the registry. It uses the Enum type and this
works find in Office 2000 but in Office 97 it does not work. I know that VBA
5 does not support the Enum type. I need to know what to use instead of the
Enum type. I have included some code below:

Public Enum RegOptions ' variable: lOptions
StoreNumbersAsStrings = 1
ReturnMultiStringsAsArrays = 2
ExpandEnvironmentStrings = 4
ShowErrorMessages = 8
End Enum
Public Enum RegRoot ' variable: lRoot
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_USER = &H80000001 ' default
HKEY_LOCAL_MACHINE = &H80000002
End Enum

Property Let Root(lProp As RegRoot)
' Don't accept an invalid Root value.
Select Case lProp
Case HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, _
HKEY_LOCAL_MACHINE
' All is well.
Case Else
lRoot = HKEY_CURRENT_USER
End Select
If lProp <> lRoot Then
lRoot = lProp
If Len(strKeyName) Then
GetKeyHandle lRoot, strKeyName
End If
End If
lRoot = lProp
End Property
 
P

Peter T

I havn't tried your code, but something like this:

#If VB6 Then
Public Enum RegOptions ' variable: lOptions
StoreNumbersAsStrings = 1
ReturnMultiStringsAsArrays = 2
ExpandEnvironmentStrings = 4
ShowErrorMessages = 8
End Enum
#Else
Public Const StoreNumbersAsStrings As Long = 1
Public Const ReturnMultiStringsAsArrays As Long = 2
Public Const ExpandEnvironmentStrings As Long = 4
Public Const ShowErrorMessages As Long = 8
#End If

Regards,
Peter T
 
G

Guest

I understand that I need to use Public Const but what about the procedure
that accepts that Enum? How will I be able to handle that?
 
P

Peter T

First of all the serious typo in my previous -

#If VB6
should read
#If VBA6

I can't test your code but with the conditional declaration for your Enum's
or public constants as previously suggested (& corrected typo), try
something like:

#If VBA6 Then
Property Let Root(lProp As RegOptions)
#Else
Property Let Root(lProp As Long)
#End If

'code

End Property

Regards,
Peter T
 
G

Guest

Thank you for your help on this but since it is not my code I am not sure how
to implement this. I have included all the code that is in the RegOp class.
If you could help me with the changes that are necessary I would appreciate
it.

Option Explicit

DefStr S
DefLng H-I, L, N
DefVar V
DefBool B
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
' RegCreateKeyEx creates the specified key. If the key
' already exists, the function opens it. The phkResult
' parameter receives the key handle.
Private Declare Function RegCreateKeyEx _
Lib "advapi32.dll" Alias _
"RegCreateKeyExA" ( _
ByVal hKey As Long, ByVal lpSubKey As String, _
ByVal Reserved As Long, ByVal lpClass As String, _
ByVal dwOptions As Long, ByVal samDesired As Long, _
lpSecurityAttributes As SECURITY_ATTRIBUTES, _
phkResult As Long, lpdwDisposition As Long) As Long
'RegCloseKey releases a handle to the specified key.
'(Key handles should not be left open any longer than
'necessary.)
Private Declare Function RegCloseKey Lib "advapi32.dll" ( _
ByVal hCurKey As Long) As Long
' RegQueryInfoKey retrieves information about the specified
'key, such as the number of subkeys and values, the length
'of the longest value and key name, and the size of the
'longest data component among the key's values.
Private Declare Function RegQueryInfoKey _
Lib "advapi32.dll" Alias "RegQueryInfoKeyA" ( _
ByVal hCurKey As Long, ByVal lpClass As String, _
lpcbClass As Long, ByVal lpReserved As Long, _
lpcSubKeys As Long, lpcbMaxSubKeyLen As Long, _
lpcbMaxClassLen As Long, lpcValues As Long, _
lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, _
lpcbSecurityDescriptor As Long, _
lpftLastWriteTime As Long) As Long
'RegEnumKeyEx enumerates subkeys of the specified open
'key. Retrieves the name (and its length) of each subkey.
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" _
Alias "RegEnumKeyExA" (ByVal hCurKey As Long, _
ByVal dwIndex As Long, ByVal lpName As String, _
lpcbName As Long, ByVal lpReserved As Long, _
ByVal lpClass As String, lpcbClass As Long, _
lpftLastWriteTime As Long) As Long
'RegEnumValue enumerates the values for the specified open
'key. Retrieves the name (and its length) of each value,
'and the type, content and size of the data.
Private Declare Function RegEnumValue Lib "advapi32.dll" _
Alias "RegEnumValueA" (ByVal hCurKey As Long, _
ByVal dwIndex As Long, ByVal lpValueName As String, _
lpcbValueName As Long, ByVal lpReserved As Long, _
lpType As Long, lpData As Any, lpcbData As Long) As Long
'RegQueryValueEx retrieves the type, content and data for
' a specified value name. Note that if you declare the
' lpData parameter as String, you must pass it By Value.
Private Declare Function RegQueryValueEx _
Lib "advapi32.dll" Alias "RegQueryValueExA" ( _
ByVal hCurKey As Long, ByVal lpValueName As String, _
ByVal lpReserved As Long, lpType As Long, _
lpData As Any, lpcbData As Long) As Long
'RegSetValueEx sets the data and type of a specified
' value under a key.
Private Declare Function RegSetValueEx Lib "advapi32.dll" _
Alias "RegSetValueExA" (ByVal hCurKey As Long, ByVal _
lpValueName As String, ByVal Reserved As Long, _
ByVal dwType As Long, lpData As Any, _
ByVal cbData As Long) As Long
'RegDeleteValue removes a named value from specified key.
Private Declare Function RegDeleteValue _
Lib "advapi32.dll" Alias "RegDeleteValueA" ( _
ByVal hCurKey As Long, ByVal lpValueName As String) _
As Long
'RegDeleteKey deletes a subkey. Under Win 95/98, also
'deletes all subkeys and values. Under Windows NT/2000,
'the subkey to be deleted must not have subkeys. The class
'attempts to use SHDeleteKey (see below) before using
'RegDeleteKey.
Private Declare Function RegDeleteKey Lib "advapi32.dll" _
Alias "RegDeleteKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String) As Long
'SHDeleteKey deletes a subkey and all its descendants.
'Under Windows NT 4.0, Internet Explorer 4.0 or later
'is required.
Private Declare Function SHDeleteKey Lib "Shlwapi" _
Alias "SHDeleteKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String) As Long
Private Declare Function LoadLibrary Lib "kernel32" _
Alias "LoadLibraryA" (ByVal lpLibFileName As String) _
As Long
Private Declare Function FreeLibrary Lib "kernel32" ( _
ByVal hLibModule As Long) As Long
Private Declare Function ExpandEnvStrings Lib "kernel32" _
Alias "ExpandEnvironmentStringsA" ( _
ByVal lpSrc As String, ByVal lpDst As String, _
ByVal nSize As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" _
Alias "GetVersionExA" ( _
lpVersionInformation As OSVERSIONINFO) As Long
Private Const REG_SZ = 1
Private Const REG_EXPAND_SZ = 2
Private Const REG_DWORD = 4
Private Const REG_DWORD_LITTLE_ENDIAN = REG_DWORD
Private Const REG_MULTI_SZ = 7

' The following values are only relevant under WinNT/2K,
' and are ignored by Win9x.
Private Const STANDARD_RIGHTS_READ = &H20000
Private Const STANDARD_RIGHTS_WRITE = &H20000
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const KEY_CREATE_LINK = &H20
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const SYNCHRONIZE = &H100000
' Access right to query and enumerate values.
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or _
KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY) And (Not SYNCHRONIZE))
'Access right to create values and keys.
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or _
KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And _
(Not SYNCHRONIZE))
'Access right to create/delete values and keys.
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or _
KEY_QUERY_VALUE Or KEY_SET_VALUE Or _
KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
Private lRequiredAccess
Private lPreviousAccess
'Return values for all registry functions.
Private Const ERROR_SUCCESS = 0
'Property variables.
Private lRoot 'default is HKEY_LOCAL_MACHINE
Private lOptions
Private strKeyName
Private strValueName
Private vData
'Variables set in GetKeyHandle.
Private hCurKey
Private nSubKeys
Private nValues
Private lMaxSubKeyLen
Private lMaxValueNameLen
Private lMaxValueLen
Private bIsWinNT


'Public Enum RegOptions ' variable: lOptions
' StoreNumbersAsStrings = 1
' ReturnMultiStringsAsArrays = 2
' ExpandEnvironmentStrings = 4
' ShowErrorMessages = 8
'End Enum
'Public Enum RegRoot ' variable: lRoot
' HKEY_CLASSES_ROOT = &H80000000
' HKEY_CURRENT_USER = &H80000001 ' default
' HKEY_LOCAL_MACHINE = &H80000002
'End Enum
'Message constants.
Private Const ERROR_NO_KEY As String = _
"No Key name specified!"
Private Const ERROR_NO_HANDLE = _
"Could not open Registry Key!"
Private Const ERR_MSG_NO_OVERWRITE As String = _
"Existing value has unsupported data type " & _
"and will not be overwritten"
Private Const RETURN_UNSUPPORTED As String = _
"(unsupported data format)"
Private ValueList As Object
Property Let Root(lProp As RegRoot)
' Don't accept an invalid Root value.
Select Case lProp
Case HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, _
HKEY_LOCAL_MACHINE
' All is well.
Case Else
lRoot = HKEY_CURRENT_USER
End Select
If lProp <> lRoot Then
lRoot = lProp
If Len(strKeyName) Then
GetKeyHandle lRoot, strKeyName
End If
End If
lRoot = lProp
End Property
Property Let Key(strProp)
' Don't accept an empty key name.
If Len(strProp) = 0 Then Exit Property
If Len(strKeyName) = 0 Then ' first time
strKeyName = strProp
ElseIf StrComp(strProp, strKeyName, _
vbTextCompare) <> 0 Then
strKeyName = strProp
GetKeyHandle lRoot, strKeyName
Else
End If
End Property
Property Let Options(lProp As RegOptions)
' Don't accept an invalid Options value.
Select Case lProp
Case 0 To 15: lOptions = lProp
Case Else:
End Select
End Property
Property Let Value(Optional ValueName As String, vValue)
If IsEmpty(vValue) Then
Exit Property
Else
vData = vValue
End If
If bIsWinNT Then lRequiredAccess = KEY_WRITE Or KEY_READ
If PropertiesOK Then
' First see if this is an existing value, and,
' if so, what data type we have here.
Dim strBuffer, lBuffer, lType
If RegQueryValueEx(hCurKey, ValueName, 0, lType, _
ByVal strBuffer, lBuffer) = ERROR_SUCCESS Then
' Make sure our new value is the same data type.
Select Case lType
Case REG_SZ, REG_EXPAND_SZ ' existing string
vData = CStr(vData)
Case REG_DWORD, REG_DWORD_LITTLE_ENDIAN
' existing long
vData = CLng(vData)
Case REG_MULTI_SZ ' existing array
vData = CVar(vData)
Case Else
ShowErrMsg ERR_MSG_NO_OVERWRITE
Exit Property
End Select
End If
If (lOptions And StoreNumbersAsStrings) Then
If IsNumeric(vData) Then vData = CStr(vData)
End If
' If nameless "(default)" value:
If Len(ValueName) = 0 Then vData = CStr(vData)
' Look at the data type of vData, and store it
' in the appropriate registry format.
If VarType(vData) And vbArray Then ' 8192
Dim sTemp As String
' REG_MULTI_SZ values must end with 2 null characters.
sTemp = Join(vData, vbNullChar) & String$(2, 0)
Call RegSetValueEx(hCurKey, ValueName, 0, _
REG_MULTI_SZ, ByVal sTemp, Len(sTemp))
Else
Select Case VarType(vData)
Case vbInteger, vbLong
Call RegSetValueEx(hCurKey, ValueName, 0, _
REG_DWORD, CLng(vData), 4)
Case vbString
If ContainsEnvString(CStr(vData)) Then
Call RegSetValueEx(hCurKey, ValueName, 0, _
REG_EXPAND_SZ, ByVal CStr(vData), _
Len(vData) + 1)
Else
Call RegSetValueEx(hCurKey, ValueName, 0, _
REG_SZ, ByVal CStr(vData), Len(vData) + 1)
End If
Case Else ' Store any other data type as string.
Call RegSetValueEx(hCurKey, ValueName, 0, _
REG_SZ, ByVal CStr(vData), Len(vData) + 1)
End Select
End If
' Update Value Count.
Call RegQueryInfoKey(hCurKey, vbNullString, 0, 0, 0, _
0, 0, nValues, 0, 0, 0, 0)
' Clear the values database.
ValueList.RemoveAll
End If
End Property
Property Get Value(Optional ValueName As String) As Variant
With ValueList
If .Count = 0 Then FillDataList
If .Exists(ValueName) Then Value = .Item(ValueName)
End With
End Property
Property Get AllValues() As Variant
If bIsWinNT Then lRequiredAccess = KEY_READ
If PropertiesOK Then
If nValues = 0 Then Exit Property
With ValueList
If .Count = 0 Then FillDataList
If .Count Then
Dim i, vKeys, vItems
vKeys = .Keys
vItems = .items
ReDim vTemp(.Count - 1, 1)
For i = 0 To .Count - 1
vTemp(i, 0) = vKeys(i)
vTemp(i, 1) = vItems(i)
Next
AllValues = vTemp
End If
End With
End If
End Property
Property Get AllKeys() As Variant
If bIsWinNT Then lRequiredAccess = KEY_READ
If PropertiesOK Then
If nSubKeys = 0 Then Exit Property
Dim i: ReDim vTemp(nSubKeys - 1)
For i = 0 To nSubKeys - 1
strKeyName = String$(lMaxSubKeyLen + 1, 0)
If RegEnumKeyEx(hCurKey, i, strKeyName, _
lMaxSubKeyLen + 1, 0, vbNullString, 0, 0) = _
ERROR_SUCCESS Then
vTemp(i) = TrimNull(strKeyName)
End If
Next
AllKeys = vTemp
End If
End Property
Function DeleteValue(Optional ValueName As String) _
As Boolean
If bIsWinNT Then lRequiredAccess = KEY_ALL_ACCESS
If PropertiesOK Then
DeleteValue = (RegDeleteValue(hCurKey, ValueName) = _
ERROR_SUCCESS)
If DeleteValue Then
Call RegQueryInfoKey(hCurKey, vbNullString, 0, 0, _
0, 0, 0, nValues, 0, 0, 0, 0)
ValueList.RemoveAll
End If
End If
End Function
Function DeleteKey() As Boolean
If Len(strKeyName) = 0 Then
ShowErrMsg ERROR_NO_KEY
Exit Function
End If
Dim n, strLastKey
n = InStrRev(strKeyName, "\")
If n > 0 And n < Len(strKeyName) Then
strLastKey = Mid$(strKeyName, n + 1)
strKeyName = Left$(strKeyName, n - 1)
If bIsWinNT Then lRequiredAccess = KEY_ALL_ACCESS
Call GetKeyHandle(lRoot, strKeyName)
If hCurKey = 0 Then Exit Function
If ShlwapiInstalled Then
' This should always work.
DeleteKey = (SHDeleteKey(hCurKey, strLastKey) = _
ERROR_SUCCESS)
Else
' This will only work under Win95/98.
DeleteKey = (RegDeleteKey(hCurKey, strLastKey) = _
ERROR_SUCCESS)
End If
If DeleteKey Then
Call RegQueryInfoKey(hCurKey, vbNullString, 0, 0, _
nSubKeys, 0, 0, 0, 0, 0, 0, 0)
ValueList.RemoveAll
End If
End If
End Function
Property Get ValueCount() As Long
If PropertiesOK Then ValueCount = nValues
End Property
Property Get KeyCount() As Long
If PropertiesOK Then KeyCount = nSubKeys
End Property

Private Function PropertiesOK() As Boolean
If Len(strKeyName) = 0 Then
ShowErrMsg ERROR_NO_KEY
Exit Function
End If
If lPreviousAccess Then
If lRequiredAccess <> lPreviousAccess Then _
CloseCurrentKey
End If
If hCurKey = 0 Then Call GetKeyHandle(lRoot, strKeyName)
If hCurKey = 0 Then
ShowErrMsg ERROR_NO_HANDLE
Exit Function
End If
PropertiesOK = True
End Function
Private Sub Class_Initialize()
lRoot = HKEY_CURRENT_USER
bIsWinNT = IsWinNT
If bIsWinNT Then lRequiredAccess = KEY_READ
On Error Resume Next
Set ValueList = CreateObject("Scripting.Dictionary")
If IsObject(ValueList) Then
ValueList.CompareMode = vbTextCompare
Else
End
End If
End Sub
Private Sub Class_Terminate()
CloseCurrentKey
Set ValueList = Nothing
End Sub
Private Sub CloseCurrentKey()
If hCurKey Then
Call RegCloseKey(hCurKey)
hCurKey = 0
End If
End Sub
Private Sub GetKeyHandle(lKey, strKey)
CloseCurrentKey
If lKey = 0 Then lKey = HKEY_CURRENT_USER
Dim SA As SECURITY_ATTRIBUTES
Call RegCreateKeyEx(lKey, strKey, 0, vbNull, 0, _
lRequiredAccess, SA, hCurKey, 0)
If hCurKey Then
Call RegQueryInfoKey(hCurKey, vbNullString, 0, 0, _
nSubKeys, lMaxSubKeyLen, 0, nValues, _
lMaxValueNameLen, lMaxValueLen, 0, 0)
ValueList.RemoveAll
lPreviousAccess = lRequiredAccess
End If
End Sub
Private Function TrimNull(ByVal strIn) As String
TrimNull = Left$(strIn, InStr(strIn, vbNullChar) - 1)
End Function
Private Function TrimDoubleNull(ByVal strIn) As String
If Len(strIn) Then _
TrimDoubleNull = _
Left$(strIn, InStr(strIn, String$(2, 0)) - 1)
End Function
Private Function ExpandString(strIn) As String
Dim nChars, strBuff, nBuffSize
nBuffSize = 1024
strBuff = String$(nBuffSize, 0)
nChars = ExpandEnvStrings(strIn, strBuff, nBuffSize)
If nChars Then ExpandString = Left$(strBuff, nChars - 1)
End Function
Private Function ShlwapiInstalled() As Boolean
Dim hLib As Long
hLib = LoadLibrary("Shlwapi")
If hLib Then
ShlwapiInstalled = True
FreeLibrary hLib
End If
End Function
Private Function ContainsEnvString(ByVal strTest) _
As Boolean
Const PCT As String = "%"
' See if there is a percent sign.
Dim n As Long:
n = InStr(strTest, PCT)
If n = 0 Then Exit Function
' See if there is a second percent sign.
If n = InStrRev(strTest, PCT) Then Exit Function
' Now we have a potential environment string.
Dim Env As String, EnvSplit() As String
Dim i As Long
For i = 1 To 100
Env = Environ(i)
If Len(Env) Then
EnvSplit = Split(Env, "=")
If InStr(1, strTest, PCT & EnvSplit(0) & PCT, _
vbTextCompare) Then
ContainsEnvString = True
Exit For
End If
Else
Exit For
End If
Next
End Function
Private Sub ShowErrMsg(strMsg)
If (lOptions And ShowErrorMessages) Then
MsgBox strMsg, vbExclamation, "Registry Error"
Else
Debug.Print strMsg
End If
End Sub
Private Function IsWinNT()
' Returns True if the OS is Windows NT/2000.
Const VER_PLATFORM_WIN32_NT As Long = 2
Dim osvi As OSVERSIONINFO
osvi.dwOSVersionInfoSize = Len(osvi)
GetVersionEx osvi
IsWinNT = (osvi.dwPlatformId = VER_PLATFORM_WIN32_NT)
End Function
Private Sub FillDataList(Optional Key As String)
If Len(Key) Then strKeyName = Key
If Len(strKeyName) = 0 Then _
ShowErrMsg ERROR_NO_KEY: Exit Sub
If bIsWinNT Then lRequiredAccess = KEY_READ
If PropertiesOK Then
If nValues = 0 Then Exit Sub
ValueList.RemoveAll
Dim i, lValuename, lType, lBuffer, strValue, strBuffer
For i = 0 To nValues - 1
lValuename = lMaxValueNameLen + 1
strValue = String$(lValuename, 0)
lBuffer = lMaxValueLen + 1
strBuffer = String$(lBuffer, 0)
If RegEnumValue(hCurKey, i, strValue, lValuename, _
0, lType, ByVal strBuffer, lBuffer) = _
ERROR_SUCCESS Then
strValue = TrimNull(strValue)
Select Case lType
Case REG_SZ
ValueList(strValue) = TrimNull(strBuffer)
Case REG_EXPAND_SZ
If (lOptions And ExpandEnvironmentStrings) Then
ValueList(strValue) = _
ExpandString(TrimNull(strBuffer))
Else
ValueList(strValue) = TrimNull(strBuffer)
End If
Case REG_MULTI_SZ
If (lOptions And _
ReturnMultiStringsAsArrays) Then
ValueList(strValue) = Split( _
TrimDoubleNull(strBuffer), vbNullChar)
Else
ValueList(strValue) = _
TrimDoubleNull(strBuffer)
End If
Case REG_DWORD, REG_DWORD_LITTLE_ENDIAN
Dim nBuffer
If RegEnumValue(hCurKey, i, strValue, _
Len(strValue) + 1, 0, REG_DWORD, nBuffer, _
4) = ERROR_SUCCESS Then
ValueList(strValue) = nBuffer
End If
Case Else
ValueList(strValue) = RETURN_UNSUPPORTED
End Select
End If
Next
End If

End Sub
 
P

Peter T

Er - anything else you need whilst I'm rewriting an unfriendly looking 500
lines! Well that was my first reaction but curiosity made me take a look.

In terms of the Enum and Property stuff there's very little to do, and that
along the lines I suggested previously. The "Public" constants need to go in
a normal module, not a Class.

However the code includes string functions Join, InstrRev and Split which
were new to VBA6 and won't work in XL97. I've included some alternatives for
XL97, some my own and an adapted version of a Split as suggestion by MS. But
I cannot figure one line

ValueList(strValue) = Split(arg's)

ValueList is a reference to ScriptingDictionary, don't know how this accepts
an array, or what sort of array. Does this work OK in the original? You
might post another question about this, extract the minimum necessary from
the code, the original reference and usage. Include the #If VBA6 then Split
lines and the Split97sArr routine.

In the class module:
Comment the Enum's
Replace original lines ending indicated ending in '##

#If VBA6 Then
Property Let Root(lProp As RegRoot) '##
#Else
Property Let Root(lProp As Long)
#End If

#If VBA6 Then
Property Let Options(lProp As RegOptions)
#Else
Property Let Options(lProp As Long)
#End If

#If VBA6 Then
sTemp = Join(vData, vbNullChar) & String$(2, 0) '##
#Else
sTemp = Join97(vData, vbNullChar) & String$(2, 0)
#End If

#If VBA6 Then
n = InStrRev(strKeyName, "\") '##
#Else
n = InStrRev97(strKeyName, "\")
#End If

#If VBA6 Then
If n = InStrRev(strTest, PCT) Then Exit Function '##
#Else
If n = InStrRev97(strTest, PCT) Then Exit Function
#End If

#If VBA6 Then
EnvSplit = Split(Env, "=") '##
#Else
Split97StrArr EnvSplit, Env, "="
#End If

''Private ValueList As Object
''Set ValueList = CreateObject("Scripting.Dictionary")
''code

#If VBA6 Then
ValueList(strValue) = Split( _
TrimDoubleNull(strBuffer), vbNullChar) '##
#Else
Dim sArr() As String 'new array to pass to Split97sArr
Split97StrArr sArr(), TrimDoubleNull(strBuffer), vbNullChar

'ValueList(strValue) = sArr() 'how ????????

#End If


''In a normal module

#If VBA6 Then
Public Enum RegOptions ' variable: lOptions
StoreNumbersAsStrings = 1
ReturnMultiStringsAsArrays = 2
ExpandEnvironmentStrings = 4
ShowErrorMessages = 8
End Enum

Public Enum RegRoot ' variable: lRoot
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_USER = &H80000001 ' default
HKEY_LOCAL_MACHINE = &H80000002
End Enum
#Else
Public Const StoreNumbersAsStrings As Long = 1
Public Const ReturnMultiStringsAsArrays As Long = 2
Public Const ExpandEnvironmentStrings As Long = 4
Public Const ShowErrorMessages As Long = 8

Public Const HKEY_CLASSES_ROOT As Long = &H80000000
Public Const HKEY_CURRENT_USER As Long = &H80000001
Public Const HKEY_LOCAL_MACHINE As Long = &H80000002
#End If


Function Join97(vArr, Optional sDelim As String) As String
Dim s As String, i As Long
On Error GoTo errH
If VarType(vArr) >= vbArray Then
s = vArr(LBound(vArr))
If UBound(vArr) Then
For i = 1 To UBound(vArr)
If Len(sDelim) Then s = s & sDelim
s = s & vArr(i)
Next
End If
Join97 = s
Else
Join97 = CStr(vArr)
End If
errH:
If Err.Number <> 0 Then
'stop '????
End If
End Function

Function InStrRev97(s1 As String, s2 As String, _
Optional nCompare As Long = vbBinaryCompare) As Long
Dim i As Long, nPos As Long

For i = Len(s1) To 1 Step -1
nPos = InStr(i, s1, s2, nCompare)
If nPos Then
InStrRev97 = nPos
Exit Function
End If
Next i

End Function

Sub Split97StrArr(sOut() As String, ByVal sIn As String, _
Optional sDelim As String, Optional nLimit As Long = -1, _
Optional nCompare As Long = vbBinaryCompare)
'http://support.microsoft.com/default.aspx?scid=kb;en-us;188007
'adapted from a function that returns a variant (array) to a Sub
'that accepts a string array
'also, MS's original VB5 version does not compile in xl97

Dim sRead As String, nC As Integer
If sDelim = "" Then
ReDim sOut(0)
sOut(0) = sIn
Else
sRead = ReadUntil(sIn, sDelim, nCompare)
Do
ReDim Preserve sOut(nC)
sOut(nC) = sRead
nC = nC + 1
If nLimit <> -1 And nC >= nLimit Then Exit Do
sRead = ReadUntil(sIn, sDelim)
Loop While sRead <> ""
ReDim Preserve sOut(nC)
sOut(nC) = sIn
End If

End Sub

Function ReadUntil(ByRef sIn As String, _
sDelim As String, _
Optional nCompare As Long = vbBinaryCompare) As String
'MS's original "nPos as String" which seems strange
Dim nPos As Long
nPos = InStr(1, sIn, sDelim, nCompare)
If nPos > 0 Then
ReadUntil = Left(sIn, nPos - 1)
sIn = Mid(sIn, nPos + Len(sDelim))
End If
End Function
'' end normal module

With these changes the code should compile in XL97. However the
"ValueList(strValue) = Split..." needs sorting out. Also, I haven't tried
any of this so can't be sure it'll work - a lot of registry stuff but what's
it all about?

Regards,
Peter T
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top