| 近 几 年 来 , 视 觉 化 软 体 开 发 工 具 大 行 其 道 , 尤 其 自 "Visual"
Basic 成 功 以 来 , 其 他 软 体 开 发 工 具 亦 纷 纷 起 而 效 之 , 除
了 在 名 称 上 冠 上 Visual 之 外 , 视 觉 化 设 计 亦 无 不 成 为 必 备
之 功 能 , 宛 如 视 觉 化 设 计 就 是 软 体 开 发 的 万 灵 丹 。
笔 者 相 信 视 觉 化 设 计 可 协 助 我 们 更 快 速 地 开 发 出 应 用 软 体 , 但 不 可 否 认 的 , 软 体 的 开 发 过 程 中 , 最 常 遭 遇 的 问 题 还 是 : 程 式 有 没 有 bug、 执 行 效 能 如 何 、 是 否 符 合 使 用 者 的 需 求 … 等 , 而 如 何 克 服 这 些 问 题 则 取 决 於 程 式 设 计 者 的 功 力 , 而 不 在 视 觉 化 开 发 工 具 上 面 。 怎 样 加 强 程 式 设 计 的 功 力 呢 ? 闭 门 苦 修 个 叁 年 五 载 ?
那 倒 不 必 , 有 没 有 速 成 班 呢 ? 笔 者 觉 得 没 有 , 但 的 确 有
若 干 重 要 的 环 节 , 若 能 打 通 , 则 可 缩 短 苦 练 的 功 夫 , 本
期 就 让 笔 者 为 您 节 说 这 些 环 节 。 |
变 数 , 这 应 该 是 基 础 的 基 础 吧 , 这 麽 简 单 的 东 西 也 能 够 增 强 程 式 设 计 的 功 力 ? 如 果 您 这 麽 想 , 那 就 大 错 特 错 了 , 变 数 犹 如 程 式 中 的 血 液 , 如 果 程 式 病 了 , 最 可 能 的 原 因 就 是 血 液 遭 受 病 毒 的 侵 袭 , 不 彻 底 研 究 血 液 , 便 很 难 把 生 病 的 程 式 治 好 。
什 麽 是 变 数 ? 我 们 写 一 个 数 学 方 程 式 , 假 设 是 :
X = Y + 10
这 里 面 就 有 两 个 变 数 , 一 个 是 X, 一 个 是 Y。 X 及 Y 在 这 里 是 变 数 的 「 名 称 」 ; 而 当 Y 等 於 2 时 , X 等 於 12, 此 时 2 及 12 分 别 是 变 数 X 与 Y 的 「 值 」 。
以 上 是 我 们 从 数 学 方 程 式 中 所 看 到 的 变 数 , 它 包 含 两 个 元 素 : 名 称 与 值 。 若 从 电 脑 的 角 度 来 看 , X 的 值 12 必 须 储 存 在 某 一 个 地 方 , 也 就 是 记 忆 体 的 某 一 个 「 位 址 」 之 下 , 所 以 位 址 又 是 变 数 的 另 一 个 元 素 。
为 了 表 达 一 个 变 数 , 只 有 以 上 叁 个 元 素 往 往 还 是 不 够
的 , 举 例 来 说 :
A = "RUN!VB "
这 时 候 储 存 变 数 A(等 於 "RUN!VB")所 需 的 空 间 , 显 然 比 储 存 变 数 X(等 於 12)所 需 的 空 间 来 得 大 , 而 且 连 操 作 两 种 变 数 的 方 式 也 会 有 所 差 异 , 例 如 我 们 可 以 这 样 写 X/2, 但 如 果 我 们 这 样 写 A/2 就 没 有 意 义 了 , 为 了 区 别 特 性 不 同 的 变 数 , 程 式 语 言 中 的 变 数 必 须 再 增 加 一 个 元 素 「 资 料 型 别 」 , 以 前 面 的 例 子 来 看 , 变 数 X 是 整 数 (Integer)型 别 , 而 变 数 A 是 字 串 (String)型 别 。
综 合 以 上 的 讨 论 , 我 们 可 以 用 以 下 四 个 元 素 : 「 名 称 」 、 「 资 料 型 别 」 、 「 位 址 」 、 及 「 值 」 来 表 示 一 个 变 数 , 如 图 -1, 在 图 -1中 , 由 於 「 值 」 是 储 存 在 某 一 个 「 位 址 」 的 记 忆 体 里 面 的 , 所 以 把 它 画 在 位 址 的 框 框 里 面 。
利 用 以 上 四 个 元 素 来 表 示 变 数 , 可 以 解 释 一 些 平 常 想 当 然 尔 的 叙 述 , 如 图 -2 的 「 X = Y + 10」 : (假 设 Y 的 值 等 於 123)
这 里 顺 便 介 绍 两 个 术 语 : r-value 及 l-value。 r-value 是 right value 的 缩 写 , 表 示 等 号 右 边 的 变 数 , 如 例 子 中 的 Y, 实 质 上 代 表 的 是 变 数 的 「 值 」 , l-value 是 left value 的 缩 写 , 表 示 等 号 左 边 的 变 数 , 如 例 子 中 的 X, 实 质 上 代 表 的 是 变 数 的 「 位 址 」 。
以 上 我 们 用 变 数 的 组 成 元 素 来 解 释 简 单 的 例 子 , 看 起 来 没 有 特 别 的 价 值 , 但 这 是 变 数 的 根 本 道 理 , 它 同 时 可 以 用 来 解 说 复 杂 、 以 及 容 易 让 人 搞 错 的 例 子 , 请 务 必 了 解 这 几 个 元 素 的 意 义 。
了 解 变 数 的 组 成 元 素 之 後 , 就 不 容 易 被 VB 的 「 定 型 变 数 」 及 「 不 定 型 变 数 」 给 搞 晕 了 , 兹 说 明 如 下 :
◆ 定型变数
此 一 类 型 的 变 数 在 宣 告 时 会 指 明 变 数 的 「 资 料 型 别 」
, 例 如 :
Dim X As Integer ' X 是整数型别
Dim S As String ' S 是字串型别
此 一 类 型 变 数 最 大 的 特 色 在 於 其 资 料 型 别 是 「 固 定 的
」 , 也 就 是 说 , 当 我 们 宣 告 变 数 时 , 指 定 给 它 某 一 型 别
後 , 它 就 永 远 是 那 个 型 别 , 而 且 将 来 就 只 能 与 型 别 「 相
同 」 或 「 相 容 」 的 变 数 做 运 算 , 举 例 来 说 , 以 下 的 例 子
会 出 现 错 误 :
Dim X as Integer
X = "这是字串" ' 执行时会出现「型态不符合」的讯息
◆ 不定型变数
什 麽 是 不 定 型 变 数 ? 请 看 以 下 例 子 :
Dim X ' 宣告一个变数 X,但未指定资料型别
X = 123 ' 此时 X 的资料是「整数」型别
...
X = "VB" ' 後来又变成了「字串」型别
变 数 X 在 某 一 个 时 间 被 指 定 成 「 整 数 」 的 资 料 型 别 , 但 是 後 来 它 又 被 指 定 成 另 一 种 资 料 型 别 — 「 字 串 」 , 像 X 这 样 , 资 料 型 别 可 以 变 来 变 去 的 变 数 就 是 「 不 定 型 」 变 数 。
不 定 型 变 数 的 缺 点 是 执 行 效 率 比 较 差 , 为 什 麽 呢 ? 由 於 它 的 资 料 型 别 是 可 变 动 的 , 因 此 每 次 执 行 时 必 须 先 判 断 变 数 当 时 的 资 料 型 别 , 无 形 中 增 加 了 执 行 上 的 负 担 。
不 过 您 也 别 把 不 定 型 变 数 想 得 太 糟 糕 , 上 述 的 「 额 外
负 担 」 对 大 部 份 的 程 式 来 说 , 其 影 响 都 相 当 有 限 , 一 般
而 言 需 要 注 意 的 地 方 是 避 免 在 费 时 较 久 的 回 圈 中 使 用 不
定 型 变 数 , 例 如 :
Dim X
Dim I
For I = 0 To 30000
X = "AAAA"
Next I
如 果 我 们 将 Dim X 及 Dim I 分 别 修 改 成 Dim X As String 及 Dim I As Integer, 则 执 行 速 度 将 有 明 显 的 改 善 。
反 观 不 定 型 变 数 有 什 麽 优 点 呢 ? 首 先 是 它 比 较 接 近 人 类 的 思 考 模 式 。 谁 规 定 变 数 一 旦 被 指 定 成 某 一 种 资 料 型 别 後 , 就 不 能 改 变 了 , 所 以 变 数 的 型 别 可 以 变 来 变 去 本 来 就 比 较 容 易 使 用 , 此 外 , 它 也 比 定 型 变 数 更 容 易 应 用 到 物 件 导 向 的 程 式 中 , 举 个 例 子 : 假 设 我 们 在 程 式 中 会 使 用 到 许 多 物 件 , 而 这 些 物 件 各 具 有 不 同 的 资 料 型 别 , 为 了 管 理 这 些 物 件 , 我 们 想 把 它 们 集 中 放 在 一 起 , 其 中 最 简 便 的 方 式 就 是 采 用 阵 列 , 所 以 程 式 可 能 是 :
Set ObjArr(1) = 物件_1
Set ObjArr(2) = 物件_2
...
Set ObjArr(N) = 物件_N
由 於 ObjArr 是 一 个 阵 列 , 假 如 我 们 把 它 宣 告 成 「 定 型 变
数 」 , 那 麽 该 将 它 定 义 成 「 物 件 _1」 的 资 料 型 别 、 还 是
「 物 件 _2」 的 资 料 型 别 , 还 是 … , 显 然 是 行 不 通 的 , 如
果 把 这 个 阵 列 宣 告 成 「 不 定 型 变 数 」 , 则 阵 列 中 的 每 一
个 元 素 就 可 以 依 程 式 执 行 时 的 状 况 来 改 变 其 资 料 型 别 ,
自 然 而 然 就 满 足 了 这 个 需 求 。
当 我 们 将 一 个 单 精 准 度 型 别 (Single)的 数 值 9.8 指 定 给 一 个 「 不 定 型 」 变 数 X 时 , 此 一 不 定 型 变 数 X 除 了 「 值 」 元 素 会 变 成 9.8 之 外 , 「 资 料 型 别 」 元 素 则 会 变 成 Single, 但 如 果 我 们 将 同 样 的 9.8 指 定 给 一 个 整 数 (Integer)型 别 的 变 数 Y, 结 果 又 如 何 呢 ? 此 时 由 於 Y 为 「 定 型 」 变 数 , 其 「 资 料 型 别 」 元 素 (等 於 Integer)是 不 可 变 的 , 因 此 , 9.8 必 须 被 转 换 成 整 数 , 然 後 才 指 定 到 Y 的「值 」 元 素 中 。
由 於 不 同 型 别 的 变 数 能 够 互 相 指 定 与 运 算 , 所 以 我 们 经 常 可 以 在 VB 程 式 中 看 到 「 值 」 转 换 的 例 子 , 如 :
Dim I As Integer
I = "123" ' 字串 "123"
先转换成 123,再指定给 I
I = 9.8 ' 9.8 先四舍五入转换成 10,再指定给
I
Dim S As String
S = 123 ' 123 先转换成 "123" 再指定给
S
Dim D As Date
D = "1997/7/1" ' "1997/7/1"
先转换成 #1997/7/1# 再指定给 D
当 然 , 我 们 也 经 常 遇 到 转 换 失 败 的 例 子 :
Dim I As Integer
I = "123A" ' "123A"
无法转换成整数,将产生错误
I = 99999 ' 99999 超过整数的最大值 32767,也会产生错误
在 此 笔 者 想 说 明 几 个 因 为 「 值 」 转 换 所 产 生 的 陷 阱 :
◆ 值转换之陷阱一
Dim L As Long, I As Integer, J As Integer
L = I * J
以 上 的 「 L = I*J」 , 乍 看 之 下 并 没 有 问 题 , 因 为 I 及 J 为 整 数 , 均 占 有 2 bytes, 而 L 为 长 整 数 , 占 有 4 bytes, 因 此 I*J 怎 样 也 不 会 超 过 L 的 数 值 范 围 , 但 实 际 上 , 当 I*J>32767 或 I*J<-32768 时 , 就 会 产 生 「 溢 位 」 , 这 是 怎 麽 一 回 事 呢 ?
L=I*J 虽 然 只 是 一 个 简 单 的 运 算 式 , 但 对 电 脑 而 言 , 却
至 少 包 含 以 下 的 运 算 过 程 :
(1) I*J, 然 後 将 结 果 储 存 於 「 暂 存 记 忆
体 」 中 。
(2) 将 「 暂 存 记 忆 体 」 的 值 指 定 给 L。
由 於 I 及 J 均 为 整 数 型 别 , 因 此 在 以 上 的 运 算 过 程 中 , 系 统 也 会 配 置 与 整 数 型 别 等 大 小 的 「 暂 存 记 忆 体 」 来 储 存 I*J 的 结 果 , 而 如 果 I*J 超 出 整 数 型 别 的 范 围 (-32768~ 32767), 则 暂 存 於 「 暂 存 记 忆 体 」 时 就 会 产 生 「 溢 位 」 的 错 误 。 解 决 的 方 法 十 分 简 单 , 只 要 将 I 或 J 的 数 值 强 制 转 换 成 长 整 数 , 再 作 运 算 即 可 , 例 如 :
L = CLng(I) * J
以 上 的 CLng 函 数 就 是 将 数 值 强 制 转 换 成 Long(长 整 数 )型
别 的 函 数 , 由 於 CLng(I) 为 一 长 整 数 , 因 此 系 统 进 行 CLng(I)*J
运 算 时 , 会 配 置 与 长 整 数 型 别 等 大 小 的 「 暂 存 记 忆 体 」
来 储 存 CLng(I)*J 运 算 的 结 果 , 如 此 一 来 , 就 不 会 产 生 「 溢
位 」 的 错 误 了 。 除 了 CLng 函 数 之 外 , 常 用 的 数 值 型 别 资
料 转 换 函 数 还 有 :
| CByte | 强制转换成 Byte 型别 |
| CCur | 强制转换成 Currency 型别 |
| CDbl | 强制转换成 Double 型别 |
| CDec | 强制转换成 Decimal 型别 |
| CInt | 强制转换成 Integer 型别 |
| CSng | 强制转换成 Single 型别 |
◆ 值转换之陷阱二
Dim X1, X2, X3
X1 = "12"
X2 = "34"
X3 = 34
Print X1 + X2 ' 结果等於 "1234"
Print X1 + X3 ' 结果等於 46
以 上 的 X1、 X2、 及 X3 都 是 「 不 定 型 」 变 数 , 而 执 行 前 叁 个 叙 述 之 後 , 它 们 的 「 资 料 型 别 」 元 素 分 别 等 於 :
X1:字串
X2:字串
X3:整数
因 此 接 下 来 的 X1+X2 将 被 视 为 字 串 的 串 接 , 所 以 结 果 等 於 "1234", 但 X1+X3, 由 於 X3 等 於 34, 为 一 整 数 , 所 以 X1 的 值 会 由 "12" 转 换 成 12 再 与 34 相 加 , 所 以 得 到 46 的 结 果 。
此 一 陷 阱 虽 然 很 容 易 识 破 , 但 也 很 容 易 疏 忽 , 如 何 防 止 这 种 错 误 , 笔 者 倒 有 个 简 单 的 方 法 : 「 资 料 的 『 串 接 』 一 律 使 用 '&' 号 , 而 不 使 用 '+' 号 , 『 数 值 』 的 运 算 须 先 确 认 被 运 算 的 资 料 是 否 为 数 值 型 别 , 若 不 是 数 值 型 别 , 则 利 用 Val 函 数 将 资 料 转 换 成 数 值 」 , 例 如 :
X1 = "12"
X2 = "34"
X3 = 34
Print X1 & X3 ' 资料串接,结果等於 "1234"
Print Val(X1) + Val(X2) ' 数值相加,结果等於 46
复 合 式 资 料 指 的 是 由 多 笔 或 多 项 基 本 资 料 所 组 成 的 资 料 , 典 型 的 代 表 有 「 阵 列 」 及 「 结 构 型 资 料 」 。 如 果 以 变 数 的 四 个 组 成 元 素 来 解 析 阵 列 , 则 可 以 表 示 成 图 -6:
阵 列 其 实 是 很 简 单 的 资 料 结 构 , 以 上 面 的 X 阵 列 为 例 , 我 们 可 以 将 它 视 为 X(1)、 X(2)… 、 X(N) 等 变 数 的 集 合 体 。
接 着 让 我 们 来 看 结 构 型 的 资 料 , 假 设 有 一 结 构 型 变 数 X 其 结 构 如 下 :
Type StructX
I As Integer
S As String
D As Date
End Type
Dim X As StructX
若 表 示 成 「 变 数 的 四 个 组 成 元 素 」 , 则 如 图 -7:
在 以 上 的 结 构 型 变 数 中 , 一 共 含 有 4 个 「 名 称 」 元 素
— X、 X.I、 X.S、 及 X.D, 值 得 注 意 的 是 I、 S、 D 为 X 的 资 料 成
员 , 因 此 不 能 直 接 使 用 I、 S、 D 的 名 称 来 存 取 I、 S、 D。
笔 者 过 去 经 常 在 Run!PC 讨 论 物 件 导 向 技 术 , 也 许 您 已 经 听 过 资 讯 隐 藏 (information hiding)、 资 料 萃 取 (data abstraction)、 继 承 (inheritance)、 多 型 (polymorphism)… 等 技 术 名 词 , 今 天 笔 者 想 抛 开 这 些 名 词 , 从 变 数 的 四 个 组 成 元 素 来 看 物 件 。
首 先 请 看 以 下 叙 述 :
Dim X As Integer
Dim OX As Object
以 上 的 X 变 数 与 OX 变 数 有 何 区 别 呢 ? 如 果 我 们 利 用 VB 内 建 的 函 数 IsObject 来 检 验 以 上 两 个 变 数 , 结 果 IsObject(X) 传 回 False, 而 IsObject(OX) 则 传 回 True, 这 表 示 OX 为 一 「 物 件 」 变 数 , 而 X 只 是 普 通 变 数 。 但 笔 者 必 须 特 别 强 调 一 点 , 物 件 变 数 也 是 由 变 数 的 四 个 元 素 所 组 成 的 , 如 图 -8:
物 件 变 数 最 特 别 的 地 方 在 於 「 值 」 元 素 , 对 一 般 变 数 而 言 , 「 值 」 元 素 会 纪 录 着 该 变 数 的 值 , 但 对 物 件 变 数 而 言 , 却 记 录 着 「 具 体 物 件 」 之 位 址 , 如 图 -9:
而 特 别 值 得 注 意 的 是 , 当 我 们 利 用 「 Dim OX As Object」 宣
告 一 个 物 件 变 数 时 , OX 并 不 包 含 图 -9中 的 「 具 体 物 件 」
。
在 VB 程 式 中 有 以 下 几 种 方 法 可 以 让 物 件 变 数 含 有 「 具
体 物 件 」 :
| 方法一: | Dim OX1 As Object Set OX1 = New ClassName |
| 方法二: | Dim OX1 As New ClassName |
| 方法叁: | Dim OX2 As Object Set OX2 = OX1 |
| 方法四: | Dim OX3 As Object Set OX3 = 建立具体物件的函数 |
兹 说 明 如 下 :
◆ 建立具体物件方法一
方 法 一 的 两 个 叙 述 可 分 解 如 图 -10:
在 方 法 一 之 中 , 比 较 值 得 注 意 的 是 New 保 留 字 , 此 一 保 留 字 的 作 用 是 建 立 一 个 ClassName 类 型 的 具 体 物 件 , 而 ClassName 必 须 是 已 存 在 之 「 物 件 类 别 」 (class), 举 例 来 说 , Collection 是 VB 所 提 供 的 物 件 类 别 , 而 以 下 叙 述 可 以 建 立 一 个 Collection 类 型 的 物 件 :
Dim X As Object
Set X = New Collection
◆ 建立具体物件方法二
方 法 二 其 实 是 把 方 法 一 的 两 个 叙 述 合 而 为 一 , 也 就 是 说 :
Dim OX2 As Object
Set OX2 = New ClassName
完 全 等 於 :
Dim OX2 As New ClassName
既 然 如 此 , 我 们 只 要 使 用 方 法 二 来 建 立 物 件 不 就 好 了 , 何 必 了 解 方 法 一 的 叙 述 呢 ? 其 实 方 法 一 与 方 法 二 是 有 区 别 的 , 方 法 二「Dim OX2 As New ClassName」 之 中 的 OX2 一 开 始 就 被 定 义 成 ClassName 类 别 , 所 以 是 一 个 「 固 定 类 别 」 的 物 件 变 数 , 如 果 我 们 设 定 其 他 类 别 的 物 件 给 这 个 物 件 变 数 , 则 会 产 生 错 误 , 此 一 道 理 与 「 定 型 变 数 」 完 全 相 同 。 至 於 方 法 一 「 Dim OX1 As Object」 之 中 的 OX1 则 属 於「不 固 定 类 别 」 的 物 件 变 数 , 所 以 下 面 的 叙 述 都 是 正 确 的 :
' 建立 ClassName1 类型的物件给 OX1
Set OX1 = New ClassName1
' 重新建立另一个 ClassName2 类型的物件给 OX1
Set OX1 = New ClassName2
◆ 建立具体物件方法叁
Dim OX2 As Object
Set OX2 = OX1 ' 将 OX1 的具体物件指定给 OX2
此 一 方 法 的 意 义 是 把 某 一 个 物 件 变 数 的 具 体 物 件 复 制 给 另 一 个 物 件 变 数 , 若 以 变 数 的 四 个 元 素 来 表 示 , 则 如 图 -11:
以 上 的 「 Set OX2 = OX1」 称 为 「 物 件 设 定 叙 述 」 (或 物 件 指 定 叙 述 ), 在 语 法 上 , 它 只 比 「 变 数 指 定 叙 述 」 (例 如 X = Y) 多 了 一 个 Set 保 留 字 , 但 是 在 系 统 内 部 的 运 作 上 , 却 复 杂 得 多 。
◆ 建立具体物件方法四
在 以 上 建 立 具 体 物 件 的 方 法 中 , 方 法 叁 是 将 一 个 已 存 在 具 体 物 件 设 定 给 另 一 个 物 件 变 数 , 而 方 法 一 及 方 法 二 则 是 利 用 New 保 留 字 为 物 件 变 数 建 立 具 体 物 件 , 但 有 些 物 件 类 别 却 无 法 使 用 New 保 留 字 来 建 立 物 件 , 例 如 VB 所 提 供 的 Picture 物 件 类 别 , 此 类 物 件 类 别 通 常 会 搭 配 有 「 建 立 具 体 物 件 的 函 数 」 来 代 为 建 立 具 体 物 件 , 例 如 以 下 是 建 立 Picture 类 别 物 件 的 方 法 :
Dim pic As Picture
Set pic = LoadPicture ( "图档名称"
)
以 上 的 LoadPicture 就 是 建 立 Picture 类 别 物 件 的 函 数 。 此 一 建 立 具 体 物 件 的 方 法 通 常 与 方 法 一 及 方 法 二 是 互 斥 的 , 例 如 Picture 类 别 物 件 的 建 立 , 若 使 用 New 叙 述 就 会 产 生 错 误 :
Dim pic As New Picture ' 将产生错误
就 所 占 用 的 记 忆 体 而 言 , 物 件 变 数 所 占 用 的 记 忆 体 是 固 定 的 , 以 VB 现 况 而 言 , 只 占 用 4 bytes(够 省 吧 !), 但 物 件 变 数 所 指 到 的 「 具 体 物 件 」 则 可 能 占 用 大 量 的 记 忆 体 , 因 此 若 程 式 随 意 建 立 具 体 物 件 , 使 用 完 毕 时 又 不 将 它 破 坏 以 归 还 给 系 统 , 就 可 能 造 成 系 统 记 忆 体 耗 尽 的 现 象 。
至 於 破 坏 具 体 物 件 , 将 记 忆 体 归 还 系 统 的 叙 述 则 十 分 简 单 , 如 图 -12:
Set 物件变数 = Nothing
此 一 叙 述 的 作 用 若 以 变 数 的 四 个 元 素 来 表 达 , 则 如 下 :
请 参 阅 以 下 副 程 式 , 想 一 想 , 假 如 我 们 没 有 执 行 「 Set 物 件 变 数 = Nothing」 , 将 会 有 怎 样 的 後 果 :
Sub SubX()
Dim X As Object
' 建立 ClassX 的具体物件给 X
Set X As new ClassX
' 结束副程式之前,忘了执行 Set X = Nothing
End Sub
结 果 以 上 副 程 式 每 被 呼 叫 一 次 , 就 会 建 立 一 个 具 体 物
件 , 但 它 并 不 会 在 副 程 式 结 束 前 , 将 具 体 物 件 归 还 系 统
, 所 以 被 呼 叫 的 次 数 越 多 , 吃 掉 的 记 忆 体 就 越 多 , 而 使
得 系 统 可 用 之 记 忆 体 越 来 越 少 。
控 制 元 件 是 VB 之 中 非 常 重 要 的 物 件 , 但 笔 者 必 须 强 调 一 点 , 控 制 元 件 的 行 径 与 前 面 介 绍 过 的 标 准 物 件 有 极 大 的 差 异 , 首 先 从 控 制 元 件 的 建 立 与 破 坏 谈 起 , 当 我 们 在 表 单 (Form) 布 置 一 个 控 制 元 件 之 後 , 将 来 只 要 这 个 表 单 被 载 入 , 控 制 元 件 就 会 跟 着 被 载 入 (建 立 ), 而 当 表 单 被 载 出 时 , 控 制 元 件 也 会 跟 着 被 载 出 (破 坏 ), 完 全 不 劳 程 式 设 计 者 费 心 , 由 於 很 多 人 是 从 控 制 元 件 开 始 学 习 VB 的 , 以 致 後 来 使 用 标 准 物 件 时 , 很 容 易 忘 了 执 行「Set 物 件 变 数 = Nothing」破 坏 具 体 物 件 。
使 用 控 制 元 件 时 , 常 见 的 问 题 是 :「如 何 动 态 地 建 立 控 制 元 件 ?」, 例 如 表 单 上 一 开 始 没 有 控 制 元 件 或 只 有 少 数 的 控 制 元 件 , 而 程 式 希 望 随 着 执 行 时 的 状 况 动 态 地 建 立 所 需 之 控 制 元 件 。 如 果 使 用 上 一 个 段 落 所 介 绍 的 方 法 , 可 能 有 人 会 撰 写 以 下 叙 述 :
Dim X As Object
Set X = New TextBox ' 建立 TextBox 控制元件
但 实 际 上 是 行 不 通 的 , 为 什 麽 ? 因 为 控 制 元 件 是 表 单 的 子 物 件 , 而 利 用「Set 物 件 变 数 = New 物 件 类 别 名」所 建 立 的 物 件 则 属 於「程 式」所 管 辖 , 而 VB 并 不 允 许 我 们 建 立 附 属 於「程 式」的 控 制 元 件 , 因 此 以 上 叙 述 会 产 生 错 误 , 但 怎 样 在 表 单 上 面 动 态 地 建 立 控 制 元 件 呢 ?
以 TextBox 控 制 元 件 的 建 立 为 例 , 至 少 必 须 在 表 单 上 先 布 置 一 个 TextBox 控 制 元 件 , 并 且 设 定 它 的 Index 属 性 , 然 後 使 用 Load 叙 述 建 立 控 制 元 件 : (假 设 此 一 TextBox 名 称 为 Text1, 而 Index 属 性 设 定 为 0)
Load Text1(I) ' I 可以是 0 以外的正整数
Text1(I).Visible = True ' 将 Text1(I) 显示出来
' 此外,可能还需要设定 Left、Top 属性以决定座标位置
假 设 我 们 执 行 了 以 下 叙 述 :
Load Text1(1)
Load Text1(3)
则 Text1 阵 列 的「值」元 素 可 以 表 达 成 图 -13:
至 於 破 坏 Text1 阵 列 中 的 某 一 个 控 制 元 件 , 方 法 则 是 :
Unload Text1(I)
以 上 被 破 坏 之 控 制 元 件 必 须 是 利 用 程 式 建 立 出 来 的
Text1(I), 假 设 Text1(0) 是 设 计 阶 段 就 已 经 布 置 在 表 单 上 面
的 控 制 元 件 , 则「Unload Text1(0)」将 会 产 生 错 误 。
在「建 立 具 体 物 件 的 几 个 方 法」的 段 落 中 , 我 们 介 绍 过「Set 物 件 变 数 1 = 物 件 变 数 2」的 叙 述 , 此 一 叙 述 的 作 用 是 复 制 物 件 变 数 2 的 具 体 物 件 给 物 件 变 数 1, 在 控 制 元 件 之 中 , 也 有 类 似 的 叙 述「Set 物 件 变 数 名 =控 制 元 件 名」, 例 如 :
Dim X As Object
Set X = Text1
但 它 的 作 用 不 是「复 制」Text1 的 具 体 物 件 给 X, 而 是 将 Text1 的 具 体 物 件 与 X 的「值」元 素 产 生 连 结 关 系 , 如 图 -14:
也 就 是 说 ,「Set X = Text1」并 不 会 建 立 具 体 物 件 , 而 执 行 此 一 叙 述 之 後 , X 与 Text1 指 的 将 是 同 一 个 具 体 物 件 , 所 以 以 下 叙 述 会 将 Text1 的 内 容 变 成 "ChangeIt!":
X.Text = "ChangeIt!"
' 作用相当於 Text1.Text = "ChangeIt!"
表 单 也 是 物 件 , 但 它 又 跟 标 准 物 件 及 控 制 元 件 又 有 些 出 入 , 以 下 让 我 们 来 比 较 几 个 操 作 表 单 的 叙 述 :
◆ Load FormX: 载 入 FormX。 与「Load 控 制 元 件 (I)」不 同 的 是 ,「Load FormX」只 能 载 入 既 有 的 表 单 , 而 无 法 动 态 地 建 立 表 单 。 此 外 请 注 意 , 载 入 并 不 等 於 显 示 出 来 , 若 要 显 示 出 来 还 要 执 行 以 下 叙 述 :
FormX.Visible = True 或
FormX.Show
◆ FormX.Show: 显 示 表 单 , 若 表 单 尚 未 载 入 , 则 此 一 叙 述 会 先 载 入 表 单 再 显 示 。
◆ Unload FormX: 载 出 表 单 。
◆ Set X = New FormX: 复 制 FormX 的 具 体 物 件 给 物 件 变 数 X, 执 行 此 一 叙 述 後 , X 与 FormX 为 两 个 独 立 的 物 件 。 (注 : 想 要 将 X 所 指 到 的 表 单 显 示 出 来 , 还 是 要 将 X.Visible 设 定 为 True)
◆ Set X = FormX: 将 X 指 到 FormX 的 具 体 物 件 , 也 就 是 说 , X 与 FormX 指 的 是 同 一 个 表 单 物 件 , 举 例 来 说 , 若 执 行 此 一 叙 述 後 , 接 着 又 执 行「X.Caption = "NewTitle"」, 则 FormX 的 标 题 将 会 变 成 "NewTitle"。
◆ Set X = Nothing: 将 X 所 指 到 的 表
单 具 体 物 件 归 还 给 系 统 。
本 期 介 绍 了 变 数 及 物 件 在 系 统 内 部 的 组 成 , 虽 然 没 有 程 式 设 计 的 技 巧 , 却 是 改 善 程 式 体 质 不 可 或 缺 的 观 念 。 了 解 变 数 及 物 件 的 组 成 , 就 好 像 了 解 血 液 是 由 红 血 球 、 白 血 球 、 血 小 板 … 所 组 成 的 一 样 , 但 血 液 不 是 静 止 的 , 同 样 的 , 变 数 及 物 件 在 程 式 中 也 不 是 静 止 的 , 静 止 的 变 数 及 物 件 是 没 有 bug 的 , 唯 有 到 处 流 窜 的 变 数 及 物 件 才 会 造 成 程 式 的 错 误 , 下 一 期 笔 者 将 介 绍 变 数 与 物 件 在 程 式 中 的 流 窜 模 式 。