У меня есть программа VBA, запущенная на моем четырехъядерном ультрабуке Acer Aspire S3. Проблема в том, что она использует только 25% процессора (другие процессы вместе используют ~1%). Ноутбук работает под управлением Windows 8.0. Версия Excel — 2013 (32-разрядная). Используется только 55% системной оперативной памяти, причем Excel использует половину из 55%.
Я думаю, что, возможно, используется только 25%, потому что Excel использует только одно ядро. Однако у меня нет ничего, что могло бы подтвердить эту теорию. Как мне ускорить программу?
Спасибо.
решение1
Похоже, что программа, которую вы пытаетесь использовать, однопоточная, то есть она может использовать только одно ядро, не зная о существовании других. На самом деле нет конкретного способа ускорить это, кроме как купить процессор с более высокой тактовой частотой одного ядра или использовать программу, которая поддерживает многопоточность.
решение2
Все нижеизложенное относится к Excel 2007 и более ранним версиям. Согласносвязь@Ƭᴇcʜιᴇ007 написал в комментариях выше, что в Excel 2013 есть встроенная поддержка многопоточности. Тем не менее, предупреждение просто забыть об этом, если вы не опытный программист, все еще актуально.
К сожалению, VBA не поддерживает многопоточность, поэтому ваши вычисления VBA будут ограничены одним ядром вашего процессора.
Однако существует продвинутый метод обмана VBA для запуска нескольких потоков путем генерации файлов VBscript и их параллельного выполнения. Это позволяет обойти проблему, выполняя ваш код вне процесса Excel и позволяя Windows управлять ресурсами, выделенными для разных потоков.
Тем не менее, чтобы это заработало, скорее всего, вам придется полностью переосмыслить логику вашего кода (т. е. вам придется придумать, как разделить задачи таким образом, чтобы они выполнялись одновременно), что вполне может оказаться невыполнимым для вашего проекта. Я сам никогда этого не реализовывал, так что не смогу вам помочь больше, чем просто рассказав то, что я уже рассказал.
Но если вы хотите шагнуть в кроличью нору, вот ваминтересный пост в блогеэто показывает пример того, как это делается. Будьте осторожны: если вы не являетесь опытным программистом, вы можете забыть эту идею и просто принять, что VBA работает в одном потоке.
Другие ресурсы на Stack Overflow для смелых:
https://stackoverflow.com/q/19159025/657668
https://stackoverflow.com/q/5721564/657668
Конечно, есть и другие способы оптимизировать код VBA без использования нескольких потоков. Не видя вашего кода, невозможно делать конкретные предложения, но вот несколько обычных подозреваемых:
- Загрузите данные из листа в массив для более быстрой обработки. Взаимодействие с рабочим листом является основным узким местом в выполнении VBA, и его можно минимизировать, работая с массивами.
- Связанная проблема заключается в том, что Excel пересчитывает рабочую книгу после каждого изменения, внесенного в ячейку. Этого можно избежать, установив
Application.Calculation = xlManual
. Просто не забудьте вернуть его в значениеApplication.Calculation = xlAutomatic
перед выходом из Sub.
решение3
Как уже сказали другие, изначально VBA не является многопоточным. Если вы хотите ускориться, вы можете рассмотреть возможность написания пользовательских функций (UDF) на другом языке.
Я бы рекомендовал вам ExcelDNA и использование C# или VB.Net. Они очень просты в использовании, если вы уже знаете, как писать на C#, и можете управлять многопоточностью в пределах UDF.
решение4
Как уже сказали другие выше, потоки могли бы стать ответом, но это не совсем осуществимое решение, а обновление до 64 бит даст незначительную разницу. Одна вещь, которую вы можете попробовать сделать, это увеличить приоритет процесса, вы можете увидеть, как это сделатьздесь.
Трудно сказать, ускорит ли это выполнение вашего скрипта, поскольку в программе может быть другое узкое место (например, чтение/запись с диска), но это, по крайней мере, даст Windows знать, что этот процесс имеет более высокий приоритет, чем другие ваши процессы.