医药GSP管理系统
摘要
【摘要】
中国加入WTO后,药品经营企业要与国际接轨,靠的就是GSP认证。药品经营企业通过GSP认证,这是药品管理法制化、科学化和规范化的要求,是国家加大对药品经营结构调整力度的要求,是药品经营企业进入国际市场、参与市场竞争的先决条件。
本章将通过医药GSP管理系统的实例,分别从医药管理系统和GSP管理系统两个方面介绍如何实现医药GSP管理系统。
【关键词】医药GSP管理系统
目录
摘要.... 2
目录.... 3
0 引言.... 1
1 可行性分析.... 1
2 总体设计.... 1
2.1 项目规划... 1
2.2 系统功能结构... 1
2.3 设计目标... 2
3 系统设计.... 2
3.1 开发及运行环境... 2
3.2 数据库设计... 2
4 主要功能模块设计.... 2
4.1 程序主界面的设计... 2
4.2 药品信息管理... 81
4.3 入库登记... 198
4.4 销售开单... 339
4.5 操作员权限的设置... 424
附录A 参考文献.... 539
附录B 数据表.... 607
附录C 文件架构.... 693
0 引言
药品在其生产、经营和使用的全过程中,由于内外因素的影响,随时都有可能发生质量事故,必须在所有这些环节上采取严格的措施,才能从根本上保证药品质量。因此,国内外为保证药品质量,确保用药安全有效,均制定了一系列质量法规。其中GSP是一系列质量控制中不可缺少的重要一环。
1 可行性分析
面对医药经营企业在日常管理过程中出现的各种情况,医药GSP管理系统在开发时,应能够达到以下目标:
q 全面、规范、完善的基础信息设置。
q 合理的权限分配。
q 全方位的快速查询,提高工作效率。
q 具有强大的报表打印功能。
q 系统具有数据备份及数据恢复功能,能够保证系统数据的安全性。
q 对药品的质量、档案、养护以及药品的停售和库房的温湿度进行系统管理。
q 从药品的采购、入库、销售、到库存形成一套严密、科学、完善的管理体系。
2 总体设计
2.1 项目规划
本系统属于小型的数据库系统,可以对中小型企业进销存进行有效管理。通过本系统可以达到以下目标:
q 灵活的运用表格批量录入数据,使信息传递更快捷。
q 系统采用人机对话方式,界面美观友好,信息查询灵活、方便,数据存储安全可靠。
q 与供应商和代理商账目清晰。
q 实施强大的后台监控功能。
q 功能强大的月营业分析。
q 实现各种查询,如定位查询、模糊查询等。
q 实现商品进货分析与统计、销售分析与统计、商品销售成本明细等功能。
q 强大的库存预警功能,尽可量地减少商家不必要的损失。
q 实现灵活的打印功能。
q 对用户输入的数据,系统进行严格的数据检验,尽可能排除人为的错误。
q 系统最大限度地实现了易安装性、易维护性和易操作性。
2.2 系统功能结构
本系统共分9大部分、41个完整的功能模块。系统结构图如图1所示。若图片无法显示请联系QQ3710167
医药GSP管理系统
图1 医药GSP管理系统
2.3 设计目标
本系统是根据中小企业的实际需求而开发的,完全能够实现企业的会议视频管理,通过本系统可以达到以下目标:
q 系统运行稳定,安全可靠。
q 界面设计美观,人机交互界面友好。
q 信息查询灵活、方便、快捷、准确,数据存储安全可靠。
q 满足键盘和鼠标的双重操作,完全支持回车键。
q 信息安全保密。
3 系统设计
3.1 开发及运行环境
系统开发平台:Microsoft Visual FoxPro 6.0。
运行平台:Windows XP/ Windows 2000/ Windows 2003
分辨率:最佳效果1024×768像素
3.2 数据库设计
1.数据库概要说明
接下来的任务就是设计数据库。数据库在一个管理系统中占居非常重要的地位,数据库结构设计的好坏将直接影响系统的效率和实现的效果。本系统采用的是Visual FoxPro自带的数据库,数据库文件名为yygsy。
2.主要数据表的结构
数据库中的数据表请参见附录B。
4 主要功能模块设计
4.1 程序主界面的设计
软件界面是人与计算机之间的媒介。用户通过软件界面来与计算机进行信息交换。因此,软件界面的质量,直接关系到应用系统的性能能否充分发挥,尤其是主界面。例如本系统的主界面就改变了用户比较熟知的Windows传统风格,取而代之的是图形化的界面风格。程序启动后,通过系统登录界面的用户身份验证后,即可进入到程序主界面,医药GSP管理系统的主界面如图2所示。若图片无法显示请联系QQ3710167
图2 程序主界面运行结果
主界面担负着根据用户的权限执行系统所允许的用户操作的任务。其中系统的主导航菜单是通过一系列的笔者自定义的按钮实现的,功能子菜单是由ListView和ImageList控件实现的。为了使用户可以自行控制功能子菜单的显示或隐藏状态,程序中还加入了控制功能子菜单显示状态的按钮。系统主界面的具体讲解如下:
1.表单设计
(1)创建一个标准项目,名称为“医药GSP管理系统”,在该项目中利用Class_Frm类创建程序主界面表单,名称为DeskTop。
(2)在该表单中添加Button_Y控件、Label控件、Image控件、ImageList控件和ListView控件。
(3)设置表单、控件的属性,其重要属性如表1所示。
表1 重要属性及值
对象
属性
值
Class_Frm12
BorderStyle
0 – 无边框
Class_Frm12
ShowWindow
2 – 作为顶层表单
Class_Frm12
TitleBar
0 – 关闭
Class_Frm12
WindowState
2 – 最大化
ListView1
Appearance
0 – Flat
ListView1
BackColor
16777215
ListView1
BorderStyle
0 – None
ListView1
HideSelection
.F. – 假
2.代码设计
当创建一个子类时,子类中的方法自动从父类中继承,但是子类的方法会重载父类中的同名方法。当需要调用父类中的方法时,可以在子类中使用::范围操作符调用父类中的方法。
医药GSP管理系统
Class_frm::load &&在子类中引用父类的方法
程序中应用了API函数时,应在表单的Load事件中进行函数声明,代码如下:
Declare integer GetSystemMetrics in user32 integer nIndex &&API函数声明
在表单的Init事件中设置收缩后的功能子菜单的代码如下:
*设置收缩后的侧菜单
Thisform.Img_EB_1.height=Thisform.Height-300
Thisform.Img_B_1.Top=THisform.Height-Thisform.Img_b_1.Height-8
Thisform.Img_EB_1.visible=.f.
Thisform.Img_B_1.visible=.f.
Thisform.Img_C_1.visible=.f.
Thisform.Img_E_1.visible=.f.
在表单Init事件中利用ListView控件显示操作员的可用功能子菜单的代码如下:
*初始化ListView控件
Thisform.Listview1.BackColor=RGB(239,247,255)
This.Listview1.listitems.clear
this.listview1.view=2 &&设置视图显示方式
this.listview1.Icons=this.imagelist1.object
this.listview1.smallicons=this.imagelist1.object
&&添加列表项--根据操作员权限设置可用的功能项
Select Tab_User
Locate For 操作员=UserName
Select * From Tab_Purview Where 操作员编号=Tab_User.操作员编号 ;
Into Cursor Temp_Purview
Select 0
Select * From Tab_Function Where 上级编号=1 Into Cursor Temp_Function
Do While !EOF()
Select Temp_Function
key=Alltrim(Temp_Function.名称)
Select Temp_Purview
If Temp_Purview.&key.=.T.
=ThisForm.listview1.listitems.add(,,key,,1)
Endif
Select Temp_Function
SKIP
EndDo
在表单Activate事件中添加如下代码设置程序主界面根据屏幕分辨率自动设置大小。
thisform.width=GetSystemMetrics(0) &&获取屏幕的宽度
thisform.height=GetSystemMetrics(1)-24 &&获取屏幕的高度
Class_frm::Init &&在子类中引用父类的方法
通过ListView控件调用相应的表单的程序代码如下:
fname=alltrim(thisform.listview1.selecteditem.text)
do form form\&fname &&通过变量调入表单
在“销售管理”按钮的Button_Click事件中加入如下代码显示销售管理功能子菜单。
Thisform.Left_Title.Caption="销售管理"
Thisform.Listview1.listitems.clear &&清空ListView控件
&&添加列表项
Select Tab_User
Locat For 操作员=UserName
Select * From Tab_Purview Where 操作员编号=Tab_User.操作员编号 Into Cursor Temp_Purview
Select 0
Select * From Tab_Function Where 上级编号=3 Into Cursor Temp_Function
Do While !EOF()
Select Temp_Function
key=Alltrim(Temp_Function.名称)
Select Temp_Purview
If Temp_Purview.&key.=.T.
=ThisForm.listview1.listitems.add(,,key,,1)
Endif
Select Temp_Function
SKIP
EndDo
4.2 药品信息管理
用户单击导航功能按钮中的“基础信息管理”按钮,在功能子菜单中选择“药品信息管理”菜单项,进入“药品信息管理”界面,该界面运行结果如图3所示。若图片无法显示请联系QQ3710167
医药GSP管理系统
图3 药品信息管理运行结果
“药品信息管理”界面主要用于查询、添加、修改和删除药品信息;根据药品剂型自动生成药品编号;根据药品的通用名自动生成药品简称;可以利用记录定位按钮实现精确记录定位;支持快速浏览药品信息等功能。
1.表单设计
(1)在“医药GSP管理系统”项目中,利用Class_Frm类创建新表单,名称为“药品信息管理”。
(2)在表单中添加Text控件、Label控件、Pageframe控件、Edit控件、Combo控件、Grid控件和Shape控件(用于修饰界面)和Button_Y控件、Button_F控件。
(3)重要控件的重要属性如表2所示。
表2 重要属性及值
对象
属性
值
Class_Frm12
BorderStyle
0 – 无边框
Class_Frm12
TitleBar
0 – 关闭
Combo1
RowSource
Tab_DoseType.剂型
Combo1、Combo2、Combo4
RowSourceType
6 – 字段
Combo1、Combo2、Combo3、Combo5、Combo6
Style
2 - 下拉列表框
Combo2
RowSource
Tab_Unit.单位名称
Combo3、Combo6
RowSource
有,无
Combo5
RowSource
年,月,天
Combo5
RowSourceType
1 – 值
Text11
InputMask
9999
PF
PageCount
2
PF
TabStyle
1 – 非两端
(4)为表单创建方法程序List_Sele。
2.代码设计
由于在设计数据库时,遵循数据规范化原则,在药品信息表中生产厂家是以厂家编号字段存储,药品的库存上/下限信息保存在库存上下限表中,所以在显示药品信息时,需要应用SQL语句的内联接查询出药品的完整信息并显示在表格中,程序代码如下:
SELECT Tab_drug.药品编号, Tab_drug.通用名, Tab_drug.曾用名,Tab_drug.英文名,;
Tab_drug.简称, Tab_drug.剂型, Tab_drug.规格,Tab_drug.包装, Tab_drug.单位,;
Tab_drug.成份, Tab_drug.性状,Tab_drug.药理毒理, Tab_drug.适应症, Tab_drug.用法用量,;
Tab_drug.不良反应,Tab_drug.禁忌, Tab_drug.注意事项, Tab_drug.药物过量, Tab_drug.贮藏,;
Tab_drug.有效期, Tab_drug.有效期单位,Tab_drug.注册商标, Tab_drug.批准文号,;
Tab_wlunit.全称 AS 生产厂家, Tab_Wlunit.编号 AS 厂家编号,Tab_drug.产地,Tab_drug.备注,;
Tab_kc_confine.库存上限 AS 上限,Tab_kc_confine.库存下限 AS 下限;
FROM yygsp!tab_drug INNER JOIN yygsp!tab_wlunit ;
ON Tab_drug.生产厂家 = Tab_wlunit.编号;
INNER JOIN yygsp!tab_kc_confine ;
ON Tab_drug.药品编号 = Tab_kc_confine.药品编号 Into Cursor Temp_Drug
Thisform.PF.P2.Grid1.ColumnCount=-1 &&设置表格的列数数据表中的字段数
Thisform.PF.P2.Grid1.RecordSource="Temp_Drug"
在“添加”按钮的Button_Click事件中添加如下代码实现自动生成以“PJ”为标识的药品编号。
Set Procedure To Procedure\UsedPrg &&打开过程文件
Select Tab_Drug
*调用自定义函数生成药品编号
Thisform.PF.P1.text1.Value=AutoNO("Tab_Drug","药品编号","PJ","7","")
在Combo1的InteractiveChange事件中添加如下代码实现根据用户选择的剂型自动生成七位的药品编号。
Set Procedure To Procedure\UsedPrg &&打开过程文件
Select 剂型标识 From Tab_DoseType Where 剂型=This.Value Into Cursor Temp_D
Thisform.PF.P1.text1.Value=AutoNO("Tab_Drug","药品编号",Temp_D.剂型标识,"7",;
"Left(药品编号,2)=Alltrim(Temp_D.剂型标识)") &&调用自定义函数生成药品编号
在“厂家编号”文本框的LostFocus事件中实现用户输入厂家编号后,自动填入厂家名称,如果不存在则给予提示。
Select 全称 From Tab_WLUnit Where Alltrim(Tab_WLUnit.编号)=Alltrim(This.Value) ;
Into Cursor Temp_WLUnit
Go Top
If Eof()
Messagebox("无效的单位编号!",48,"系统提示:")
This.Value=""
This.Parent.Combo4.Setfocus
Else
This.Parent.Combo4.DisplayValue=Temp_WLUnit.全称
Endif
在“厂家名称”下拉列表框的InterActiveChange事件中添加如下代码实现自动填入厂家编号的功能。
Select Tab_WLUnit
Select 编号,全称 From Tab_WLUnit Where 全称=Alltrim(This.Value) Into Cursor Temp_WLUnit
If !Empty(Temp_WLUnit.编号)
This.Parent.Text5.Value=Alltrim(Temp_WLUnit.编号)
Endif
在“保存”按钮的Button_Click事件中的代码主要实现保存用户新添加的药品信息或修改后的药品信息,关键代码如下:
If Flag=1 &&单击“添加”按钮后单击“保存”按钮
Locat For 通用名=alltrim(Thisform.PF.P1.Text2.Value) And;
规格=alltrim(Thisform.PF.P1.Text8.Value) And;
剂型=alltrim(Thisform.PF.P1.Combo1.Value) And;
产地=alltrim(Thisform.PF.P1.Text1.Value)
If Found()
Messagebox("该药品信息已经添加!",48,"系统提示:")
Else
Insert into Tab_Drug Values(NO,TYName,CYName,YWName,JC,JX,GG,BZ,;
DW,CF,XZ,YLDL,SYZ,YFYL,BLFY,JJ,ZYSX,YWGL,ZC,YXQ,YXQDW,ZCSB,;
PZWH,cCD,SCCJ,Memo) &&保存药品信息
Insert into Tab_KC_confine Values(NO,0,SX,XX) &&保存药品库存上下限信息
Messagebox("药品信息添加成功!",48,"系统提示:")
Flag=0
Endif
Endif
If Flag=2 &&单击“修改”按钮后单击“保存”按钮
Update Tab_Drug Set 药品编号=NO,通用名=TYName,曾用名=CYName,英文名=YWName,;
简称=JC,规格=GG,包装=BZ,单位=DW,成份=CF,性状=XZ,药理毒理=YLDL,适应症=SYZ,;
用法用量=YFYL,不良反应=BLFY,禁忌=JJ,注意事项=ZYSX,药物过量=YWGL,贮藏=ZC,;
有效期=YXQ,有效期单位=YXQDW,注册商标=ZCSB,批准文号=PZWH,产地=cCD,;
生产厂家=SCCJ,备注=Memo Where 药品编号=NO &&修改药品信息
Update Tab_KC_confine Set 库存上限=SX,库存下限=XX Where 药品编号=NO
Messagebox("药品信息修改成功!",48,"系统提示:")
Flag=0
Endif
“删除”按钮主要实现判断所要删除的药品在库存中是否还有,如果没有则删除该药品信息和该药品的库存上下限信息,否则提示该药品信息不能删除。
在“查询”按钮的Button_Click事件中添加如下代码实现根据用户在控件中选择的查询条件进行查询,当用户选择“Like”操作符时,执行模糊查询。
QFields=Alltrim(Thisform.Combo1.Value)
Operate=Alltrim(Thisform.Combo2.Value)
QValue=Alltrim(Thisform.Text1.Value)
SELECT Tab_drug.药品编号, Tab_drug.通用名, Tab_drug.曾用名,Tab_drug.英文名,;
Tab_drug.简称, Tab_drug.剂型, Tab_drug.规格,Tab_drug.包装, Tab_drug.单位,;
Tab_drug.成份, Tab_drug.性状,Tab_drug.药理毒理, Tab_drug.适应症,;
Tab_drug.用法用量, Tab_drug.不良反应,Tab_drug.禁忌, Tab_drug.注意事项,;
Tab_drug.药物过量, Tab_drug.贮藏, Tab_drug.有效期, Tab_drug.有效期单位,;
Tab_drug.注册商标, Tab_drug.批准文号, Tab_wlunit.全称 AS 生产厂家,;
Tab_Wlunit.编号 AS 厂家编号,Tab_drug.产地,Tab_drug.备注,;
Tab_kc_confine.库存上限 AS 上限,Tab_kc_confine.库存下限 AS 下限;
FROM yygsp!tab_drug INNER JOIN yygsp!tab_wlunit ;
ON Tab_drug.生产厂家 = Tab_wlunit.编号;
INNER JOIN yygsp!tab_kc_confine ;
ON Tab_drug.药品编号 = Tab_kc_confine.药品编号 ;
Into Cursor Temp_Drug1
If Operate="Like"
*模糊查询
SELECT * FROM Temp_Drug1 Where &QFields. Like'%&QValue.%' Into Cursor Temp_Drug
Else
SELECT * FROM Temp_Drug1 Where &QFields. ='&QValue.' Into Cursor Temp_Drug
Endif
4.3 入库登记
用户单击导航功能按钮中的“采购/入库管理”按钮,在功能子菜单中选择“入库登记”菜单项,进入“入库登记”界面,该界面运行结果如图4所示。 若图片无法显示请联系QQ3710167
医药GSP管理系统
图5 销售开单运行结果
“销售开单”界面采用智能化表格式数据录入,实现一次销售多种药品的功能。程序中还加入了自动生成销售票号、自动计算合计金额等功能,为了方便用户操作,程序还提供了如下功能:当用户在“药品编号”列输入药品编号的前几个字符或按“PageDown”键,系统将自动利用列表框显示相关药品信息。使用“↓”键或“↑”键选择药品,按回车键该药品的基本信息自动添加到表格中。同时按照GSP认证的有关规定,在药品销售时还遵循“先进先出”原则。
1.表单设计
(1)在“医药GSP管理系统”项目中,利用Class_Frm类创建新表单,名称为“销售开单”。
(2)在表单中添加Text控件、Label控件、Combo控件、List控件、Grid控件、Shape控件(用于修饰界面)和Button_F控件。
(3)重要控件的重要属性如表4所示。
表4 重要属性及值
对象
属性
值
Combo1
RowSource
tab_jsfs.结算方式
Combo1、Combo2
RowSourceType
6 – 字段
List1
ColumnCount
6
List1
ColumnWidth
50,85,60,95,95,90
List1
ItemTips
.T. – 真
Grid1
ColumnCount
18
Grid1
DeleteMark
.F.
(4)为表单创建方法程序AddListValue。
2.代码设计
在Grid1.Column9.Text1控件(数量)的KeyPress事件中添加如下代码实现当用户按下回车键时,自动计算药品金额并判断库存数量,如果该批号的药品数量不足,则提示从下一批号销售,自动计算从下一批号销售的数量。
If nKeyCode=13
Option=Thisform.Grid1.Column9.Text1.Value*Thisform.Grid1.Column11.Text1.Value
Thisform.Grid1.Column12.Text1.Value=Option &&自动计算金额
Select Temp_YP
If Temp_YP.库存数量
CZ=This.Value-Temp_YP.库存数量
Messagebox("该批号药品的库存数量不足,需要从下一批号销售["+;
Alltrim(Str(CZ))+"]个。",48,"系统提示:")
This.Value=Temp_YP.库存数量
P_YPNO=Temp_YP.药品编号
P_SCPH=Temp_YP.生产批号
Dime Next_PH(1)
Next_PH=""
Select Top 1 生产批号 From Tab_KC Where 药品编号=P_YPNO And 生产批号>P_SCPH ;
Order By 生产批号 Into Array Next_PH
If Empty(Next_PH)
Messagebox("该药品无下一批号的产品,只能销售["+;
Alltrim(Str(Temp_YP.库存数量))+"]。",48,"系统提示:")
Else
P_SCPH=Next_PH
Endif
EndIf
Endif
“保存”按钮主要完成将销售信息分别保存在销售登记主表、销售登记备份表(在实现按销售票号进行销售退货时应用该表)和销售登记明细表中,并修改库存信息表和库存上下限表中的库存数量,并将销售事件插入库存明细表中,最后设置相应控件是否有效,其关键代码如下:
Select Temp_XS
If Thisform.Text6.value=0
Messagebox("请输入要销售的药品!",48,"系统提示:")
Return
Endif
Insert into Tab_Sell_Main alues(NO,KH,LXR,PZS,HPZS,HJJE,MDate,MTime,JSFS,KPY,SKY,BGY,FHY)
Select Temp_XS
Go Top
Do While !Eof() And Temp_XS.数量!=0 And Temp_XS.单价!=0
YPNO=Temp_XS.药品编号
Select 编号 AS 货位编号 From Tab_PackHouse Where 名称=Temp_XS.货位 Into Array HWBH
SCPH=Temp_XS.产品批号
SCDate=Temp_XS.生产日期
YXQZ=Temp_XS.有效期至
SL=Temp_XS.数量
DW=Temp_XS.单位
DJ=Temp_XS.单价
JE=Temp_XS.金额
WGZL=Temp_XS.外观质量
BZZL=Temp_XS.包装质量
Insert into Tab_Sell_Detail ;
Values(NO,YPNO,HWBH,SCPH,SCDate,YXQZ,SL,DW,DJ,JE,WGZL,BZZL)&&保存销售明细信息
Insert into Tab_Sell_Bak alues(NO,YPNO,HWBH,SCPH,SCDate,YXQZ,SL,DW,DJ,JE,WGZL,BZZL)
*保存库存信息
DIME AKCSL(1) &&定义一维数组
AKCSL=0
Select 库存数量 From Tab_KC Where 药品编号=YPNO And 生产批号=SCPH Into Array AKCSL
Update Tab_KC Set 库存数量=库存数量-SL,单价=DJ,金额=库存数量*单价;
Where 药品编号=YPNO And 生产批号=SCPH
Update Tab_KC_Confine Set Tab_KC_Confine.库存数量=Tab_KC_Confine.库存数量-SL;
Where 药品编号=YPNO
Dime Y_SL(1)
Y_SL(1)=0
Select Top 1 库存 From Tab_KC_Detail Where 药品编号=YPNO Order By 时间 DESC ;
Into Array Y_SL
Insert Into Tab_KC_Detail Values(YPNO,"销售",SL,Y_SL-SL,DT,NO) &&插入库存明细表
Skip
EndDo
Messagebox("药品销售完成!",48,"系统提示:")
sele Temp_XS
Zap
4.5 操作员权限的设置
用户单击导航功能按钮中的“系统管理”按钮,在功能子菜单中选择“权限设置”菜单项,进入“权限设置”界面,该界面运行结果如图6所示。
图4 入库登记运行结果若图片无法显示请联系QQ3710167
医药GSP管理系统
图6 权限设置运行结果
“权限设置”界面主要实现利用ListView控件显示操作员及其头像列表和采用树状视图型式显示和设置权限的功能。
1.表单设计
(1)在“医药GSP管理系统”项目中,利用Class_Frm类创建新表单,名称为“权限设置”。
(2)在表单中添加Shape控件(用于修饰界面)、Button_F控件(和ActiveX控件中的TreeView(Microsoft TreeView Control 6.0 (SP4))控件、ImageList(Microsoft ImageList Control 6.0 (SP4))控件、ListView(Microsoft ListView Control 6.0 (SP4))控件。
(3)重要控件的重要属性如表5所示。
表5 重要属性及值
对象
属性
值
Class_Frm12
BorderStyle
0 – 无边框
Class_Frm12
TitleBar
0 – 关闭
TreeView1
Checkboxes
.T. – 假
TreeView1
LineStyle
1 - RootLines
(4)为表单创建方法程序List_Sele。
2.代码设计
在表单的新添加的方法List_Sele中添加如下代码实现利用树状视图显示操作员权限。
For I=1 to thisform.treeview.nodes.count
thisform.treeview.nodes(I).checked=.f.
thisform.treeview.nodes(I).expanded=.f.
endfor
sele Tab_Purview.* from Tab_Purview Inner Join Tab_User On Tab_Purview.;
操作员编号=Tab_User.操作员编号;
Where Tab_User.操作员=alltrim(thisform.listview1.selecteditem.text) into cursor Temp_User
sele Temp_User
n=2
for I=1 to thisform.treeview.nodes.count
if thisform.treeview.nodes(I).children=0 &&如果没有子节点
mycol=field(n,"Temp_User")
n=n+1
thisform.treeview.nodes(I).checked= Temp_User.&mycol.
if thisform.treeview.nodes(I).checked=.t.
if thisform.treeview.nodes(I).parent.checked=.f.
thisform.treeview.nodes(I).parent.checked=.t.
thisform.treeview.nodes(I).parent.expanded=.t.
endif
endif
thisform.treeview.refresh
endif
endfor
在表单的Init事件中添加如下代码实现在ListView控件中显示操作员及其头像列表。
*初始化ListView控件
thisform.listview1.view=0 &&设置视图显示方式
thisform.listview1.icons=thisform.imagelist1.object
select tab_user &&选定Tab_User工作区为当前工作区
select * from tab_user;
order by tab_user.操作员;
into cursor Temp_CZY
do while !EOF() &&测试当前记录指针是否在文件尾
key=alltrim(Temp_CZY.操作员)
=thisform.listview1.listitems.add(,,key,Temp_CZY.头像) &&添加一个列表项
skip &&相对移动记录指针
enddo
This.List_Value
在TreeView1控件的Init事件中添加如下代码,将系统主菜单和其子菜单项利用树型视图显示。
Dime A_Main(8)
A_Main=""
Select 名称 From Tab_Function Where 上级编号=0 Order By 编号 Into Array A_Main
Go Top
For I=1 To 8
This.Nodes.Add(,,Alltrim(A_Main(I)),Alltrim(A_Main(I)),,) &&添加主菜单节点
Select * From Tab_Function Where 上级编号=I Into Cursor Temp_Child
Go Top
Do While !Eof()
NodeName="NODE"+Padl(Alltrim(Str(编号)),2,"0")
This.Nodes.Add(Alltrim(A_Main(I)),4,NodeName,Alltrim(名称),,) &&添加子菜单节点
Skip
EndDo
EndFor
在TreeView1控件的NodeCheck事件中添加如下代码:
On Error
If Node.Checked = .t. Then &&如果节点被选中
If Node.Children <> 0 Then &&判断是否有子节点
Node.Selected = .t. &&展开此节点
myFirst = Node.Child.FirstSibling.Index
myLast = Node.Child.LastSibling.Index
For I = myFirst To myLast
this.Nodes(I).Checked = .t. &&使所有子节点都被选中
endfor
Else &&如果没有子节点
Node.Checked = Not Node.Checked
If Node.Parent.Checked = .f. Then &&如果父节点没有被选中
Node.Parent.Checked = .t. &&父节点被选中
EndIf
EndIf
Else &&如果此节点并没有被选中
If Node.Children <> 0 && 判断是否有子节点
Node.Selected = .t. &&展开此节点
myFirst = Node.Child.FirstSibling.Index
myLast = Node.Child.LastSibling.Index
For I = myFirst To myLast
this.Nodes(I).Checked = .f. &&使所有子节点都不被选中
endfor
Else &&如果没有子节点
Node.Checked = Not Node.Checked
EndIf
EndIf
在“保存”按钮的Button_Click事件中添加如下代码:
Select Tab_User
Locat For 操作员=alltrim(thisform.listview1.selecteditem.text)
CZYNO=Tab_User.操作员编号
Select Tab_Purview
For I = 1 To thisform.TreeView.Nodes.Count
if thisform.treeview.nodes(I).children=0
mytext=alltrim(thisform.treeview.nodes(I).text) &&取出树视图中每一个节点的标签
If thisform.TreeView.Nodes(I).Checked = .t. &&用新值替换数据表中指定字段的值
repl Tab_Purview.&mytext. with .t. For 操作员编号=CZYNO
else
repl Tab_Purview.&mytext. with .f. For 操作员编号=CZYNO
EndIf
endif
next
messagebox("权限设置成功!",48,"系统提示")
附录A 参考文献
1.《Visual Basic精彩编程200例》机械工业出版社 赛奎春、高春艳等
2003年1月
2.《Visual Basic数据库开发实例解析》机械工业出版社 刘志铭、高春艳等
2003年8月
3.《Visual FoxPro数据库开发实例解析》机械工业出版社 王晶莹、王国辉等
2003年9月
4.《Power Builder数据库开发实例解析》机械工业出版社 华传铭、张振坤等
2003年9月
5.《Delphi数据库开发实例解析》机械工业出版社 赛奎春、郑骁鹏等
2004年2月
6.《PowerBuilder 精彩编程200例》机械工业出版社 张振坤、李文立等
2004年9月
7.《Visual FoxPro 精彩编程200例》机械工业出版社 王国辉、董韶华等
2004年9月
8.《ASP数据库开发实例解析》机械工业出版社 李严、于亚芳、王国辉 2004年12月
9.《Delphi工程应用与项目实践》机械工业出版社 宋坤、赵智勇等
2005年1月
10.《Visual Basic工程应用与项目实践》机械工业出版社 高春艳、李俊民等
2005年1月
11.《Visual C++工程应用与项目实践》机械工业出版社 张雨、阮伟良等
2005年1月
12.《JSP工程应用与项目实践》机械工业出版社 陈威、白伟明、李楠
2005年2月
13.《ASP工程应用与项目实践》机械工业出版社 王国辉、牛强、李南南
2005年4月
14.《Visual Basic 信息系统开发实例精选》机械工业出版社 高春艳、李俊民、张耀庭等
2005年7月
15.《ASP 信息系统开发实例精选》机械工业出版社 王国辉、牛强、李南南等
2005年7月
16.《Delphi 信息系统开发实例精选》机械工业出版社 宋坤、赵智勇、刘强等
2005年7月
17.《Visual foxpro数据库开发关键技术与实例应用》人民邮电出版社 周桓、张雨、王国辉
2004年5月
18.《Power Builder数据库开发关键技术与实例应用》人民邮电出版社 刘志铭、张振坤、冯文萃 2004年5月
19.《Delphi数据库开发关键技术与实例应用》人民邮电出版社 赛奎春、陈紫鸿、宋昆
2004年5月
20.《Visual basic数据库开发关键技术与实例应用》人民邮电出版社 高春艳、李艳
2004年5月
21.《Visual C++ 管理信息系统完整项目实例剖析》人民邮电出版社 明日科技
2005年7月
22.《Visual Basic 管理信息系统完整项目实例剖析》人民邮电出版社 明日科技
2005年7月
23.《PowerBuilder 管理信息系统完整项目实例剖析》人民邮电出版社 明日科技
2005年7月
24.《Visual FoxPro管理信息系统完整项目实例剖析》人民邮电出版社 明日科技
2005年7月
25.《SQL Server数据库开发实例解析》机械工业出版社 宋昆、李严等
2006年1月
26.《Access数据库开发实例解析》机械工业出版社 李俊民、高春燕等
2006年1月
27.《Visual Basic数据库系统开发完全手册》人民邮电出版社 明日科技王春才、高春艳、
李俊民 2006年3月
28.《Visual C++ 数据库系统开发完全手册》人民邮电出版社 明日科技 王端、于速、张雨
2006年3月
29.《Delphi数据库系统开发完全手册》人民邮电出版社 明日科技 宋坤、邹天思
2006年3月
30.《JSP数据库系统开发完全手册》人民邮电出版社 明日科技 王国辉、李文立、杨亮
2006年3月
31.《Visual Basic数据库系统开发案例精选》人民邮电出版社 明日科技 高春艳、李俊民、
刘彬彬 2006年5月
32.《Delphi 数据库系统开发案例精选》人民邮电出版社 明日科技 李文立、刘强、梁冰
2006年5月
33.《ASP数据库系统开发案例精选》人民邮电出版社 明日科技 孙明丽、邹天思、盖天宇
2006年5月
34.《JSP数据库系统开发案例精选》人民邮电出版社 明日科技 王国辉、王易
2006年5月
医药GSP管理系统
附录B 数据表
q 药品信息表
药品信息表(Tab_Drug)用来存储药品基本信息。表Tab_Drug的表结构如表6所示。
表6 表Tab_Drug的结构
字段名称
数据类型
字段大小
索引
药品编号
字符型
10
升序
通用名
字符型
50
曾用名
字符型
50
英文名
字符型
50
简称
字符型
25
剂型
字符型
10
规格
字符型
30
包装
字符型
30
单位
字符型
3
成份
字符型
100
性状
字符型
100
药理毒理
备注型
4
适应症
字符型
100
用法用量
字符型
100
不良反应
备注型
4
禁忌
字符型
150
注意事项
备注型
4
药物过量
备注型
4
贮藏
字符型
20
有效期
数值型
3
有效期单位
字符型
2
注册商标
字符型
10
批准文号
字符型
20
产地
字符型
30
生产厂家
字符型
10
备注
备注型
4
q 采购订单主表
采购订单主表(Tab_Procure_Main)用来存储采购订单的主要信息。表Tab_Procure_Main的表结构如表7所示。
表7 表Tab_Procure_Main的结构
字段名称
数据类型
字段大小
索引
票号
字符型
20
升序
供应商编号
字符型
10
联系人
字符型
10
品种数
数值型
6
货品总数
数值型
6
合计金额
货币型
8
结算方式
字符型
10
日期
日期型
8
开票员
字符型
10
采购员
字符型
10
q 销售登记主表
销售登记主表(Tab_Sell_Main)用来存储销售登记的主要信息。表Tab_Sell_Main的表结构如表8所示。
表8 表Tab_Sell_Main的结构
字段名称
数据类型
字段大小
索引
票号
字符型
20
客户编号
字符型
10
联系人
字符型
10
品种数
数值型
10
货品总数
数值型
10
合计金额
货币型
8
日期
日期型
8
时间
字符型
8
结算方式
字符型
10
开票员
字符型
10
收款员
字符型
10
保管员
字符型
10
出库复核员
字符型
10
q 药品养护档案表
药品养护档案表(Tab_YPYHDA)用来保存药品养护档案信息。表Tab_YPYHDA的表结构如表9所示。
表9 表Tab_YPYHDA的结构
字段名称
数据类型
字段大小
索引
编号
数值型
4
建卡日期
日期型
8
药品编号
字符型
10
负责期
字符型
10
使用期
字符型
10
质量标准
字符型
50
检验项目
字符型
50
内
字符型
50
中
字符型
50
外
字符型
50
体积
数值型
10
q 权限表
权限表(Tab_Purview)用来保存操作员的权限信息。表Tab_Purview的表结构如表10所示。
表10 表Tab_Purview的结构
字段名称
数据类型
字段大小
索引
操作员编号
字符型
10
升序
部门设置
逻辑型
1
员工信息管理
逻辑型
1
仓库管理
逻辑型
1
……
附录C 文件架构
主文件架构如图7所示。若图片无法显示请联系QQ3710167
“入库登记”界面采用智能化表格式数据录入,实现一次录入多种药品的功能。同时加入了自动生成入库票号、自动计算合计金额和根据药品信息表中的有效期和生产日期自动计算有效期至等功能。
1.表单设计
(1)在“医药GSP管理系统”项目中,利用Class_Frm类创建新表单,名称为“入库登记”。
(2)在表单中添加Text控件、Label控件、Combo控件、Grid控件(在该控件的第1列、第2列、第17列和第18列分别加入Combo控件并将该件设置为默认控件)、Shape控件(用于修饰界面)和Button_Y控件、Button_F控件。
(3)重要控件的重要属性如表3所示。
表3 重要属性及值
对象
属性
值
Combo1
RowSource
tab_jsfs.结算方式
Combo1、Combo2
RowSourceType
6 – 字段
Text2
Value
{}
Grid1
ColumnCount
12
Grid1
DeleteMark
.F.
2.代码设计
在Grid1.Column9.Text1控件(数量)的LostFocus事件中添加如下代码实现自动计算金额并判断该药品的库存数量是否超出库存上限,如果超出,那么要求用户做出选择。当用户选择“是”时继续入库,否则删除该条记录。
Option=Thisform.Grid1.Column9.Text1.Value*Thisform.Grid1.Column11.Text1.Value
Thisform.Grid1.Column12.Text1.Value=Option
YPNO=Alltrim(Thisform.Grid1.Column1.Combo1.DisplayValue)
Select * From Tab_KC_Confine Where 药品编号=YPNO Into Cursor Temp_SXX
If Temp_SXX.库存数量+This.Value>Temp_SXX.库存上限
If Messagebox("库存数量超出库存上限,是否入库?",4+32,"系统提示:")=7
Select Temp_RK
If Reccount("Temp_RK")!=1
Set Deleted On &&忽略标有删除标记的记录
Delete For 药品编号=YPNO &&逻辑删除
go bottom
Thisform.Grid1.Column1.Combo1.Setfocus
thisform.grid1.ActivateCell(reccount(),1) &&激活表格控件中的一个单元格
Thisform.Refresh
Endif
Endif
EndIf
在Grid1.Column15.Text1控件(生产日期)的LostFocus事件中添加如下代码实现根据输入的生产日期和药品信息表中的有效期自动计算“有效期至”列的值,并判断该药品是否过期,如果过期将禁止入库。
Select * From Tab_Drug Where 药品编号=Alltrim(Thisform.Grid1.Column1.Combo1.Value) ;
Into Cursor Temp_YXQ
Do Case Temp_YXQ.有效期单位
Case Temp_YXQ.有效期单位="年"
YXQ=Temp_YXQ.有效期*12
THisform.Grid1.Column16.Text1.value=Gomonth(This.Value,YXQ)
Case Temp_YXQ.有效期单位="月"
YXQ=Temp_YXQ.有效期
THisform.Grid1.Column16.Text1.value=Gomonth(This.Value,YXQ)
Case Temp_YXQ.有效期单位="天"
THisform.Grid1.Column16.Text1.value=This.Value+Temp_YXQ.有效期
EndCase
YPNO=Alltrim(THisform.Grid1.Column1.Combo1.value)
If THisform.Grid1.Column16.Text1.value<=Date()
Messagebox("该药品已经过期,不可以入库!",48,"系统提示:")
Select Temp_RK
Set Deleted On &&忽略标有删除标记的记录
Delete For 药品编号=YPNO &&逻辑删除
Set Procedure To Procedure\UsedPrg &&打开过程文件
RecSum=DelCount() &&调用自定义函数获取已经打上删除标记的记录个数
If RecCount("Temp_RK")-RecSum=0
append blank
thisform.refresh
Endif
go bottom
Thisform.Grid1.Column1.Combo1.Setfocus
thisform.grid1.ActivateCell(reccount(),1) &&激活表格控件中的一个单元格
Thisform.Refresh
Endif
在Grid1.Column17.Combo1控件(仓库)的Init事件中添加如下代码实现在“仓库”下拉列表框中显示有货位信息的仓库名称。
*利用自连接实现只显示有货位信息的仓库名称
Select CK.名称 From Tab_PackHouse CK Join Tab_PackHouse HW ON CK.编号=HW.上级编号 And;
CK.类型=0Group By CK.编号 INTO Cursor Temp_CK
This.RowSourceType=6
This.RowSource="Temp_CK.名称"
this.listindex=1
在Grid1.Column17.Combo1控件(仓库)的KeyPress事件中添加如下代码实现根据用户选择的仓库在下一个组合框中列出该仓库的货位信息。
*当控件失去焦点时,根据用户选择的仓库在下一个组合框中列出该仓库的货位信息
CKName=Alltrim(Thisform.Grid1.Column17.Combo1.Value)
Select 编号 From Tab_PackHouse Where 名称=CKName Into Cursor Temp_CKNO
Select 名称 From Tab_PackHouse Where 类型=1 And 上级编号=Temp_CKNO.编号;
INTO Cursor Temp_HW
Thisform.Grid1.Column18.Combo1.Value="Temp_HW.名称"
Thisform.Grid1.Column18.Combo1.listindex=1
在Grid1.Column20.Combo1控件(包装质量)的KeyPress事件中添加如下代码实现当用户按下回车键时,判断用户输入信息的正确性,并询问用户是否继续录入入库信息,并统计器品种数、货品总数和合计金额。
If nKeyCode=13
Nodefault &&屏蔽对回车响应的缺省操作
Option=Thisform.Grid1.Column9.Text1.Value*Thisform.Grid1.Column11.Text1.Value
Thisform.Grid1.Column12.Text1.Value=Option
If Empty(Thisform.Grid1.Column1.Combo1.DisplayValue)
Messagebox("请选择入库的药品!",48,"系统提示:")
else
…… &&判断入库数量和单价是否零,如果为零,则给予提示并返回
select Temp_RK
Select 药品编号 From Temp_RK Group By 药品编号 Into Cursor Temp_PZS &&统计品种数
Thisform.Text6.Value=Reccount("Temp_PZS")
select Temp_RK
If Messagebox("是否继续入库?",4+32,'系统提示:')=6
append blank
thisform.refresh
RecSum=RecSum+1
go bottom
Thisform.Grid1.Column1.Combo1.Setfocus
thisform.grid1.ActivateCell(reccount()+1,1) &&激活表格控件中的一个单元格
Thisform.Grid1.Column1.Combo1.ListIndex=1
Else
Thisform.Text10.Setfocus
Endif
Select Sum(数量) AS 货品总数 ,Sum(金额) AS 合计金额 From Temp_RK;
Into Cursor Temp_HJ
Thisform.Text7.Value=Temp_HJ.货品总数
Thisform.Text8.Value=Temp_HJ.合计金额
select Temp_RK
endif
Endif
“保存”按钮主要完成将入库信息分别保存在入库登记主表和入库登记明细表中,并判断库存信息表中是否存在该药品信息,如果存在则修改该药品数量,否则在库存信息表中添加该药品信息,并将入库事件插入库存明细表中,最后设置相应控件是否有效,其关键代码如下:
Insert into Tab_Inhouse_Main Values(NO,GYS,LXR,PZS,HPZS,HJJE,MDate,;
MTime,JSFS,KPY,YSJL,CGY,YSY,BGY) &&保存入库信息
Select Temp_RK
Go Top
Do While !Eof() And Temp_RK.数量!=0 And Temp_RK.单价!=0
…… &&此处省略了从临时表中分别取出入库信息的代码,如:YPNO=Temp_RK.药品编号
Insert into Tab_Inhouse_Detail Values(NO,YPNO,HWBH,SCPH,SCDate,YXQZ,SL,;
DW,DJ,JE,PFJ,LSJ,WGZL,BZZL) &&保存入库明细信息
*保存库存信息
DIME AKCSL(1) &&定义一维数组
AKCSL=0
Select 库存数量 From Tab_KC Where 药品编号=YPNO And 生产日期=SCDate Into Array AKCSL
If AKCSL=0
Insert into Tab_KC ;
Values(YPNO,HWBH,SCPH,SCDate,YXQZ,SL,DW,DJ,JE,PFJ,LSJ,WGZL,BZZL)
Else
Update Tab_KC Set 库存数量=库存数量+SL,单价=DJ,金额=库存数量*单价;
Where 药品编号=YPNO And 生产日期=SCDate
Endif
Update Tab_KC_Confine Set 库存数量=库存数量+SL Where 药品编号=YPNO
Dime Y_SL(1)
Y_SL(1)=0
Select Top 1 库存 From Tab_KC_Detail Where 药品编号=YPNO Order By 时间 DESC;
Into Array Y_SL
Insert Into Tab_KC_Detail Values(YPNO,"入库",SL,Y_SL+SL,DT,NO) &&插入库存明细表
Skip
EndDo
Messagebox("药品入库完成!",48,"系统提示:")
sele Temp_RK
Zap &&清空临时入库信息表
4.4 销售开单
用户单击导航功能按钮中的“销售管理”按钮,在功能子菜单中选择“销售开单”菜单项,进入“销售开单”界面,该界面运行结果如图5所示。