zoukankan      html  css  js  c++  java
  • CallByName的深入研究

    由于工作的需要,我希望将长长的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 = 0As 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 StringAs 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 StringAs 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的一些缺陷
  • 相关阅读:
    Apache日志分析
    iptables日志探秘
    php与其他一些相关工具的安装步骤分享
    ERROR 1 (HY000): Can't create/write to file '/tmp/#sql_830_0.MYI' (Errcode: 13)
    一些可能需要的正则
    restful api的简单理解
    认识MySQL Replication
    如何处理缓存失效、缓存穿透、缓存并发等问题
    经典算法mark
    php常用的一些代码
  • 原文地址:https://www.cnblogs.com/Duiker/p/227966.html
Copyright © 2011-2022 走看看