Производительность Excel Automation клиентского приложения VB6 по сравнению с клиентским приложением C # - PullRequest
0 голосов
/ 05 августа 2011

Я потратил много времени на преобразование какого-то старого кода VB6 / * .xla в приложение на C # и теперь обнаружил, что закопал себя в серьезную дыру в производительности.Кажется, что автоматизация Excel из C # (VS 2010) оказывает некоторое влияние на производительность.Я написал «точный» код в тестовом приложении VB6, и вычисления выполняются примерно за 1-2 секунды.Где, как код в C # занимает больше минуты.Общий поток кода выглядит следующим образом ... (где клиент - приложение VB6 или C #).

- выполняется только один раз за время жизни клиентского приложения

  1. Клиент создает и открывает и приложение Excel

  2. Клиент автоматизирует Excel для загрузки необходимых надстроек, необходимых для расчетов.

    - Готово длякаждый выполненный расчет

  3. Клиент автоматизирует Excel, чтобы закрыть любой существующий файл * .xls и открыть нужный файл * .xls.

  4. Клиент вызывает макрос из Excel, добавленный с помощью ExcelAppObject.Run («AddIn.xla! GetConfiguration»), чтобы получить конфигурацию * .xls, открытой на шаге 3.

  5. Клиент вызывает макрос из Excelдобавить с помощью ExcelAppObject.Run («AddIn.xla! LoadInputs», InputsXmlString)

    1. Макрос загружает InputsXmlString в объект MSXML.DOMDocument40.
    2. Макрос превращает приложение.Расчет = xlCalculationManual (для ускорения заполнениянесколько «таблиц» входных данных)
    3. Макрос устанавливает Application.EnableEvents = false
    4. Макрос зацикливает все «настроенные» входы / таблицы на рабочем листе «Ввод» и очищает их (в случае, если переданный в xml не содержит «все» входные данные)
    5. Макрос зацикливает весь переданный xml и загружает в соответствующие места на рабочем листе «Ввод».
  6. Клиент вызывает макрос из Excel, добавляемый с помощью ExcelAppObject.Run («AddIn.xla! GetResults», DataXmlString)

    1. Макрос загружает DataXmlString в объект MSXML.DOMDocument40.
    2. Макрос зацикливает все «сконфигурированные» значения данных на рабочем листе «Ввод» и очищает их (в случае, если переданный в xml не содержит «все» данные или не удаляет предыдущие вычисления)
      Это отличается от LoadInputs, потому чтоу нас может быть пакетное вычисление, в котором входные данные одинаковы для каждого вычисления, но «данные участника» очевидно различны для каждого вычисления
    3. Макрос загружает вседанные из DataXmlString в соответствующие местоположения на рабочем листе «Ввод»
    4. Макрос устанавливает Application.EnableEvents = true
    5. Макрос превращает Application.Calculation = xlCalculationAutomatic (чтобы убедиться, что вычисление происходит теперь, когдавсе данные / входные данные были загружены)
    6. Макрос зацикливает все настроенные «ячейки результата» и возвращает их через строку XML.

Итаккак видите, для каждого вычисления у меня есть только три перекрестных вызова из клиента в Excel (GetConfiguration, LoadInputs и GetResults), чтобы попытаться минимизировать эту известную проблему «плохой» производительности.Проблема в том, что при вызове точно такого же кода из приложения VB6 шаги 4-6 занимают около 2 секунд.Когда клиентское приложение является приложением C #, 4-6 занимают около 70 секунд. Все из этих 70 секунд происходят на шаге 6, когда я возвращаю расчет обратно в автоматический режим.

Известна ли проблема в приложениях C #, автоматизирующих Excel по сравнению с устаревшими приложениями VB6, и / или есть ли какие-либо предлагаемыеОбойти это так, чтобы я мог сохранить свой код C #, но каким-то образом достичь той же производительности, что и VB6?

1 Ответ

0 голосов
/ 07 августа 2011

Использование C # для взаимодействия с Excel через COM Interop, как правило, крайне плохое с точки зрения производительности: я хотел бы предложить, что если вы хотите продолжить работу с C #, вы посмотрите на Excel DNA или Addin Express, оба из которых позволяют вам использоватьнамного быстрее XLL взаимодействует с C #.См. http://fastexcel.wordpress.com/2011/07/07/excel-udf-technology-choices-snakes-ladders-with-vba-vb6-net-c-com-xll-interop/ для моей краткой оценки доступных в настоящее время технологических решений для взаимодействия с Excel.

Основным узким местом производительности с C # обычно является перенос данных из Excel в C #: каждый вызов передачи данных вызывает большоенакладные расходы, поэтому обычно гораздо быстрее передавать большие блоки данных с помощью массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...