[返回]

摘自微电脑世界

下拉数据窗口dddw在PB中的应用

北京燕化集团化工二厂动力处 刘荣芳

    作 为 目 前 比 较 流 行 的 数 据 库 前 端 开 发 工 具,PowerBuilder 显 著 的 一 个 特 点 就 是 其 数 据 窗 口(DataWindow) 技 术, 为 了 更 灵 活 地 使 用 数 据 窗 口,PB 还 提 供 了 下 拉 数 据 窗 口(DropDownDataWindow)。 为 便 于 说 明, 以 下 面 这 个DataWindow 为 例。 其 中 灰 显 的 字 段 表 示该 字 段 来 自 其 它 的 表。
pb116_1.gif (15155 字节)

  1、 在 创 建 录 入 界 面 时, 各 录 入 项 的 内 容 往 往 是 上 下 关 联 的, 在 上 图 中,“ 设 备 位 号(location_no)” 录 入 项 的 可 选 范 围 由 前 录 入 项“ 部 门 代 码(dept_no)” 和“ 分 类 代 码(class_id)” 的 当 前 值 决 定。 字 段“ 设 备 位 号” 的 属 性Edit 中 的EditStyle 为DDDW, 其 对 应 的DataWindow 的SQL 脚 本 为:



SELECT equipment_account.location_noFROM equip_item, equipment_account

WHERE (equipment_account.equip_id= equip_item.equip_id )

AND ( ( equipment_account.dept_no = :d_no ) AND ( equip_item.class_id = :c_id ) )

ORDER BY equipment_account.location_no ASC

  其 中d_no 和c_id 为 检 索 参 数(retrieve argument)。

  为 了 能 够 动 态 地 改 变DDDW 检 索 出 来 的 值, 首 先 要 获 得 该DDDW 的 控 制 句 柄, 在 窗 口 中 定 义 一 实 例 变 量(Instance Variable):datawindowchildd_ch 。 在 打 开 上 面 这 个DW 之 前 先 创 建 子 数 据 窗 口:( 在 窗 口 的open 脚 本 中 加 入)

< pre >

dw_1.getchild("equipment_account_location_no",d_ch)

d_ch.settransobject(sqlca)

if d_ch.retrieve(d_no,c_id) < 1 then

d_ch.insertrow(0)/* 每 次 检 索 主 窗 口 之 前,

系 统 先 检 索 下 拉 窗 口。 此 语 句 抑 制location_no

列 下 拉 窗 口 要 求 输 入 检 索 条 件d_no,c_id 的 窗 口 的 出 现*/

else

        lo_no=d_ch.getitemstring(1,1)/*

有 数 据 则 取DDDW 中 第 一 个 值*/

il_cr = dw_1.retrieve(d_no,lo_no)/*

检 索 上 面 这 个DW, 返 回 行 号 放 在il_cr 中*/

...

end if

  为 了 能 获 得“ 设 备 位 号” 的 值, 在 上 面 这 个DW 中 的itemchanged 事 件 中 判 断 用 户 是 否 修 改DEPT_NO 和CLASS_ID 的 值, 若 修 改 则 触 发 以 下 脚 本 的 执 行:

if dwo.name="equipment_account_dept_no" then/*

用 户 改 变 部 门 代 码 字 段*/   

    de_no=trim(data)/*data 为 获 得 焦 点 的 字 段 的 值*/

    de_no1 = de_no

        dw_1.setcolumn ("equip_item_class_id")/*

将 光 标 移 到“ 分 类 代 码” 字 段, 让 用 户 选 择

dw_1.setitem ( row, "equip_item_class_id",""

end if

if dwo.name="equip_item_class_id" then/* 用 户 改 变 分 类 代 码 字 段*/

DataWindowChildd_ch

dw_1.GetChild("equipment_account_location_no",d_ch)

d_ch.settransobject(sqlca)

if de_no="" then             

de_no=de_no1/* 如 果 用 户 直 接 改 变“ 分 类 代 码” 的 值,

则de_no 的 值 为 空, 所 以 必 须 有 此 赋 值 语 句*/

cl_id = data

d_ch.retrieve(de_no,data)/* 检 索“ 设 备 位 号” 下 拉 窗 口     */

dw_1.setcolumn ("equipment_account_location_no")")/* 将 光 标 移 到

“ 设 备 位 号” 字 段, 让 用 户 选 择*/

dw_1.setitem ( row, "equipment_account_location_no","" ))/* 将 该 字 段 设 为 空*/

end if

if dwo.name="equipment_account_location_no" then/* 用 户 改 变

“ 设 备 位 号” 字 段*/

lo_no=trim(data)

if de_no="" then             

de_no = de_no1

if cl_id="" then            

cl_id = cl_id1/* 如 果 用 户 直 接 改 变“ 设 备 位 号” 的 值,

则de_no 和cl_id 的 值 均 为 空, 所 以 必 须 有 这 两 个 赋 值 语 句*/

il_cr = dw_1.retrieve(de_no,lo_no) /* 检 索 上 面 这 个DW,

返 回 行 号 放 在il_cr 中*/

            ...

end if

  这 样, 只 要 用 户 改 变“ 部 门 代 码” 和“ 分 类 代 码” 录 入 项 时, 字 段“ 设 备 位 号” 的 值 会 自 动 变 化。

  2、 上 面 这 个DW 要 求 厂 级 设 备 员 可 以 检 索 各 个 下 属 部 门 的 设 备, 而 各 部 门 设 备 员 只 能 检 索 本 部 门 的 设 备, 不 能 检 索 别 的 部 门 的 设 备, 即 厂 级 设 备 员 可 下 拉 字 段“ 部 门 代 码” 的 数 据 窗 口, 其 它 设 备 员 不 能 下 拉 该 字 段, 解 决 方 法 是:

  // 根 据 用 户 名 称 决 定 部 门 代 码DDDW, 全 局 变 量 用 户 名 称 放 在gs_user_name 中,sb 为 厂 级 设 备 员 的 用 户 名 称, 全 局 变 量d_no 存 放 各 用 户 对 应 的 部 门 代 码

if not gs_user_name = "sb"then dw_1.settaborder

("equipment_account_dept_no",0)

dw_1.object.equipment_account_dept_no[li_Row] = d_no

de_no1 = d_no

...

  即 用 户 名 不 为“sb” 时, 字 段“ 部 门 代 码” 的tab 值 设 为0, 用 户 不 能 下 拉 此 数 据 窗 口, 并 将 该 字 段 的 值 赋 为d_no, 用 此 方 法 可 实 现 数 据 的 安 全。

  3、 在 上 面 这 个DW 中 的“ 分 类 代 码” 字 段 中, 要 求 仪 表 车 间 设 备 员 只 能 检 索 仪 表 类 的 设 备, 其 它 车 间 设 备 员 只 检 索 非 仪 表 类 的 设 备, 而 厂 级 设 备 员 检 索 所 有 类 别 的 设 备。 一 般 情 况 下, 类 似 的 问 题 采 用 检 索 参 数 解 决, 可 在 此 处, 分 类 代 码 所 在 的 表 中 没 有 与 用 户 名 称 相 联 系 的 字 段, 无 法 采 用 检 索 参 数, 解 决 方 法 如 下: 字 段“ 分 类 代 码” 的 属 性Edit 中 的EditStyle 为DDDW, 其 对 应 的DataWindow 为D_DDDW_CLASS_ID, 在DataWindow painter 中 打 开 此DDDW, 从 菜 单 条 选 择 Rows →Data 后 单 击Retrieve 按 钮, 检 索 出 所 有 数 据 后, 删 除 仪 表 类 的 数 据 后 单 击OK, 再 存 盘 退 出。 另 做 一DW, 取 名 为D_DDDW_CLASS_ID_I, 和 上 一DDDW 一 样, 只 是 在 检 索 出 所 有 数 据 后, 删 除 非 仪 表 类 的 数 据。 在 窗 口 的open 事 件 中 写 入 如 下 脚 本:

  // 根 据 用 户 名 称 决 定 分 类 代 码DDDW,sb 为 厂 级 设 备 员 的 用 户 名 称, yb 为 仪 表 车 间 设 备 员 的 用 户 名 称, 仪 表 采 用:D_DDDW_CLASS_ID_I

if (gs_user_name = "yb") or (gs_user_name = "sb") then

    datawindowchild idwc_c_id

    dw_1.object.equip_item_class_id.dddw.name = "d_dddw_class_id_i"

    // 改 变 参 数 后 必 须 重 新getchild 使 改 变 后 的 属 性 生 效

    dw_1.getchild ("equip_item_class_id",idwc_c_id)

    idwc_c_id.settransobject (sqlca)

    if gs_user_name = "sb" then idwc_c_id.retrieve()

end if

  这 样, 其 他 车 间 的 设 备 员 以 自 己 各 自 的 用 户 名 进 入 系 统 后, 程 序 跳 过 上 述 脚 本, 字 段“ 分 类 代 码” 取 的 是D_DDDW_CLASS_ID 中 非 仪 表 类 的 数 据; 仪 表 车 间 的 设 备 员 取 的 是D_DDDW_CLASS_ID_I 中 仪 表 类 的 数 据, 厂 级 设 备 员 进 入 系 统 后, 由 于 重 新 检 索DDDW, 取 的 是D_DDDW_CLASS_ID_I 中 所 有 数 据。

  4、 一 般 情 况 下 多 利 用DDDW 让 用 户 选 择 数 据 以 供 查 询 用, 如 上 述“ 部 门 代 码”、“ 分 类 代 码”、“ 设 备 位 号” 等 字 段。 如 果 在 查 询 出 数 据 后, 要 求 查 出“ 技 术 参 数”、“ 单 台 技 术 参 数”, 如 上 面 这 个DW 所 示, 即 以 该 字 段 的 值 为 检 索 参 数 检 索 另 外 两 个 表 中 的 内 容, 这 两 个 表 的 结 构 如 下:
     

equip_parameter 设 备 技 术 参 数 值 single_parameter 单 台 设 备 技 术 参 数
equip_id 同 类 设 备 编 码 equip_id 同 类 设 备 编 码
tech_item 技 术 参 数 项 tech_item0 技 术 参 数 项
item_value 技 术 参 数 值 item_value 技 术 参 数 值
seq_no 序 号 seq_no 序 号
    dept_no 部 门 代 码
    location_no 设 备 位 号


  以“ 技 术 参 数(equipment_account_equip_id)” 为 例 说 明: 字 段“ 技 术 参 数” 的 属 性Edit 中 的EditStyle 为DDDW, 其 对 应 的DataWindow 的SQL 脚 本 为:



SELECT equip_parameter.equip_id,

equip_parameter.tech_item,

        equip_parameter.item_value,

    equip_parameter.seq_no

FROM equip_parameter

WHERE equip_parameter.equip_id = :equip_id


  其 中equip_id 为 检 索 参 数(retrieve argument)。 要 实 现 上 述 目 标 的 技 术 要 点 是: 在 主DW 检 索 出 数 据 后, 马 上 取 出 该 字 段 的 值 传 给 该 字 段 的DDDW, 具 体 脚 本 如 下:

dw_1.getchild("equip_item_equip_id",idw_child1)/* idw_child1 为 实 例 变 量*/

    idw_child1.SetTransObject (sqlca)

    if idw_child1.rowcount()=0 then          idw_child1.insertrow(0)

    ... 检 索 主DW...

// 传 递 参 数

    eq_id = dw_1.getitemstring(il_cr,"equipment_account_equip_id")

    idw_child1.retrieve(eq_id)

  这 样, 达 到 了 在 一 个DW 中 可 看 到 多 类 信 息 的 目 的, 更 方 便 了 用 户 的 使 用。

  以 上 是 我 平 时 开 发 程 序 时 积 累 的 一 点 经 验, 只 要 我 们 多 动 脑 筋、 多 琢 磨, 一 定 可 以 发 现 更 多 的 技 巧。 上 述 这 些 方 法 在Windows95 平 台 上、PowerBuilder5.0 上 实 现, 全 部 可 以 正 确 运 行。