2017-08-10 84 views
1

我有excel表命名爲mer_SVC和MS Access數據庫表名爲GIS。我想在字段Account No的基礎上找到不匹配的。我生成了sql查詢(如下所示)從設計視圖導入Excel表格中的Excel表格。Excel表格和MS Access表格加入visual studio C#

我正在使用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; 
+0

藝術至少你需要兩個IN後面的空格。我現在不在,這裏是8點25分,但你還沒有修好,我會在早上嘗試 –

+0

你試過了嗎? – Sibghat

+0

對不起被拖走了!現在看看 –

回答

0

那真是太有趣了!首先,我不認爲你可以按照你希望的方式來做,因爲OleDbAdapter一次只能連接一個連接。然而,你可以通過分階段實現你想要的東西。

首先創建兩個DataTables,一個來自Access,另一個來自Excel。然後將它們變成一個打字清單。接下來使用一點LINQ來獲取缺失的行。最後從結果中構建一個新的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中的帳號是整數,但在創建DataTable時,它們被視爲雙打,因此請注意拆箱(int)g.Field<double>("Account No"),而不是訪問版本g.Field<int>("Account No")

附錄

如果使用類,而不是一個結構的,那麼你可以使用丟失的列表作爲源爲您的DataGridView(節省建立數據表)。像這樣:

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; 
+0

感謝您的時間和精力。有用! – Sibghat

+0

我的榮幸。很高興有幫助 –

+0

親愛的喬納森,我想修改查詢。在訪問表中,我有狀態列,並希望不匹配的查詢在帳戶號碼相等和狀態=是。我試過使用和運營商,但沒有工作 – Sibghat