【问题标题】:DataGridView doesn't refresh/load properlyDataGridView 无法正确刷新/加载
【发布时间】:2021-10-21 06:07:27
【问题描述】:

我正在编写一个使用“Excel Sheets”的程序。

我正在通过按钮将它们加载到 DataGridView 中。如果我完成了 Sheet 的工作,我可以按相同的按钮加载另一个 Sheet。问题是即使我正在清除和刷新我的 DataGridView,旧的 Sheet 并没有消失,而新的 Sheet 只是添加到了旧的。这是为什么呢?

按钮点击事件的代码:

private void button1_Click(object sender, EventArgs e)
{
    //Excell Prozess kill (wenn "Datei öffnen" geklickt)
    Process[] excelProcs = Process.GetProcessesByName("EXCEL");
    foreach (Process proc in excelProcs)
    {
        proc.Kill();
    }

    //Preparing Excel
    Excel.Workbook theWorkbook = null;
    Excel.Application ExcelObj = null;
    Excel.Sheets sheets = null;
    Excel.Worksheet worksheet = null;

    if (dataGridView1.DataSource != null)
    {
        dataGridView1.DataSource = null;
        dataGridView1.Refresh();
    }
    else
    {
        dataGridView1.Columns.Clear();
    }

    //Deklaration
    string filePath = string.Empty;
    string fileExt = string.Empty;

    //File dialog
    OpenFileDialog dialog = new OpenFileDialog();
    dialog.Filter = "Excel Datei (*.xlsx *.xls)|*.xlsx; *.xls; |All Files (*.*)|*.*";

    if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        filePath = dialog.FileName; //get the path of the file  
        fileExt = Path.GetExtension(filePath); //get the extension from the file

        //File Path zeigen
        label1.Text = filePath;

        //Nur .xls und .xlsx 
        if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsx") == 0)
        {
            try
            {
                ExcelObj = new Excel.Application();

                //open ExcelObj and load it into theWorkbook
                theWorkbook = ExcelObj.Workbooks.Open(filePath);

                sheets = theWorkbook.Worksheets;
                //Get the reference of second worksheet
                worksheet = (Excel.Worksheet)sheets.get_Item(1);
                //Get the name of worksheet
                string strWorksheetName = worksheet.Name;

                //string for database con
                String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
                                filePath
                                 + ";Extended Properties='Excel 12.0 XML;HDR=NO;';";

                OleDbConnection con = new OleDbConnection(constr);


                //select sheet from excel file
                OleDbCommand oconn = new OleDbCommand("Select * From [" + strWorksheetName + "$]", con);

                //open db
                con.Open();

                OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
                sda.Fill(data);

                //insert data into datagridview
                dataGridView1.DataSource = data;

                //Select all from table date
                DataRow[] rows = data.Select();

                //close db
                con.Close();

                //close ExcelObj
                ExcelObj.Quit();
            }

            //if error -> show
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

            finally
            {
                //ComObject release
                if (sheets != null) Marshal.ReleaseComObject(sheets);
                if (ExcelObj != null) Marshal.ReleaseComObject(ExcelObj);
                if (worksheet != null) Marshal.ReleaseComObject(worksheet);
                if (theWorkbook != null) Marshal.ReleaseComObject(theWorkbook);

            }

我认为问题是由于 “Excel 文件” 没有在 “准备 Excel” 部分中正确释放,但 “Excel” 在许多情况下通过“Excel Prozess Kill”代码关闭。我通过任务管理器看了几次。那么是什么导致了问题呢?有什么意见吗?

【问题讨论】:

标签: c# excel button datagridview


【解决方案1】:

您当前的代码中有一些令人头疼的事情,您可能需要重新考虑。

首先……杀死所有“Excel”进程很好……很奇怪。您的代码可能没有启动这些进程;但是代码会杀死他们。和那个开始运行 Excel 并离开去喝咖啡的人见鬼去吧。

代码“似乎”可以正确发布 Excel 进程,但是,在您发布工作簿“之后”发布 Excel 应用程序似乎是合乎逻辑的。具体来说,发布sheets,然后是worksheet,然后是theWorkbook,最后是应用程序ExcelObj。因为代码“似乎”可以正确释放 Excel com 对象,所以我会转储所有杀死 Excel 进程的代码。

接下来,我建议在处理 Excel 文件时寻找第三方解决方案。对于非商业用途,我发现 EPPlus 是一个不错的选择,而不是 OleDb 和/或 Interop,并且可以在 NuGet 中找到。只是一个想法。

最后我确实有一个简单的解决方案来解决您的问题。由于您没有显示其定义,因此我可以破译的是变量data。在我看来,这个data 对象是DataTable。在我的小测试中,正如您所描述的,当您选择第二个 Excel 文件时,它确实“附加”到现有的dataDataTable。由于代码“似乎”在填充 data 表之前永远不会清除它,所以当你调用时......

sda.Fill(data);

第二次,适配器会主动“追加”数据。

要解决此问题,只需在填写之前清除 data 表...

data = new DataTable();
sda.Fill(data);

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多