2017-01-17 6 views
0

Я запускаю хранимую процедуру, которую я хочу сбросить в шаблоне Excel.Datatable непосредственно в 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 Directly и ввести свой SQL - exec dbo.CODE_RED_2017
  4. Когда вы закроете MS Query, он спросит вас, куда вы хотите поместить данные. Выберите ячейку.
  5. Вуаля

Лучше всего, когда пришло время, чтобы обновить, щелкнув правой кнопкой мыши на таблице и выберите «Обновить», и он будет повторно выполнить вашу процедуру (или запрос). По моему опыту, Excel фактически отображает данные быстрее, чем большинство браузеров баз данных.

Вот ссылка Microsoft с большим количеством деталей:

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(); 
Смежные вопросы