我运行一个我要在Excel模板上转储的存储过程。
它目前有效,但只是花了太长时间。在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];
}
}
}
答案 0 :(得分:1)
Excel已经有一个内置工具,可以完成此操作,并且不会超过运行查询并获取结果所需的时间。它叫做MS Query。简而言之,你会:
exec dbo.CODE_RED_2017
最重要的是,当需要刷新时,右键单击表并选择“刷新”,它将重新执行您的过程(或查询)。根据我的经验,Excel实际上比大多数数据库浏览器提供的数据更快。
这是一个包含更多详细信息的Microsoft链接:
所以,你根本不需要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();