0

私のアプリは、XLSXスプレッドシートから大量のデータ(400k以上のレコード)を取得し、フォームのDataGridViewの各シートにデータを表示し、選択したシートのデータをmySQLにエクスポートできるようにすることを目的としています。

エクスポートはそれ自体のスレッドで行われます(ここにはまだ完了していないものがたくさんあることに注意してください):

    private AddItemCallBack AddItemDelegate = new AddItemCallBack(AddItemMethod);
    private delegate void AddItemCallBack(int Total);

    private void lnkExport_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
        sName = ddlTables.SelectedValue.ToString();
        pb = progressBar1;

        var t = new Thread(() => ExportData(sName));
        t.Start();
    }

    private void ExportData(string SheetName = "")
    {
        string sql = "select * from " + String.Format(tablename, SheetName);
        OleDbCommand cmd = new OleDbCommand(sql, conn);

        DataSet ds = new DataSet();
        OleDbDataAdapter da = new OleDbDataAdapter();

        da.SelectCommand = cmd;
        da.Fill(ds);

        connStr = "Data Source=localhost; Initial Catalog=test; User ID=root; Password=Ly@12157114";
        MySqlConnection con = new MySqlConnection(connStr);
        totalRecords = ds.Tables[0].Rows.Count;
        currentRecords = 0;

        foreach (DataRow row in ds.Tables[0].Rows)
        {
            sql = "insert into planet(clubid, clubname, acctno, title, firstname, lastname, cell, email, derp, accttype) " +
            "values(@id, @name, @acct, @title, @fname, @lname, @cell, @email, @derp, @type)";

            MySqlCommand command = new MySqlCommand(sql, con);

            command.Parameters.AddWithValue("@id", row[0]);
            command.Parameters.AddWithValue("@name", row[1]);
            command.Parameters.AddWithValue("@acct", row[2]);
            command.Parameters.AddWithValue("@title", row[3]);
            command.Parameters.AddWithValue("@fname", row[4]);
            command.Parameters.AddWithValue("@lname", row[5]);
            command.Parameters.AddWithValue("@cell", row[6]);
            command.Parameters.AddWithValue("@email", row[7]);
            command.Parameters.AddWithValue("@derp", row[8]);
            command.Parameters.AddWithValue("@type", row[9]);

            try
            {
                con.Open();
                command.ExecuteNonQuery();
                con.Close();
                currentRecords = currentRecords + 1;

                this.Invoke(this.AddItemDelegate, new object[] { totalRecords });
            }
            catch (MySqlException ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

    }

    private static void AddItemMethod(int Total)
    {
        progressBar1.Maximum = Total;

        if (progressBar1.Value < progressBar1.Maximum)
        {
            progressBar1.Value = progressBar1.Value + 1;
        }
        else
        {
            progressBar1.Value = 0;
        }            
    }

VSはそれを不平を言っています

エラー1非静的フィールド、メソッド、またはプロパティにはオブジェクト参照が必要です'ImportExcel.Form1.progressBar1' G:\ ImportExcel \ ImportExcel \ Form1.cs 139 13 ImportExcel

PASSWORDMethodvoidのprogressBar1コントロール参照のすべてのインスタンスに対して。

ボイドから静的型の定義を削除することはできますが、コールバックを定義する行で同じエラーが発生し、PASSWORDMethodは静的ではないというメッセージが表示されます。

本当にここで何をすべきかわからない。助言がありますか?

4

4 に答える 4

6

PASSWORDMethodを非静的にし、コンストラクターを使用してコールバックを初期化します。

private AddItemCallBack AddItemDelegate;
private delegate void AddItemCallBack(int Total); 

private void AddItemMethod(int Total)
{
    progressBar1.Maximum = Total; 
    if (progressBar1.Value < progressBar1.Maximum)
    {
        progressBar1.Value = progressBar1.Value + 1;
    } 
    else 
    { 
        progressBar1.Value = 0; 
    }
}

public Form1()
{
    InitializeComponent();
    AddItemDelegate = new AddItemCallBack(AddItemMethod);
}
于 2012-09-21T07:53:25.247 に答える
0

progressBar1インスタンスフィールドであるため、メソッドでアクセスすることはできませんstaticstaticフィールドにするかAddItemMethod、インスタンスメソッドに変更する必要があります。

于 2012-09-21T07:52:33.143 に答える
0
  1. 静的メソッドは(静的フィールドではなく)インスタンスフィールドを参照できません。progressBar1は静的ではないと思います。解決策は、AddItemMethod非静的にすることです。
  2. AddItemCallbackフィールド初期化子はコンストラクターの直前に実行されるため、非静的メンバーに依存しない可能性があるため、フィールド初期化子をインスタンスメソッドに設定することはできません。そのAddItemMethodため、インスタンスメソッドに変更するだけでコンパイラが文句を言います。これを回避するには、コンストラクターでフィールドを初期化します。
private AddItemCallBack AddItemDelegate;

public Form1() 
{
    AddItemDelegate = AddItemMethod;
    // ... other stuff
    InitializeComponents(); // totally guessed, but seems like Form1 is auto generated
}
于 2012-09-21T07:53:48.720 に答える
-1

これ以上コードが表示されない場合の最も簡単な方法は、progressBar1をパラメーターとして静的メソッドPASSWORDMethodに渡すことです。

于 2012-09-21T07:50:14.657 に答える