Excel工作表和MS Access表joinVisual Studio C#

我有一个名为mer_SVC excel表和名为GIS MS Access数据库表。我想通过在Access表中导入Excel工作表,在devise视图中生成sql查询(如下所示)。

我正在使用Visual Studio 2015在DataGrid视图中显示输出。 现在使用两个OleDbConnection我怎么能生成上面的查询。 查询语法错误即将到来。

 string stringconn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + textselect.Text + ";" + "Extended Properties='Excel 8.0;HDR=YES;'"; OleDbConnection conn = new OleDbConnection(stringconn); string stringcon = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source = C:\Users\GIS\Documents\Match.accdb;"; OleDbConnection conn1 = new OleDbConnection(stringcon); string path = @"F:\RAEC\RAECOEXCEL\Customer Data from CRM - Copy.XLSX" + " Excel 8.0"; string query = "Select * from [mer_SVC$] IN" + path + " LEFT JOIN GIS ON Account No From [mer_SVC$] IN" + "path " + " = GIS.[Account No] WHERE (((GIS.[Account No]) Is Null))"; OleDbDataAdapter da = new OleDbDataAdapter(query, conn1); DataTable dt = new DataTable(); da.Fill(dt); dataGridView1.DataSource = dt; 

那真是太有趣了! 首先我不认为你可以按照你希望的方式来做,因为OleDbAdapter一次只能连接一个连接。 但是,你可以通过分阶段的做事达到你想要的。

首先创build两个数据表,一个来自Access,另一个来自Excel。 然后把它们变成一个打字清单。 接下来使用一些LINQ来获取缺失的行。 最后从结果中build立一个新的DataTable。

总而言之,它应该是这样的:

 private struct GIS { public int AccountNo; public string AccountName; } private void Test() { try { string xlConnStr = @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Users\jonat\Documents\TestCSharp.xlsx;Extended Properties='Excel 8.0;HDR=Yes;';"; var xlConn = new OleDbConnection(xlConnStr); var da = new OleDbDataAdapter("SELECT * FROM [mer_SVC$]", xlConn); var xlDT = new DataTable(); da.Fill(xlDT); List<GIS> xl = xlDT.AsEnumerable().Select(g => new GIS() { AccountNo = (int)g.Field<double>("Account No"), AccountName = g.Field<string>("Account Name") }).ToList(); string acConnStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\Users\jonat\Documents\PricingTools.accdb;Jet OLEDB:Engine Type=5;Persist Security Info=False;"; var acConn = new OleDbConnection(acConnStr); da = new OleDbDataAdapter("SELECT * FROM GIS", acConn); var acDT = new DataTable(); da.Fill(acDT); List<GIS> ac = acDT.AsEnumerable().Select(g => new GIS() { AccountNo = g.Field<int>("Account No"), AccountName = g.Field<string>("Account Name") }).ToList(); var missing = xl.Where(x => !ac.Any(a => a.AccountNo == x.AccountNo)); DataTable dt = acDT.Clone(); foreach (var m in missing) { var n = dt.NewRow(); n["Account No"] = m.AccountNo; n["Account Name"] = m.AccountName; dt.Rows.Add(n); } dataGridView1.DataSource = dt; } catch (Exception ex) { MessageBox.Show("Exception thrown; " + ex.Message); } } 

有几件事要提到。 我在Access中的表格和我在Excel中的数据只包含两个字段,帐号和帐号名称。 我认为你有更多,但技术仍然是一样的。 其次,虽然Excel中的帐号是整数,但在创buildDataTable时,它们被视为双精度,所以请注意拆箱(int)g.Field<double>("Account No") ,而不是访问版本g.Field<int>("Account No")

附录

如果您使用类而不是结构,那么您可以使用缺less的列表作为DataGridView的源代码(保存构buildDataTable)。 喜欢这个:

 private class GIS { public int AccountNo { get; set; } public string AccountName { get; set; } } var missing = xl.Where(x => !ac.Any(a => a.AccountNo == x.AccountNo)); var bS = new BindingSource(); bS.DataSource = missing; dataGridView1.DataSource = bS;