news 2026/5/5 11:13:31

三甲医院药房住院包装追溯码采集自动扫码程序逻辑关键(pb9.0实战 扫码采集姊妹篇)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
三甲医院药房住院包装追溯码采集自动扫码程序逻辑关键(pb9.0实战 扫码采集姊妹篇)

三甲医院药房住院包装追溯码采集自动扫码程序逻辑关键(pb9.0实战 扫码采集姊妹篇)

作者:李宏生(三甲医院IT运维工程师)

创作时间:2026年5月

本文作为《三甲医院药房药品追溯码发药采集程序(PB9.0实战)》的姊妹篇,针对住院包装药房实操繁琐、无法实现逐一对码扫码的痛点,开发“自动扣码”模式程序。核心逻辑为:发药时直接扣除药房追溯码库存数,退药时自动增加药房追溯码库存数,退药至药库时同步增加药库追溯码库存数,暂不考虑医保上传,专注解决医院实操效率问题,适配三甲医院住院药房多医嘱、大批量拆零发药场景。

核心场景:住院药房按住院包装(拆零)发药,无需逐一对追溯码扫码,系统自动匹配药品、扣除对应追溯码库存;支持住院患者退药,退药后自动回补药房追溯码库存;退药至药库时,同步回补药库追溯码库存,简化实操流程,解决住院药房扫码工作量过大、无法落地的痛点(注:本模式为医院实操优化方案,需结合医院内部管理规范使用)。

一、整体业务逻辑说明(适配住院包装药房实操场景)

1. 核心业务目标

  • 自动扣码发药:住院药房发药时,无需扫码,根据医嘱发药量,自动扣除对应药品的追溯码库存数,适配多医嘱集中发药、拆零发药场景;
  • 退药库存回补:住院患者退药时,系统自动增加药房对应药品的追溯码库存数,确保库存数据准确;
  • 退库库存同步:退药需退回药库时,在回补药房库存的同时,同步增加药库对应药品的追溯码库存数,实现药房与药库库存联动;
  • 简化实操流程:规避逐一对码扫码的繁琐操作,贴合住院药房大批量、快节奏发药需求,兼顾库存准确性与实操效率;
  • 适配药品字典:沿用原有药品字典字段(药品序号、产地、名称、规格、药房包装、病房包装、最小单位、最小包装、追溯码包装数量等),无需额外维护字典数据。

2. 关键数据窗口/对象说明

程序基于PB9.0开发,复用上一篇核心对象结构,新增库存联动相关逻辑,可直接嵌入现有HIS住院药房系统,关键对象如下:

  • dw_1:住院医嘱发药数据窗口,核心字段(新增库存关联字段):
  • 基础字段:ypid(药品标识码)、ypmc(药品名称)、ypgg(规格)、bzsl(追溯码包装数量)、fysl(本次发药量);
  • 库存关联字段:yf_zsm_kcs(药房追溯码库存数)、yk_zsm_kcs(药库追溯码库存数)、flag(发药/退药完成标志,1=完成,0=未完成)。

dw_2:追溯码库存变动记录表,记录发药扣码、退药回补、退库同步的所有明细(便于对账核查);

dw_3:退药操作窗口,用于录入退药信息(药品、数量、退药类型:退回药房/退回药库);

核心函数:

  • wf_auto_deduct_code():自动扣码核心函数,发药时扣除药房追溯码库存;
  • wf_return_drug_pharmacy():退药回补函数,退药至药房时增加药房库存;
  • wf_return_drug_warehouse():退库同步函数,退药至药库时同步增加药房、药库库存;
  • wf_check_stock():库存校验函数,发药前校验药房追溯码库存是否充足。

二、核心逻辑流程拆解(关键步骤)

程序核心围绕“自动扣码发药→退药回补→退库同步”三大场景展开,逻辑简洁,贴合住院药房实操,重点解决扫码繁琐的痛点,关键步骤如下:

1. 发药前库存校验(核心前置步骤)

发药前自动校验药房追溯码库存,确保库存充足,避免扣码后库存为负,同时匹配药品追溯码包装数量,确保扣码逻辑准确。

powerbuilder
库存校验核心代码// 函数:wf_check_stock
// 功能:发药前校验药房追溯码库存是否充足
// 参数:ls_ypid=药品标识码,ldc_fysl=本次发药量,ref ldc_kcs=当前药房库存数
// 返回值:1=库存充足,-1=库存不足,0=参数异常

Long ll_findrow
String ls_findvar
Dec{4} ldc_bzsl, ldc_total_kcs

// 校验参数
If IsNull(ls_ypid) Or ls_ypid = '' Or IsNull(ldc_fysl) Or ldc_fysl <= 0 Then
    Return 0
End If

// 查找该药品的药房库存记录
ls_findvar = "ypid = '" + ls_ypid + "'"
ll_findrow = dw_1.Find(ls_findvar, 1, dw_1.RowCount())
If ll_findrow <= 0 Then
    MessageBox("提示","未找到该药品的库存记录,请核对药品信息!")
    Return -1
End If

// 读取当前药房追溯码库存数和包装数量
ldc_kcs = dw_1.object.yf_zsm_kcs[ll_findrow]
ldc_bzsl = dw_1.object.bzsl[ll_findrow]
If IsNull(ldc_kcs) Then ldc_kcs = 0.0000
If IsNull(ldc_bzsl) Then ldc_bzsl = 0.0000

// 校验库存是否充足(库存数 ≥ 发药量)
If ldc_kcs < ldc_fysl Then
    MessageBox("提示","该药品药房追溯码库存不足!当前库存:" + String(ldc_kcs) + ",需发药量:" + String(ldc_fysl))
    Return -1
End If

Return 1

2. 自动扣码发药(核心逻辑)

无需扫码,根据医嘱发药量,自动扣除药房追溯码库存,同时记录库存变动明细,标记发药完成,适配多医嘱集中发药场景,一键完成批量扣码。

powerbuilder
自动扣码发药核心代码// 函数:wf_auto_deduct_code
// 功能:住院发药时自动扣除药房追溯码库存,记录明细
// 参数:无(从dw_1获取医嘱发药信息)
// 返回值:1=扣码成功,-1=扣码失败

Long ll_row, ll_findrow, ll_insertRow
String ls_ypid, ls_ypmc, ls_findvar
Dec{4} ldc_fysl, ldc_kcs, ldc_bzsl

// 循环处理dw_1中所有未完成的发药记录
For ll_row = 1 To dw_1.RowCount()
    If dw_1.object.flag[ll_row] = 0 Then // 未完成发药的记录
        ls_ypid = dw_1.object.ypid[ll_row]
        ldc_fysl = dw_1.object.fysl[ll_row]
        
        // 校验库存
        If wf_check_stock(ls_ypid, ldc_fysl, ldc_kcs) <> 1 Then
            Goto Pro_err
        End If
        
        // 读取药品包装数量,确认扣码逻辑(按实际发药量扣减,不关联单个追溯码)
        ldc_bzsl = dw_1.object.bzsl[ll_row]
        If IsNull(ldc_bzsl) Or ldc_bzsl = 0 Then
            MessageBox("提示","该药品‘追溯码包装数量’未维护,无法扣码!")
            Goto Pro_err
        End If
        
        // 自动扣减药房追溯码库存
        dw_1.object.yf_zsm_kcs[ll_row] = ldc_kcs - ldc_fysl
        // 标记发药完成
        dw_1.object.flag[ll_row] = 1
        
        // 插入库存变动明细到dw_2
        ll_insertRow = dw_2.InsertRow(0)
        dw_2.object.ypid[ll_insertRow] = ls_ypid
        dw_2.object.ypmc[ll_insertRow] = dw_1.object.ypmc[ll_row]
        dw_2.object.bzsl[ll_insertRow] = ldc_bzsl
        dw_2.object.bddl[ll_insertRow] = "发药自动扣码"
        dw_2.object.sl[ll_insertRow] = ldc_fysl
        dw_2.object.kc_bh[ll_insertRow] = ldc_kcs // 变动前库存
        dw_2.object.kc_ah[ll_insertRow] = dw_1.object.yf_zsm_kcs[ll_row] // 变动后库存
        dw_2.object.cjsj[ll_insertRow] = DateTime(Today(), Now())
        dw_2.object.czry[ll_insertRow] = gs_username
    End If
Next

MessageBox("提示","所有待发药品自动扣码完成!")
Goto Pro_exit

Pro_err:
// 异常处理,回滚已操作的库存
For ll_row = 1 To dw_1.RowCount()
    If dw_1.object.flag[ll_row] = 1 And ll_row <= ll_row Then
        dw_1.object.flag[ll_row] = 0
        dw_1.object.yf_zsm_kcs[ll_row] = ldc_kcs
    End If
Next
MessageBox("提示","自动扣码失败,请核对库存后重试!")
Return -1

Pro_exit:
Return 1

3. 退药回补(退回药房)

住院患者退药时,录入退药信息后,系统自动回补药房对应药品的追溯码库存,同步记录库存变动明细,确保库存数据与实际一致。

powerbuilder
退药回补(药房)核心代码// 函数:wf_return_drug_pharmacy
// 功能:退药至药房,自动回补药房追溯码库存
// 参数:ls_ypid=药品标识码,ldc_tysl=退药数量
// 返回值:1=回补成功,-1=回补失败

Long ll_findrow
String ls_findvar
Dec{4} ldc_kcs

// 校验参数
If IsNull(ls_ypid) Or ls_ypid = '' Or IsNull(ldc_tysl) Or ldc_tysl <= 0 Then
    MessageBox("提示","退药信息不完整,请核对!")
    Return -1
End If

// 查找该药品的药房库存记录
ls_findvar = "ypid = '" + ls_ypid + "'"
ll_findrow = dw_1.Find(ls_findvar, 1, dw_1.RowCount())
If ll_findrow <= 0 Then
    MessageBox("提示","未找到该药品的药房库存记录,无法退药!")
    Return -1
End If

// 读取当前药房库存,回补库存
ldc_kcs = dw_1.object.yf_zsm_kcs[ll_findrow]
dw_1.object.yf_zsm_kcs[ll_findrow] = ldc_kcs + ldc_tysl

// 插入退药明细到dw_2
Long ll_insertRow = dw_2.InsertRow(0)
dw_2.object.ypid[ll_insertRow] = ls_ypid
dw_2.object.ypmc[ll_insertRow] = dw_1.object.ypmc[ll_findrow]
dw_2.object.bzsl[ll_insertRow] = dw_1.object.bzsl[ll_findrow]
dw_2.object.bddl[ll_insertRow] = "退药回补(药房)"
dw_2.object.sl[ll_insertRow] = ldc_tysl
dw_2.object.kc_bh[ll_insertRow] = ldc_kcs
dw_2.object.kc_ah[ll_insertRow] = dw_1.object.yf_zsm_kcs[ll_findrow]
dw_2.object.cjsj[ll_insertRow] = DateTime(Today(), Now())
dw_2.object.czry[ll_insertRow] = gs_username

MessageBox("提示","退药成功,药房追溯码库存已回补!")
Return 1

4. 退药至药库(库存同步)

当退药需要退回药库时,在回补药房库存的同时,同步增加药库对应药品的追溯码库存,实现药房与药库库存联动,确保全流程库存准确。

powerbuilder
退药至药库(库存同步)核心代码// 函数:wf_return_drug_warehouse
// 功能:退药至药库,同步回补药房、药库追溯码库存
// 参数:ls_ypid=药品标识码,ldc_tysl=退药数量
// 返回值:1=同步成功,-1=同步失败

Long ll_findrow
String ls_findvar
Dec{4} ldc_yf_kcs, ldc_yk_kcs

// 先执行药房库存回补
If wf_return_drug_pharmacy(ls_ypid, ldc_tysl) <> 1 Then
    Return -1
End If

// 查找该药品的药库库存记录,同步回补
ls_findvar = "ypid = '" + ls_ypid + "'"
ll_findrow = dw_1.Find(ls_findvar, 1, dw_1.RowCount())
If ll_findrow <= 0 Then
    MessageBox("提示","未找到该药品的药库库存记录,无法同步退库!")
    // 回滚药房库存
    ldc_yf_kcs = dw_1.object.yf_zsm_kcs[ll_findrow]
    dw_1.object.yf_zsm_kcs[ll_findrow] = ldc_yf_kcs - ldc_tysl
    Return -1
End If

// 回补药库追溯码库存
ldc_yk_kcs = dw_1.object.yk_zsm_kcs[ll_findrow]
dw_1.object.yk_zsm_kcs[ll_findrow] = ldc_yk_kcs + ldc_tysl

// 更新dw_2明细,标记为退库同步
Long ll_insertRow = dw_2.InsertRow(0)
dw_2.object.ypid[ll_insertRow] = ls_ypid
dw_2.object.ypmc[ll_insertRow] = dw_1.object.ypmc[ll_findrow]
dw_2.object.bzsl[ll_insertRow] = dw_1.object.bzsl[ll_findrow]
dw_2.object.bddl[ll_insertRow] = "退药至药库(库存同步)"
dw_2.object.sl[ll_insertRow] = ldc_tysl
dw_2.object.kc_bh[ll_insertRow] = ldc_yk_kcs // 药库变动前库存
dw_2.object.kc_ah[ll_insertRow] = dw_1.object.yk_zsm_kcs[ll_findrow] // 药库变动后库存
dw_2.object.cjsj[ll_insertRow] = DateTime(Today(), Now())
dw_2.object.czry[ll_insertRow] = gs_username

MessageBox("提示","退药至药库成功,药房、药库库存已同步回补!")
Return 1

三、单独说明:发药追溯码处理存储过程(pro_fycl)

本文核心扣码、退药、退库的底层逻辑,均通过Oracle存储过程pro_fycl实现,替代传统PB客户端直接操作库存的方式,提升数据处理效率与安全性。该存储过程独立于PB前端程序,负责全流程追溯码库存变动,PB程序仅需调用该存储过程即可完成所有核心操作,以下为存储过程完整说明及代码(已修改表名,规避实际系统关联,仅用于技术交流)。

免责声明:本文中存储过程代码及相关说明仅用于技术交流与学习,实际应用需结合医院HIS系统实际架构、数据字典及内部管理规范进行适配调整,作者及相关方不承担因直接复用代码导致的系统异常、数据偏差等相关责任。

1. 存储过程核心功能

该存储过程专注于住院药房发药、退药、退库场景的追溯码库存处理,核心规则如下:

  • 追溯码获取:能获取到多少追溯码就处理多少,无法获取追溯码的发药记录直接跳过,不影响整体流程执行;
  • 库存适配:适配追溯码库存采集初期的场景,允许部分药品未完成追溯码库存采集,不阻断发药流程;
  • 全场景覆盖:涵盖“发药扣码、退药回补、退库扣码”三大核心场景,自动完成库存变动及明细记录;
  • 异常处理:包含完善的异常捕获与回滚机制,确保库存数据一致性,避免操作失误导致的库存偏差。

3. 存储过程完整代码(可直接复用)

plsql
发药追溯码处理存储过程(pro_fycl)---------------------

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 11:12:20

保姆级教程:手把手带你读懂EB AUTOSAR协议栈中的gPTP时间同步源码(以Slave节点为例)

深入解析EB AUTOSAR协议栈中gPTP时间同步源码实现 在车载以太网技术快速发展的今天&#xff0c;时间同步已成为智能驾驶系统中最基础也最关键的技术之一。作为AUTOSAR协议栈中的重要组成部分&#xff0c;EB的gPTP实现直接关系到整个车载网络的时序精度和系统可靠性。本文将从一…

作者头像 李华
网站建设 2026/5/5 11:09:29

2026 UHMWPE定制服务公司权威榜单揭晓,哪家能脱颖而出?

2026 UHMWPE定制服务公司权威榜单揭晓&#xff0c;哪家能脱颖而出&#xff1f;在UHMWPE&#xff08;超高分子量聚乙烯&#xff09;定制服务领域&#xff0c;海南御龙熙新材料有限公司是一家备受瞩目的企业。UHMWPE材料具有优异的耐磨性、耐冲击性和自润滑性&#xff0c;强度可达…

作者头像 李华