WCF医院管理系统技术解析(十一)医生体检收入查询(带一定判断的导出Excel)
医院支持对各个科室的体检收入,同时也可以查询到每个体检科室收入的审核医生。效果如图所示:
界面用到的控件有:
控件 | 说明
从工具箱中找到对应的控件,可以设置控件的一些属性和事件。如显示的文本,命名是规范
|
复选框(CheckBox) |
下拉框 (ComBobox)
数据表格 (DataGridView)
按钮(Button)
标签 (Label)
涉及到的数据库中的表和关系有:
表1:员工 表(BT_StaffTable)
列名 | 数据类型 | 主键/外键 | 说明 |
StaffID | int | 主键 | 员工ID |
TechnicalOfficesID | int | 外键 | 科室ID |
StaffNumber | nchar (20) |
| 员工编号 |
StaffName | nchar (20) |
| 员工名称 |
WhetherOperator | bit |
| 操作员否 |
AlphabeticBrevityCode | nchar (20) |
| 拼音简码 |
WubiInCode | nchar (20) |
| 五笔简码 |
AS_StaffPositionID | int | 外键 | 员工职务ID |
AS_MedicalTitlesID | int | 外键 | 医务职称ID |
AS_WorkingStatusID | int | 外键 | 工作状态ID |
AS_SexID | int | 外键 | 性别ID |
ContactTelephone | nchar (50) |
| 联系电话 |
WhetherBuiltIn | bit |
| 内置否 |
RegisteredSum | decimal (18, 2) |
| 挂号金额 |
AS_IntoTheHobbyID | int | 外键 | 录入爱好ID |
StaffPhotos | char (200) |
| 员工照片 |
| nchar (70) |
| 电子邮件 |
IDCardNo | nchar (100) |
| 身份证号 |
ContactAddress | nchar (100) |
| 联系地址 |
Birthday | datetime |
| 出生日期 |
WhetherBirthdayRemind | bit |
| 生日提醒否 |
WorkDate | datetime |
| 工作日期 |
TerminationDate | datetime |
| 离职日期 |
AS_OfficialAcademicCredentialsID | int | 外键 | 最高学历ID |
StudySubject | nchar (70) |
| 学习专业 |
AS_PoliticsStatusID | int | 外键 | 政治面貌ID |
Remarks | nchar (100) |
| 员工备注 |
WhetherEffective | bit | ((1)) | 有效否 |
表2:项目表(BT_ItemTable)
列名 | 数据类型 | 主键/外键 | 说明 |
ItemID | int | 主键 | 项目ID |
ItemName | nchar (70) | 外键 | 项目名称 |
ItemCoding | nchar (50) |
| 项目编号 |
AS_UserStatusID | int | 外键 | 使用状态ID |
ProjectPrice | decimal (18, 2) |
| 现金价格 |
TechnicalOfficesID | int | 外键 | 科室ID |
DiscountProportion | decimal (18, 2) |
| 折扣比例 |
WhetherEffective | bit | ((1)) | 有效否 |
ItemRemarks | nchar (100) |
| 项目备注 |
ItemUnit | nchar (20) |
| 项目单位 |
表3:体检执行表:【PhysicalExaminationExecuteTable】
列名 | 数据类型 | 主键/外键 | 说明 |
PhysicalExaminationExecuteID | int | 主键 | 体检执行ID |
ChargeBillID | int | 外键 | 收费单ID |
ExecuteDoctor_StaffID | int | 外键 | 执行医生ID |
ExecuteNumber | nchar (20) |
| 体检执行单号 |
Remarks | nchar (200) |
| 备注 |
HealthSuggest | nchar (200) |
| 健康建议 |
WhetherEffective | bit | ((1)) | 是否有效 |
表4: 科室表: (BT_ TechnicalOfficesTable)
列名 | 数据类型 | 主键/外键 | 说明 |
TechnicalOfficesID | int | 主键 | 科室ID |
DepartmentID | int | 外键 | 部门ID |
TechnicalOfficesNumber | nchar (20) |
| 科室编号 |
TechnicalOfficesName | nchar (20) |
| 科室名称 |
RegisterSum | decimal (18, 2) |
| 挂号金额 |
WhetherAllowRegister | bit |
| 允许挂号否 |
AlphabeticBrevityCode | nchar (20) |
| 拼音简码 |
WubiInCode | nchar (20) |
| 五笔简码 |
TechnicalOfficesLocation | nchar (100) |
| 科室位置 |
Remarks | nchar (200) |
| 备注 |
WhetherEffective | bit | ((1)) | 有效否 |
表5:体检执行内容明细表【PW_PhysicalExaminationExecuteContentDetailTable】
列名 | 数据类型 | 主键/外键 | 说明 |
PhysicalExaminationExecuteContentDetailID | int - Identity | 主键 | 体检执行内容明细ID |
PhysicalExaminationContentID | int | 外键 | 体检执行内容ID |
ItemID | int | 外键 | 项目ID |
PhysicalExaminationExecuteContentMessage | nchar (250) | 体检执行内容信息 | |
WhetherEffective | bit | ((1)) | 有效否 |
PhysicalExaminationExecuteID | int | 外键 | 体检执行ID |
ReportDoctor_StaffID | int | 外键 | 报告医生ID |
ReportTime | date | 报告时间 |
数据库涉及到的储存过程有:
--医生体检收入查询汇总
if @Type = 'FRM_TiJianZhongHeBaoBiao_Load_Doctor_Income'
BEGIN
SELECT DISTINCT
BT_StaffTable.StaffName, BT_TechnicalOfficesTable.TechnicalOfficesName, BT_TechnicalOfficesTable.TechnicalOfficesID, BT_ItemTable.ItemName,
PW_PhysicalExaminationExecuteTable.PhysicalExaminationExecuteID, BT_ItemTable.ItemID, PW_PhysicalExaminationExecuteContentDetailTable.ReportDoctor_StaffID,
BT_ItemTable.ProjectPrice
FROM PW_PhysicalExaminationExecuteTable INNER JOIN
PW_PhysicalExaminationExecuteContentDetailTable ON
PW_PhysicalExaminationExecuteTable.PhysicalExaminationExecuteID = PW_PhysicalExaminationExecuteContentDetailTable.PhysicalExaminationExecuteID INNER JOIN
BT_ItemTable ON PW_PhysicalExaminationExecuteContentDetailTable.ItemID = BT_ItemTable.ItemID INNER JOIN
BT_StaffTable ON PW_PhysicalExaminationExecuteContentDetailTable.ReportDoctor_StaffID = BT_StaffTable.StaffID INNER JOIN
BT_TechnicalOfficesTable ON BT_StaffTable.TechnicalOfficesID = BT_TechnicalOfficesTable.TechnicalOfficesID
END
BLL中对应的方法有:
//医生体检收入查询汇总
[OperationContract]
public DataSet FRM_TiJianZhongHeBaoBiao_Load_Doctor_Income()
{
SqlParameter[] mySqlParameters = {
new SqlParameter("@Type",SqlDbType .Char ),
};
mySqlParameters[0].Value = "FRM_TiJianZhongHeBaoBiao_Load_Doctor_Income ";
DataTable dt = myDALMethod.QueryDataTable("TiJianZhongXin_FRM_TiJianZhongHeBaoBiao_Main", mySqlParameters);
DataSet ds = new DataSet();
ds.Tables.Add(dt);
return ds;
}
UIL中与之对应的代码有:
#region dgv数据绑定
{
DataTable dtcbo_Valuation = new DataTable();//声明一个空表
//查询出数据库中的体检执行项目中的医生和科室存放在dt中
DataTable dt = myFRM_TiJianZhongHeBaoBiao_MainClient.FRM_TiJianZhongHeBaoBiao_Load_Doctor_Income().Tables[0];
//把dt中的的数据进行筛选并存放在 dtcbo_Valuation中
dtcbo_Valuation = dt.DefaultView.ToTable(true, "TechnicalOfficesName", "TechnicalOfficesID", "StaffName", "ReportDoctor_StaffID");
//在dtcbo_Valuation中添加金额列
dtcbo_Valuation.Columns.Add("金额");
DataTable dtShuJuMessage = dtcbo_Valuation;//把dtcbo_Valuation绑定到dgv中
dtShuJuMessage.Columns.Add("项次");
DataTable dtCopy = dt.Copy();//另外声明一个表,复制dt中的数据
int intSelect = 0; decimal decProjectPrice = Convert.ToDecimal(0.00);
int intYiSheng = 0; int intKeShiID = 0; int intCiShu = 0; //用于获取体检次数汇总
decimal decJinE = 0;//用于获取总金额汇总
for (int j = 0; j < dtShuJuMessage.Rows.Count; j++)//遍历dtShuJuMessage
{
intSelect = 0; decimal decTruePrice = Convert.ToDecimal(0.00);
if (intKeShiID == Convert.ToInt32(dtShuJuMessage.Rows[j]["TechnicalOfficesID"]) && //判断已循环数据的科室ID与未循环的科室UD
intYiSheng == Convert.ToInt32(dtShuJuMessage.Rows[j]["ReportDoctor_StaffID"]))//判断已循环数据的报告医生ID与未循环的报告医生ID
{
break;//如果相等就跳出循环
}
else
{
for (int i = 0; i < dt.Rows.Count; i++)//遍历dt,获取项目价格和科室ID与报告医生ID
{
int intTechnicalOfficesID1 = Convert.ToInt32(dtShuJuMessage.Rows[j]["TechnicalOfficesID"]);
int YishenID = Convert.ToInt32(dtShuJuMessage.Rows[j]["ReportDoctor_StaffID"]);
decProjectPrice = Convert.ToDecimal(dt.Rows[i]["ProjectPrice"]);//获取项目价格
if (intTechnicalOfficesID1 == Convert.ToInt32(dt.Rows[i]["TechnicalOfficesID"]) &&//判断dgv中的科室ID是否和dt表中的科室ID进行比较
YishenID == Convert.ToInt32(dt.Rows[i]["ReportDoctor_StaffID"]))//判断已循环数据的报告医生ID与未循环的报告医生ID比较
{
//如果相等,那么
intSelect++;//声明一个变量累加项次
intYiSheng = YishenID;//用变量分别获取医生ID 和科室ID,用于判断之后的医生和科室ID是否和已经循环的医生和科室ID
intKeShiID = intTechnicalOfficesID1;
decTruePrice = decProjectPrice + decTruePrice;//对应体检项目价格进行累加
}
}
dtShuJuMessage.Rows[j]["项次"] = intSelect;//把累加的项次变量结果赋值给次数
dtShuJuMessage.Rows[j]["金额"] = decTruePrice;//项目价格赋值给金额
intCiShu += intSelect;//获取体检次数
decJinE += decTruePrice;//获取总金额
if (Convert.ToInt32(dtShuJuMessage.Rows[j]["项次"]) == 0)//如果项次为零的,就移除该行
{
dtShuJuMessage.Rows.RemoveAt(j);
}
}
}
DataRow dr = dtShuJuMessage.NewRow();//往dtShuJuMessage中添加新行
dr["TechnicalOfficesName"] = "总计:";
dr["项次"] = intCiShu;
dr["金额"] = decJinE;
dtShuJuMessage.Rows.Add(dr);
dgv_AllDoctorIncomeMessage.DataSource = dtShuJuMessage;
#endregion
}
点击导出会把数据表格中的数据导出到Excel中,其导出效果如下图:
功能实现步骤一:点击解决方案总的引用
添加如下几个引用
如下图:
当点击导出,把数据导出到数据表格当中,在导出按钮后面写如下代码:
if (dgv_AllDoctorIncomeMessage.Rows.Count > 0)
{
PublicStaticMothd.DataGridViewToExcel(dgv_AllDoctorIncomeMessage);
}
为公共方法:代码如下:
public static void DataGridViewToExcel(DataGridView dgv)
{
#region 验证可操作性
SaveFileDialog dlg = new SaveFileDialog();//申明保存对话框
dlg.DefaultExt = "xls ";//默认文件后缀
dlg.Filter = "EXCEL文件(*.XLS)|*.xls ";//文件后缀列表
dlg.InitialDirectory = Directory.GetCurrentDirectory();//默然路径是系统当前路径
if (dlg.ShowDialog() == DialogResult.Cancel) return;//打开保存对话框
string fileNameString = dlg.FileName; //返回文件路径
if (fileNameString.Trim() == " ") //验证strFileName是否为空或值无效
{
MessageBox.Show("名字不能为空,请输入文件名字!", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
int rowscount = dgv.Rows.Count; //定义表格内数据的行数和列数
int colscount = dgv.Columns.Count;
if (rowscount <= 0) //行数必须大于0
{
MessageBox.Show("没有数据可供保存!", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (colscount <= 0) //列数必须大于0
{
MessageBox.Show("没有数据可供保存!", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (rowscount > 65536) //行数不可以大于65536
{
MessageBox.Show("数据记录数太多(最多不能超过65536条),不能保存!", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (colscount > 255)//列数不可以大于255
{
MessageBox.Show("数据记录列数太多,不能保存!", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
FileInfo file = new FileInfo(fileNameString); //验证以fileNameString命名的文件是否存在,如果存在删除它
if (file.Exists)//对存在fileNameString命名的文件进行删除
{
try
{
file.Delete();//删除
}
catch (Exception error)
{
MessageBox.Show(error.Message, "删除失败!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
}
#endregion
Microsoft.Office.Interop.Excel.Application objExcel = null;
Microsoft.Office.Interop.Excel.Workbook objWorkbook = null;
Microsoft.Office.Interop.Excel.Worksheet objsheet = null;
try
{
objExcel = new Microsoft.Office.Interop.Excel.Application();//申明对象
objWorkbook = objExcel.Workbooks.Add(Missing.Value);
objsheet = (Microsoft.Office.Interop.Excel.Worksheet)objWorkbook.ActiveSheet;
objExcel.Visible = false;//设置EXCEL不可见
int displayColumnsCount = 1; //向Excel中写入表格的表头
for (int i = 0; i <= dgv.ColumnCount - 1; i++)//遍历dgv中的列名数据集合
{
if (dgv.Columns[i].Visible == true)
{
objExcel.Cells[1, displayColumnsCount] = dgv.Columns[i].HeaderText.Trim();
displayColumnsCount++;
}
}
for (int row = 0; row <= dgv.RowCount - 1; row++)//遍历dgv中行数据集合
{
displayColumnsCount = 1;
for (int col = 0; col < colscount; col++)
{
if (dgv.Columns[col].Visible == true)
{
try
{
objExcel.Cells[row + 2, displayColumnsCount] = dgv.Rows[row].Cells[col].Value.ToString().Trim();
displayColumnsCount++;
}
catch (Exception)
{
}
}
}
}
objWorkbook.SaveAs(fileNameString, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value);
}
catch (Exception error)
{
MessageBox.Show(error.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
finally
{
//关闭Excel应用
if (objWorkbook != null) objWorkbook.Close(Missing.Value, Missing.Value, Missing.Value);
if (objExcel.Workbooks != null) objExcel.Workbooks.Close();
if (objExcel != null) objExcel.Quit();
objsheet = null;
objWorkbook = null;
objExcel = null;
}
MessageBox.Show(fileNameString + "\n\n导出完毕!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
这样就可以把数据表格中的数据导出到Excel中。