2017-03-04 84 views
1

我已经编写了这个教程,下面是一个youtube教程,该教程中的DataSource是一个AOD.NET实体数据模型,我使用的是Access数据库。我编译的代码,但我得到的各种错误,如C#DataGridView到Excel文件错误

The name 'productBindingSource' does not exist in the current context

The name 'DB' does not exist in the current context

The type or namespace name 'Product' could not be found

我不知道如果我错过了增加一个参考或者如果这些错误是由于数据源不同?

Visual Studio自动添加了//TODO: This line of code etc...,我将其更改为教程中的显示方式。

我希望有人能帮助告诉我我做错了什么?

教程:https://www.youtube.com/watch?v=-wGzK1vsqS8

enter image description here

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace ExportWebsiteData 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void label1_Click(object sender, EventArgs e) 
     { 

     } 

     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      List<Product> list = ((DataParameter)e.Argument).ProductList; 
      string filename = ((DataParameter)e.Argument).FileName; 
      Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); 
      Workbook wb = excel.Workbooks.Add(XlSheetType.xlWorksheet); 
      Worksheet ws = (Worksheet)excel.ActiveSheet; 
      excel.Visible = false; 
      int index = 1; 
      int process = list.Count; 
      //Add Column 
      ws.Cells[1, 1] = "Item Number"; 
      ws.cells[1, 2] = "Model"; 
      ws.cells[1, 3] = "Manufacturer"; 
      ws.cells[1, 4] = "Category"; 
      ws.cells[1, 5] = "Subcategory"; 
      // 
      foreach(Product p in list) 
      { 
       if (!backgroundWorker.CancellationPending) 
       { 
        backgroundWorker.ReportProgress(index++ * 100/process); 
        ws.Cells[index, 1] = p.ItemNumber.ToString(); 
        ws.Cells[index, 2] = p.Model.ToString(); 
        ws.Cells[index, 3] = p.Manufacturer.ToString(); 
        ws.Cells[index, 4] = p.Category.ToString(); 
        ws.Cells[index, 5] = p.SubCategory.ToString(); 
       } 
      } 
      //Save file 
      ws.SaveAs(filename, XlFileFormat.xlWorkbookdefault, Type.Missing, Type.Missing, true, false, XlSaveConflictResolution.xlLocalSessionChanges, Type.Missing, Type.Missing); 
      excel.Quit(); 
     } 

     struct DataParameter 
     { 
      public List<Product> ProductList; 
      public string FileName { get; set; } 
     } 

     DataParameter _inputParameter; 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      using (this.inventoryTableAdapter.Fill(this._Wizard_Data_2016_10_17DataSet.Inventory); = new _Wizard_Data_2016_10_17DataSet()) 
      { 
       productBindingSource.DataSource = DB.Products.ToList(); 
      } 

      // TODO: This line of code loads data into the '_Wizard_Data_2016_10_17DataSet.Inventory' table. You can move, or remove it, as needed. 
      //this.inventoryTableAdapter.Fill(this._Wizard_Data_2016_10_17DataSet.Inventory); 

     } 

     private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      progressBar.Value = e.ProgressPercentage; 
      lblStatus.Text = string.Format("Processing...{0}", e.ProgressPercentage); 
      progressBar.Update(); 
     } 

     private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if(e.Error == null) 
      { 
       Thread.Sleep(100); 
       lblStatus.Text = "Your data has been successfully exported."; 
      } 
     } 

     private void btnExport_Click(object sender, EventArgs e) 
     { 
      if (backgroundWorker.IsBusy) 
       return; 
      using (SaveFileDialog sfd = new SaveFileDialog() { Filter = "Excel Workbook|*.xls" }) 
      { 
       if (sdf.ShowDialog() == DialogResult.OK) 
       { 
        _inputParameter.FileName = sfd.FileName; 
        _inputParameter.ProductList = productBindingSource.DataSource as List<product>; 
        progressBar.Minimum = 0; 
        progressBar.Value = 0; 
        backgroundWorker.RunWorkerAsync(_inputParameter); 
       } 
      } 
     } 
    } 
} 

UPDATE:

约翰的回答没有解决我的错误,但数据网格目前正在由CS代码而不是数据库填充。如果有人能让我知道他们认为是什么问题,我已经制作了一个视频来更详细地解释问题。

https://www.dropbox.com/s/1l5iw1j32a6oroj/C%23Excel.wmv?dl=0

+1

你好亚历克斯,其他人可能连看都不看这个问题,因为它已经回答了你的问题(连接到访问数据库)与原始文章不同。稍后我会尝试更新我的答案,因为有多种方法可以连接到您的访问数据库。你可以考虑发布另一个关于'Form1_Load'代码的问题,这个代码就是这个连接发生的地方。如果你希望我们可以建立一个聊天,如果它会帮助。 – JohnG

+0

你好约翰,聊天会很棒,我们该如何进行? – UserSN

+1

请给我一分钟,如果可能的话我会尝试着手。 – JohnG

回答

1

从发布代码中有几个错误和错别字。看来在获取数据的方法Form1_Load中存在一些问题。为了解决这个问题,并且由于看起来使用的数据是一个Product对象列表,下面的代码使用个Product对象。该列表然后填入一些测试数据。该测试数据将作为DataSource用于DataGridView。一旦数据在DataGridView中,导出按钮将成功将数据从DataGridView导出到Excel工作簿。

错别字在上面贴的代码:

ws.Cells[1, 1] = "Item Number"; 
ws.cells[1, 2] = "Model"; 

小写字母“C”的单元格列2,3,4,5将抛出错误未找到定义。

ws.SaveAs(filename, XlFileFormat.xlWorkbookdefault, ……); 

以上,这可能取决于版本,xlWorkbookdefault应该有一个大写字母“d”:

XlFileFormat.xlWorkbookDefault 

最后错字是在ShowDialogSaveFileDialog

SaveFileDialog sfd = new SaveFileDialog() 

然后下一行试图使用:

sdf.ShowDialog() 

上面的行应该是“sfd”而不是“sdf”。

看着你发布的图片显示了错误,并且在观看你链接的视频后,视频可能会遗漏一些东西。从顶部开始,似乎有一个名为Product的东西缺少其定义。这看起来像一个类,从代码看来,该类有Item Number,Model,Manufacturer,Category和SubCategory。我不确定该视频是否忽略了这一点,或者Product是我缺少的其他内容。在这种情况下,为了解决这个缺失的定义,下面的代码使用上面的属性创建了一个Product类。

public class Product { 
    public string ItemNumber { get; set; } 
    public string Model { get; set; } 
    public string Manufacturer { get; set; } 
    public string Category { get; set; } 
    public string SubCategory { get; set; } 

    public Product(string iNum, string model, string manuf, string cat, string subCat) { 
    ItemNumber = iNum; 
    Model = model; 
    Manufacturer = manuf; 
    Category = cat; 
    SubCategory = subCat; 
    } 

接下来的2个错误(XlFileFormat和XlSaveConflictResolution)的生成,因为你缺少一个using语句中的代码。这似乎不在视频中。要修复这两个错误,请将下面的行放在using语句所在文件的顶部。

using Microsoft.Office.Interop.Excel; 

错误:int:在using语句中使用的类型...请参阅下面的表单加载。

这两个错误productBindingSource不存在。视频放置了一个BackgroundWorker到表单上,但我没有看到放置的BindingSource。为了解决这个问题...在设计人员中,从工具箱中选择一个BindingSource组件,并将其放到窗体上,然后将其名称更改为productBindingSource

“DB”错误将被注释掉以使用产品对象列表。请参阅下面的Form_Load。

“线程”错误表示缺少使用语句:将下面的行与其他使用语句放在一起。

using System.Threading; 

上面已经介绍了“sdf”。最后一个错误是从下面的行:

productBindingSource.DataSource as List<product>; 

product应该有一个上壳体“P”:List<Product>;

通过以上所作的修改,唯一的误差应在Form_Load方法。

private void Form1_Load(object sender, EventArgs e) 
{ 
    using (this.inventoryTableAdapter.Fill(this._Wizard_Data_2016_10_17DataSet.Inventory); = new _Wizard_Data_2016_10_17DataSet()) 
    { 
    productBindingSource.DataSource = DB.Products.ToList(); 
    } 
} 

上面一行是畸形的,但似乎试图获得DataSet。我稍后会留下来供你考虑。由于productBindingSource似乎在采用产品对象列表,因此代码将其替换为测试数据并创建了产品对象列表。将方法更改为将productBindingSource设置为测试数据列表的下面的代码,然后将此绑定源指定为DataGridViewDataSource。视频中缺少这一点。

private void Form2_Load(object sender, EventArgs e) { 
    List<Product> list = GetProductList(); 
    productBindingSource.DataSource = list; 
    dataGridView1.DataSource = productBindingSource; 
} 

随着上述变化代码导出按预期。希望这可以帮助。

private List<Product> GetProductList() { 
    List<Product> products = new List<Product>(); 
    for (int i = 0; i < 14; i++) { 
    products.Add(new Product(i.ToString(), "Model_" + i, "Manufacture_" + i, "Cat_" + i, "SubCat_" + i)); 
    } 
    return products; 
} 

编辑更新,以获得从访问数据库中的表不使用类

System.Data.DataTable dt = new System.Data.DataTable(); 

public Form2() { 
    InitializeComponent(); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { 
    //List<Product> list = ((DataParameter)e.Argument).ProductList; 
    System.Data.DataTable list = ((DataParameter)e.Argument).ProductList; 
    string filename = ((DataParameter)e.Argument).FileName; 
    Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); 
    Workbook wb = excel.Workbooks.Add(XlSheetType.xlWorksheet); 
    Worksheet ws = (Worksheet)excel.ActiveSheet; 
    excel.Visible = false; 
    int index = 1; 
    //int process = list.Count; 
    int process = list.Rows.Count; 
    //Add Column 
    ws.Cells[1, 1] = "Item Number"; 
    ws.Cells[1, 2] = "Model"; 
    ws.Cells[1, 3] = "Manufacturer"; 
    ws.Cells[1, 4] = "Category"; 
    ws.Cells[1, 5] = "Subcategory"; 
    foreach (DataRow dr in list.Rows) { 
    if (!backgroundWorker.CancellationPending) { 
     backgroundWorker.ReportProgress(index++ * 100/process); 
     ws.Cells[index, 1] = dr.ItemArray[1].ToString(); 
     ws.Cells[index, 2] = dr.ItemArray[2].ToString(); 
     ws.Cells[index, 3] = dr.ItemArray[3].ToString(); 
     ws.Cells[index, 4] = dr.ItemArray[4].ToString(); 
     ws.Cells[index, 5] = dr.ItemArray[5].ToString(); 
    } 
    } 
    //Save file 
    ws.SaveAs(filename, XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, true, false, XlSaveConflictResolution.xlLocalSessionChanges, Type.Missing, Type.Missing); 
    excel.Quit(); 
} 

struct DataParameter { 
    public System.Data.DataTable ProductList; 
    public string FileName { get; set; } 
} 

DataParameter _inputParameter; 

private void Form2_Load(object sender, EventArgs e) { 
    string ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Test\Test3.accdb"; 
    using (OleDbConnection olcon = new OleDbConnection(ConnectionString)) { 
    using (OleDbDataAdapter adapter = new OleDbDataAdapter()) { 

     string command = "SELECT * FROM [Products]"; 
     //cmd.CommandText = "SELECT * FROM [" + sheetName + "]"; 

     OleDbCommand cmd = new OleDbCommand(command, olcon); 
     //Fill Gridview with Data from Access 
     try { 
     dt.Clear(); 
     adapter.SelectCommand = cmd; 
     adapter.Fill(dt); 
     productBindingSource.DataSource = dt; 
     dataGridView1.DataSource = productBindingSource; 
     } 
     catch (Exception ex) { 
     MessageBox.Show(ex.ToString()); 
     } 
     finally { 
     olcon.Close(); 
     var totalWidth = dataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.None); 
     } 
    } 
    } 

} 

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { 
    progressBar.Value = e.ProgressPercentage; 
    lblStatus.Text = string.Format("Processing...{0}", e.ProgressPercentage); 
    progressBar.Update(); 
} 

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
    if (e.Error == null) { 
    Thread.Sleep(100); 
    lblStatus.Text = "Your data has been successfully exported."; 
    } 
} 

private void btnExport_Click(object sender, EventArgs e) { 
    if (backgroundWorker.IsBusy) 
    return; 
    using (SaveFileDialog sfd = new SaveFileDialog() { Filter = "Excel Workbook|*.xls" }) { 
    if (sfd.ShowDialog() == DialogResult.OK) { 
     _inputParameter.FileName = sfd.FileName; 
     //_inputParameter.ProductList = GetProductsList2(); 
     _inputParameter.ProductList = (System.Data.DataTable)productBindingSource.DataSource; 
     progressBar.Minimum = 0; 
     progressBar.Value = 0; 
     backgroundWorker.RunWorkerAsync(_inputParameter); 
    } 
    } 
} 
+0

高度赞赏这个详细的答案,它真的有助于理解发生了什么以及如何解决它。 谢谢。 – UserSN

+0

再次感谢您的回答我已修复所有错误。现在格式错误的'Connection String'因为我对C#的知识中缺少一个更好的单词,我从它在视频中显示的内容中修改了一些内容,以便用'access数据库'中的信息填充我的'datagrid',而不是在视频中使用不同' datasource'来自'northwinds DB'。 有了这些更改,我的应用程序的运行没有任何错误,但用数据填充数据网格(我认为我们硬编码到.cs文件中),而不是从访问数据库中抓取数据? 道歉,如果我错了一些术语我是在有限的C#知识 – UserSN

+0

我做了一个简短的视频解释好一点我想要在我上面的评论来形容,如果你有几分钟随时取看。 https://www.dropbox.com/s/1l5iw1j32a6oroj/C%23Excel.wmv?dl=0 非常感谢, 亚历 – UserSN