檢驗串口儀器探祕

一直對盒子串口儀器接口缺乏系統的瞭解。爲什麼儀器控制能啓動停止,爲什麼能讀到數據,接口結構爲什麼要那樣寫等等,特地系統的學習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");
        }
    }
}

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