一直对盒子串口仪器接口缺乏系统的了解。为什么仪器控制能启动停止,为什么能读到数据,接口结构为什么要那样写等等,特地系统的学习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(3),ack=c(5),eot=c(10),cr=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");
}
}
}