国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

集合類:VBA集合對象的安全包裝

2019-11-18 17:55:24
字體:
來源:轉載
供稿:網友
你遲早都要管理一組由VBA類模塊創建的自定義對象,VBACollection對象是實現這一目的的理想工具。我們在該雜志的
當然,如果你能保證每個對象都具有相同得類型,并且具有相同得屬性何方法的話,那么在Collection中處理對象就變得異常簡單。例如,作為本月范例
ExcelVBA項目的組成部分,我們創建一個自定義的File類來代表一個磁盤文件。這個File類有幾個屬性,其中包括Path,Size,和ShortName。如果你創建了一個File對象的Collection,那么你將希望這個Collection中的每個對象都具有這些屬性。你可以毫無異議地使用與下面類似的代碼:


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


但是,如果colFilesCollection中的第一個對象不是File,將會出現什么情況呢?如果它是一個Form或Control對象,又會怎樣呢?如果它根本就不是一個對象呢?當然,當它試圖執行該代碼的時候,VBA將生成運行時間錯誤。




圖1(左)VBACollection對象可以容納任何類型的對象



圖2(右)創建一個Collection類來防止不想要的對象進入集合


輸入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方法來將錯誤傳遞、給調用過程。

圖3這個表單通過顯示文件信息來說明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(strPath&strFile)
'Getthenextfile.
strFile=Dir()
Loop

'Savethepath.
pstrPath=strPath

EndProperty

圖4向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

請注意該過程是如何使用


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新源县| 松江区| 沅江市| 北辰区| 惠水县| 四会市| 宜宾市| 德昌县| 肇源县| 黎城县| 乐陵市| 西城区| 娱乐| 繁峙县| 河源市| 旬阳县| 十堰市| 长泰县| 双城市| 金昌市| 安达市| 石嘴山市| 晋州市| 安义县| 连山| 涡阳县| 安岳县| 张家口市| 华阴市| 峨山| 容城县| 达拉特旗| 平遥县| 德令哈市| 玉门市| 仙桃市| 柏乡县| 普陀区| 沈阳市| 丹寨县| 子长县|