@kojisan78

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【C#】mysqlと接続した状態(Fill)にて、DataGridViewの最後尾にデータを入力、確定させたい。

Q&A

Closed

やりたいこと

エクセルの行をコピーして、DataGridView上にペーストするアプリケーションを
作成したい。

状況

mysqlと接続しない状態では、エクセル行を複数コピーしてペーストできるが、
mysqlと接続した状態(Fill)で実施すると、1行目が確定されない状態で、2行目に
処理がいってしまうので、インデックスエラーとなってしまう。

解決したいこと

やりたいこととしましては、mysqlと接続した状態(Fill)にて、最後尾にどんどん行(データ)を追加していき、追加した行分をUpdateしたい。その為に、まずFill状態でDataGridViewに入れたデータを確定させるヒントを頂きたい。

自分で試したこと

手動では、Fill状態で、DataGridViewの最後尾にデータ手動入力⇒自動で追加行が作成される⇒データ入力の繰り返しにて、最後にUpdateし、mysqlへのUpdateは可能。

Fill状態で、以下のコードを実行したところ、DataGridViewの最後尾に「123」がはいったものの、
その行をクリックすると、入力された「123」が消えてしまう。
よって、Fill状態で、DataGridViewの「123」が確定していないことが原因だと思われ、
dataGridView1.BindingContext[dataGridView1.DataSource].EndCurrentEdit();を入れるも
改善なし。

    private void Last_row_Click(object sender, EventArgs e)
    {
        int dgvRowCnt;
        dgvRowCnt = dataGridView1.Rows.Count;
        dataGridView1[0, dgvRowCnt-1].Value = "123";
        dataGridView1.BindingContext[dataGridView1.DataSource].EndCurrentEdit();
        dataTable1BindingSource.AddNew();
    }

開発環境

OS :Win10
Visual Studio :2022
MySQL: 8.0.28
MySql.Data: 8.0.29
NET Framework : 4.7.2

0 likes

2Answer

質問するときは最低限何を作っているかと開発環境を書いてください。

DataGridView という言葉から WinForms アプリを作っていると想像してますがちゃんと書いてください。

開発環境というのは OS, Visual Studio, MySQL, Connector/NET, MySQL for Visual Studio のバージョン, .NET or .NET Framework のどっちなのかとそのバージョンのこと。

加えて、どのようなコードを書いているのかも書いてください。

以上は質問欄を編集して追記してください。


【追記】

具体例を書いておきます。

デザイン画面で Form に DataGridView, BindingSource, Button x 3 をドラッグドロップして以下のようなコードを書けば、

using System;
using System.Data;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace WindowsFormsMySql
{
    public partial class Form2 : Form
    {
        MySqlDataAdapter adapter;
        DataTable table;

        public Form2()
        {
            InitializeComponent();

            this.dataGridView1.DataSource = this.bindingSource1;
        }

        private void Form2_Load(object sender, EventArgs e)
        {       
            var connString = "接続文字列";
            var selectQuery = "select Id, Name, Qty, UnitPrice from list";

            var connection = new MySqlConnection(connString);
            var command = new MySqlCommand(selectQuery, connection);
            this.adapter = new MySqlDataAdapter();
            this.adapter.SelectCommand = command;
            _ = new MySqlCommandBuilder(this.adapter);
            this.table = new DataTable();

            this.adapter.Fill(this.table);
            this.bindingSource1.DataSource = this.table;

            this.components.Add(connection);
            this.components.Add(command);
        }

        private void Update_Click(object sender, EventArgs e)
        {
            this.bindingSource1.EndEdit();
            this.adapter.Update(this.table);
        }

        private void Remove_Click(object sender, EventArgs e)
        {
            this.bindingSource1.RemoveCurrent();
        }

        private void Paste_Click(object sender, EventArgs e)
        {
            string data = Clipboard.GetText();
            if (!string.IsNullOrEmpty(data))
            {
                string[] array = data.Split(new char[] { '\t' });
                if (array.Length == 4)
                {
                    DataRow row = this.table.NewRow();
                    row["Id"] = int.Parse(array[0]);
                    row["Name"] = array[1];
                    row["Qty"] = int.Parse(array[2]);
                    row["UnitPrice"] = decimal.Parse(array[3].Trim());

                    table.Rows.Add(row);
                }
            }
        }
    }
}

Excel のコピペしたい部分をクリップボードに取得してから、

Excel1.jpg

上の WinForms アプリの [Paste] ボタンをクリックすれば以下のように DataGridView に反映されます。

DataGridView.jpg

その後で [Update All] ボタンをクリックすれば MySQL に追加されます。

1Like

Comments

  1. @kojisan78

    Questioner

    C#初学者で、困っていたため、目に止めて頂きまして、ありがとうございます。
    ご指摘のとおり、質問欄に詳細を記載させて頂きました。

    アドバイス頂けると幸いです。
    よろしくお願いいたします。

  2. アプリがどういう構造になっているか質問の情報では分かりませんが・・・

    とにかく、

    DataGridview ⇔ BindingSource / BindingNavigator ⇔ DataSet / DataTable ⇔ DataAdapter ⇔ MySQL

    という構造にしてください。

    それでどういうことができるかと言うと、以下の記事の「非接続型のデータ更新」のセクションの図1と図2を見てください。とりあえず文章は読まなくてもいいので、まずは図だけ見てください。

    DB 設計者のための明解 ADO.NET 第 1 回
    https://docs.microsoft.com/ja-jp/previous-versions/cc482903%28v=msdn.10%29

    図2の DataSet (中に DataTable がある) の左側に BindingSource / BindingNavigator 経由で DataGridView が接続されていると思ってください。

    ユーザーが DataGridView を操作(行の削除・追加・訂正)した結果は図1にあるように DataSet / DataTable に反映されます。ユーザーの編集操作が終わったら Update メソッドで図1の編集結果が一度に DB に反映されます。そういうアプリが簡単に作れるようにできているのです。検討してみてください。

    不明点があれば下のコメント欄に書いてください。

  3. 質問者さん、その後無言ですが、サンプルを回答欄に追記しましたので、見て、フィードバックを返してください。

  4. @kojisan78

    Questioner

    コードのご紹介ありがとうございます。
    お手本として、私のコードを修正したいと思います。

    1点、あれからいろいろトライしてみたところ、Fill状態では、
    dataGridView1.BeginEdit(true);
    で編集モードにすれば、ペーストできることがわかりました。(正しいかわかりませんが、、)

    ご紹介頂きましたコードは、Fill状態でもペースト可能でしょうか?

  5. ご紹介頂きましたコードは、Fill状態でもペースト可能でしょうか?、

    Fill とは何のことを言ってますか? MySqlDataAdapter.Fill メソッドのことなら、「mysqlと接続した状態(Fill)」とか大きな勘違いがあると思いますけど。

    上の私のサンプルコードの this.adapter.Fill(this.table); で使っていますが、それは接続を Open して DataTable に MySQL からデータを取得した後、接続を Close しています(自動的に Open / Close されます)。「mysqlと接続した状態」なんかではありません。

  6. @kojisan78

    Questioner

    見落としていました。はい、MYSQLでデータ取得後に最後尾にエクセルからペースト、これがやりたかった事です。

    ご教示頂きましたコードを参考に、自分のコードを修正したいと思います。教えていただき本当に助かりました。ありがとうございます。

Your answer might help someone💌