Превосходная производительность автоматизации при ручном применении форматирования ко многим ячейкам и строкам

У меня есть код, который вручную копирует данные из двух таблиц в две таблицы 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 секунд.

Другие вопросы по тегам