Превосходная производительность автоматизации при ручном применении форматирования ко многим ячейкам и строкам
У меня есть код, который вручную копирует данные из двух таблиц в две таблицы Excel, а затем сравнивает данные в двух таблицах.
У меня гораздо лучше получается вставлять данные в Excel, но я думаю, что у меня есть бутылочное горлышко, в котором я выбираю отсутствующие строки, выделяю их красным и выделяю ячейки, которые отличаются, и выделяю их желтым цветом.
Я задаюсь вопросом о вызовах, где я нахожу диапазон и вызываю.Select(), а затем устанавливаю Selection.Style.
Я уже делаю: oldInstance.Application.ScreenUpdating = false;
Просто интересно, есть ли другие предложения по повышению производительности?
В приведенном ниже коде есть много циклов и т. Д., Но основной удар по производительности, похоже, заключается в применении форматирования в Excel (если я закомментирую код, который выполняет.Select и устанавливает Selection.Style, это происходит намного быстрее).
IEnumerable<DataRow> oldOnly = oldTable.Rows.OfType<DataRow>().Except( newTable.Rows.OfType<DataRow>(), lambdaComparer );
int oldOnlyRows = 0;
foreach ( var dataRow in oldOnly )
{
int excelRowIndex = dataRow[ addedRowIndexColumnName ].ToString().ParseInt() + 2;
// Logger.Info( "Row: {0} Old Only: {0}",excelRowIndex , dataRow[ keyColumnName ] );
( oldInstance.ActiveSheet.Rows[ excelRowIndex ] as Range ).Select();
oldInstance.Selection.Style = "Bad";
oldOnlyRows++;
}
int newOnlyRows = 0;
IEnumerable<DataRow> newOnly = newTable.Rows.OfType<DataRow>().Except( oldTable.Rows.OfType<DataRow>(), lambdaComparer );
foreach ( var dataRow in newOnly )
{
int excelRowIndex = dataRow[ addedRowIndexColumnName ].ToString().ParseInt() + 2;
// Logger.Info( "Row: {0} New Only: {0}", excelRowIndex, dataRow[ keyColumnName ] );
( newInstance.ActiveSheet.Rows[ excelRowIndex ] as Range ).Select();
newInstance.Selection.Style = "Bad";
newOnlyRows++;
}
int differentCells = 0;
var enumerable = ( ( from o in oldTable.Rows.OfType<DataRow>() join n in newTable.Rows.OfType<DataRow>() on o[ keyColumnName ] equals n[ keyColumnName ] select new { o, n } ) );
foreach ( var x1 in enumerable )
{
for ( int i = 0; i < newTable.Columns.Count -1; i++ ) // use Count - 1 so we ignore the last "RowIndex" column
{
if ( x1.o[ i ].ToString() != x1.n[ i ].ToString() )
{
int oldExcelRowIndex = x1.o[ addedRowIndexColumnName ].ToString().ParseInt() + 2;
var oldRange = oldInstance.GetCell( oldExcelRowIndex, i + 1 );
oldRange.Select();
oldInstance.Selection.Style = "Neutral";
int newExcelRowIndex = x1.n[ addedRowIndexColumnName ].ToString().ParseInt() + 2;
var newRange = newInstance.GetCell( newExcelRowIndex, i + 1 );
newRange.Select();
newInstance.Selection.Style = "Neutral";
differentCells ++;
}
}
}
1 ответ
Хитрость заключается в том, чтобы избежать звонков в Select.
Например:
( oldInstance.ActiveSheet.Rows[ excelRowIndex ] as Range ).Select();
oldInstance.Selection.Style = "Bad";
Должно быть:
( oldInstance.ActiveSheet.Rows[ excelRowIndex ] as Range ).Style = "Bad";
Это занимает мой код форматирования от 41 до 9 секунд.