员工评估评分表

时间:2017-03-17 13:38:04

标签: datagridview

我有一个员工评估计划(C#WinForm),经理应该看到他们的员工并根据某些标准对他们进行评分。简化的数据库图如图1所示  enter image description here

表格定义:
Prs:人员(员工)
工作:人员工作 发布:Prs和Job的加入表(因为他们有多对多的关系)
SubCrt:评估员工的标准 评分:应保存员工分数的表

必要的描述:
- 评估每3个月进行一次(称为季节)
- 每项工作的标准与其他工作不同 - 每个员工在一个季节可能有一个以上的职位(因为工作变化)。所以我们必须处理它的结果

WinForm如图2所示。

方案:
- 经理选择一份工作 - DataGridView 将基于ComboBox的选定作业 填充,如图3所示。

  • 现在,经理可以输入与每个条件相关的每个员工的分数

我的主要问题是如何在 DataGridView 中实现可用于 数据输入 的表格(插入,更新,删除分数)?

您对DB,它的关系,C#表格和...的额外想法和建议将不胜感激 此致

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Scoring_Form
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        DataClasses1DataContext db = new DataClasses1DataContext();
        public int rows(int JobId)
        {
            var row = from crt in db.SubCrts
                      join job in db.Jobs
                      on crt.JobId equals job.JobId
                      where job.JobId == JobId
                      select crt.JobId;
            return row.Count();

        }
        public int columns(int JobId)
        {
            var Col = from prs in db.Prs
                      join post in db.Posts
                      on prs.PrsId equals post.PrsId
                      join job in db.Jobs
                      on post.JobId equals job.JobId
                      where job.JobId == JobId
                      select prs.PrsId;
            return Col.Count();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.DataSource = db.Jobs.ToList();
            comboBox1.DisplayMember = "JobTitle";
            comboBox1.ValueMember = "JobId";

            //===================================================
            string[] PrsID = new string[columns(Convert.ToInt32(comboBox1.SelectedValue)) - 1];
            string[] PrsName = new string[columns(Convert.ToInt32(comboBox1.SelectedValue)) - 1];
            string[] CrtID = new string[rows(Convert.ToInt32(comboBox1.SelectedValue)) - 1];
            string[] CrtName = new string[rows(Convert.ToInt32(comboBox1.SelectedValue)) - 1];
            string[,] tbl = new string[rows(Convert.ToInt32(comboBox1.SelectedValue))+2,
                                       columns(Convert.ToInt32(comboBox1.SelectedValue))+2];

            for (int i = 0; i < columns(Convert.ToInt32(comboBox1.SelectedValue)) - 1; i++)
            {
                var a = from prs in db.Prs
                        join post in db.Posts
                        on prs.PrsId equals post.PrsId
                        join job in db.Jobs
                        on post.JobId equals job.JobId
                        select prs.PrsId;
                PrsID[i] = a.ElementAt(i).ToString();
                var b = from prs in db.Prs
                        select (prs.FName + ' ' + prs.LName).ToString();
                PrsName[i] = b.ElementAt(i);
            }
            for (int j = 0; j < rows(Convert.ToInt32(comboBox1.SelectedValue)) - 1; j++)
            {
                var c = from crt in db.SubCrts
                        join job in db.Jobs
                        on crt.JobId equals job.JobId
                        select crt.SubCId;
                CrtID[j] = c.ElementAt(j).ToString();
                var d = from crt in db.SubCrts
                        select crt.Title;
                CrtName[j] = d.ElementAt(j);
            }
            tbl[0, 0] = ""; tbl[0, 1] = ""; tbl[1, 0] = ""; tbl[1, 1] = "";
            for (int l = 2; l < columns(Convert.ToInt32(comboBox1.SelectedValue)) + 1; l++)
            {
                for (int m = 2; m < rows(Convert.ToInt32(comboBox1.SelectedValue)) + 1; m++)
                {
                    tbl[0, l] = PrsID.ElementAt(l - 2);
                    tbl[1, l] = PrsName.ElementAt(l - 2);
                    tbl[m, 0] = CrtID.ElementAt(m - 2);
                    tbl[m, 1] = CrtName.ElementAt(m - 2);

                    var h = from sss in db.Scorings
                            where sss.PrsId == Convert.ToInt32(tbl[0, l])
                            where sss.SubCId == Convert.ToInt32(tbl[m, 0])
                            select sss.Score;
                    tbl[l, m] = h.ElementAt(0).ToString();

                }
            }
            dataGridView1.DataSource = tbl;
        }
    }
}

在做了一些搜索之后,我发现了Rob Sedgwick将一维数组转换为数据表的代码安静

        public DataTable ConvertArrayToDatatable(MarketUnit[] arrList)
{
    DataTable dt = new DataTable();
    try
    {
        if (arrList.Count() > 0)
        {
            Type arrype = arrList[0].GetType();
            dt = new DataTable(arrype.Name);

            foreach (PropertyInfo propInfo in arrype.GetProperties())
            {
                dt.Columns.Add(new DataColumn(propInfo.Name));
            }

            foreach (object obj in arrList)
            {
                DataRow dr = dt.NewRow();

                foreach (DataColumn dc in dt.Columns)
                {
                    dr[dc.ColumnName] = obj.GetType().GetProperty(dc.ColumnName).GetValue(obj, null);
                }
                dt.Rows.Add(dr);

            }
        }


        return dt;
    }
    catch (Exception ex)
    {
        return dt;
    }

}

是否可以将其更改为用于我的2D数组(Tbl)?

2 个答案:

答案 0 :(得分:0)

正如我的评论所述......你的问题范围很广。有许多方法可以实现创建此“员工评估”表单的目标。所以我希望这个答案至少可以帮助构建和管理用作DataTableDataSource的{​​{1}}。我的回答演示了如何过滤DataGridView,以便DataTable只显示符合过滤条件或按多个条件过滤的项目...即过滤DataGridView对作业类型的选择。请注意,这与基本相同,并使用Manager的{​​{1}}属性来实现此过滤。这个RowFilter有些限制,如果数据与原始数据库解耦,CRUD功能可能会成为您的问题。所以仅以此为例。

您发布的代码似乎比以前更加困难。以下示例中所有DataTableRowFilter的{​​{1}}为DataSource!。发布的代码坚持将数据源转换为字符串数组是不必要的。

我使用的方法与数据库图片显示的方法不同。有四(4)DataGridViewsComboBoxes,用作DATATABLES DataTables的数据源; employeesDT数据表用作DataGridView dgvEmployees的数据源; jobsCBDT用作ComboBox cbJobs的数据源; managersCBDT用作ComboBox cbManagers的数据源。

我的方法把它分解为三个主要的“对象”:一个“员工”对象,可能是一个经理。这个“Employee”对象有一个额外的布尔属性来指示员工是否是经理; “作业”对象,定义不同的“作业”类型;最后是“评价”对象。此“评估”类将具有以下属性。您可以在不使用课程的情况下完成此操作,但我建议您考虑它们的用途。但evaluationsDT是必要的。

DataGridView

以下是此dgvEvaluations课程的DataTable定义。

public class Evaluation {
  public int ID { get; set; }
  public Employee EmployeeEvaluated { get; set; }
  public Employee EvaluatingManager { get; set; }
  public Job JobEvaluated { get; set; }
  public DateTime StartDate { get; set; }
  public DateTime EndDate { get; set; }
  public double PersonalScore { get; set; }
  public double ImpactScore { get; set; }
  public double CommunicationScore { get; set; }
  public double DecisionMakingScore { get; set; }
  public double KnowledgeSkillsScore { get; set; }
  public double CareerDevelopmentScore { get; set; }
  public double InterpersonalScore { get; set; }
  public Evaluation() { }
}

此帖子中似乎缺少此“评估”结构。这是一项评估,员工可以进行多项评估。发布的图片中的图3似乎是向后的。我猜这里......我认为会有很多评估和同一员工的一些评估。图片将其设置为列。另一方面,行似乎是静态的。使用这种策略,每个评估都会有一个列,可能会有很多。我将其切换为列,即每个区域的分数,行是员工的“评估”。我希望我不会错过这里的内容,例如根据所选的工作类型,有不同的评分标准。

enter image description here

以上是以下代码中的表格。您可能需要调整表格以满足您的需求。顶部DataTable Evaluation显示所有员工。右侧的按钮将此列表过滤为“仅限管理员”,“所有员工”以及将此数据“保存”到文件的按钮。如果需要,您可以在此处更新数据库。

下面是包含所有当前评估的public static DataTable GetEvaluationsDTStructure() { DataTable dt = new DataTable("Evaluations"); dt.Columns.Add("ID", typeof(int)); dt.Columns.Add("Employee Evaluated", typeof(string)); dt.Columns.Add("Evaluating Manager", typeof(string)); dt.Columns.Add("Job Title", typeof(string)); dt.Columns.Add("Start Date", typeof(DateTime)); dt.Columns.Add("End Date", typeof(DateTime)); dt.Columns.Add("Personal Score", typeof(double)); dt.Columns.Add("Impact Score", typeof(double)); dt.Columns.Add("Communication Score", typeof(double)); dt.Columns.Add("Decision Making Score", typeof(double)); dt.Columns.Add("Knowledge Skills Score", typeof(double)); dt.Columns.Add("Career Development Score", typeof(double)); dt.Columns.Add("Interpersonal Score", typeof(double)); return dt; } DataGridView。如果有许多评估,您可能希望过滤行或搜索特定的员工,经理或工作。这就是组合框在datagridview下面的作用。组合框中添加了一个额外的空白项目以清除任何过滤器,或者用户可以单击“清除过滤器”按钮。在这里,您可以筛选所选员工的评估,并评估经理和工作。

您可以更改当前项目并添加新评估。最后,右侧有一个按钮可保存任何更改。同样,我只是将数据表写入文件。您将更新您的数据库。

注意添加新评估。

当允许用户输入数据时,必须检查有效数据。例如,分数的dgvEmployees列设置为DataGridView的类型。如果用户输入字符,除非您解决此问题,否则代码将崩溃。这同样适用于日期列。为了以一种简单的方式解决这个问题(不是最好的),dgvEvaluations事件被连线以在发生这种情况时捕获,然后只是向用户显示输入无效的消息并取消网格中的任何更改。这可以防止在输入分数或日期时用户输入错误。

其他用户输入问题是用户键入新评估的员工姓名。如果用户没有准确输入名称,则稍后会出现问题。如果有新员工,则需要先将该员工添加到员工的数据库中。同样的事情将适用于“职务”,如果用户输入的内容不是现有职位,那么您以后会遇到错误。由于这些是员工和工作......也许,这里的ComboBox单元可以使用户更容易选择员工以及评估经理和工作。这样,您可以避免用户输入错误的信息。您可以在这些“员工”列中查找DataTable。这个组合框单元格的帖子末尾有评论代码。对于有日期的单元格,有一篇很好的文章介绍了如何使double列运行良好,用户友好并几乎保证用户输入有效日期。 How to: Host Controls in Windows Forms DataGridView Cells

话虽如此,下面的代码存在许多问题,例如,如果您将新员工添加到顶部网格然后保存数据...下面的组合框将不会更新。这是你必须解决的问题。另一个考虑因素是如果用户想要添加新评估该怎么做。使用DataError允许用户执行此操作很方便,但是您必须实现多个事件并通过DataGridViewComboBoxColumn进行检查。恕我直言,可以更容易地简单地添加一个按钮来“添加”新的评估,并使用此按钮打开评估表单,用户可以在其中添加分数,更改员工等...然后保存评估。这可能会使事情变得更容易,并且用户友好。

我希望这有帮助,如果我完全遗漏了某些东西......请告诉我,我会删除答案。祝你好运

DataTable定义 - 上面定义的evaluationationsDT

DateTimePicker

DataGridView

DataGridView经理dataTable是相同的结构

jobsCBDT

主要表格方法

private static DataTable GetJobsDTStruc() {
  DataTable dt = new DataTable();
  dt.Columns.Add("ID", typeof(int));
  dt.Columns.Add("Job Title", typeof(string));
  dt.Columns.Add("Job Description", typeof(string));
  return dt;
}

希望这有帮助!

答案 1 :(得分:0)

非常感谢亲爱的JohnG提供完整的指导和答案,以下是我最后根据之前的描述显示数据的方法。我将尽快分享我的解决方案,以便尽快插入数据。

namespace Scoring_Form
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    DataClasses1DataContext db = new DataClasses1DataContext();

    private void Form1_Load(object sender, EventArgs e)
    {
        comboBox1.DataSource = db.Jobs.ToList();
        comboBox1.DisplayMember = "JobTitle";
        comboBox1.ValueMember = "JobId";
    }

    public DataTable subcrt(int JobId)
    {
        var row = from crt in db.SubCrts
                  join job in db.Jobs
                  on crt.JobId equals job.JobId
                  where job.JobId == JobId
                  select crt;

        MessageBox.Show(row.Count().ToString());
        return (DataTable)row;

    }
    private void button2_Click(object sender, EventArgs e)
    {
        var querySubCrts = from crt in db.SubCrts
                           where crt.JobId == (int)comboBox1.SelectedValue
                           select crt;
        //--------- Add Personal Name  in Header
        var queryPersonal = from rwPr in db.Prs
                            select rwPr;
        dataGridView1.ColumnCount = queryPersonal.Count() + 1;
        int j = 0;
        foreach (var rwPrs in queryPersonal)
        {
            j++;
            dataGridView1.Columns[j].HeaderText = rwPrs.FName + " " + rwPrs.LName;

            dataGridView1.RowCount = querySubCrts.Count() + 1;
            int i = -1;

            foreach (var crt in querySubCrts)
            {
                i++;
                dataGridView1.Rows[i].Cells[0].Value = crt.Title;
                //-------------
                var queryScoring = from rwScoring in db.Scorings
                                   where (rwScoring.SubCId == crt.SubCId) && (rwScoring.PrsId == rwPrs.PrsId)
                                   select rwScoring;

                foreach (var rwScoring in queryScoring)
                {
                    dataGridView1.Rows[i].Cells[j].Value = rwScoring.Score;
                }
            }
        }
    }