VB中的Dictionary对象介绍+小结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VBA中Dictionary对象使用小结
Dim dict
' 创建Dictionary
Set dict = CreateObject("Scripting.Dictionary")
' 增加项目
dict.Add "A", 300
dict.Add "B", 400
dict.Add "C", 500
' 统计项目数
n = dict.Count
' 删除项目
dict.Remove ("A")
' 判断字典中是否包含关键字
dict.exists ("B")
' 取关键字对应的值,注意在使用前需要判断是否存在key,否则dict中会多出一条记录
Value = dict.Item("B")
' 修改关键字对应的值,如不存在则创建新的项目
dict.Item("B") = 1000
dict.Item("D") = 800
' 对字典进行循环
k = dict.keys
v = dict.Items
For i = 0 To dict.Count - 1
key = k(i)
Value = v(i)
MsgBox key & Value
Next
' 删除所有项目
dict.Removeall
实例:
Sub 宏1()
Set dic = CreateObject("Scripting.Dictionary") '字典
For i = 1 To 10000
If Not i Like "*4*" Then
dic.Add i, "" '如果不包含“1”
End If
Next
Range("a2").Resize(dic.Count, 1) = Application.WorksheetFunction.Transpose(dic.keys) '从A2单元开始向下放置
End Sub
VB中的Dictionary对象
核心归纳:
1、更换键名,用obj.key("xx")="newxx"
2、更换键值或访问指定键:1、重设键值:obj.item("xx")="newxx",2、取得键值:response.write obj.item("xx")=" ,如果obj.item("xx")="newxx" 中的KEY键“xx”未设定时,会在对象的后面增加一个键值对。
3、获得条目数:obj.count (从1开始)
4、增加键值对:obj.add key,value
5、移除键:obj.remove("key") , obj.removeall()
6、判定键是否存在:obj.Exists("key")
7、遍历:先把键和值各自赋给一个变量,构成一维数组,再用FOR遍历
a=d.keys
b=d.Items
'For x=0 to d.count-1 '或从上到下遍历,
For x=d.Count-1 To 0 Step -1 '从下到上遍历wan : abc zuo : 10254
Response.write a(x)
Response.write " : "
Response.write b(x)
Response.write "<br />"
Next
8、用pareMode = 0(二进制,默认,大小写敏感)或pareMode = 1(文本,大小写不区分,但不会后面的覆盖前面)来指定比较模式,
=================================================================
简单的理解:Scripting.Dictionary对象相当于二维数组,但比二维数组更灵活,可以随时操纵其中某个键,而二维数组还要遍历。
以下用一个简单的案例来帮助理解:
set d=server.CreateObject("scripting.dictionary")
d.add "zuo",21312
d.add "wan","abc"
response.write d.Count '计数,从1开始
Response.write "<br />"
a=d.keys
b=d.Items
'For x=0 to d.count-1 '或从上到下遍历,
For x=d.Count-1 To 0 Step -1 '从下到上遍历wan : abc zuo : 10254
Response.write a(x)
Response.write " : "
Response.write b(x)
Response.write "<br />"
Next
Response.write d.item("wan") '输出指定的key值
Response.write "<br />"
d.item("wan")="新值"
Response.write d.item("wan") '输出指定的key值
Response.write "<br />"
d.key("wan")="newwan" '更改键名
'wan键名更改了,是否还有值?
Response.write "执行d.key(""wan"")=""newwan""后再输出wan"
Response.write d.item("wan") '无值输出。
但要注意:d.item("wan") 不存在,可用d.Exists("wan")检测。
Response.write "<br />输出新名称newwan的值:"
Response.write d.item("newwan")
Response.write "<br />"
Response.write d.Exists("newwan") '分析是否存在这个键True。
d.Remove("newwan")
Response.write "<br />"
Response.write d.Exists("wan") '分析是否存在这个键True。
Response.write "<br />"
For x=d.Count-1 To 0 Step -1 '从下到上遍历wan : abc zuo : 10254
Response.write a(x)
Response.write " : "
Response.write b(x)
Response.write "<br />"
Next
详细:
许多Microsoft的编程语言,如Visual Basic、VBScript和Jscript,都提供集合(collection)。
可以把集合想象为数组,可以使用其中内建的函数完成存储和操纵数据等基本任务。
无须担心数据是在哪些行列,而是使用唯一的键进行访问。
VBScript和Jscript都提供类似的对象,通称Scripting.Dictionary对象或Dictionary对象。
它类似于二维数组,把键和相关条目的数据存放在一起。
然而真正的面向对象的方法,不应直接访问数据条目,必须使用Dictionary对象支持的方法和属性来实现。
创建和使用Dictionary对象
创建一个Dictionary对象的示例如下:
‘In VBScript:
Dim objMyData
Set objMyData = Server.CreateObject(“Scripting.Dictionary”)
//In Jscript:
var objMyData = Server.CreateObject(…Scripting.Dictionary‟);
<!-- Server-Side with an OBJECT element -->
<OBJECT RUNAT=”SERVER” SCOPE=”PAGE” ID=”objMyData”
PROGID=”Scripting.Dictionary”>
</OBJECT>
Dictionary对象还可用于客户端的IE中。
1.Dictionary对象的成员概要
当增加一个键/条目对时,如果该键已存在;或者删除一个键/条目对时,该关键字/条目对不存在,或改变已包含数据的Dictionary对象的CompareMode,都将产生错误。
属性说明
CompareMode (仅用于VBScript)设定或返回键的字符串比较模式
Count 只读。
返回Dictionary里的键/条目对的数量---从1开始,而不像数组从0开始计数
Item(key) 设定或返回指定的键的值
Key(key) 设定键名值
方法说明
Add(key,item) 增加键/条目对到Dictionary
Exists(key) 如果指定的键存在,返回True,否则返回False
Items() 返回一个包含Dictionary对象中所有条目的数组
Keys() 返回一个包含Dictionary对象中所有键的数组
Remove(key) 删除一个指定的键/条目对
RemoveAll() 删除全部键/条目对
2.对Dictionary中增加和删除条目
一旦得到一个新的(空的)Dictionary,可以对其添加条目,从中获取条目以及删除条目:
‘In VBScript:
objMyData.Add “MyKey”, “MyItem”
objMyData.Add “YourKey”, ”YourItem”
blnIsThere = objMyData.Exists(“MyKey”)
strItem = objMyData.Item(“YourKey”)
strItem = objMyData.Remove(“MyKey”)
objMyData.RemoveAll
3.修改键或条目的值
可以通过修改键的值,或通过修改与特定的键关联的条目的数据,来改变存储在Dictionary内的数据。
下面的代码改变键为MyKey的条目中的数据。
ObjMyData.Item(“MyKey”) = “NewValue” … In VBScript
ObjMyData.Item(…MyKey‟) = …NewValue‟; // In JScript
如果指定的键在Dictionary未找到,将在Dictionary中后面位置创建一个以MyKey为键,以New Value 为其条目值的新的键/条目对。
有意思的是,如果使用一个不存在的键来检索条目,不仅得到一个空的字符串(这是可以想到的),而且还在Dictionary里添加一个新的键/条目对,键即是指定的键,但条目的数据为空。
可以使用Key属性仅改变键名的值而不改变与之对应的条目的数据。
将一个已存在的键MyKey改变为MyNewKey,可以用:
objMyData.Key(“MyKey”) = “MyNewValue” … In VBScript
objMyData.Item(…MyKey‟) = …MyNewValue‟; // In JScript
如果指定的键未找到,则产生运行期错误。
4.设置比较模式
Dictionary的CompareMode属性仅适用于VBScript,不能在JScript中使用。
当比较字符串键时,允许指定比较的方式。
两个允许的值为BinaryCompare(0)和TextCompare(1)。
BinaryCompare(0)为二进制数对照(即区分大小写);TextCompare(1)为文本对照(即不区分大小写)。
5.遍历Dictionary
研究Dictionary时,有两个方法和一个属性需要特别注意,它们允许我们遍历存储在Dictionary里的所有键/条目对。
Items方法用一个一维数组的形式返回Dictionary里所有的条目数据,而keys方法用一个一维数组返回所有已存在的键值。
可以使用Count属性得到键或条目的数量。
例如,可以使用下列代码得到名称为objMyData的Dictionary中所有的键和条目值。
注意,虽然Count
属性保存了在Dictionary里的键/条目数量,但VBScript和JScript的数组总是从下标0开始的。
因此,数组下标应从0到Count-1。
‘In VBScript:
arrKeys = objMyData.Keys …Get all the keys into an array
arrItems = objMyData.Items …Get all the items into an array
For intLoop = 0 To objMyData.Count –1 …Iterate through the array
StrThisKey = arrKeys(intLoop) …This is the key value
StrThisItem = arrItems(in tLoop) …This is the item (data) value
Next
// In JScript
// Get VB-style arrays using the Keys() and Items() methods
var arrKeys = new VBArray(objMyData.Keys()).toArray();
var arrItems = new VBArray(objMyData.Items()).toArray();
for (intLoop = 0; intLoop < objMyData.Count; intLoop++) {
// Iterate through the arrays
strThisKey = arrKeys[intLoop]; // This is the key value
strThisItem = arrItems[intLoop]; // This is the item (data) value
}
在VBScript里也可以使用For Each …Next语句完成同样的功能:
arrKeys = objMyData.Keys
arrItems = objMyData.Items
For Each objItem in arrItems
Response.Write objItem & “ = “ & arrItems(objItem) & “<BR>”
Next
5.3.2 Dictionary对象示例
本书提供了一系列示例文件可用来试验脚本运行时间库的各种属性。
本章代码的缺省页面提供了一系列可使用的VBScript示例链接。
有些示例对JScript同样有效。
这些示例存放在Chapter05目录下相应的子目录里,显示的界面如图5-2所示:
要查看Dictionary对象的运行,在菜单页面点击第一个链接,打开名叫show_dictionary.asp的页面。
这个页面显示了我们提供的Dictionary对象的内容,允许试验其属性和方法。
屏幕如图5-3所示:1.Dictionary的global.asa文件
随Dictionary对象示例页面提供的文件之一是global.asa。
它创建并预先填充了一个会话层作用域的Dictionary对象,因此其内容在页面请求之间不会丢失。
一般说来(考虑到可扩展性),这不是一个理想的做法。
在这个例子里,可以看到Dictionary的属性和方法的效果。
如果在自己的服务器上下载并安装示例,必须创建一个基于此global.asa文件的虚拟应用程序。
或者将其内容添加到缺省站点的根文件夹中的global.asa文件里。
在第3章讲述了如何用向导创建虚拟应用程序。
然而对于本示例,创建一个虚拟应用程序最简单的方法是在Chapter05示例文件夹内右击dictionary子文件夹,在Properties对话框的Home Directory选项卡里,点击Create按钮,如图5-4所示:
在这个global.asa文件里,代码使用<OBJECT>元素创建一个会话层作用域的Scripting.Dictionary对象实例。
然后在Session_onStart事件处理程序里将一系列值用Add方法放入Dictionary中,并将对Dictionary对象的引用指定给ASP会话变量MyDictionary:
<OBJECT ID="objBookList" RUNAT="SERVER" SCOPE="SESSION"
PROGID="Scripting.Dictionary">
</OBJECT>
<SCRIPT LANGUAGE="VBScript" RUNAT="SERVER">
Sub Session_onStart()
objBookList.Add "2610", "Professional Active Server Pages 3.0"
objBookList.Add "1274", "Instant JavaScript"
objBookList.Add "2882", "Beginning ASP Components"
objBookList.Add "1797", "Professional ASP Techniques"
objBookList.Add "1835", "AD0 2.0 Programmer's Reference"
Set Session("MyDictionary") = objBookList
End Sub
</SCRIPT>
2.Dictionary示例页面
在“Scripting.Dictionary Object”主页面里,首要的任务是得到一个会话层作用域的Dictionary对象实例的引用。
注意,这个引用是一个对象变量,因此必须在VBScript里使用Set关键字。
然后,检查一下是否得到了一个对象(这是个好习惯),如果没有正确地建立包含global.asa文件的虚拟应用程序,检查一下问题出在哪里。
你将看到我们自己的消息代替了ASP的错误消息(但是注意,对于这一操作必须关闭缺省的错误处理)。
<%
on error resume next ' turn off error handling to test if object exists
'retrieve Dictionary object from user's session
Set objMyData = Session("MyDictionary")
If IsObject(objMyData) Then 'found Dictionary object in Session
…
%>
<P><DIV CLASS="subhead">Iterating the Dictionary with Arrays</DIV>
<%
arrKeysArray = objMyData.Keys 'get all the keys into an array
arrItemsArray = objMyData.Items 'get all the items into an array
For intLoop = 0 To objMyData.Count - 1 'iterate through the array
Response.Write "Key: <B>" & arrKeysArray(intLoop) & "</B> Value: <B>" _
& arrItemsArray(intLoop)& "</B><BR>"
Next
%>
…
…Other code and controls go here …
…
<%
Else
'could not find Dictionary object in the session
Response.Write "Dictionary object not available in global.asa for session"
End If
%>
显示在页面上的Dictionary内容列表是使用Dictionary对象的Key和Items方法创建的两个数组,可使用前面的代码遍历它们。
3.Dictionary页面控件
在Dictionary的内容列表下是一系列的HTML控件,可用于设定Dictionary对象的某些属性和执行各种方法。
这些控件全部在一个<FORM>内,其ACTION属性值是本页面,所以窗体的内容提交回本页面。
在前面的章节的示例里使用了同样的技术。
在<FORM>段中,改变属性或执行一个方法是通过一个按钮(没有标题)实现的。
用于属性和方法的值放入按钮旁的文本框或列表框中。
该页的第一个按钮用于设定Dictionary里的条目的Key属性。
这里使用了一个下拉列表,可以选择一个已经存在的Key值。
下面的代码创建了页面内该部分的控件。
为了填充列表,使用了另外一个遍历Dictionary对象的技术,即For Each …Next语句。
代码如下:
…
<FORM ACTION="<% = Request.ServerVariables("SCRIPT_NAME") %>" METHOD="POST">
<P><DIV CLASS="subhead">The Dictionary Properties</DIV>
<INPUT TYPE="SUBMIT" NAME="cmdChangeKey" V ALUE=" ">
Dictionary.Key ("
<SELECT NAME="lstChangeKey" SIZE="1">
<%
For Each objItem in objMyData
Response.Write "<OPTION>" & objItem
Next
%>
</SELECT> ") = "
<INPUT TYPE="TEXT" NAME="txtChangeKey" SIZE="15" V ALUE="New Key Name"> "
<BR>
…
…Other controls go here …
…
</FORM>
…
4.使用Dictionary的属性和方法
在“Scription.Dictionary Object”页面,点击用来检查并改变条目的Key属性的按钮,如图5-5所示:把窗体再次提交给页面。
该页面包含一个脚本段,检查被点击的按钮的值。
它通过在Resquest.Form 集合里查找按钮的名字来断定单击的是哪个按钮。
如果发现一个对应于cmdChangKey的值,则从列表中或文本框中得到相应的值并用来改变Key属性:
…
'look for a command sent from the FORM section buttons
If Len(Request.Form("cmdChangeKey")) Then
strKeyName = Request.Form("lstChangeKey") 'Existing key from list box
strNewKey = Request.Form("txtChangeKey") 'New key value from text box
objMyData.Key(strKeyName) = strNewKey 'Set key property of this item
End If
…
页面重新载入后,在Dictionary的内容列表里能看到相应的结果,如图5-6所示:
页面的其余代码用来设定一个条目的Item属性,或者执行Dictionary对象的方法。
下面是这些操作的代码,每段代码与演示Key属性的代码非常类似。
每次都将结果显示在Dictionary的内容列表中:
…
If Len(Request.Form("cmdChangeItem")) Then
strKeyName = Request.Form("lstChangeItem") 'Existing key from list box
strNewValue = Request.Form("txtChangeItem") 'New item value from text box
objMyData.Item(strKeyName) = strNewValue 'Set the Item property
End If
If Len(Request.Form("cmdAdd")) Then
strKeyName = Request.Form("txtAddKey") 'New key value from text box
strItemValue = Request.Form("txtAddItem") 'New item value from text box
objMyData.Add strKeyName, strItemValue 'Execute the Add method
End If
If Len(Request.Form("cmdRemove")) Then
strKeyName = Request.Form("lstRemove") 'Existion key from list box
objMyData.Remove strKeyName 'Execute the Remove method
End If
If Len(Request.Form("cmdRemoveAll")) Then
objMyData.RemoveAll 'Execute the RemoveAll method
End If
…
例如,如果现在点击Add方法的按钮,在Dictionary的内容列表里将增加一个新的条目,如图5-7所示:
结果如图5-8所示:
可以在这个页面中试验Dictionary对象的属性和方法,你将会发现什么因素及在什么环境下能引起Dictionary对象错误。
例如,尝试用与已经存在的一个条目相同的键值增加一个条目,看看会出现什么结果。
关于CompareMode 属性
描述
设置并返回在Dictionary 对象中比较字符串关键字的比较模式。
语法
pareMode[ = compare]
CompareMode 属性有以下部分:
部分描述
object 必选。
Dictionary 对象的名称。
compare 可选。
如果提供此参数,compare 参数为数值,表示由函数如StrComp 使用的比较模式。
设置
compare 参数设置如下:
Constant Value Description
vbBinaryCompare 0 执行二进制比较.
vbTextCompare 1 执行文本比较.
说明
大于 2 的值可用来进行使用国别Ids 的比较(LCID)如果试图更改已经包含数据的Dictionary 对象
的比较模式,则会出现错误。
CompareMode 属性使用与StrComp 函数中compare 参数相同的值。
下面例子举例说明如何使用CompareMode 属性:
Dim d
Set d = CreateObject("Scripting.Dictionary")
pareMode = vbTextCompare
d.Add "a", "Athens" '添加一些键和项目。
d.Add "b", "Belgrade"
d.Add "c", "Cairo"
d.Add "B", "Baltimore" '在该行添加方法失败,因为
'字母b 已经在Dictionary 中存在。