0

我的应用程序旨在从 XLSX 电子表格中获取大量数据(40 万多条记录),在表单上的 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

对于 AddItemMethod void 中的progressBar1 控件引用的每个实例。

我可以从 void 中删除静态类型定义,但随后在定义 CallBack 的行上出现相同的错误,说 AddItemMethod 不是静态的。

真的不知道在这里做什么。有什么建议么?

4

4 回答 4

6

使您的 AddItemMethod 非静态并使用构造函数来初始化您的回调。

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是一个实例字段,因此您无法在static方法中访问它。您需要将其设为static字段或更改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 作为参数传递给静态方法AddItemMethod

于 2012-09-21T07:50:14.657 回答