Distinguish LO Basic Built in Objects for User Objects

I am trying to write a function (TypeNameEx) which will return a string which, using a call to VarType(), effectively identifies the type of a a (variant) variable, eg VarType 2 returns “integer” and VarType 3 returns “Long”.
All is fine until I get to VarType 9 which is an object. I COULD just return “Object” and have done with it but would rather something more specific. To this end, I have been able to work out how to establish if it is a UNO object and return “Object-UNO” but, beyond that, have been unable to make a distinction between one of LO’s built in objects or a user object (as defined in a Class Module). For my own Class Modules, I can give all of my classes a .MyClass property but I cannot do the same for class modules written/supplied by AN Other, is there a way to separate built-in objects from user objects?

I have included my code so far below, it is IsIntrinsicObject which I am stuck on

Function IsIntrinsicObject(ByRef rvarObject As Variant) As Boolean

  'Return the result of a test for a property method or name which a built in'
  ' object will have but a user object will not have.'
  'As I understand that there no particular property method or name which is'
  ' owned by ALL built-in non-UNO objects, this probably boils down ta a '
  ' large Select Case statement which tests a number of things'

End Function 'IsIntrinsicObject'


Function IsUNOObject(ByRef rvarObject As Variant) As Boolean

  Dim varDummy As Variant

  On Error Goto ErrorHandler
    'If our object DOES have .Dbg_Properties and .Dbg_Methods then'
    ' it may still be a none-UNO object, if it doesn´t then it '
    ' will fire error 423 if IS a UNO object and error 91 if it is' 
    ' any other type of object'
    'So here´s the belt    '
    varDummy= rvarObject.Dbg_Properties
    'And here´s the braces - less chance of someone else' 
    ' implementing BOTH properties in their own class module than'
    ' just the one!'
    varDummy = rvarObject.Dbg_Methods
    'Add in some superglue!'
    '-If our object is NOT a UNO object this test will fail with'
    ' error 438'
    varDummy = rvarObject.queryInterface(0)
    IsUnoObject = True
  On Error Goto 0

Exit Function 'IsUNOObject'

ErrorHandler: 'Function IsUNOObject'
  
  Select Case Err
    Case 423
      Resume Next
    Case 438
      Resume Next
    Case 91
      IsUNOObject = False
    Case Else
      IsUNOObject = False
  End Select 'Err'

  On Error Goto 0  

End Function 'IsUNOObject'


Function ObjectType(ByRef rvarObject As Variant) As String

  Dim strRet As String
  
  If IsUNOObject(rvarObject) _
  Then
    strRet = "Object-UNO"
  Else 'IsUNOObject(rvobject)'
    On Error Goto ErrorHandler
      strRet = "Object-" & rvarObject.MyClass
    On Error Goto 0
  End If 'IsUNOObject(rvarObject)'
  
  ObjectType = strRet

Exit Function 'ObjectType'

ErrorHandler: 'Function ObjectType'

  On Error Goto 0
  If IsIntrinsicObject(rvarObject) _
  Then
    ObjectType = "Object-Intrinsic"
  Else 'IsIntrinsicObject(rvarObject)'
    ObjectType = "Object-UnknownUserClass"
  End If 'IsIntrinsicObject(rvarObject)'

End Function 'ObjectType'


Function TypeNameEx(ByRef rvarVariable As Variant) As String
  
  Dim lngType As Long
  Dim strRet As String
  
  lngType = VarType(rvarVariable)
  Select Case lngType
    Case 0
      strRet = "Empty"
    Case 1
      strRet = "Null"
    Case 2
      strRet = "Integer"
    Case 3
      strRet = "Long"
    Case 4
      strRet = "Single"
    Case 5
      strRet = "Double"
    Case 6
      strRet = "Currency"
    Case 7
      strRet = "Date"
    Case 8
      strRet = "String"
    Case 9
      strRet = ObjectType(rvarVariable)
    Case Else
      strRet = "Unknown"
  End Select 'lngType'
  
  TypeNameEx = strRet
  
End Function 'TypeNameEx'

There in do distinction between “built-in” UNO objects, and “user” UNO objects. Some “built-ins” are implemented in Python; some are (still) implemented as extensions. An UNO object is just anything that implements a specific UNO interface. Don’t expect that there is some difference.

Thanks Mike - I think I’m going to have to settle for “Object-ClassUnknown” (maybe just “Object”) for any that are built in to LO or haven’t got my .MyClass property.

If I had a comprehensive list of the none-UNO intrinsics and some way to tell whether an object was this type or that (eg a Collection or ErrorObject) then I could just build a monstrously large Select Case statement testing for each in turn.

You can try

Sub Test()
  Dim v
  v = New MyClassModule
  Msgbox HasUnoInterfaces(v, "com.sun.star.uno.XInterface") Or IsUnoStruct(v)
End Sub

For objects that are instances of “ordinary” Basic class modules, False should be returned.

Hi Soko - Thank you for getting back to me. The question is, does the HasUnoInterfaces Or IsUnoStruct get us any further along when trying to distinguish a class module object from a built-in LO Basic class?

I’m being obtuse. Would you, please, give me an example of such a thing?

You may not be being obtuse!

It is my understanding that things like Collections and Arrays (for the sake of just 2 examples) are objects within LO Basic but are not UNO objects, it is that group of objects/classes which I wish to distinguish from user (class module) objects

Start testing with this macro:

Sub ShowObjectType(arg)
  Dim t as String, s as String
  t = TypeName(arg)
  
  If Not IsObject(arg) Then
    s = "is not object"
    
  ElseIf IsUnoStruct(arg) then
    s = "is UNO struct"
 
  ElseIf HasUnoInterfaces(arg, "com.sun.star.uno.XInterface") Then
    s = "is UNO object"
    
  Else
    s = "is other object"
  End If
  
  Msgbox "Parameter (" & t & ") " & s      
End Sub

Sub TestShowObjectType()
  Dim v
  v = new com.sun.star.beans.PropertyValue
  ShowObjectType(v)
  ShowObjectType(ThisComponent)
  v = new Collection
  ShowObjectType(v)
End Sub 

Mmmm - This still doesn’t help me in distinguishing between one of LO Basic’s built in objects and one declared as a user class.
My own code gets us as far as yours does (although your UNO object tell-tales may well be better than the ones which I have employed)

Only one (?) non-UNO object - Collection.

So - ALL LO’s built-in objects/classes are UNO except Collection and (by extension) my IsUNOObject() function will return TRUE for all of them? Have I got that right?

@SVCooper I very much suspect that you and @sokol92 talk past one another, just because you failed to describe what you need, clearly enough. It would be great if you provided a sample pseudocode, like

  type MyType
     ...
  end type

  o1 = new MyType
  o2 = ThisComponent.Sheets(0)
  o3 = ...

  myFunc(o1) ' I want it to produce foo
  myFunc(o2) ' I want it to produce bar
  myFunc(o3) ' I want it to produce baz

I didn’t test your function, but you tested mine, so if you don’t mind, let’s discuss my function. :slight_smile:
I also remembered about the Err object, which can occur when using the Option VBASupport 1 option.
Other objects that are returned by built-in Basic functions are UNO objects (check, maybe something else is not mentioned).

OK, try this

objA = New SomeClassModule (ie one defined in a Class Module)
objB = SomeUNOObjectOrOther (ie any one of ALL the UNO objects)
objC = SomeObjectBuiltIntoLOThatIsntAUNOObject

MyFunc(objA) = “UserClass”
MyFunc(objB) = “UNOClass”
MyFunc(objC) = “IntrinsicLOClass”

My code is likely to already produce the required output for objB (but it may well be refined to make this more likely, I simply don’t know)

I can specify MY OWN class modules to include a .MyClass property so that any object declared as such a (let’s say, “well behaved”), for objA, but I cannot legislate for code written/supplied by AN Other.

I’m struggling to come up with a test that will produce the required output for objC if and only if the object is one of those built into LO which ISN’T a UNO object. By object, by the way, I mean a variable (say V) where VarType(V) = 9.

It may be that:
A - There is no such thing as a built in LO object which ISNT a UNO object, if that is the case then can someone tell me so?
B - There is actually no way in which we can distinguish between a general (ie not my) user object and a built in none UNO LO object, once again, if that is the case then someone please tell me?

I doubt if I can be more clear or concise than that

Your snippet

Else
s = “is other object”
End If

simply tells us that the object is not a UNO object, I’m looking to find out what it is if it ISN’T a UNO object

In LO Basic we have found 2 (two) such objects so far.
If you load application libraries (ScriptForge, …) and those libraries can return objects, you should study how the authors “mark” their objects.