资源描述
解码程序开发手册(LIS)
本手册对整个LIS都有所讲解,但重点还是放在LISLiod上面。从整个程序的框架的架构,到每个配置文件的说明,每种解码算法的好处等,一一的让你学会LISLiod。
完成一台仪器,一般是四个步镞,1。分析仪器,2。分析原始数据,3。编写LIS解码程序,4。调试
一、分析仪器大概有以下几点
1. 会看仪器
2. 熟悉LIS系统的流程
3. 会做线
4. 一些基本的沟通
5. 注意卫生。
二、分析原始数据,这是总过流程中最困难,也是最关键的一个环节。原始数据不只是TXT文本,还有数据库等其他格式的文件。有四个步骤:
1.找出每个标本的起始符与结束符
2.找出每个标本的日期和样本号
3.找出每个项目数据或图象数据对应的位置
4.最后总结,得到规律。
三、所谓LIS解码程序(LISLoid),就是一段小的程序,自动的完成把仪器做完标本所产生的有用数据(往往这些数据都比较复杂难以看懂,所以才叫解码)存入到HIS和LIS系统里面,使HIS和LIS系统能够灵活的调用这些数据。做一个桥梁把仪器和HIS和LIS系统连在一起。
LISLoid是由舞个基本的部分组成:
1. 通信程序。
2. 解码算法程序。
3. 插入数据库的程序
4. 报告程序。
5. 历史备份
四、调试,除了完善LISLiod,还有报表格式的调整,打印机等测试。
分析仪器
1. 会看仪器,不是要你学会怎样使用仪器,而是根据实际的情况把这台仪器定位到我们解决它的四个位置中,哪四一个位置?
第一,仪器已经很旧,一些取数据的接口已经损坏,使用次数很少。象这类型的仪器迟早会要淘汰去,做了意义也不大,所以对这些仪器我们采用“手工项目”,直接手工填写数据,保存到LIS系统,解码程序也就省了。
第二,中小型的仪器,一般都是有COM接口的,标本的样本号由仪器本身输出。对这种我们用通信程序直接截取数据进行解码。(如:电解质仪器,尿液分析仪。。。。)
第三,很先进的大仪器,这种一般都比较复杂,就算能用通信程序截取到数据,我们对它进行完全解码也比较困难,而仪器一般都自带有一套操作软件,所以我们从它的软件中做接口,大部分仪器在这方面都留有接口,可以找说明书,也可以直接打电话询问仪器产家。(通常的接口有:本地数据库,result文件。。。。)
最后,还有一些非常特需的仪器,旧,用的少,有复杂的图象,没有上面所说的接口。
这种就不能用常规的方法解决,如:利用钩子程序,直接截取它的结果,利用截屏的程序获取图象。。。
、
2. 熟悉LIS系统的流程,这个非常重要,因为要使一台仪器能正常运行,需要对LIS系统进行很多的配置,只有正确的配置好了,仪器里的数据才会准确无误的传入到LIS系统。“lis模块功能”,“LIS软件流程”,“LIS系统库表”,“LIS项目实施文档”,“培训教材”等这些都要认真阅读,最好还要能够掌握LIS数据库里的所有表结构。
3. 会做线,首先知道接线的规则,有25钟的接口,9钟的,公母匹配。。。。。认真阅读“RS-232-C详解”文档,对通信程序的理解也很有帮助。学会这个可以节哟成本。
4. 沟通很重要,因为我们要做的仪器,现在都已经正在正常使用,你首先就要调查清楚每台仪器的使用时间,然后调试仪器,这些都需要每台仪器的操作员配合的。所以沟通显得有所必要。
5. 注意卫生,检验科,是医院所有地方最需要注意的地方。不过也没有那么可怕,多注意一下,不要随便乱碰拿什么东西,进出一定洗手。一般就不会有什么问题。
原始数据分析
对TXT文本的数据分析就一定会用到“原始数据分析”这个工具,会把数据转化为ASCII码用网格定位的显示出来,还能颜色区分特需字符,精确定位字符。下面我们看具体的列子:
(图一)
这是一台型号为FA-150的尿液分析仪取出的原始数据,用记事本打开。在用“原始数据分析”打开看看。
(图二)
现在我们结合这两个工具找出我们需要的数据。
一般开始符和结束符都是一些特需的字符,会用红色表示出来,通过图二,我们就可以看得出他们的
开始符为13,13,2,13,13,10结束符3 (用ASCII码表示)
日期的开始位为6结束位25
标本号 49---51
GLU 60----74
BIL 82----96
KET 104----118
SG 126----140
BLD 148----162
PH 170----184
PRO 192----206
URO 214----221
NIT 236----250
LEU 258----272
还有我们发现每个标本的长度相等都是276位
根据这些规律我们就可以写出算法来得到每个项目对应的数据
下面我们接着来分析一个数据库的数据.
数据库是哪来的了?有这个数据库当然就有和它匹配的软件,这套软件一般是由仪器产商提供的一套软件和仪器一起买出,通常这套软件都是一个小型的LIS系统,也就是这台仪器的通讯程序和解码程序都已经集合在这套软件里面了,所以我们就没必要自己再重新给这台仪器安装一个通讯程序,然后再编写一个对应的解码程序。这样不但费力,更重要的是自己写的肯定是没有产商的这套程序准确。我们就不能走这条路了,有条更简单快截的方法,就是直接访问产商软件的数据库,把标本的结果取出来就可以了。和数据库做接口有几个前提条件,1。了解它的数据库类型,是ACESS数据库了,还是其他类型的数据,并找到它通过ADO连接他的驱动程序。2。看它是否设了密码,如果有就的象产商获取。3。分析掌握它的表结构,如果自己分析不出来,也要找产商要。
下面我们来看这台ACESS数据库的-----酶标仪
这是它的所有表名。
现在我们来分析它的表结构,找出对我们有用的表和他们之间的关系。
上图是我们需要的三个表的表结构,下图是三个表之间的关系。
Tb_method项目表,本仪器所做的所有仪器的项目
Tb_plate一次标本做了多少个项目
Tb_plate_data一个项目做了多少个标本和他们结果值
通过上面的分析,可以用下面的方法来解决。
因为这种仪器做标本是成套成套的做的,一次至少就是几十个上百个,所以我们记录上次做完后他的最后ID不能保存样本表的ID,要保存板子表的ID。我们记录TB_PLATE表的PLATE_ID字段,下次解码就只要解上次记录的后面的数据。
LISLiod学习
LIS解码程序(LISLoid),就是一段小的程序,自动的完成把仪器做完标本所产生的有用数据(往往这些数据都比较复杂难以看懂,所以才叫解码)存入到HIS和LIS系统里面,使HIS和LIS系统能够灵活的调用这些数据。做一个桥梁把仪器和HIS和LIS系统连在一起。
即使是一段小程序,为了编写的方便和理解,把这段程序分开来解释。共四个部分,前台界面操作显示,解码类,数据插入数据库类,配置文件操作类。
一, 前台界面:
主界面上有五个按钮,分别是:HELP,SET,DECODE,DUG,STOP。HELP就是显示帮助文档,SET修改配置文件和解码启动方式,DECODE点击开始解码图标变蓝,STOP停止解码,DUG调试显示单个样本解码结果。其中还有一个隐藏配置方式快捷键F9,显示该解码程序是和哪台仪器匹配,仪器的哪些项目。右键菜单》恢复。下面显示一个文本框,显示当前样本解码后的结果。
二,解码类:
解码类又分为了一次解码和二次解码,一次解码主要是把原始数据里项目的值取出来存入DATAXML,二次解码就是把一次取出的项目结果再次进行分析,合并特定公式或特定条件,最后得到的是最终需要的结果存如DATAXML。
public class DataDeCode
{
public delegate void DataInsertEventHandler(object sender, EventArgs e);
/// <summary>
/// 数据插入数据库事件
/// </summary>
public event DataInsertEventHandler DataInsert;
/// <summary>
/// 解码进度事件
/// </summary>
public delegate void FrmTrayIconChangeEventHandler(int trye,int allcount,int nowcount);
public static event FrmTrayIconChangeEventHandler FrmTrayIcon;
/// <summary>
/// 存放最后得到的数据
/// </summary>
public string DataXML=null;
private string resultfilename=@"result\"+DateTime.Now.ToString("yyMMdd")+".txt";
/// <summary>
/// 数据库连接
/// </summary>
//private System.Data.OleDb.OleDbConnection conn=null;
public DataDeCode()
{
}
public void decode()
{
this.DataXML=null;
DataXML=DataXML+"<?xml version=\"1.0\" encoding=\"utf-8\"?>";
DataXML=DataXML+"<comdata>";
this.loadXML();
DataDeCode.FrmTrayIcon();
DataXML=DataXML+"</comdata>";
PublicClass.outxml_Appendfile(resultfilename,DataXML);
PublicClass.BindDataXML(DataXML);
if(this.DataInsert!=null)
this.DataInsert(this,EventArgs.Empty);
PublicClass.updateNode();
}
/// <summary>
/// 得到的数据存入XML中
/// </summary>
/// <param name="sd"></param>
/// <param name="name"></param>
/// <param name="codename"></param>
private void loadXML(string sd,string name,string codename,int num)
{
this.DataXML=DataXML+"<Data name=\""+name+"\" codename=\""+codename+"\" codenum=\""+num.ToString()+"\">"+sd+"</Data>";
}
}
上面的DataDeCode类就是一次解码类,
decode()为解码方法,界面上的DECODE按钮就是首先调用这个方法。
Decode方法中有些常用的功能方法,
1.this.loadXML();就是把取到的结果构建成XML文档形式。
2.DataDeCode.FrmTrayIcon();方法是在界面上显示解码的进度,按百分比这样显示。3.PublicClass.outxml_Appendfile(resultfilename,DataXML);方法是备份这次解码的结果。以后还可以本地查询结果。
4.PublicClass.BindDataXML(DataXML);方法,传递数据给插入数据库类。
if(this.DataInsert!=null)
this.DataInsert(this,EventArgs.Empty);
调用插入数据库类。不写此方法数据就不会插入到数据库。
5.PublicClass.updateNode();方法记录解码的点位,程序退出,下次解码就从次记录开始。
public class ChangeDataXML
{
public ChangeDataXML()
{
PublicClass.DataXMLChange+=new LISLoid.PublicClass.DataXMLChangeEventHandler(PublicClass_DataXMLChange);
}
private void PublicClass_DataXMLChange()
{
string val=null;
PublicClass.readNode(PublicClass.filename,"Isdecode2",ref val);
if(val.Trim()!="0")
{
this.decode2();
}
}
/// <summary>
/// 二次解码方法
/// </summary>
private void decode2()
{
}
上面二次解码类代码。
从上面的解析我们可以看出,其实我们写一台新仪器的解码程序,就只要对decode方法和decode2方法进行修改就可以了,还有就是配置到这台仪器的代码。
三,插入数据库类。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using XcjwHIS.DatabaseAccessLayer;
using XcjwHIS.PubicBaseClasses;
using XcjwHIS.BussinessLogicLayer.Classes;
using System.Data;
using System.Xml;
using System.IO;
namespace LISLoid
{
/// <summary>
/// 数据插入到数据库类
/// </summary>
public class DataInsertClass
{
public delegate void FrmTrayIconChangeEventHandler(int trye,int allcount,int nowcount);
public static event FrmTrayIconChangeEventHandler FrmTrayIcon;
#region 类变量
public string filename="DataInsertSetting.xml";
/// <summary>
/// 配置文件数据
/// </summary>
private DataSet ds=null;
/// <summary>
/// 解码数据
/// </summary>
private DataSet ds_Data=null;
/// <summary>
/// 标本号
/// </summary>
private string bb_num=null;
/// <summary>
/// 验单号
/// </summary>
private int yd_num=0;
/// <summary>
/// 图片号
/// </summary>
private string pic_num=null;
/// <summary>
/// 组合代码
/// </summary>
private string group_code=null;
/// <summary>
/// 检验科室代码
/// </summary>
private string room_code=null;
/// <summary>
/// 分类代码
/// </summary>
private string cls_code=null;
/// <summary>
/// 仪器代码
/// </summary>
private string mach_code=null;
/// <summary>
/// 样本代码
/// </summary>
private string samp_code=null;
/// <summary>
/// 质控代码1
/// </summary>
private string zkbb1=null;
/// <summary>
/// 质控代码2
/// </summary>
private string zkbb2=null;
/// <summary>
/// 质控代码3
/// </summary>
private string zkbb3=null;
/// <summary>
/// 检验日期
/// </summary>
private DateTime date=DateTime.Now;
/// <summary>
/// 多项目仪器
/// </summary>
private string ismuch=null;
/// <summary>
/// 是否是血常规三分类的仪器
/// </summary>
private string IsThreepic=null;
/// <summary>
/// 取出数据
/// </summary>
private DataTable tb_data=null;
/// <summary>
/// 配置文件数据
/// </summary>
private DataTable tb_node=null;
#endregion
public DataInsertClass()
{
MainFrm.ddc.DataInsert+=new LISLoid.DataDeCode.DataInsertEventHandler(dc_DataInsert);
}
/// <summary>
/// 开始解码事件,调用解码方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void dc_DataInsert(object sender, EventArgs e)
{
date=DateTime.Now;
this.bindBaseData();
if(tb_data==null)return;//如果传过来的dataxml没有数据就跳到下一个去
if(bb_num.Trim()=="-1")return;//如果标本号为-1就跳到下一个去
if(bb_num.Trim()==zkbb1.Trim() ||bb_num.Trim()==zkbb2.Trim() || bb_num.Trim()==zkbb3.Trim())
{
this.DataInsertQC();
}
else
{
this.DataInsert();
}
}
/// <summary>
/// 配置文件转化为dataset
/// </summary>
private void bindxmlds()
{
ds=new DataSet();
ds.ReadXml(filename);
}
/// <summary>
/// 得到的数据转化为dataset
/// </summary>
private void binddatads()
{
try
{
ds_Data=new DataSet();
string dtxml=null;
dtxml=PublicClass.DataXML;
System.IO.StringReader sr=new System.IO.StringReader(dtxml);
ds_Data.ReadXml(sr);
}
catch{}
}
/// <summary>
/// 绑定基础数据
/// </summary>
private void bindBaseData()
{
}
}
上面是插入数据库类,把DATAXML里面的数据插入到数据库里面。数据插入分为质控数据插入和结果数据插入。
四,配置程序和仪器匹配。
先选择数据库里对应的仪器,左边就自动的显示出数据库这台仪器里的项目。中间就是解码后的项目,点对应后就生成对应项目到右边。
特别注意:中间项目的项目代码一定要和解码中配置文件的项目代码一样。
所有配置文件:
1. DecodeSetting.xml解码中所用到配置文件
<?xml version="1.0" encoding="utf-8"?>
<COMDATA>
<BaseConfig>
<date>2007-12-18 0:00:00</date>
<repno>1</repno>
<lastendnum>0</lastendnum>
<long>
</long>
<beginbyte>
</beginbyte>
<endbyte>
</endbyte>
<rawpath>raw/</rawpath>
</BaseConfig>
<setdecode>
</setdecode>
</COMDATA>
2.KeyDecodeSetting.xml 二次解码的配置文件
<?xml version="1.0" encoding="utf-8" ?>
<COMDATA>
<BaseConfig>
</BaseConfig>
</COMDATA>
3.DataInsertSetting.xml 插入数据库配置文件
<?xml version="1.0" encoding="utf-8"?>
<COMDATA>
<!-- 根节点 -->
<!-- 前台DataXML读取的项目和数据库中项目设置对应 -->
<!--bb_name="标本名" bb_codename ="项目代码" bb_codenum ="对应项目位置"-->
<!--pic_name="图片名" pic_codename="项目代码" pic_codenum="对应项目位置"-->
<!--date_name="日期名" date_codename="项目代码" date_codenum="对应项目位置"-->
<DataInsert bb_name="标本号" bb_codename="No" bb_codenum="1" pic_name="" pic_codename="" pic_codenum="" date_name="" date_codename="" date_codenum="">
</DataInsert>
<BaseConfig>
<!-- 基本参数 -->
<group_code>90</group_code>
<!-- 组合代码 -->
<room_code>4</room_code>
<!-- 科室代码 -->
<cls_code>1</cls_code>
<!-- 分类代码 -->
<mach_code>9002</mach_code>
<!-- 仪器代码 -->
<samp_code>76</samp_code>
<!-- 样本代码 -->
<zkbb1>801</zkbb1>
<!-- 质控标本号一 -->
<zkbb2>802</zkbb2>
<!-- 质控标本号二 -->
<zkbb3>803</zkbb3>
<!-- 质控标本号三 -->
<startup>0</startup>
<!-- 程序启动方式(0:手工启动,1:自动启动) -->
<Isdate>0</Isdate>
<!-- 是否取仪器的日期为标本日期(0:否,1:是) -->
<Isrepno>0</Isrepno>
<!-- 是否自定义标本号(0:否 取仪器的标本号,1:是) -->
<date>2007-4-16 0:00:00</date>
<!-- 当天日期 -->
<repno>2354</repno>
<!-- 最后一个自定义ID号 -->
<Isdecode2>0</Isdecode2>
<!-- 是否进行二次数据解码(0不解1解) -->
<IsMuchItem>1</IsMuchItem>
<!-- 是否按多项目解码-->
<!--0不按适合固定的项目个数,允许重名的项目=1 按适合不固定项目,不允许有重名项目 -->
<ConnectString>Provider=Microsoft.Jet.OLEDB.4.0;Data source=test.mdb</ConnectString>
<!--连接数据库字符串(如果不是数据库的解码此不用)-->
<IsThreepic>0</IsThreepic>
<!--是否是血常规三分类的仪器,有三个图象要插入-->
</BaseConfig>
<DoData>
<!-- 手工指定仪器的所有项目 -->
<Data name="日期" codename="date" codenum="0">
</Data>
<Data name="标本号" codename="bb_num" codenum="1">
</Data>
</DoData>
</COMDATA>
总个软件的流程:
展开阅读全文