Menu

问题 使用已选定的项目检索数据行

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
大家好,

我有三张表,如下所示;
TBL_Product:ProdId,Prodname,Price
tbl_department:部门,部门名称
tbl_allocation. : ProdID, DepartmentID

这requirement is, the products has to be allocated accordingly to the different departments (assume there are 10 products in total) and time to time I should be able to manage the products assigned to the departments.
假设我已经为3个产品分配给了"Department A",现在我想向同一个部门添加一个新产品。
因此,当我加载数据时"Department A",我需要查看所有10个产品,重要的是,在各个部门的选定3个产品前面勾选。

笔记
请在此示例中找到附加的示例DataGridView。

DataGridView.png.


结果,我有7种产品可供分配给"Department A" at the moment.

感谢您对如何完成此任务的反馈。

谢谢你。

亲切的问候,

安德鲁
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
似乎直截了当,所以你尝试过什么,想到或尝试?所以你理解,我们不为您编写代码。我们帮助您使用您已尝试使用的代码。

让我们看看你尝试过什么并解释你的问题。
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
嗨毛皮,

感谢您的回复。

基本上,到目前为止我写的逻辑是,

1.装载所有"Departments"在表单窗口上的ComboBox允许用户选择部门。
2.用户选择了部门后,用户将加载所有"Products"在DataGridView中。各个代码如下所示;

C#:
  dataGridView1.Rows.Clear();
            SqlDataAdapter sda = new SqlDataAdapter("SELECT ProdID, ProdName FROM tbl_Product", con);
            DataTable dt = new DataTable();
            sda.Fill(dt);

            foreach(DataRow item in dt.Rows)
            {
                int n = dataGridView1.Rows.Add();
                dataGridView1.Rows[n].Cells[1].Value = item["ProdID"].ToString();
                dataGridView1.Rows[n].Cells[2].Value = item["ProdName"].ToString();
                dataGridView1.Rows[n].Cells[3].Value = cmbDepartmentID.Text;
            }

对于此测试示例,我在检索数据时尚未使用参数。

因此,用户将选择必须分配给所选部门的产品,并将数据保存到名为的DB表中,"tbl_Allocation".

这respective code looks like below;

将数据保存到表,"tbl_Allocation":
 for (int i=0; i<dataGridView1 .RowCount -1; i++)
            {
                if(Convert.ToBoolean (dataGridView1 .Rows[i].Cells["selectedItem"].Value) == true)
                {
                    con.Open();
                    cmd = new SqlCommand (@"INSERT INTO tbl_Allocation (ProdID,DepartmentID ) VALUES('"+dataGridView1.Rows[i].Cells[1].Value + "', '"+dataGridView1.Rows[i].Cells[3].Value + "')",con);
                    cmd.ExecuteNonQuery();
                    con.Close();
                }               
            }

我的要求是下面解释的;
4.当用户打开表单时,如果选择了先前选择的部门,则DataGridView应与所有产品一起加载数据,并且已分配的产品应在相应的情况下勾选"Selected Item" column.
基本上,当逻辑的步骤没有运行时,我想检查所选部门是否有一些与产品相关的数据并相应地勾选产品。

感谢您的反馈。

亲切的问候,

安德鲁
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
抱歉迟到的回复,我一直很忙。

所以有什么问题?您可以选择一个部门,并根据部门的不同,您将控件与数据填满,然后使用“选定的复选框”,您可以使用DataGridView复选框列迭代并检查其CheckStates,并请使用这些对象值。

使其成为开始使用参数的练习,无论您可能正在处理什么类型的数据库。
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
你好,

谢谢你的评论。我写下了以下命令并收到错误"".

C#:
 if (con.State != ConnectionState.Open)
            {
                con.Open();
                dataGridView1.Rows.Clear();
                SqlDataAdapter sda = new SqlDataAdapter("SELECT ProdID, ProdName FROM tbl_Product", con);
                DataTable dt = new DataTable();
                sda.Fill(dt);

                foreach (DataRow item in dt.Rows)
                {
                    int n = dataGridView1.Rows.Add();
                    dataGridView1.Rows[n].Cells[1].Value = item["ProdID"].ToString();
                    dataGridView1.Rows[n].Cells[2].Value = item["ProdName"].ToString();
                    dataGridView1.Rows[n].Cells[3].Value = cmbDepartmentID.Text;
                    dataGridView1.Rows[n].Cells[4].Value = item["ProdID"].ToString() + cmbDepartmentID.Text;
                }
                con.Close();
            }              
   
            cmd = new SqlCommand("从tbl_allocation中选择值 WHERE DepartmentID = @aDepartmentID", con);
            cmd.Parameters.Add("@aDepartmentID", SqlDbType.Int).Value = cmbDepartmentID.Text;
            if (con.State != ConnectionState.Open)
                {
                   con.Open();
                 
                    SqlDataReader dr = cmd.ExecuteReader();
               
                    if (dr.HasRows)
                    {
                        DataTable dt1 = new DataTable();
                        SqlDataAdapter sda1 = new SqlDataAdapter(cmd);
                        sda1.Fill(dt1);                      
                        for (int row = 0; row <= dataGridView1.Rows.Count -1; row++)

                            if (DataGridView1.columns ["Value"].ToString().Equals(Value))
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = true;
                            }
                            else
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = false;
                            }
                    }
                    dr.Close();
                    dr.Dispose();              
                }
                con.Close();

请为上述问题查找上述代码。由于我无法测试整个代码(由于上述错误),您也可以在产品已经分配给产品的部门的产品(复选框)的CheckStatus上建议。

笔记
tbl_allocation. got the fields: ProdID, DepartmentID, Value (This is the concatination of "ProdID" and "DepartmentID").

这updated datagridview got an additional column named, "Value".


期待您的来信。

谢谢你。

亲切的问候,

安德鲁
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
您只需要将读者Sqldatareader dr = cmd.executeReader()包装。在使用块或为SQLDataAdapter SDA1 = New SQLDataAdapter(CMD)提供新的命令/连接;并与您的读者关闭您之前的一个。虽然您的读者读取,请考虑将结果读入合适的对象,当读者完成执行时,您可以访问数据。这样做将允许其余的代码执行。
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
你好,

抱歉创建了麻烦。

仍然略微混淆了缠​​绕DataReader对象。它是用类似的东西"using"命令包装读者?

我也为DataReader创建了一个新的连接。

C#:
cmd. = new SqlCommand("从tbl_allocation中选择值 WHERE DepartmentID = @aDepartmentID", con2);
            cmd.Parameters.Add("@aDepartmentID", SqlDbType.Int).Value = cmbDepartmentID.Text;
            if (con2.State != ConnectionState.Open)
                {
                 con2.Open();

                 using (SqlDataReader dr = cmd.ExecuteReader()) {
                
                    if (dr.HasRows)
                    {
                        DataTable dt1 = new DataTable();
                        SqlDataAdapter sda1 = new SqlDataAdapter(cmd);
                        sda1.Fill(dt1);                       
                        for (int row = 0; row <= dataGridView1.Rows.Count -1; row++)

                            if (DataGridView1.columns ["Value"].ToString().Equals(Value))
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = true;
                            }
                            else
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = false;
                            }
                    }
                    //dr.Close();
                    //dr.Dispose();
                }
            }
                con2.Close();

但是,我仍然得到同样的问题。

欣赏你的FeedBak。

亲切的问候,

安德鲁
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
您的错误在这里sqldataAdapter sda1 = new sqldataAdapter(cmd); ?

从帖子6中应用第二部分和第三部分。您只添加了使用块。您的使用块直接运行到下一个命令中,您需要更改代码并在第12行执行新命令之前关闭。您所做的不是我建议的内容。我没有看到您在哪里将结果读到一个物体中......

这error is clear : "".
从7到12,您在已经执行时使用相同的命令。重读以前的回复。
 
Last edited:

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
您使用数据读取器相当毫无意义。如果您要做的只是检查是否有行。 Executescaler会更好。如果要检查是否有匹配的记录,则可以计算它们。您应该尽可能多地使用使用语句,因为它还可以在以后清理清理。
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
嗨毛皮,

我明白,DataReader和SQLDataAdapter都使用相同"cmd"命令是一个错误。

我调整了以下代码并删除了SQLDataAdapter。

您能否就以下代码发出给我建议我,

C#:
SqlCommand cmd = new SqlCommand("从tbl_allocation中选择值 WHERE DepartmentID = @aDepartmentID", con);
            cmd.Parameters.Add("@aDepartmentID", SqlDbType.Int).Value = cmbDepartmentID.Text;
            if (con.State != ConnectionState.Open)
                {
                 con.Open();

                 using (SqlDataReader dr = cmd.ExecuteReader())
                {
                    if (dr.HasRows)
                    {               
                        for (int row = 0; row <= dataGridView1.Rows.Count -1; row++)
                                              
                           if (DataGridView1.columns ["Value"].ToString().Equals(Value))
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = true;
                            }
                            else
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = false;
                            }
                    }
                   dr.Dispose();
                }
            }
                con.Close();

基本上,我正在尝试通过DataGridView的各个数据记录迭代并比较"Value"针对从中检索值的列"tbl_Allocation"表,如果找到匹配,我正在设置"selectedItem" checkbox value to "true".
欣赏你宝贵的建议。对不起,如果我仍然再次错过了一些东西。

谢谢你。

亲切的问候,

安德鲁
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
价值 in your your SQL statement on line 1 will not magically appear as the 价值 in your C# code on line 13. You need to have some extra bit of code to read that value out of the data row dr.

你为什么比较列"Value"在第13行?你不应该看一下细胞列的每一行"Value"?
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
你好,

您的评论并不错误。

我尚未将整个代码添加到帖子10中,请在下面的相应事件中找到代码。

Code:
 if (con.State != ConnectionState.Open)
            {
                con.Open();
                dataGridView1.Rows.Clear();
                SqlDataAdapter sda = new SqlDataAdapter("SELECT ProdID, ProdName FROM tbl_Product", con);
              
                DataTable dt = new DataTable();               
                sda.Fill(dt);

                foreach (DataRow item in dt.Rows)
                {
                    int n = dataGridView1.Rows.Add();
                    dataGridView1.Rows[n].Cells[1].Value = item["ProdID"].ToString();
                    dataGridView1.Rows[n].Cells[2].Value = item["ProdName"].ToString();
                    dataGridView1.Rows[n].Cells[3].Value = cmbDepartmentID.Text;
                    dataGridView1.Rows[n].Cells[4].Value = Convert.ToInt32 (item["ProdID"].ToString()+cmbDepartmentID.Text);
                } 
                con.Close();
            }
          
            SqlCommand cmd = new SqlCommand("从tbl_allocation中选择值 WHERE DepartmentID = @aDepartmentID", con);
            cmd.Parameters.Add("@aDepartmentID", SqlDbType.Int).Value = cmbDepartmentID.Text;
            if (con.State != ConnectionState.Open)
                {
                 con.Open();

                 using (SqlDataReader dr = cmd.ExecuteReader())
                {
                    if (dr.HasRows)
                    {               
                        for (int row = 0; row <= dataGridView1.Rows.Count -1; row++)
                                              
                           if (DataGridView1.columns ["Value"].Equals(Value))
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = true;
                            }
                            else
                            {
                                dataGridView1.Rows[row].Cells["selectedItem"].Value = false;
                            }
                    }
                    //dr.Close();
                    dr.Dispose();
                }
            }
                con.Close();


目前,我能够获得仅针对已分配/分配的产品的部门检查的物品。但是,问题是,只假设只有几家产品分配给部门的总共6个产品,部门的加载数据将检查所有产品,无论已经分配的产品。

笔记
请找到我项目的示例DataGridView
1567645978825.png.


感谢您对这里缺少的宝贵反馈。

亲切的问候,

安德鲁
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
你好,

是的,我正在使用"DataGridViewCheckBoxColumn.."对于所选项目列。

这issue is even though I have allocated only two products to a department, when I select it, it check all the check boxes (all the products) irrespective of the allocated number o f products.

似乎产品的分配给部门正在正确评估,但不检查已分配给部门的唯一项目。

欣赏你的想法。

亲切的问候,

安德鲁
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
错过了你的剩余回应。

关于拉动值,
DataGridView1.columns ["Value"将所有产品数据加载到DataGridView中(EX -
C#:
 dataGridView1.Rows[n].Cells[4].Value = Convert.ToInt32 (item["ProdID"].ToString()+cmbDepartmentID.Text);
)

等于(值)来自TBL_Allocation表。数据被保存为整数。

谢谢你。

安德鲁
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
我会重复在第11篇文章中所说的。
这"Value" in Equals(Value) is not the same Value from "从tbl_allocation中选择值". There is no way for the SQL server to go reach out from the server and modify the memory location for 价值 that is currently running. I suspect that 价值 is a class variable or constant that you have declared somewhere else in your class.

And again, I'll ask: Why are you doing this: DataGridView1.columns ["Value"].Equals(Value)? You are check to see if the 柱子 is equal to 价值 which you said is an integer. Perhaps you meant check the value in the "Value" column of the current row that you are iterating over. dataGridView1.Rows[row].Cells["Value"].Value == Value ?
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
你好,

我会解释我的要求。

基本上,我有一个表单窗口,看起来与下面完全相同。有三张表;

TBL_Product:ProdId,Prodname,Price
tbl_department:部门,部门名称
tbl_allocation. : ProdID, DepartmentID , CombinedCode (I just changed the field name "Value" to "CombinedCode"避免任何混淆)

TBL_Prodcut中有六种产品,在TBL_Department表中有5个部门。

每个部门将根据业务运营分配产品。 (与产品A,产品B和部门金融产品A,产品D,产品E等)

因此,如果我选择一个部门,我需要在DataGridView中显示所有产品,如果所选部门已经分配了一些产品,则只应检查各个产品。 (EC - 如果用户选择部门HR,在DataGridView中的所有6个产品中,产品A和产品B应该已经检查过。该"Selected Item" column is a "DataGridViewCheckBoxColumn..".

1567658107039.png.


因此,
C#:
DataGridView1.columns ["CombinedCode"].Equals(CombinedCode)
是检查DataGridView的"CombinedCode"列与DataReader有任何匹配值"CombinedCode"从tbl_allocation和满足时重新定位,我需要检查复选框。如果没有,请将复选框值设置为false。

希望我的要求现在很清楚。

谢谢你。

亲切的问候,

安德鲁
 

附件

  • 1567657201951.png.
    1567657201951.png.
    11 KB · Views: 22

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
所有你所做的只是重复你在原来的帖子和后续帖子中所说的。让我尝试更直接的问题:

你在哪里 多变的 组合代码 declared?

它如何初始化?
 

安德鲁manuja.

众所周知的成员
加入
2019年5月30日
消息
75
编程经验
Beginner
你好,

抱歉延迟回复。

生病了,无法进入电脑。

实际上,我没有声明一个名为的变量,"CombinedCode". I create the "CombinedCode"将产品数据加载到DataGridView时,加入PRODID和DEMPTIONID。此数据将保存到TBL_Allocation表中"Save" event.

我正在使用for循环来检查生成的"CombinedCode"(如上所述)对付价值"CombinedCode"从tbl_allocation加载的值。

我在这里做错了吗?

感谢您的反馈。

谢谢你。

亲切的问候,


安德鲁
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
Okay, so that is the origin of your 组合代码 variable. Can you explain why you think that this:
C#:
DataGridView1.columns ["CombinedCode"].Equals(CombinedCode)
将要:
检查DataGridView的"CombinedCode"列与DataReader有任何匹配值"CombinedCode"从tbl_allocation重新定位

How does the value read by the SqlDataReader dr make it into the DataGridView1.columns ["CombinedCode"] so that you can make a reasonable comparison? For reference, here's how I assume you are using the SQL data reader:

C#:
SqlCommand cmd = new SqlCommand("SELECT CombinedCode FROM tbl_Allocation WHERE DepartmentID = @aDepartmentID", con);
cmd.Parameters.Add("@aDepartmentID", SqlDbType.Int).Value = cmbDepartmentID.Text;
:
using (SqlDataReader dr = cmd.ExecuteReader())
{
    :
    if (DataGridView1.columns ["CombinedCode"].Equals(CombinedCode))
    :

从我的角度来看,价值"CombinedColumn"从数据读取器中从未使其进入数据网格视图。要检查重返的数据读者,您需要做的事情如下:
C#:
使用 (SqlDataReader dr = cmd.ExecuteReader())
{
    while (dr.Read())
    {
        if (dr["CombinedValue"].ToString() == ...)
        :
    }
}
要遍历每一行,然后尝试将那些与您在DataGrid视图中的现有行相匹配。

实际上,通过让数据库完成所有工作,实际上有更好的方法来实现你想要的东西。有一种方法可以构建一个SQL查询,将为您提供所需的值"Selected Value"列作为布尔值,并同时为您提供所需视图的行和列。不幸的是,我在NoSQL阵营中,无法为您提供任何可靠的建议,准确地构建该查询。这也许是一个为你启动: 如何从SQL Server返回布尔值
 
最佳 底部