检验串口仪器探秘

一直对盒子串口仪器接口缺乏系统的了解。为什么仪器控制能启动停止,为什么能读到数据,接口结构为什么要那样写等等,特地系统的学习LIS连接TCP的秘密。

1.为啥仪器控制能启动仪器和停止仪器接口
启动
启动仪器接口

停止
在这里插入图片描述

在这里插入图片描述
2.知道启动停止的机制后我们能做什么?
对于调试仪器接口时候就可以不用界面启动仪器和停止仪器了,可以直接用terminal启动仪器接口主方法这样传输数据就能断点调试,增加调试效率,替换之前写globle猜测的方式(要注意仪器超时的问题)。
在这里插入图片描述
3.为什么执行主方法后能连接盒子的TCP
重要的启动在$$Start^MI.MIF000
在这里插入图片描述
关键是对拼好的仪器端口串进行open命令启动tcp,同时设置连接的编码格式
在这里插入图片描述
在这里插入图片描述

4.Mian循环方法解读
一个字符一个字符读取命令
在这里插入图片描述
ASTM协议响应
在这里插入图片描述
读数据
在这里插入图片描述
解析保存结果
在这里插入图片描述

上传信息
在这里插入图片描述

事列代码

MIFLISVMachine(mi)  
	s mi=$g(mi) 
	i '$l(mi) q
	s ItemDeli=$li(^dbo.BTMIMachineParameterD(mi),12) //项目分隔符
	s ResultDeli=$li(^dbo.BTMIMachineParameterD(mi),13) //结果分隔符
	s AntDeli=$li(^dbo.BTMIMachineParameterD(mi),14) //抗生素分隔符
	s SenDeli=$li(^dbo.BTMIMachineParameterD(mi),15) //药敏结果分隔符
	s Port="|TCP|"_$li(^dbo.BTMIMachineParameterD(mi),17) //端口号
	//控制字符
  	s stx=$c(2),etx=$c(3),ack=$c(6),enq=$c(5),eot=$c(4)
  	s lf=$c(10),cr=$c(13),nak=$c(21),(result,epis)="",etb=$c(23)
	S $ZT="RuntimeError",$ECODE="",iError=0 //捕获运行时错误,并显示
	//启动tcp连接,然后就会侦听tcp发来的消息和给tcp发送数据
	i $$Start^MI.MIF000(mi) q
	//循环执行Mian方法取或者发送数据到tcp
	f  d Main i $$Stop^MI.MIF000(mi) q
  	c Port
  	q

 //在循环的Main方法读取一个字符直到收到ENQ的不可见字符控制命令(READ命令是阻塞的所以不会跳过去)
Main r *R:10 e  d  q
  //收到ENQ才进入下面逻辑
  i $c(R)'=enq q
  s AllRecord=""
  d Trace^MI.MIF000(mi,"ENQ","H<--M")
  //先回复仪器我收到ENQ控制命令并且准备好接收数据了
  d ACK
  //循环等着读取数据,一直读到EOT结束(READ命令是阻塞的所以不会跳过去)
  f  r *R:10 q:$c(R)=eot  d
  .//这里没收到STX都认为是没用的数据退出掉
  .i $c(R)'=stx q
  .//收到STX后开始读取正式数据(调用包装的读取数据方法,还是指向READ阻塞读数据)
  .s record=$$Read^MI.MIF000(mi,"",lf) q:'$l(record)
  .d Trace^MI.MIF000(mi,record,"H<--M")
  .//把读取的记录拼接到总记录串上
  .s AllRecord=AllRecord_$p(record,etb,1)
  .//回复收到数据
  .d ACK
  d Trace^MI.MIF000(mi,$s($c(R)=eot:"EOT",1:R),"H<--M")
  //读取数据完成一轮就处理解析
  s (epis,rec,res,result,date,time,QC)=""
  f i=1:1:$l(AllRecord,cr) d
  .s rec=$p(AllRecord,cr,i)
  .s type=$tr($p(rec,"|")," ")
  .//判断为获取条码信息,给仪器上传标本信息
  .//格式:GetPatInfo|条码号|LISVMachine1.0|||||||||
  .//仪器要求格式:PatInfo|条码号|LISVMachine1.0|患者姓名|性别|年龄|科室|病区|诊断|采集日期|传输日期|通道^通道^通道
  .i type="GetPatInfo" d
  ..s epis=$tr($p(rec,"|",2)," ")
  ..s ^TMP($zn,$j,"ENQ",epis)=""
  .//判断为结果信息,解析结果
  .//格式:Result|条码号|通道|结果$c(13)
  .i type="Result" d  
  ..s epis=$tr($p(rec,"|",2)," ")
  ..s code=$tr($p(rec,"|",3)," ")
  ..s res=$tr($p(rec,"|",4)," ")
  ..s result=result_code_ResultDeli_res_ItemDeli
  .//格式:Last|条码号|END|$c(13)
  .i type="Last" d Last q
  d BUILD
  q
  
Last	
	s AllRecord=""
	s epis=$tr($p(rec,"|",2)," ")
	i $l(epis),$l(result) d
	.d Save^MI.MIF000(mi,epis,result,date,time,QC)  
	q
 
BUILD
  i '$d(^TMP($zn)) q
  i '$d(^TMP($zn,$j)) q 
  s labno="" f  s labno=$o(^TMP($zn,$j,"ENQ",labno)) q:labno=""  d
  .d ScanOne^MI.MIF000(mi,labno)
  .s tcx=""
  .s chl="" f  s chl=$o(^TMP("MIFTESTCODE",$j,mi,labno,chl)) q:chl=""  d
  ..i $l(tcx) s tcx=tcx_"^"_chl
  ..e  s tcx=tcx_chl
  .i '$l(tcx) s tcx="Chl1^Chl2^Chl3^Chl4^Chl5"
  .s date=$zd(+$h,8)
  .s time=$tr($zt($p($h,",",2)),":")
  .s temepis=""
  .//取患者信息
  .s (PatName,Sex,Age,Location,Ward,Symptom,CollectDate,TransmitDate)=""
  .i $d(^dbo.RPVisitNumberI("IndexVisitNumber"," "_$zcvt(labno,"U"))) d
  ..s VisitNumberDR=$o(^dbo.RPVisitNumberI("IndexVisitNumber"," "_$zcvt(labno,"U"),""))
  ..//姓名
  ..s PatName=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),13)
  ..//性别
  ..s SpeciesDR=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),15)
  ..s Sex=""
  ..i $l(SpeciesDR) s Sex=$lg($g(^dbo.BTSpeciesD(SpeciesDR)),3)
  ..//年龄
  ..s Age=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),18)
  ..s AgeUnitDR=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),19)
  ..s AgeUnit=""
  ..i $l(AgeUnitDR) s AgeUnit=$lg($g(^dbo.BTAgeUnitD(AgeUnitDR)),3)
  ..s Age=Age_AgeUnit
  ..s LocationDR=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),22)
  ..//科室
  ..s Location=""
  ..i $l(LocationDR) s Location=$lg($g(^dbo.BTLocationD(LocationDR)),3)
  ..s WardDR=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),26)
  ..//病区
  ..s Ward=""
  ..i $l(WardDR) s Ward=$lg($g(^dbo.BTWardD(WardDR)),3)
  ..//诊断
  ..s Symptom=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),28)
  ..//采集日期
  ..s CollectDate=$lg($g(^dbo.RPVisitNumberD(VisitNumberDR)),51)
  ..//传输日期
  ..s TransmitDate=CollectDate
  .//要求格式:PatInfo|条码号|LISVMachine1.0|患者姓名|性别|年龄|科室|病区|诊断|采集日期|传输日期|通道^通道^通道
  .s str="PatInfo|"_labno_"|LISVMachine1.0|"_PatName_"|"_Sex_"|"_Age_"|"_Location_"|"_Ward_"|"_Symptom_"|"_CollectDate_"|"_TransmitDate_"|"_tcx
  .d Send(labno,str) 
  .k ^TMP($zn,$j,"ENQ",labno)
  q

Send(epis,str)  ; send list of orders if exists
  w enq,*-3 d Trace^MI.MIF000(mi,"ENQ","H-->M")
  f j=1:1:10 r *R:1 i $c(R)=ack!($c(R)=enq) q
  //d trace^MIF000(mi,$s($c(R)=ack:"ACK",$c(R)=enq:"ENQ",$c(R)=nak:"NAK",1:R),"1H<--M")
  d Trace^MI.MIF000(mi,$s($c(R)=ack:"ACK",$c(R)=enq:"ENQ",$c(R)=nak:"NAK",1:R),"H<--M")
  i $c(R)=enq q
  i $c(R)'=ack w eot,*-3 d Trace^MI.MIF000(mi,"EOT","H-->M") q
  i $l(str)>241 d
  .s str1=$e(str,1,241)
  .s ret=$$SEND(str1,1)
  .s str2="2"_$e(str,242,$l(str))
  .s ret=$$SEND(str2,0)
  e  d
  .s ret=$$SEND(str,0)
  ;f j=1:1:10 r *R:1 i $c(R)=ack!($c(R)=enq) q
  ;d trace^MIF000(mi,$s($c(R)=ack:"ACK",$c(R)=enq:"ENQ",$c(R)=nak:"NAK",1:R),"2H<--M")
  w eot,*-3 d Trace^MI.MIF000(mi,"EOT","H-->M")
  q
 
SEND(str,flag)  ; send string to instrument
  i flag=1 d
  .s str=str_etb
  .s chsum=$$CHSUM(str)
  e  d
  .s str=str_etx
  .s chsum=$$CHSUM(str)
  w stx,str,chsum,cr,lf,*-3 d Trace^MI.MIF000(mi,str_chsum,"H-->M")
  f j=1:1:6 r *R:1 i ($c(R)=ack)!($c(R)=eot) q
  i $c(R)=ack d Trace^MI.MIF000(mi,"ACK","H<--M") q 0
  i $c(R)=eot d Trace^MI.MIF000(mi,"EOT","H<--M") q 0
  i $c(R)=-1 w nak,*-3
  d Trace^MI.MIF000(mi,R,"H<--M")
  q 1
  
CHSUM(x)  ; calculate check sum
  n (x) s z=0 f y=1:1:$l(x) s z=z+$a(x,y)
  s z=$e("0123456789ABCDEF",z#256\16+1)_$e("0123456789ABCDEF",z#16+1)
  q z
ACK  ; send 'ack' to instrument
  w ack,*-3
  d Trace^MI.MIF000(mi,"ACK","H-->M")
  q

RuntimeError
	h 5
	s iError=+$g(iError)+1
    d Trace^MI.MIF000(mi,"Error Code:"_$ECODE_",Error:"_$ZERROR,"Runtime Error")
    i iError>100  s ret=$$Stop^MI.MIF000(mi)
    Q    
      

总结
1.仪器接口一定要在mac里吗?
接口没有要求,只是仪器控制启动进程那里拼串是mac调用,正常类方法也行,只是需要启动仪器控制的支持。
2.调试仪器的时候只能写globle观察猜吗?
可以直接terminal运行仪器接口的入口方法,然后进行断点调试,只是停止仪器时候可能需要到portal杀进程。
3.仪器接口的核心命令就是用了OPEN命令和READ命令,为什么READ要分那么几次for循环读取呢,而不用一层循环一直READ?
分层次读协议的体现更清晰,解析协议的是协议,读数据的是读数据逻辑。

ASTM简单交互(ENQ开始、ACK中间回复、EOT结束)
仪器给LIS发数据
1.先发ENQ告诉LIS我要给你发数据
2.LIS回复ACK给仪器
3.仪器收到ACK后开发发数据给LIS,每段发送一STX控制开始LIS收到数据还是回ACK
4.仪器如果发送数据完了后给LIS发送EOT告诉发送完毕(一个通信过程就完毕)
在这里插入图片描述

LIS给仪器发数据
1.先发ENQ告诉仪器我要给你发数据
2.仪器回复ACK给LIS
3.仪器收到ACK后开发发数据给仪器,每段发送一STX控制开始仪器收到数据还是回ACK
4.LIS如果发送数据完了后给仪器发送EOT告诉发送完毕(一个通信过程就完毕)
在这里插入图片描述

HL7简单交互(SB开始、CR分次,EB结束)
HL7定义了消息交互结构,为:[SB]data[CR]data[CR][EB][CR]
SB:消息开始控制字符
EB:消息结束控制字符
CR:消息换行控制字符

仪器给LIS发数据
1.先发SB给LIS告诉我要给你发数据
2.LIS收到SB后准备接收发来的数据
3.仪器接着发送要传输的数据(HL7格式的串,多个用CR分开发送)
4.仪器发送完数据后发送EB、CR告诉LIS发送数据完毕
在这里插入图片描述

LIS给仪器发数据
1.先发SB给仪器告诉我要给你发数据
2.仪器收到SB后准备接收发来的数据
3.LIS接着发送要传输的数据(HL7格式的串,多个用CR分开发送)
4.LIS发送完数据后发送EB、CR告诉仪器发送数据完毕
在这里插入图片描述

以上说的ENQ,EOT,STX,ACK,SB,EB,CR都是ascii不可见字符,用不可见字符控制交互
//控制字符
stx=c(2),etx=c(2),etx=c(3),ack=c(6),enq=c(6),enq=c(5),eot=c(4)lf=c(4) lf=c(10),cr=c(13),nak=c(13),nak=c(21),etb=$c(23)

附(C#模拟astm协议实现的虚拟仪器,重点就是txtLabNo_KeyDown触发的给LIS发数据和machSerialPort_DataReceived解析LIS发来的数据部分,帮助更深入了解交互)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;

namespace LISVMachine
{
    /// <summary>
    /// 绑定数据委托
    /// </summary>
    /// <param name="result"></param>
    delegate void BindDataDelegate(string result);

    public partial class FrmMian : Form
    {
        /// <summary>
        /// 通信模式,0:串口,1:文本,2:数据库
        /// </summary>
        private int Model = 0;

        /// <summary>
        /// ack
        /// </summary>
        private string ACK = "[6]";

        /// <summary>
        /// enq
        /// </summary>
        private string ENQ = "[5]";

        /// <summary>
        /// eot
        /// </summary>
        private string EOT = "[4]";

        /// <summary>
        /// stx
        /// </summary>
        private string STX = "[2]";

        /// <summary>
        /// etx
        /// </summary>
        private string ETX = "[3]";

        /// <summary>
        /// 存待发送信息
        /// </summary>
        private List<string> SendList = new List<string>();

        /// <summary>
        /// 存收到的字符串
        /// </summary>
        private string ReciveStr = "";

        /// <summary>
        /// 状态。0:正常,1:等待发送,2:等待接收
        /// </summary>
        private int State = 0;

        /// <summary>
        /// 连接串
        /// </summary>
        string ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb";

        public FrmMian()
        {
            InitializeComponent();
        }

        private void FrmMian_Load(object sender, EventArgs e)
        {
            ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + "\\db.mdb";
            //初始化下拉串口名称列表框
            string[] ports = SerialPort.GetPortNames();
            Array.Sort(ports);
            cmbPortName.Items.AddRange(ports);
            cmbPortName.SelectedIndex = cmbPortName.Items.Count > 0 ? 0 : -1;
            RefreshGrid("1");
        }

        /// <summary>
        /// 通信方式切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbPortName_SelectedIndexChanged(object sender, EventArgs e)
        {
            ChangeModel();
        }

        /// <summary>
        /// 切换通信方式
        /// </summary>
        private void ChangeModel()
        {
            try
            {
                if (machSerialPort.IsOpen)
                {
                    WriteLog("关闭已打开串口");
                    machSerialPort.Close();
                }
                machSerialPort.PortName = cmbPortName.Text;
                WriteLog("尝试启动串口:" + machSerialPort.PortName);
                machSerialPort.Open();
                WriteLog("启动串口:" + machSerialPort.PortName + "成功");
                WriteLog("串口通信模式");
                labInfo.Text = "波特率9600,数据位8,停止位1,校验位None。文本上传在Order文件夹下,结果数据在Result文件夹下,图片在Image文件夹下。数据库双向直接操作MachResult表上传和取结果";

            }
            catch (Exception ex)
            {
                WriteLog("启动串口异常:" + ex.Message);
                //现实异常信息给客户。                    
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK);
            }
        }


        /// <summary>
        /// 扫描
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtLabNo_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (txtLabNo.Text != "")
                {
                    //等待发送数据
                    State = 1;
                    SendList.Add("GetPatInfo|" + txtLabNo.Text + "|LISVMachine1.0|||||||||");
                    Send(ENQ);
                    txtLabNo.Text = "";
                }
            }
        }

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="sendStr"></param>
        private void Send(string sendStr)
        {
            //串口打开的话就转给串口
            if (machSerialPort.IsOpen)
            {
                //处理为不可见字符
                sendStr = DealNotSeeChar(sendStr);
                byte[] byteArray = System.Text.Encoding.Default.GetBytes(sendStr);
                //转发给串口
                machSerialPort.Write(byteArray, 0, byteArray.Count());
                WriteLog("发送给LIS:" + DealNotSeeToSeeCharLIS(sendStr));
            }
            else
            {
                WriteLog("发送给LIS:串口未打开,无法发送");
            }
        }



        /// <summary>
        /// 串口收到数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void machSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int n = machSerialPort.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
            byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
            machSerialPort.Read(buf, 0, n);//读取缓冲数据
            string lineStr = System.Text.Encoding.Default.GetString(buf);
            string lineOld = lineStr;
            lineStr = DealNotSeeToSeeChar(lineStr);
            WriteLog("LIS给仪器:" + DealNotSeeToSeeCharLIS(lineOld));
            if (lineStr == ACK && State == 1)
            {
                if (SendList.Count > 0)
                {
                    string sendStr = SendList[0];
                    SendList.RemoveAt(0);
                    Send(STX);
                    Send(sendStr);
                }
                else
                {
                    Send(EOT);
                    State = 0;
                }
            }
            if (lineStr == ENQ)
            {
                //等待接收数据
                State = 2;
                Send(ACK);
                ReciveStr = "";
            }
            if (lineStr == EOT)
            {
                //正常状态
                State = 0;
                //存数据
                WriteLog("接收数据完毕,仪器分析中");
                //要求格式:PatInfo|条码号|LISVMachine1.0|患者姓名|性别|年龄|科室|病区|诊断|采集日期|传输日期|通道^通道^通道
                if (ReciveStr != "")
                {
                    List<string> resListRet = DealPatInfo(ReciveStr);
                    if (resListRet != null && resListRet.Count > 0)
                    {
                        SendList.AddRange(resListRet);
                        WriteLog("仪器出结果");
                        Send(ENQ);
                        //待发送数据状态
                        State = 1;
                    }
                }
            }
            //接收数据
            if (State == 2 && lineStr != ENQ && lineStr != EOT && lineStr != STX)
            {
                ReciveStr += lineStr.Replace(STX, "");
                Send(ACK);
            }
        }



        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="log"></param>
        private void WriteLog(string log)
        {
            //组装参数
            object[] paras = new object[] { log };
            this.Invoke(new BindDataDelegate(BindData), paras);
        }

        /// <summary>
        /// 绑定监听数据
        /// </summary>
        private void BindData(string log)
        {
            txtLog.Text += DateTime.Now.ToString("hh:mm:ss: ") + log + "\n";
        }

        /// <summary>
        /// 刷新表格数据
        /// </summary>
        /// <param name="log"></param>
        private void RefreshGrid(string code)
        {
            //组装参数
            object[] paras = new object[] { code };
            this.Invoke(new BindDataDelegate(BindGridData), paras);
        }

        /// <summary>
        /// 绑定监听数据
        /// </summary>
        private void BindGridData(string code)
        {
            dgData.DataSource = DBHelper.QryData(ConnectionString, "select * from MachResult");
        }

        /// <summary>
        /// 处理为不可见字符
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private string DealNotSeeChar(string s)
        {
            for (int i = 0; i <= 31; i++)
            {
                s = s.Replace("[" + i + "]", (char)i + "");
            }
            s = s.Replace("[127]", (char)127 + "");
            return s;
        }

        /// <summary>
        /// 处理不可见字符
        /// </summary>
        /// <param name="data">数据</param>
        /// <returns>返回</returns>
        public string DealNotSeeToSeeChar(string data)
        {
            for (int i = 0; i <= 31; i++)
            {
                data = data.Replace((char)i + "", "[" + i + "]");
            }
            data.Replace((char)127 + "", "[127]");
            return data;
        }


        /// <summary>
        /// 处理不可见字符
        /// </summary>
        /// <param name="data">数据</param>
        /// <returns>返回</returns>
        public string DealNotSeeToSeeCharLIS(string data)
        {
            for (int i = 0; i <= 31; i++)
            {
                if (i == 6)
                {
                    data = data.Replace((char)i + "", "[ACK]");
                }
                else if (i == 5)
                {
                    data = data.Replace((char)i + "", "[ENQ]");
                }
                else if (i == 4)
                {
                    data = data.Replace((char)i + "", "[EOT]");
                }
                else if (i == 3)
                {
                    data = data.Replace((char)i + "", "[ETX]");
                }
                else if (i == 4)
                {
                    data = data.Replace((char)i + "", "[STX]");
                }
                else
                {
                    data = data.Replace((char)i + "", "[" + i + "]");
                }
            }
            data.Replace((char)127 + "", "[127]");
            return data;
        }

        /// <summary>
        /// 定时器,定时检测上传数据和出结果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerMian_Tick(object sender, EventArgs e)
        {
            string orderPath = Application.StartupPath + "\\Order";
            DirectoryInfo di = new DirectoryInfo(orderPath);
            FileInfo[] orders = di.GetFiles("*.imedicallis");
            WriteLog("检测Order下是否有*.imedicallis的上传文件");
            if (orders != null && orders.Length > 0)
            {
                foreach (FileInfo f in orders)
                {
                    string orderStr = TxtUtil.ReadTxt(f.FullName);
                    WriteLog("解析:" + f.FullName);
                    DealPatInfo(orderStr);
                    File.Delete(f.FullName);
                }
            }
            WriteLog("查询数据库SendFlag为空的上传记录");
            DataTable dt = DBHelper.QryData(ConnectionString, "select * from MachResult where SendFlag is null");
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow r in dt.Rows)
                {
                    List<string> randomRes = new List<string>();
                    for (int i = 0; i < 20; i++)
                    {
                        Random rand = new Random(DateTime.Now.Millisecond);
                        randomRes.Add((rand.NextDouble() * 100).ToString());
                    }
                    string UPChl = r["UPChl"].ToString();
                    string updateSq = "update MachResult set SendFlag='" + DateTime.Now.ToString("yyyyMMddhhmmss") + "'";
                    for (int i = 0; i < 20; i++)
                    {
                        if ((UPChl != "") && (!UPChl.Contains("Chl" + (i + 1))))
                        {
                            continue;
                        }
                        updateSq += ",Chl" + (i + 1) + "='" + randomRes[i] + "'";
                    }
                    updateSq += " where RowID=" + r["RowID"].ToString();
                    try
                    {
                        int ret = DBHelper.ExeSql(ConnectionString, updateSq);
                        if (ret == 1)
                        {
                            WriteLog("更新" + r["EpisNo"].ToString() + "数据库结果");
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteLog("仪器数据库结果插入异常" + ex.Message);
                    }
                }
            }
        }

        /// <summary>
        /// 处理患者信息出结果
        /// </summary>
        /// <param name="oderStr"></param>
        /// <returns></returns>
        private List<string> DealPatInfo(string oderStr)
        {
            List<string> retList = new List<string>();
            if (oderStr != "")
            {
                string[] patInfoArr = oderStr.Split('|');
                if (patInfoArr.Length >= 12)
                {
                    if (patInfoArr[0] == "PatInfo")
                    {
                        string EpisNo = patInfoArr[1];
                        string PatName = patInfoArr[3];
                        string Sex = patInfoArr[4];
                        string PatAge = patInfoArr[5];
                        string Location = patInfoArr[6];
                        string Ward = patInfoArr[7];
                        string Diagnose = patInfoArr[8];
                        string CollDate = patInfoArr[9];
                        if (CollDate == "")
                        {
                            CollDate = DateTime.Now.ToString("yyyyMMdd");
                        }
                        string TransDate = patInfoArr[10];
                        if (TransDate == "")
                        {
                            TransDate = DateTime.Now.ToString("yyyyMMdd");
                        }
                        string Chl = patInfoArr[11];
                        if (EpisNo != "" && PatName != "")
                        {
                            List<string> randomRes = new List<string>();
                            for (int i = 0; i < 20; i++)
                            {
                                Random rand = new Random(DateTime.Now.Millisecond);
                                randomRes.Add((rand.NextDouble() * 100).ToString());
                            }
                            string sql = "insert into MachResult(EpisNo,PatName,PatAge,Sex,Location,Ward,Diagnose,CollDate,TransDate,UPChl,Chl1,Chl2,Chl3,Chl4,Chl5,Chl6,Chl7,Chl8,Chl9,Chl10,Chl11,Chl12,Chl13,Chl14,Chl15,Chl16,Chl17,Chl18,Chl19,Chl20,Img1,Img2,SendFlag) values('" + EpisNo + "','" + PatName + "','" + PatAge + "','" + Sex + "','" + Location + "','" + Ward + "','" + Diagnose + "','" + CollDate + "','" + TransDate + "','" + Chl + "','" + randomRes[0] + "','" + randomRes[1] + "','" + randomRes[2] + "','" + randomRes[3] + "','" + randomRes[4] + "','" + randomRes[5] + "','" + randomRes[6] + "','" + randomRes[7] + "','" + randomRes[8] + "','" + randomRes[9] + "','" + randomRes[10] + "','" + randomRes[11] + "','" + randomRes[12] + "','" + randomRes[13] + "','" + randomRes[14] + "','" + randomRes[15] + "','" + randomRes[16] + "','" + randomRes[17] + "','" + randomRes[18] + "','" + randomRes[19] + "','" + "Image\\Img1.bmp" + "','" + "Image\\Img2.bmp" + "','" + DateTime.Now.ToString("yyyyMMddhhmmss") + "')";
                            try
                            {
                                int ret = DBHelper.ExeSql(ConnectionString, sql);
                                RefreshGrid("1");
                                string[] ChlArr = Chl.Split('^');
                                for (int j = 0; j < ChlArr.Length; j++)
                                {
                                    string chlOne = ChlArr[j];
                                    if (chlOne == "Chl1")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[0] + (char)13);
                                    }
                                    else if (chlOne == "Chl2")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[1] + (char)13);
                                    }
                                    else if (chlOne == "Chl3")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[2] + (char)13);
                                    }
                                    else if (chlOne == "Chl4")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[3] + (char)13);
                                    }
                                    else if (chlOne == "Chl5")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[4] + (char)13);
                                    }
                                    else if (chlOne == "Chl6")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[5] + (char)13);
                                    }
                                    else if (chlOne == "Chl7")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[6] + (char)13);
                                    }
                                    else if (chlOne == "Chl8")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[7] + (char)13);
                                    }
                                    else if (chlOne == "Chl9")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[8] + (char)13);
                                    }
                                    else if (chlOne == "Chl10")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[9] + (char)13);
                                    }
                                    else if (chlOne == "Chl11")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[10] + (char)13);
                                    }
                                    else if (chlOne == "Chl12")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[11] + (char)13);
                                    }
                                    else if (chlOne == "Chl13")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[12] + (char)13);
                                    }
                                    else if (chlOne == "Chl14")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[13] + (char)13);
                                    }
                                    else if (chlOne == "Chl15")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[14] + (char)13);
                                    }
                                    else if (chlOne == "Chl16")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[15] + (char)13);
                                    }
                                    else if (chlOne == "Chl17")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[16] + (char)13);
                                    }
                                    else if (chlOne == "Chl18")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[17] + (char)13);
                                    }
                                    else if (chlOne == "Chl19")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[18] + (char)13);
                                    }
                                    else if (chlOne == "Chl20")
                                    {
                                        retList.Add("Result|" + EpisNo + "|" + chlOne + "|" + randomRes[19] + (char)13);
                                    }
                                    else
                                    {
                                        WriteLog("非Chl1-Chl20的通道");
                                    }
                                }
                                retList.Add("Last|" + EpisNo + "|END|" + (char)13);
                                StringBuilder sb = new StringBuilder();
                                foreach (var v in retList)
                                {
                                    sb.Append(v);
                                }
                                string resultPath = Application.StartupPath + "\\Result\\" + DateTime.Now.ToString("yyyyMMddhhmmss-") + EpisNo + ".lisres";
                                TxtUtil.WriteTxt(resultPath, sb.ToString());
                                WriteLog("生成文件到:" + resultPath);
                            }
                            catch (Exception ex)
                            {
                                WriteLog("患者信息入库失败:" + ex.Message);
                            }
                        }
                        else
                        {
                            WriteLog("流水号和患者姓名不能为空");
                        }
                    }
                    else
                    {
                        WriteLog("患者信息没有PatInfo头,例如:PatInfo|条码号|LISVMachine1.0|患者姓名|性别|年龄|科室|病区|诊断|采集日期|传输日期|通道^通道^通道");
                    }
                }
                else
                {
                    WriteLog("患者信息位数不足,例如:PatInfo|条码号|LISVMachine1.0|患者姓名|性别|年龄|科室|病区|诊断|采集日期|传输日期|通道^通道^通道");
                }
            }
            return retList;
        }

        /// <summary>
        /// 重传
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnToLis_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dgData.Rows.Count; i++)
            {
                if ((bool)dgData.Rows[i].Cells["Check"].EditedFormattedValue == true)
                {
                    if (dgData.Rows[i].Cells["RowID"] == null)
                    {
                        continue;
                    }
                    string RowID = dgData.Rows[i].Cells["RowID"].Value.ToString();
                    DataTable dt = DBHelper.QryData(ConnectionString, "select * from MachResult where RowID=" + RowID);
                    if (dt.Rows.Count >= 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        foreach (DataRow r in dt.Rows)
                        {
                            string EpisNo = r["EpisNo"].ToString();
                            for (int j = 0; j < 20; j++)
                            {
                                string chl = "Chl" + (j + 1);
                                string res = r[chl].ToString();
                                if (res != "")
                                {
                                    sb.Append("Result|" + EpisNo + "|" + chl + "|" + res + (char)13);
                                }
                            }
                            sb.Append("Last|" + EpisNo + "|END|" + (char)13);
                            string resultPath = Application.StartupPath + "\\Result\\" + DateTime.Now.ToString("yyyyMMddhhmmss-") + EpisNo + ".lisres";
                            TxtUtil.WriteTxt(resultPath, sb.ToString());
                            WriteLog("生成文件到:" + resultPath);
                            DBHelper.ExeSql(ConnectionString, "update MachResult set SendFlag='" + DateTime.Now.ToString("yyyyMMddhhmmss") + "' where RowID=" + r["RowID"].ToString());
                            WriteLog("更新" + r["RowID"].ToString() + "的SendFlag为当前时间");
                        }
                    }
                }
            }
            MessageBox.Show("重传成功!", "提示", MessageBoxButtons.OK);
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelect_Click(object sender, EventArgs e)
        {
            string dateStr=dtDate.Value.ToString("yyyyMMdd");
            dgData.DataSource = DBHelper.QryData(ConnectionString, "select * from MachResult where CollDate='" + dateStr+"'");
        }

        /// <summary>
        /// 查全部
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            string dateStr = dtDate.Value.ToString("yyyyMMdd");
            dgData.DataSource = DBHelper.QryData(ConnectionString, "select * from MachResult");
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章