您的位置:首页 > 其它

CallByName的深入研究

2005-09-01 15:47 351 查看
由于工作的需要,我希望将长长的Case取消掉,但是CallbyName在层次和集合对象上的处理十分头疼,为了解决这个问题只能想别的办法了,唯一的办法是重新包装Callbyname,代码如下:

'ClassName :ParaseTier

'缺陷没有考虑错误处理

Public Event onError()

'根据字符串得到具体的属性值
Public Function GetAttributeValue(Object As Object, ByVal AttributeName As String)
GetAttributeValue = VBA.Interaction.CallByName(GetObject(Object, AttributeName), Trim(AttributeName), VbGet)
End Function

'根据字符串得到具体的对象
'AttributeIsObject = 0,表示当AttributeName表示的是属性名称
'AttributeIsObject = 1,表示当AttributeName表示的是对象名称
Public Function GetObject(ByVal Object As Object, ByRef AtrributeName As String, Optional AttributeIsObject = 0) As Object
Dim parseProcName() As String
parseProcName = Split(AtrributeName, ".")
Dim i As Integer
Set GetObject = Object
For i = 0 To UBound(parseProcName) - 1
If IsCollectionAttribute(parseProcName(i)) Then
Set GetObject = GetItemObject(GetObject, parseProcName(i))
Else
If IsObject(VBA.Interaction.CallByName(GetObject, parseProcName(i), VbGet)) Then
Set GetObject = VBA.Interaction.CallByName(GetObject, parseProcName(i), VbGet)
End If
End If
Next

'处理需要单独返回对象的属性
If AttributeIsObject = 1 Then
If IsObject(VBA.Interaction.CallByName(GetObject, parseProcName(0), VbGet)) Then
Set GetObject = VBA.Interaction.CallByName(GetObject, parseProcName(0), VbGet)
End If
End If

AtrributeName = parseProcName(UBound(parseProcName))
Erase parseProcName
End Function

'解析集合类对象
'用来解释如“Sections(1)”格式的集合对象
'要求集合对象必须包含Item方法
'字符串不允许包含类似Item(1)的方法
Public Function GetItemObject(ByVal Object As Object, ByVal AttributeName As String) As Object
Dim parseProcName() As String
parseProcName = Split(AttributeName, "(")
AttributeName = Trim(parseProcName(0))
Dim Index As Integer
Index = Trim(Replace(parseProcName(1), ")", ""))
Set GetItemObject = GetObject(Object, AttributeName, 1)
Set GetItemObject = GetItemObject.Item(Index)
Erase parseProcName
End Function

'判断当前的对象是否为集合对象
Private Function IsCollectionAttribute(ByVal AttributeName As String) As Boolean
IsCollectionAttribute = (InStr(1, AttributeName, "(") > 0)
End Function

相关测试类:

'ClassName :Student
Public Name As String
Public Sex As String

测试模块:

Public Sub Test1()
Dim pt As New ParaseTier
Dim o As Object
Set o = Word.Application.ActiveDocument

'Demo 使用字符串获得属性
Debug.Print pt.GetAttributeValue(o, "Paragraphs(1).Range.Font.Name")

'Demo 使用字符串获得集合对象属性
Debug.Print pt.GetItemObject(o, "Paragraphs(1)").Range.Font.Name

'Demo 使用字符串获得对象
Debug.Print pt.GetObject(o, "Paragraphs", 1).Count

Set o = Nothing
Set pt = Nothing
End Sub

Public Sub Test2()
Dim pt As New ParaseTier
Dim o As Object
Set o = Word.Application.ActiveDocument
'Demo 使用字符串获得属性
Debug.Print pt.GetAttributeValue(o, "Paragraphs(1).Range.Font.Name")
'Demo 使用字符串获得集合对象属性
Debug.Print pt.GetItemObject(o, "Sections(1)").Index
'Demo 使用字符串获得对象
Debug.Print pt.GetObject(o, "Paragraphs", 1).Count
Set o = Nothing
Set pt = Nothing
End Sub

Public Sub test3()
Dim s As New Student
s.Name = "Duiker"
s.Sex = "男"
Dim ss As String
ss = InputBox("请输入需要获得的属性名称", "Name")

Select Case ss
Case "Name"
Debug.Print s.Name
Case "Sex"
Debug.Print s.Sex
End Select

Set s = Nothing
End Sub

Public Sub test4()
Dim s As New Student
s.Name = "Duiker"
s.Sex = "男"
Dim ss As String
ss = InputBox("请输入需要获得的属性名称", "Name")
Dim pt As New ParaseTier
Debug.Print pt.GetAttributeValue(s, ss)
Set s = Nothing
End Sub

这只是一个简易的框架,自己用来玩玩还行,主要的好处就是通过字符串可以快速的生成对象,或者获取属性的值,而且支持多层次的属性字符串,也支持类似于Item格式的对象集合。

参考文章:

1:vb6框架设计-对象导航
2:CallByName的一些缺陷
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: