码迷,mamicode.com
首页 > Windows程序 > 详细

C#桌面办公应用-工资管理系统系列九

时间:2016-07-17 16:59:02      阅读:446      评论:0      收藏:0      [点我收藏+]

标签:

C#桌面办公应用-工资管理系统系列九

     今天介绍介绍一下我自主开发的工资管理系统中的“汇总查询打印”模块,改小模块具有以下的功能:可以汇总统计员工的工资发放明细信息,可以查询指定的某个部门下的某些员工的工资发放明细信息,并打印成报表!开发的流程为:建立一个用于汇总的数据库表、制作报表、汇总、查询打印!我自己觉得这个功能是相当有趣的,而且在实际的企业中也具有一定的适用性,可以根据企业的需要自主定制相应的报表!若有博友想获取该系统的源码,或者想作为自己的毕业设计的系统实现,可以加我QQ:1974544863进行交流!

     下面以“部门下的员工工资发放明细的汇总统计查询”为例,首先,建立汇总数据库表:tb_employeeSalarySummary

技术分享


     接着,制作企业定制的报表,采用的控件是微软的CrystalReport,即传说中的“水晶报表”。关于其制作过程,我觉得还是需要有技巧的,如果不知道这是个啥玩意,建议还是先去网上了解了解!!日后有时间了再来补充水晶报表的制作!下面是我自主制作的比较简陋的一个“员工工资发放明细”报表

技术分享


     接下来就是重点了,“汇总统计部门下某些或者某个员工的工资发放明细”或者“汇总统计单个员工的工资发放明细”。这个过程,实现起来还是挺辛苦的,由于涉及到“多个表与表之间的关联”,故而,在获取数据的时候,需要根据主外键进行关联,所以获取数据时候需要有一定的时间!

     下面是“汇总部门下员工工资发放明细”的核心代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;
using SMS.sevice;

namespace SMS.queryAndSumPrint
{
    //汇总员工工资
    class SummaryEmployeeSalary
    {

        public void QueryPrintSalOfEmpFunc(String strQueryType,String strQueryEmpLoinName)
        {
            try
            {
                EmployeeService employeeService = new EmployeeService();
                SalaryPayDetailsService salaryPayDetailsService = new SalaryPayDetailsService();

                //先删除原汇总表的数据
                String strIsDBExist = "select COUNT(*) from tb_employeeSalarySummary";
                int dbDataSum = salaryPayDetailsService.getCount(strIsDBExist);
                if (dbDataSum != 0)
                {
                    String strDeleteDBData = "Truncate Table tb_employeeSalarySummary";
                    salaryPayDetailsService.saveOrUpdatePart(strDeleteDBData);
                }


                //工资编号的个数     
                String strGetSalarySQL = "select COUNT(salaryId) from tb_salaryPayDetails";
                if (strQueryType == "员工查询与统计")
                {
                    strGetSalarySQL = "select COUNT(salaryId) from tb_salaryPayDetails,tb_employee where tb_salaryPayDetails.empId=tb_employee.empId and tb_employee.loginName='"+strQueryEmpLoinName+"'";
                }
                int salaryIdCount = salaryPayDetailsService.getCount(strGetSalarySQL);
                if (salaryIdCount == 0)
                {
                    return;
                }

                //获取工资编号
                int[] salaryIds = new int[salaryIdCount];
                String strGetSalaryId = "select salaryId from tb_salaryPayDetails";
                if (strQueryType == "员工查询与统计")
                {
                    strGetSalaryId = "select salaryId from tb_salaryPayDetails,tb_employee where tb_salaryPayDetails.empId=tb_employee.empId and tb_employee.loginName='"+strQueryEmpLoinName+"'";
                }

                String[] tempResult=salaryPayDetailsService.getQueryDataSet(strGetSalaryId, salaryIdCount);
                for (int i = 0; i < tempResult.Length;i++ )
                {
                    salaryIds[i]=Convert.ToInt32(tempResult[i]);
                }
                
                //根据工资编号获取   员工编号,员工姓名,所属部门名称,工资年份,工资月份,基本工资类型
                //奖励金类型,工资备注
                String[,] empIdNameAndPartName=new String[salaryIdCount,8];
                String[] infoFields=new String[]{
                    "empId","empName","partName","salYear","salMonth","salaryLevel","rewardType","salMemo"
                };
                for (int i = 0; i < salaryIdCount;i++ )
                {
                    String getInfoSQL = "select tb_employee.empId,empName,partName,salYear,salMonth,salaryLevel,rewardType,tb_salaryPayDetails.salMemo from tb_salaryPayDetails,tb_employee,tb_part where tb_salaryPayDetails.empId=tb_employee.empId and tb_employee.partID=tb_part.partId and salaryId='" + salaryIds[i] + "'";
                    String[] tempInfoResult=salaryPayDetailsService.getSpecificColumnValues(getInfoSQL, infoFields);
                    empIdNameAndPartName[i, 0] = tempInfoResult[0];
                    empIdNameAndPartName[i, 1] = tempInfoResult[1];
                    empIdNameAndPartName[i, 2] = tempInfoResult[2];
                    empIdNameAndPartName[i, 3] = tempInfoResult[3];
                    empIdNameAndPartName[i, 4] = tempInfoResult[4];
                    empIdNameAndPartName[i, 5] = tempInfoResult[5];
                    empIdNameAndPartName[i, 6] = tempInfoResult[6];
                    empIdNameAndPartName[i, 7] = tempInfoResult[7];
                }
                

                //根据工资编号获取 工资津贴,罚金,基本工资,奖励金金额,发放总金额
                Double[,] empSalaryData = new Double[salaryIdCount, 5];
                String[] salaryFields = new String[]{
                    "salJingTie","salFaJing","salaryAmount","rewardAmount","salSumAmount"
                };
                for (int i = 0; i < salaryIdCount; i++)
                {
                    String getInfoSQL = "select salJingTie,salFaJing,salaryAmount,rewardAmount,salSumAmount from tb_salaryPayDetails,tb_basicSalary,tb_rewardType where tb_salaryPayDetails.salaryLevel=tb_basicSalary.salaryLevel and tb_salaryPayDetails.rewardType=tb_rewardType.rewardType and salaryId='"+salaryIds[i]+"'";
                    String[] tempInfoResult = salaryPayDetailsService.getSpecificColumnValues(getInfoSQL, salaryFields);
                    empSalaryData[i, 0] = Convert.ToDouble(tempInfoResult[0]);
                    empSalaryData[i, 1] = Convert.ToDouble(tempInfoResult[2]);
                    empSalaryData[i, 2] = Convert.ToDouble(tempInfoResult[2]);
                    empSalaryData[i, 3] = Convert.ToDouble(tempInfoResult[3]);
                    empSalaryData[i, 4] = Convert.ToDouble(tempInfoResult[4]);
                }
                
                //根据员工编号和年份 获取  该员工该年总收入
                Double[,] yearSalaryAmount=new Double[salaryIdCount,1];
                for (int i = 0; i < salaryIdCount; i++)
                {
                    String getYearSalary = "select SUM(salSumAmount) from tb_salaryPayDetails where empId='" + empIdNameAndPartName[i, 0] + "' and salYear='" + empIdNameAndPartName[i, 3] + "'";
                    yearSalaryAmount[i, 0] = Convert.ToDouble(salaryPayDetailsService.getQueryDataSet(getYearSalary, 1)[0]);
                }
                //Console.WriteLine("dd");

                //开始汇总数据
                for (int i = 0; i < salaryIdCount; i++)
                {
                    try
                    {
                        String strInsertSQL = "insert into tb_employeeSalarySummary(salaryId,empId,empName,partName,salaryYear,salaryMonth,salaryJinTie,salaryFaJin,basicSalaryType,basicSalary,rewardType,rewardSalary,salarySumAmount,yearSumAmount,salaryMemo) values('" + salaryIds[i] + "','" + empIdNameAndPartName[i, 0] + "','" + empIdNameAndPartName[i, 1] + "','" + empIdNameAndPartName[i, 2] + "','" + empIdNameAndPartName[i, 3] + "','" + empIdNameAndPartName[i, 4] + "','" + empSalaryData[i, 0] + "','" + empSalaryData[i, 1] + "','" + empIdNameAndPartName[i, 5] + "','" + empSalaryData[i, 2] + "','" + empIdNameAndPartName[i, 6] + "','" + empSalaryData[i, 3] + "','" + empSalaryData[i, 4] + "','" + yearSalaryAmount[i,0] + "','" + empIdNameAndPartName[i, 7] + "')";
                        salaryPayDetailsService.saveOrUpdatePart(strInsertSQL);
                        

                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("汇总信息时出错: \n" + ex.Message);
                    }
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("发生异常: " + ex.Message);
            }
        }
    }
}

     其实,会发现,做的最多的是“根据某个外键获取另外的主键所在的表的其它字段信息”,而这在salaryPayDetailService类中已经进行了封装!

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 SMS.dbOperation;
using SMS.utils;

namespace SMS.sevice
{
    //工资发放明细服务层
    class SalaryPayDetailsService
    {
        private DBOperate operate = new DBOperate();
        private CommonUtils cmmUtils = new CommonUtils();

        /// <summary>
        /// 绑定Sql语句查询的结果到dataGridView中
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="dataGridView"></param>
        public void bindSqlResultToDatagridView(DataGridView dataGridView, String sql)
        {
            operate.BindDataGridView(dataGridView, sql);
            #region MyRegion //设置好datagriview中的列的显示宽度
            dataGridView.Columns[0].Width = 120;
            dataGridView.Columns[1].Width = 120;
            dataGridView.Columns[2].Width = 140;
            dataGridView.Columns[3].Width = 160;
            dataGridView.Columns[4].Width = 120;
            dataGridView.Columns[5].Width = 120;
            dataGridView.Columns[6].Width = 120;
            dataGridView.Columns[7].Width = 100;
            dataGridView.Columns[8].Width = 180;
            dataGridView.Columns[9].Width = 120;
            dataGridView.Columns[10].Width = 180;
            dataGridView.Columns[11].Width = 180;
            dataGridView.Columns[12].Width = 180;
            dataGridView.Columns[13].Width = 200;
            #endregion
        }

        /// <summary>
        /// 绑定SQL查询语句中的指定列到下拉列表
        /// </summary>
        /// <param name="strSQL">SQL语句:在里面指定需要绑定的数据库表列的名字--select typeName...</param>
        /// <param name="cb">取0</param>
        public void bindSpecificColumnToComboBox(String strSQL, ComboBox cb)
        {
            operate.BindDropdownlist(strSQL, cb, 0);
        }

        /// <summary>
        /// 用于判断指定的字段值 是否已经存在
        /// </summary>
        /// <param name="strSQL">其中sql语句为:select count(columnName) from ...格式</param>
        /// <returns></returns>
        public Boolean isExistSpecificObject(String strSQL)
        {
            Boolean res = false;
            int i = operate.HumanNum(strSQL);
            if (i > 0)
            {
                res = true;
            }
            return res;
        }

        /// <summary>
        /// 根据SQL获取数量值
        /// </summary>
        /// <param name="strSQL"></param>
        /// <returns></returns>
        public int getCount(String strSQL)
        {
            return operate.HumanNum(strSQL);
        }

        /// <summary>
        /// 保存或者更新(删除,修改)工资发放明细信息
        /// </summary>
        /// <param name="strSQL"></param>
        public int saveOrUpdatePart(String strSQL)
        {
            int i = operate.OperateData(strSQL);
            Console.WriteLine("操作的结果: " + i);
            return i;
        }

        /// <summary>
        /// 获取指定的数据库某一字段的值
        /// </summary>
        /// <param name="strObjectSQL">查询的SQL--指定了要查询的数据库字段</param>
        /// <param name="fieldNames">数据库字段数组</param>
        /// <returns></returns>
        public String getSpecificColumnValue(String strObjectSQL, String[] fieldNames)
        {
            return operate.GetDatasFromSelectedTable(strObjectSQL, fieldNames)[0];
        }

        /// <summary>
        /// 获取指定的数据库某些字段的值
        /// </summary>
        /// <param name="strObjectSQL">查询的SQL--指定了要查询的数据库字段</param>
        /// <param name="fieldNames">数据库字段数组</param>
        /// <returns></returns>
        public String[] getSpecificColumnValues(String strObjectSQL, String[] fieldNames)
        {
            return operate.GetDatasFromSelectedTable(strObjectSQL, fieldNames);
        }

        /// <summary>
        /// 根据SQL语句查询得到的DataSet获取DataSet那一列的所有值
        /// </summary>
        /// <param name="strQuerySQL"></param>
        /// <param name="count">将要获取的列的所有值的个数</param>
        /// <returns></returns>
        public String[] getQueryDataSet(String strQuerySQL,int count)
        {
            String[] results = new String[count];
            DataSet dsResult = operate.GetTable(strQuerySQL);
            dsResult.Dispose();
            if (dsResult.Tables[0].Rows.Count != 0)
            {
                for (int i = 0; i < count; i++)
                {
                    results[i] = dsResult.Tables[0].Rows[i][0].ToString().Trim();
                }
            }
            return results;
        }
    }
}

     下面是前端汇总统计查询界面的制作:技术分享

     下面是点击“打印”之后打印报表的“报表界面”的制作:需要放置一个crystalReportView的控件

技术分享

     下面是进入“汇总统计查询初始化加载时候汇总统计部门下员工工资发放明细信息”事件代码:

        private void frmPartEmployeeSalarySummary_Load(object sender, EventArgs e)
        {
            try
            {
                //汇总数据:“无”只是用来标识-这是“部门下员工工资的发放明细打印”
                summaryEmpSalary.QueryPrintSalOfEmpFunc("全部", "无");

                //加载信息
                String  strLoadSQL  = "select salaryId as '工资编号',empId as '员工编号',empName as '员工姓名',partName as '所属部门',salaryYear as '工资年份',salaryMonth as '工资月份',salaryJinTie as '工资津贴',salaryFaJin as '罚金',basicSalaryType as '基本工资类型',basicSalary as '基本工资',rewardType as '奖励金类型',rewardSalary as '奖励金金额',salarySumAmount as '发放总金额',yearSumAmount as '改年总收入',salaryMemo as '备注信息' from tb_employeeSalarySummary ";
                salaryPayDetailsService.bindSqlResultToDatagridView(dataGridViewSalaryPayDetailsInfo, strLoadSQL);
                dataGridViewSalaryPayDetailsInfo.Columns[14].Width = 200;

            }
            catch (System.Exception ex)
            {
                Console.WriteLine("初始化家在信息出错: " + ex.Message);
            }
        }

      下面是效果图:

技术分享


      下面是“打印”事件对应的源代码:

        private void buttonSave_Click(object sender, EventArgs e)
        {
            //记录当前列表的行数以及工资编号数组
            int salaryIdCount = 0;
            int[] salaryIds;

            try
            {
                int rows = dataGridViewSalaryPayDetailsInfo.Rows.Count;
                if (rows == 0)
                {
                    MessageBox.Show("当前没有可以打印的数据", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                if (DialogResult.OK == MessageBox.Show("是否打印上述员工的工资发放明细信息?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation))
                {
                    salaryIdCount = rows;
                    salaryIds = new int[rows];
                    for (int i = 0; i < rows; i++)
                    {
                        //MessageBox.Show(dataGridViewSalaryPayDetailsInfo.Rows[i].Cells[0].Value.ToString().Trim());
                        salaryIds[i] = Convert.ToInt32(dataGridViewSalaryPayDetailsInfo.Rows[i].Cells[0].Value.ToString().Trim());
                    }
                    frmPrintEmployeeSalary printEmployeeSalary = new frmPrintEmployeeSalary(salaryIdCount, salaryIds);
                    printEmployeeSalary.ShowDialog();
                }

            }
            catch (System.Exception ex)
            {
                Console.WriteLine("打印发生异常: " + ex.Message);
            }
        }

       特别注意的是,确定打印之后,需要记录有多少行数据以及各行数据对应的“工资编号”是多少,因为这是“主键”,然后在“打印窗体中”,接收这两个参数,下面是打印窗体对应的源代码:

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 SMS.dbOperation;
using SMS.crystalReport;
using CrystalDecisions.CrystalReports.Engine;
using System.IO;

namespace SMS.printForm
{
    public partial class frmPrintEmployeeSalary : Form
    {
        public frmPrintEmployeeSalary(int rows,int[] salaryIds)
        {
            InitializeComponent();
            this.printRows = rows;
            this.printSalaryIds = salaryIds;
        }

        DBOperate operate = new DBOperate();

        //记录打印的两个数据
        private int printRows;
        private int[] printSalaryIds;

        //测试数据
        private void frmPrintEmployeeSalary_Load(object sender, EventArgs e)
        {

        }

        //加载打印数据
        private void crystalReportViewer1_Load(object sender, EventArgs e)
        {
            string strSQL = "";
            try
            {
                strSQL = "select * from tb_employeeSalarySummary where salaryId = ";
                for (int i = 0; i < printRows; i++)
                {
                    strSQL += "'" + printSalaryIds[i] + "' or salaryId = ";
                }

                int index=strSQL.LastIndexOf("or");
                //Console.WriteLine(index);
                String newStr=strSQL.Substring(0, index);
                Console.WriteLine("真正的打印语句: "+newStr);

                //strSQL = strSQL.Substring(0, strSQL.LastIndexOf("or salaryId=")).Trim();

                DataSet dsDrivOfPerMsg = operate.GetTable(newStr);
                //dsDrivOfPerMsg.Dispose();

                //E:\vs2008-workspace\SMS\SMS\bin\Debug
                String rootPath = Environment.CurrentDirectory;
                String newPath=rootPath.Substring(0, rootPath.LastIndexOf("bin"));
                String crystalReportPath = newPath + "crystalReport\\CrystalReportOne.rpt";
                Console.WriteLine(crystalReportPath);
<span style="white-space:pre">		</span>//下面四条简洁的语句:将需要打印的数据塞进“打印”窗体中!这个很用的
                ReportDocument doc = new ReportDocument();
                doc.Load(crystalReportPath);
                doc.SetDataSource(dsDrivOfPerMsg.Tables[0]);
                crystalReportViewer1.ReportSource = doc;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("打印出错信息: \n" + ex.Message);
            }
        }
    }
}

       下面是“查询财物部门”下的员工的工资发放明细信息进行打印!

技术分享

        

      查询得到三条数据,下面点击“打印”,将打印“这三条数据”:

技术分享


     好了,今天介绍到这里吧!

     需要说明的是,我自主的开发的这个工资管理系统的介绍已经接近尾声,当然了,其实还有其他很多功能:比如数据备份,比如基础数据的维护,比如如何查看通过软件查看帮助文档等等,这些我都会在系列10以一个文档进行介绍,有兴趣的博友可以下载浏览,这个管理系统可以作为个人毕业设计时的系统实现,如果觉得可以的话,可以加我QQ,我愿意低价出售给你!不过,还是那句话,主要是为了交流!






C#桌面办公应用-工资管理系统系列九

标签:

原文地址:http://blog.csdn.net/u013871100/article/details/51931139

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!