翰文个人计算机学习网
  • 翰文快讯
  • 翰文PC快讯
  • 综合软件区
  • 操作系统
  • 注册表解析
  • Windows系列
  • Unix/Linux
  • 其他系统
  • 应用软件
  • 微软MS Office
  • WPS Office
  • 多媒体软件
  • 图像处理
  • Photoshop
  • Painter
  • Illustrator
  • CorelDRAW
  • 三维空间
  • AutoCAD
  • 3DMAX
  • 3DMAYA
  • 硬件资源
  • 攒机指南
  • 硬件超频
  • 维修指南
  • 网络资源
  • 在线通讯
  • 网上冲浪
  • 浏览器中心
  • 网络故障解析
  • 病毒资料
  • 病毒通报
  • 病毒防治
  • 病毒常识
  • 黑客技巧
  • SQL/MySQL
  • Oracle
  • Delphi
  • 编程资源
  •  C/C#/C++/VC++/VC.NET
  •  Basic/VB/VB.NET/VBScript
  •  FoxBasic/FoxPro/VF/VF.NET
  •  Java/JavaScript
  • PowerBuilder
  • 热门词:
  • 翰文计算机学习网首页
  • >
  • Basic/VB/VB.NET/VBScript
  • >
  • VBA集合对象的安全包装
  • VBA集合对象的安全包装

  • 资源来源:
  • HW-PCS.ORG
  • 资源作者:
  • 翰文计算机学习网
  • 人气指数:
  • [4434]
  •   你迟早都要管理一组由VBA类模块创建的自定义对象,VBACollection对象是实现这一目的的理想工具。我们在该杂志的Premiere期刊中曾经介绍过Collections,并且阐述了如何使用Collection对象来存储其他对象。虽然该项技术十分有用,但它确实还存在一些局限。在本文中,我们讨论了这些局限,并向你展示如何通过使用(你猜是什么)类模块来克服这些局限。

      Collections中遇到的麻烦

      Collections对象中到底有什么问题呢?它似乎存储对象存储得非常好。事实上,它工作起来的确是太好了。Collections对象得最大是它可以存储到任何数据类型得引用,例如Integer,String,Long,Variant,等。

      当然,如果你能保证每个对象都具有相同得类型,并且具有相同得属性何方法的话,那么在Collection中处理对象就变得异常简单。例如,作为本月范例ExcelVBA项目的组成部分,我们创建一个自定义的File类来代表一个磁盘文件。这个File类有几个属性,其中包括Path,Size,和ShortName。如果你创建了一个File对象的Collection,那么你将希望这个Collection中的每个对象都具有这些属性。你可以毫无异议地使用与下面类似的代码:

    ’PrintthesizeofthefirstfileintheCollection.
    Debug.PrintcolFiles.Item(1).Size

      但是,如果colFilesCollection中的第一个对象不是File,将会出现什么情况呢?如果它是一个Form或Control对象,又会怎样呢?如果它根本就不是一个对象呢?当然,当它试图执行该代码的时候,VBA将生成运行时间错误。

      输入Collection类

      Collection类可以充当Collection对象的过滤器,限制你可以在里面存储的对象类型(如图2所示)。通过与你的应用程序中的Collection类(二不是Collection对象本身)的互相作用,你可以防止不想要的对象的进入。创建和使用Collection类允许你扩展Collection对象的属性和方法(后面我们将举例说明)。

      为了说明Collection类以及如何创建一个Collection类,我们将使用带有通过扫描磁盘目录创建的文件集合的Excel97项目。图3显示了一个表单,它用你选择了路径之后存储在自定义Collection类中的文件信息使得列表框通俗化。

      这个表单使用一个叫做Files的Collection类来通俗化列表框。在创建Collection的时候,以向你的VBA项目添加一个新的类模块作为开始,然后在这个新模块的声明段声明一个PrivateCollection对象。下面是来自Files类模块的声明:

    ’Collectionoffiles.
    PrivatepcolFilesAsNewCollection

      为了将Collection对象与外界"隔绝",并阻止程序的其他部分用无用的东西填充它,必须将Collection对象声明为Private。

      复制所需要的方法

      当然,一旦你已经将Collection对象声明为Private,那么对于任何过程都没有办法向其中添加项目或从中删除项目了。因而,下一步就是复制Collection对象的标准方法了。尽管听起来象是做了大量额外的工作,实际上仍然在做我们前面所提及的""工作。

      请记住,内建的Collection对象具有Add方法,该方法接受对象引用和独特的、包括文字与数字的标识符。如果你的应用程序正在直接使用Collection对象,那么它将极有可能创建对象的一个新的实例,并将其添加到Collection本身。

    ’Createanewinstanceofanobject.
    DimobjFileAsNewFile
    objFile.Path="C:AUTOEXEC.BAT"

    ’AddtoaCollectionobject.
    colFiles.AddobjFile,objFile.ShortName

      应用Collection类,应用程序调用该类的Add方法,传递任何必需的信息。请将先前的代码与Files类的Add方法做一比较:

    WithaCollectionclass,theapplicationcallstheAddmethodoftheclass,
    passinganyrequiredinformation.ContrastthepreviouscodewiththeAddmethodoftheFilesclass:

    PublicFunctionAdd(PathAsString)AsFile

    DimobjFileAsFile

    ’CreatethenewFileobject.
    SetobjFile=NewFile
    objFile.Path=Path

    ’AddittothePrivatecollection.
    pcolFiles.AddobjFile,objFile.ShortName

    ’Returnapointertothenewobject.
    SetAdd=objFile

    EndFunction

      在本例中,到Collection的对象创建和添加发生在Add方法内部;而类则保留了完整的控制。任何必需的信息(例如文件的路径)是作为参数向方法提供的。由应用程序调用将文件添加到Collection的代码然后可以简化为:

    ’Addafiletothecollection.
    colFiles.Add"C:AUTOEXEC.BAT"
    InadditiontotheAddmethod,
    theCollectionclassshouldalsoimplementtheItemandRemovemethods,aswellasaCountproperty:

    PublicFunctionItem(KeyAsVariant)AsFile
    ’Returnaniteminthecollection.
    SetItem=pcolFiles.Item(Key)
    EndFunction

    PublicSubRemove(KeyAsVariant)
    ’Removeanitemfromthecollection.
    pcolFiles.RemoveKey
    EndSub

    PropertyGetCount()AsLong
    ’Returnthenumberofitems.
    Count=pcolFiles.Count
    EndProperty

      请注意,在这三种方法中,我们省略了错误处理--有些事情你是从来都不应该做的!至少应该包括一个器,通过使用Err对象的Raise方法来将错误传递、给调用过程。

      表单通过显示文件信息来说明Collection类

    ’Privatevariabletostorepath.
    PrivatepstrPathAsString

    PropertyGetPath()AsString
    ’Returnstoredpathvalue.
    Path=pstrPath
    EndProperty

    PropertyLetPath(strPathAsString)

    DimstrFileAsString

    ’Clearthecollection.
    SetpcolFiles=NewCollection

    ’Makesurethere’sabackslash.
    IfRight(strPath,1)""Then
    strPath=strPath""
    EndIf

    ’Getthefirstfile.
    strFile=Dir(strPath"*.*",_
    vbReadOnlyOrvbHiddenOrvbArchiveOrvbSystem)
    DoUntilLen(strFile)=0
    ’Addittothecollection.
    CallAdd(strPathstrFile)
    ’Getthenextfile.
    strFile=Dir()
    Loop

    ’Savethepath.
    pstrPath=strPath

    EndProperty

      向Collection类添加Path属性。将该属性和类设置为扫描目录并将所找到的每个文件添加到私有Collection对象。

      扩展Collection类

      现在,你可以通过声明Files类的一个实例来使用它了,并为曾经由Dir函数找到的每个文件反复调用该类的Add方法。但这不是我们的例子要完成的工作。为什么不是呢?使用Collection类的一个优点是你可以通过添加更多的属性和方法来扩展它的功能;不仅仅限于Add,Remove,Item,和Count。

      在我们的Files类的情形中,它难道不对在类本身,而不是使用该类的每个应用程序里面,放置扫描目录的代码做更多的检测吗?这是面向对象设计的一个指导原则:将代码放在最靠近需要它的地方。

      为了阐述这个概念,我们向Collection类添加了一个Path属性。当你设置这个属性的时候,这个类将对目录进行扫描,并向Collection对象添加它所找到的每个文件(见图4)。

      当一个过程改变该类的Path属性的时候,将触发PropertyLet过程。在我们的例子中,它发生在你从浏览器对话框选择了一个路径之后。这里是完成用文件列表填充Collection任务的简单代码。

    ’Reinitializethecollection.
    SetmobjFiles=NewFiles

    ’Setthepathproperty.
    mobjFiles.Path=strPath

      一旦设置了Path属性,Files类就将通俗化它自己的Collection,并且使它可以提供给应用程序。这已经是另一个例子了,在这个例子里面,过程的"guts"存在于类自己内部(你可以证明类已不再需要它的Add和Remove方法了。在有些应用程序中,可能确实是这样,但为了达到说明的目的,我们已经选择了留下它们作为该类的一部分)。

      一些不利之处

      使用VBACollection类的生活并不总是美酒和玫瑰。当你使用Collection类代替Collection对象时,必须放弃两样东西。第一样是Collection对象的默认方法,Item。默认的方法允许你从你的代码中省略单词"Item"。例如,如下两条语句是一样的,都是假定colFiles引用一个Collection对象。

    Debug.PrintcolFiles.Item(1).Size
    Debug.PrintcolFiles(1).Size

      除非你正在使用的是VisualBasic5.0,否则没有办法为一个类指定默认的方法。因而,你必须总是显式调用Item方法。

      Collection类的第二个主要的不足之处是不能创建列举函数。列举类就是可以使ForEach循环工作的类。如果你想重复Collection中的每一个项目,那么就必须用老式的方法来完成,也就是使用Count属性和ForNext循环。例如,下面的代码可以通俗化列表框:

    ’Fillthelistboxwithinfo.
    lstFiles.Clear
    ForlngCount=1TomobjFiles.Count
    WithmobjFiles.Item(lngCount)
    lstFiles.AddItem.ShortName_
    Space(12-Len(.ShortName))_
    vbTab.AttributeString_
    vbTab.Size
    EndWith
    Next

      请注意该过程是如何使用计数器变量lngCount来完成从1到Collection中项目数的循环的。With语句使用了Item方法来引用Collection中的每个对象。

      请注意,VisualBasic5.0用户可以通过创建列举函数来克服这一局限。在VisualBasicBookOnline中搜索关键字"enumeration"可以得到更为详细的信息。

    感谢您对翰文计算机学习网的支持

  • 关于我们
  • 联系方式
  • 成功案例
  • 技术报价
  • RSS索引
  • 网站地图
  • 翰文电脑学习网
  • MSN:LNDDYGYC9@HOTMAIL.COM Powered by 翰文个人计算机学习网 版权所有,未经允许不得转载
    ICP备案号码:[沪ICP备12020678号] Copyright 2008-2020 HW-PCS.ORG, All Rights Reserved.