My function is used to replace an apostrophe, i.e. ' in any of an object's properties. The function uses the TypeLib library to achieve this, by looping through all the object's members, i.e.
Public Function EscapeWildCards(ByRef obj As Object, _
Optional ByVal bEscape As Boolean = True) As Boolean
On Error GoTo EscapeWildCards_Err
Dim tTLI As TLIApplication
Dim tMem As MemberInfo
Dim tInvoke As InvokeKinds
Dim tName As String 'used as lower case....
Dim tString As String
1 Set tTLI = New TLIApplication
'... if True, we are setting else we are getting
2 tInvoke = IIf(bEscape, VbGet, VbLet)
3 If obj Is Nothing Then Exit Function
4 For Each tMem In TLI.InterfaceInfoFromObject(obj).Members
5 'tName = LCase$(tMem.Name)
6 If tMem.InvokeKind = tInvoke Then 'And tMem.Parameters.Count = 0
'could be object/something else that can't handle
On Error Resume Next
' get the oobject property value
7 tString = CallByName(obj, tMem.Name, VbGet)
8 If tInvoke = VbGet Then
9 If IndexOf(tString, "'") > 0 Then
10 tString = Replace$(tString, "'", "`")
11 CallByName obj, tMem.Name, VbLet, tString
End If
Else
'... set data replacing aposthrophe
12 If IndexOf(tString, "'") > 0 Then
13 tString = Replace$(tString, "`", "'")
14 CallByName obj, tMem.Name, VbLet, tString
End If
End If
'Debug.Print tName, " = ", tString
On Error GoTo EscapeWildCards_Err
End If
Next
Exit Function
EscapeWildCards_Err:
ErrReport Err.Description, "modCommon.EscapeWildCards", Erl
Resume Next
End Function
When I test the code in the IDE, I don't get any errors. But when I compile and test as an EXE, I get the following errors:
Object doesn't support this action. LineNo 4
Object variable or With block variable not set. LineNo 5
Object variable or With block variable not set. LineNo 6
For loop not initialized. LineNo 14
Why don't I get any errors when the app is running in the IDE, but I do when it is compiled? Can someone please point me to what am doing wrong?
First of all, you aren't helping yourself by your error handling. Doing a Resume Next without doing some form of checking the actual error is a one-stop way to confusion and bug city. Your title is misleading - it's not the "For Each" statement which is causing the problem. It is:
TLI.InterfaceInfoFromObject(obj).Members
To be precise, it is Members property which is failing. (Oh, and you obviously haven't done a straight copy and paste, because I assume that "TLI" should be "tTLI".). The reason for this is probably that the object you are trying to use does not have a public interface registered in a Type Library.
My guess is that you are trying to do this with an internal VB class, such as a Form or a private Class. At run-time, the VB IDE creates run-time type library information on the fly (how do you think you can use uncompiled DLL projects at run-time?). Whilst in the IDE, VB creates type lib info for your class, on the fly. But when compiled, this information does not exist, thus the error.
If this is the case, you will have to create interfaces for your private classes manually by creating a DLL which exposes the interface you want to use. This interface would then be implemented into the private class. Sadly, you can't do this with Form instances.