簡體   English   中英

Excel工作表和MS Access表加入Visual Studio C#

[英]Excel sheet and MS Access table Join visual studio C#

我有一個名為mer_SVC excel表和一個名為GIS MS Access數據庫表。我想根據字段Account No查找不匹配的表。我已經通過將excel表導入訪問表從設計視圖中生成了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一次只能建立一個連接。 但是,通過分階段進行,您可以實現所需的目標。

首先創建兩個數據表,一個來自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時,它們被視為雙精度型,因此請注意與訪問版本g.Field<int>("Account No")相對的拆箱(int)g.Field<double>("Account No") g.Field<int>("Account No")

附錄

如果使用類而不是結構,則可以將缺少的列表用作DataGridView的源(節省構建DataTable的時間)。 像這樣:

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM