Нам нужно найти ошибки формул в большой рабочей книге, содержащей около 3 миллионов ячеек. Производительность имеет решающее значение. Мы реализовали функцию-обертку вокруг специальных ячеек, которая позволяет нам отлавливать исключение в случае отсутствия ячеек ошибок на этом листе. Аналогично:
Обработка «Ячейки не найдены». Ошибка в Excel
Но проблема в том, что проверка становится мучительно медленной, когда выдается исключение COM. Более конкретно, когда на листе есть хотя бы одна ошибка, мы записали время выполнения от 1 до 4 мс. Когда выдается ошибка, мы наблюдаем около 80 мс.
Есть ли у кого-нибудь креативная быстрая альтернатива проверке на отсутствие ошибок?
Наш код:
try
{
dynamic cellsWithErrors = cells.SpecialCells(cellType, valueType);
return cellsWithErrors;
}
catch (COMException)
{
return null;
}
Примечания:
Нахождение ошибок, когда они существуют, прекрасно, поэтому нет необходимости фокусироваться на этом.
Я уже обнаружил умеренное ускорение, используя вместо типов Range динамические типы
Наша проверка повторяет все листы во всей книге. Поэтому мы будем рады любому решению, которое также распространяется на всю книгу, но сомневаемся, что оно существует.
Мы пишем это как часть надстройки VSTO и используем слой Interop.
Решения уже рассмотрены
Мы могли читать весь диапазон как значения и перебирать его, но надеялись увидеть, есть ли что-то еще. Потому что в случае ошибок это будет медленнее.
Текущая идея
Так что загадка сводится к этому. С одной стороны, SpecialCells исключительно быстр, когда он находит результаты. Но исключение может привести к замедлению в 20–80 раз. С другой стороны, чтение всего используемого диапазона листа довольно стабильно с точки зрения производительности: я бы сказал, что оно линейно по числу ячеек с небольшим постоянным авансовым платежом. Теперь, проверяя значения ячеек, можно найти ошибки, используя ответ Майка Розенблюма: Как узнать, есть ли в ячейке ошибка в формуле в C # . Если так, то у нас был бы альтернативный способ проверки ошибок.
Идея состоит в том, чтобы написать главную функцию, которая поворачивается на размер рассматриваемого листа. Если это очень большой лист (у нас один с примерно 2 миллионами ячеек), то мы могли бы просто использовать SpecialCells и принять стоимость исключения, если оно произойдет. Но для меньших листов, где стоимость исключения превышает стоимость чтения во всем диапазоне и повторения его в памяти, мы должны просто сделать последнее.
Ключевую вещь, которую нам нужно определитьдля этого подхода и есть точка пересечения: где SpecialCells начинает превосходить чтение и итерацию? Мы также можем захотеть использовать наши собственные знания нашей рабочей книги, чтобы эвристически угадать, какие листы могут иметь ошибки, а какие нет. Я отправлю ответ, если мы его разработаем, и у меня будет время.