2017-01-17 178 views
0

我運行了一個存儲過程,我想在Excel模板上進行轉儲。直接將數據表導入Excel C#

它目前的作品,但只是太長時間。在SQL Server Management Studio中,查詢運行正常,但是當我寫入模板時,它確實很慢。

任何人都可以提出一個更有效的方法來實現相同的結果嗎?

這裏是我的代碼部分:

sdate = StartDate.Value.ToString(); 
edate = EndDate.Value.ToString(); 

Excel.Application oXL; 
Excel._Workbook oWB; 
Excel._Worksheet aSheet; 

try 
{ 
//Start Excel and get Application object. 
oXL = new Excel.Application(); 
oXL.Visible = true; 

//open the excel template 
oWB = oXL.Workbooks.Open("C:\\TEMP\\template.xlsm"); 

//oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value)); 

//Call to service 
//aSheet = (Excel._Worksheet)oWB.Worksheets.get_Item(1); 
aSheet = (Excel._Worksheet)oWB.ActiveSheet; 
//backgroundWorker1.ReportProgress(i++); 
writedata_from_proc(aSheet, "dbo.CODE_RED_2017"); 
//backgroundWorker1.ReportProgress(i++); 


//Make sure Excel is visible and give the user control 
//of Microsoft Excel's lifetime. 
//backgroundWorker1.ReportProgress(i++); 
MessageBox.Show("Data extraction complete"); 
oXL.Visible = true; 
oXL.UserControl = true; 
//SaveExcel(oWB); 

//clean up the COM objects to remove them from the memory 
Marshal.FinalReleaseComObject(aSheet); 
Marshal.FinalReleaseComObject(oWB); 
Marshal.FinalReleaseComObject(oXL); 
} 
catch (Exception theException) 
{ 
String errorMessage; 
errorMessage = "Error: "; 
errorMessage = String.Concat(errorMessage, theException.Message); 
errorMessage = String.Concat(errorMessage, " Line: "); 
errorMessage = String.Concat(errorMessage, theException.Source); 

MessageBox.Show(errorMessage, "Error"); 
} 
    } 

這裏是我最初無緣代碼:

public void writedata_from_proc(Excel._Worksheet oWS,string sentproc) 
     { 
      int rowCount = 0; 
      SqlCommand cmd = new SqlCommand(sentproc.ToString()); 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("@start_date", SqlDbType.DateTime).Value = getsdate(); 
      cmd.Parameters.Add("@end_date",SqlDbType.DateTime).Value=getedate(); 
      cmd.CommandTimeout = 0; 

      DataTable dt = GetData(cmd); 
      oWS.UsedRange.Rows.Count.ToString(); 
      if (sentproc.Contains("CODE_RED")) 
      { 
       rowCount = 1; 
      } 
      else 
      { 
       rowCount = oWS.UsedRange.Rows.Count; 
     } 
     foreach (DataRow dr in dt.Rows) 
     { 
      rowCount += 1; 
      for (int i = 1; i < dt.Columns.Count + 1; i++) 
      { 
       // Add the header the first time through 
       if (rowCount == 2) 
       { 
        oWS.Cells[1, i] = dt.Columns[i - 1].ColumnName; 
       } 
       oWS.Cells[rowCount, i] = dr[i - 1]; 
      } 
     } 

    } 
+1

writedata_from_proc方法做什麼?它的源代碼是什麼? –

+0

您沒有包含來自**'writedata_from_proc' **的主代碼。 – ManishChristian

+1

定義'但只是太長了'。 –

回答

1

Excel中已經有一個內置的工具,正是這一點,它需要不再比運行查詢和獲取結果要好。它被稱爲MS Query。簡而言之,你會:

  1. 轉到Excel的功能區中的「數據」選項卡
  2. 選擇「獲取外部數據」(功能區組) - >「自其他來源」 - >「從SQL服務器。」我假設這是SQL Server。從你的語法來看,它可能是Sybase,在這種情況下,你仍然可以通過ODBC(SQL Server下面的幾個選項)來做到這一點。
  3. 繞過所有的設計者,你將登陸MS查詢窗口。從這裏,您可以直接編輯SQL並輸入您的SQL - 當您關閉MS Query時,它會詢問您要放置數據的位置。選擇一個單元格。

最重要的是,當它的時間來刷新,你在桌子上單擊鼠標右鍵,選擇「刷新」,它會重新執行你的程序(或查詢)。根據我的經驗,Excel實際上比大多數數據庫瀏覽器更快地提供數據更快

這裏有更多的細節微軟鏈接:

https://support.office.com/en-us/article/Use-Microsoft-Query-to-retrieve-external-data-42a2ea18-44d9-40b3-9c38-4c62f252da2e?ui=en-US&rs=en-US&ad=US&fromAR=1

所以,你不需要C#的。也就是說,如果你通過C#以某種方式實現自動化,那麼也可以這樣做。這裏是一個例子:

string sql = "exec dbo.CODE_RED_2017"; 
string source = "your connection string here"; 
Excel.Range r = activeSheet.Range["A1"]; 

Excel.ListObject lo = sheet.ListObjects.AddEx(Excel.XlListObjectSourceType.xlSrcQuery, 
    source, true, Excel.XlYesNoGuess.xlGuess, r); 

lo.QueryTable.CommandText = sql; 
lo.Refresh();