Линейный индикатор выполнения (прогресс бар) в Excel

Линейный индикатор выполнения (прогресс бар) в Excel

Разберёмся как создать и настроить линейный индикатор выполнения (прогресс-бар) в виде диаграммы в Excel.

Приветствую всех, уважаемые читатели блога TutorExcel.Ru!

В современную экономическую жизнь прочно вошли понятия КПЭ (ключевые показатели эффективности, или KPI) и дашборда, которые помогают нам увидеть насколько эффективно выполняются те или иные цели. Грамотная визуализация позволяет сделать это приятным и понятным глазу языком.

Мы уже разбирали с вами примеры пулевой диаграммы, диаграммы в виде спидометра, сейчас остановимся ещё на одном варианте визуализации — индикаторе выполнения (также встречаются названия индикатор процесса или прогресс-бар от английского progress bar).

Для начала давайте поймем, что же это именно такое?

Прогресс бар — это графический элемент в виде полоски (горизонтальной, вертикальной, круговой и т.д.), показывающий статус процесса с помощью заполнения полоски по мере выполнения. Вы часто можете видеть горизонтальный вариант графика во время ожидания загрузки файлов или установки программ.

Сегодня предлагаю подробно рассмотреть линейный вариант графика, который представляет собой простую горизонтальную или вертикальную полосу:

Также в целом можно выделить 2 способа построения графика:

  • Без делений на шкале; в этом случае полоска нарисована как единый объект.
  • С делениями. В этом случае дополнительно рисуется шкала, которая отображает уровни выполнения (к примеру от 0% до 40% — красная зона, от 40% до 70% — желтая зона и т.д.).

Построение линейного индикатора (прогресс бара)

Вариант 1. Прогресс бар без шкалы

Давайте приступим к построению и начнем с самого простого варианта.

Для начала создадим таблицу, состоящую всего из 2 рядов с данными, в первом будет исходный процент (к примеру 85%), а во втором оставшаяся недостающая часть до 100% (т.е. в данном случае 15% = 100% — 85%):

Выделяем диапазон с данными A1:B2 и строим гистограмму с накоплением (в панели вкладок выбираем Вставка -> Диаграммы -> Линейчатая гистограмма с накоплением):

Как видим Excel не совсем правильно интерпретировал данные и построил график с 2 рядами данных, поэтому для корректного отображения поменяем местами строки и столбцы (выделяем диаграмму и в панели вкладок Конструктор выбираем Строка/Столбец), этим мы добьемся отображения всех данных в одному ряду:

Отлично, диаграмма уже начинает приобретать узнаваемый вид.

Далее устанавливаем минимальную и максимальную границы для оси (щелкаем правой кнопкой мыши по горизонтальной оси и попадаем в настройки Формата оси), как 0 и 1 соответственно, чтобы наша полоска полностью помещалась и показывалась на графике:

В результате мы получаем следующий вид графика:

Уберем ненужные на текущий момент детали в виде названия, дополнительных осей и прочего, чтобы они не отвлекали от построения (их, безусловно, можно не удалять и компоновать на ваше усмотрение):

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

Поэтому, чтобы растянуть диаграмму на всю возможную ширину и убрать лишние полосы, установим боковой зазор для ряда равным нулю (выделяем любой ряд с данными, щелкаем правой кнопкой мыши и выбираем Формат ряда данных -> Параметры ряда):

В итоге получаем более компактный вид:

Остались небольшие детали, покрасим части полоски в подходящие цвета и добавим подпись данных на ряд:

Все готово, перейдем к следующему варианту.

Вариант 2. Прогресс бар со шкалой

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

Для начала несколько модифицируем нашу таблицу и добавим на нее дополнительные ряды для построения шкалы:

В данном случае я указал шаг шкалы равным 10%, но можно поставить абсолютно любой по вашему усмотрению, главное чтобы сумма всех таких шагов давала 100% (10 шагов по 10% как в примере, или 20 шагов по 5% и т.д.).

Выделяем диапазон с данными A1:B11 и, как и в предыдущем примере, строим линейчатую гистограмму с накоплением:

Повторяем алгоритм и меняем строки и столбцы местами, чтобы диаграмма приобрела необходимый нам вид:

Как мы видим, у нас появилась достаточно длинная полоса, где в начале находится полоска, а в конце как раз разместилась шкала в виде маленьких разноцветных прямоугольников.

Покрасим каждый шаг шкалы в подходящий цвет, для этого левой кнопкой мыши выделяем каждый ряд по отдельности и делаем заливку соответствующим цветом (к примеру, первые 4 шага красим красным, 3 средние — желтым и 3 последние — зеленым):

Так как шкала должна быть подложкой (т.е. находиться позади основного ряда), то поместим основной ряд на второстепенную ось, чтобы он всегда находился над шкалой. Для этого в настройке формата ряда данных указываем построить ряд по вспомогательной оси (именно для ряда с основной полоской):

В результате настройки типов осей получаем:

Далее также для обеих осей указываем 0 и 1 как минимальную и максимальную границы, чтобы график был ровно от 0% до 100%:

Убираем название, оси данных и прочие ненужные в данный момент детали, настраиваем нулевой боковой зазор:

Так как шкала на полученной диаграмме не видна за основной полоской, то для основного ряда с данными установим прозрачность (щелкаем по ряду правой кнопкой мыши, в контекстном меню выбираем Формат ряда данных -> Заливка и границы -> Заливка):

Также добавим подпись данных и получаем:

По усмотрению шкалу можно сделать не сплошной, а с разделителями, для этого установим для каждого ряда шкалы белую границу:

Спасибо за внимание!
Если у вас есть вопросы по теме статьи — пишите в комментариях.

Источник:
http://tutorexcel.ru/diagrammy/linejnyj-indikator-vypolneniya-progress-bar-v-excel/

ProgressBar – создание полосы загрузки на VBA

Во время выполнения кода программ в Excel, в случае длительного исполнения какого-либо процесса, возникает необходимость сообщить пользователю, что приложение стабильно работает, а вовсе не зависло, как это может показаться на первый взгляд.

Способ вывода таких сообщений предусмотрен приложением. Называется он Статус бар и вызывается он прямо из кода в редакторе Visual Basic следующей записью:
Application.StatusBar = “сообщение для пользователя”.

Во многих случаях, этого вполне достаточно, чтобы успокоить пользователей Ваших программ. Если Вы хотите сообщать больше информации, сообщить оставшееся время обработки, процент выполнения, позволить остановить процедуру, то одним статус баром не обойтись.

В данной статье описано, как создать окно загрузки (или по-другому прогресс бар) для Ваших процедур без загромождения их кодом.

Скачать файл с классом можно в конце статьи.

Состав прогресс бара

Строится окно загрузки на основе простой пользовательской формы UserForm, которая содержит следующие элементы:

  1. Два элемента Label. Используются в совокупности для отображения полосы загрузки. Первый применяется как контейнер и имеет отличный от фона формы фон. Второй вкладывается в первый и имеет динамическую ширину, которая меняется вместе с процентом выполнения процесса. Ее фон отличный от фона формы и фона родительского элемента. Эти элементы можно заменить на один дополнительный, который так и называется — ProgressBar, но с его использованием могут быть связаны некоторые проблемы, речь о которых пойдет ниже.
  2. Три элемента Label. Каждый из них не зависит от остальных и предназначается для вывода конкретной информации: продолжительность процесса, оставшееся время, количество пройденных этапов процесса.
  3. ТехBox для вывода специальных сообщений пользователю.

Если вывести все элементы на форму, то она будет иметь такой вид:

В случае ненадобности тех или иных элементов, их можно не выводить. Контроль за выводом элементов осуществляет класс «ProgressBar», экземпляр которого для начала необходимо создать (Set var = New ProgressBar). Затем, используя созданный класс, можно программным образом заполнить форму элементами и задавать им конкретные значения.

Описание класса и способов создания окна загрузки

Для начала рассмотрим доступные методы данного класса, не концентрируясь на коде, а только на его функциональности:

  • Метод createLoadingBar – создает полосу загрузки на форме;
  • createString – создает сроку «Обработано: … %»;
  • createtimeDuration – создает сроку «Продолжительность обработки: …»;
  • createtimeFinish – создает строку «Оставшееся время обработки: …»;
  • createTextBox – создает элемент TextBox;
  • setParameters – задает параметры окна загрузки для предстоящего процесса. Принимает 3 аргумента:
    • expProcess_INT – обязательный аргумент. Принимает целое число, сообщающее, из какого количества этапов состоит последующий процесс;
    • UpdateInterval_INT – необязательный аргумент. С его помощью можно задать интервал обновления формы, т.е. через какое количество этапов все элементы окна загрузки необходимо обновить;
    • UpdTimeInterval_INT_SEC – необязательный аргумент. Задает интервал обновления формы в секундах. Аргумент имеет смысл только в том случае, если не задан аргумент UpdateInterval_INT.
  • В том случае, если оба аргумента, задающие интервал, не указаны или принимают значение 0, то по умолчанию интервал обновления будет равняться одной секунде.
  • Метод Start – запускает окно загрузки. Данный метод важен потому, что он отображает саму форму и запоминает время запуска, которое в дальнейшем используется для расчетов. Метод принимает один необязательный аргумент — title. С его помощью можно задать заголовок формы полосы загрузки. Значение заголовка по умолчанию равняется строке «Процесс выполнения».
  • Update – обновляет форму, если прошел интервал заданный методом setParameters. Данный метод принимает два необязательных аргумента:
    • curProcess – целое число. Номер текущего этапа процесса;
    • stringTextBox – строка для элемента TextBox.
  • exitBar – закрывает прогресс бар и выгружает форму из памяти.
  • getForm – возвращает ссылку на форму прогресс бара.

Можно заметить, что прогресс бар обязательно устанавливает интервал обновления окна загрузки. Поэтому сообщения, заданные в аргументе stringTextBox метода Update, попадут в форму только в случае, если интервал это позволит. Но можно напрямую обратиться к форме и внести сообщение – ссылка_на_форму.Text = “сообщение”.

Это сделано по двум причинам.

Первая причина. При выводе в форму оставшегося времени обработки, его расчет производится, исходя из среднего времени, затраченного на один этап процесса, а затем умноженного на число оставшихся процессов. Данный способ является достаточно простым и понятным, но так как этапы выполняются не всегда с одной и той же скоростью, то время постоянно перепрыгивает с одного показателя на другой, что не позволяет адекватно его оценивать. Особенно данный эффект заметен в начале, когда прошедших этапов для оценки не так много. Установив интервал, Вы можете смягчить данный эффект. Рекомендуемого интервала в данном случае нет, так как все зависит от конкретного процесса.

Второй причиной является производительность. Не смотря на то, что идея вывода информации по загрузке является вполне обоснованной, само ее использование сильно замедляет процесс. Например, с использованием ProgressBar время обработки нижеприведенного примера составляет 1 минута 17 секунд при установленном интервале обновления в секунду. При обновлении формы на каждом этапе, за 2 минуты обработалось чуть больше 2 сотых процента. Без использования на все ушло 8 секунд. Поэтому старайтесь использовать прогресс бар только в случаях, когда это действительно важно и применяйте к нему оптимальный интервал – секунды достаточно, свыше данного значения особых изменений в производительности не наблюдается.

Также предусмотрена возможность остановить выполнение всех процессов, закрыв окно загрузки. Предварительно пользователю будет выведено окно с подтверждением.

Пример подключения прогресс бара к макросу

Далее приводиться простой пример перебора символов строки. Процедура сама по себе смысла не имеет, но хорошо демонстрирует возможности окна загрузки.

Многоуровневая полоса загрузки

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

Никаких дополнительных действий не требуется, достаточно создать новый экземпляр класса (New ProgressBar) и работать с ним независимо от родительского процесса.

Рекомендация: Для дочерних процессов добавляйте к формам загрузок уникальные заголовки (ProgressBar.Start Заголовок). Это уведомит пользователя программы о том, что сейчас выполняется подпроцесс.

Специальный элемент Microsoft ProgressBar Control

Выше было сказано о том, что саму полосу загрузки можно заменить дополнительным элементом управления формы, который специально предназначен для этого и называется Microsoft ProgressBar Control, version 6.0. Чтобы применить его, достаточно нажать правой кнопкой мыши на панели Tollbox и выбрать пункт «Additional Control. «.

Но с применением этого элемента могут быть связаны проблемы работоспособности программы на разных версиях MS Office (в основном 2010 и 2013) и Windows, когда Вы попытаетесь добавить его в UserForm. Приложение выдаст ошибку «Библиотека не зарегистрирована».

Для ее устранения сначала проверьте наличие на Вашем компьютере файла MSCOMTCL.ocx. Это библиотека содержащая общие элементы управления Windows 6.0. Он должен располагаться в папке WindowsSysWOW64 для 64-разрядных ОС либо WindowsSistem32 для 32-разрядных. В случае необходимости скачайте его и разместите в требуемую папку.

После того, как Вы убедились в наличии библиотеки, следует ее зарегистрировать. Запустите командную строку от имени администратора (Пуск -> Все программы -> Стандартные -> Командная строка) и выполните команду regsvr32 MSCOMTCL.ocx.

Скачать пример полосы загрузки на VBA

Скачать пример progressbar VBA c применением Microsoft ProgressBar Control.

Источник:
http://office-menu.ru/inye-kategorii/gotovye-resheniya/42-progressbar-sozdanie-polosy-zagruzki-na-vba

Отобразить процесс выполнения

Часто при создании кодов в VBA используется обращение к ячейкам, листам, книгам и т.д. и их обработка в циклах. Пара примеров подобных циклов:

  • Просмотреть все файлы в папке — цикл по файлам в папке — Do While sFiles <> «» и For Each objFile In objFolder.Files
  • Массовая замена слов — цикл по ячейкам(массивам) — For lr = 1 To UBound(avArr, 1)
  • Не работают/пропали меню — цикл по всем панелям — For Each cmdBar In Application.CommandBars

Если операция в цикле выполняется за пару секунд — это вполне приемлемо и отражать графически подобные действия нет нужды. Но, если циклы «крутятся» по полчаса — вполне неплохо иметь возможность видеть на какой стадии цикл. Здесь есть один нюанс: циклы могут быть как с заранее известным кол-вом итераций, так и без этого понимания.
Цикл Do While из первого кода статьи Просмотреть все файлы в папке является циклом условия. Т.е. заранее неизвестно сколько файлов будет обработано и следовательно невозможно отразить прогресс выполнения задачи в процентах.
Циклы вроде For Each и For . Next как правило дают возможность определить общее кол-во элементов к обработке, т.к. применяются как правило к коллекциям и объектам, у которых есть свойство .Count. Углубляться в этой статье не стану — это лишь предисловие, чтобы было ясно, почему и зачем далее в статье продемонстрированы разные подходы отображения процесса выполнения.
Отобразить же процесс можно двумя способами:

Читайте также  Округление числа в Excel

Использование Application.StatusBar
Самый простой вариант отображения процесса выполнения кода. Он может быть без проблем использован на любом ПК.
Application.StatusBar — это специальный элемент интерфейса, расположенный в левой нижней части окна Excel и который может показывать дополнительную информацию в зависимости от действий пользователя. Все не раз видели его в работе. Например, после того как мы скопировали ячейки StatusBar покажет нам доп.информацию:

И из VBA есть доступ к этому элементу. Чтобы написать слово привет в StatusBar надо выполнить всего одну строку кода:

Чтобы сбросить значения StatusBar и передать управление им обратно самому Excel необходимо выполнить строку:

делать это обязательно, т.к. в противном случае вместо системных доп.сообщений будет постоянно показываться то значение, которое мы задали. Конечно, можно перезапустить Excel, но куда правильнее дописать в код строку, приведенную выше.
Как я уже упоминал — циклы могут быть с заранее неизвестным кол-вом итераций. В таких случаях очень удобно показывать стадию выполнения хотя бы из тех побуждений, чтобы пользователь видел, что программа не «зависла». на примере кода из статьи Просмотреть все файлы в папке:

Sub Get_All_File_from_Folder() Dim sFolder As String, sFiles As String ‘диалог запроса выбора папки с файлами With Application.FileDialog(msoFileDialogFolderPicker) If .Show = False Then Exit Sub sFolder = .SelectedItems(1) End With sFolder = sFolder & IIf(Right(sFolder, 1) = Application.PathSeparator, «», Application.PathSeparator) ‘отключаем обновление экрана, чтобы наши действия не мелькали Application.ScreenUpdating = False sFiles = Dir(sFolder & «*.xls*») Do While sFiles <> «» ‘показываем этап выполнения Application.StatusBar = «Обрабатывается файл ‘» & sFiles & «‘» ‘открываем книгу Workbooks.Open sFolder & sFiles ‘действия с файлом ‘Запишем на первый лист книги в ячейку А1 — www.excel-vba.ru ActiveWorkbook.Sheets(1).Range(«A1»).Value = «www.excel-vba.ru» ‘Закрываем книгу с сохранением изменений ActiveWorkbook.Close True ‘если поставить False — книга будет закрыта без сохранения sFiles = Dir Loop ‘возвращаем ранее отключенное обновление экрана Application.ScreenUpdating = True ‘сбрасываем значение статусной строки Application.StatusBar = False End Sub

Если запустить код, то перед открытием каждой книги в строке StatusBar будет показано какой именно файл отрывается и обрабатывается. И так с каждым файлом:

В случае же с циклами, количество итераций которых есть возможность определить, можно показывать этап выполнения в процентах. Например, цикл по всем выделенным ячейкам:

Sub ShowProgressBar() Dim lAllCnt As Long, lr as Long Dim rc As Range ‘кол-во ячеек в выделенной области lAllCnt = Selection.Count ‘цикл по всем ячейкам в выделенной области For Each rc In Selection ‘прибавляем 1 при каждом шаге lr = lr + 1 Application.StatusBar = «Выполнено: » & Int(100 * lr / lAllCnt) & «%» DoEvents ‘чтобы форма перерисовывалась Next ‘сбрасываем значение статусной строки Application.StatusBar = False End Sub

В строке статуса это будет выглядеть так:

Но можно показывать информацию и в чуть более изощренных формах:
Вариант отображения % и блоками-цифрами от 1 до 10 (1 = 10% выполнения)

Sub StatusBar1() Dim lr As Long, lrr As Long, lp As Double Dim lAllCnt As Long ‘кол-во итераций Dim s As String lAllCnt = 10000 ‘основной цикл For lr = 1 To lAllCnt lp = lr 100 ‘десятая часть всего массива s = «» ‘формируем строку символов(от 1 до 10) For lrr = 10102 To 10102 + lp 10 s = s & ChrW(lrr) Next ‘выводим текущее состояние выполнения Application.StatusBar = «Выполнено: » & lp & «% » & s: DoEvents DoEvents Next ‘очищаем статус-бар от значений после выполнения Application.StatusBar = False End Sub

Вариант отображения % и стрелками -> (1 стрелка = 10% выполнения)

Sub StatusBar2() Dim lr As Long, lp As Double Dim lAllCnt As Long ‘кол-во итераций Dim s As String lAllCnt = 10000 For lr = 1 To lAllCnt lp = lr 100 ‘десятая часть всего массива ‘формируем строку символов(от 1 до 10) s = String(lp 10, ChrW(10152)) & String(11 — lp 10, ChrW(8700)) Application.StatusBar = «Выполнено: » & lp & «% » & s: DoEvents DoEvents Next ‘очищаем статус-бар от значений после выполнения Application.StatusBar = False End Sub

Вариант отображения % и квадратами (кол-во квадратов можно изменять. Если lMaxQuad=20 — каждый квадрат одна 20-я часть всего массива)

Sub StatusBar3() Dim lr As Long Dim lAllCnt As Long ‘кол-во итераций Const lMaxQuad As Long = 20 ‘сколько квадратов выводить lAllCnt = 10000 For lr = 1 To lAllCnt Application.StatusBar = «Выполнено: » & Int(100 * lr / lAllCnt) & «%» & String(CLng(lMaxQuad * lr / lAllCnt), ChrW(9632)) & String(lMaxQuad — CLng(lMaxQuad * lr / lAllCnt), ChrW(9633)) DoEvents Next ‘очищаем статус-бар от значений после выполнения Application.StatusBar = False End Sub

Этот вариант мне нравится больше всего.
При желании можно сделать и иные варианты — главное найти символы, которые будут показываться и определить их числовой код.

Использование UserForm
Использование стандартного элемента ProgressBar
Для Userform можно использовать стандартный контрол ProgressBar, но я лично не люблю добавлять на формы элементы, которые надо подключать отдельно. Потому как впоследствии контрол может отказаться работать, т.к. нужной версии не окажется на конечном ПК пользователя. Например в моем офисе 2010 для 64-битных систем его нет.
Поэтому про него кратко и в файле примере его нет. Как его создать:

  • создаем UserForm (в меню VBE —InsertUserForm. Подробнее про вставку модулей и форм — Что такое модуль? Какие бывают модули?)
  • отображаем окно конструктора(если не отображено): ViewToolbox
  • далее в меню ToolsAdditional Controls
  • там ищем что-то имеющее в названии ProgressBar и отмечаем его. Жмем Ок.

Теперь в окне Toolbox появится элемент ProgressBar. Просто перетаскиваем его на форму. В свойствах можно задать цвет и стиль отображения полосы прогресса. Останется лишь при необходимости программно показывать форму и задавать для элемента ProgressBar значения минимума и максимума. Примерно это выглядеть будет так:
Практический код
Например, надо обработать все выделенные ячейки. Если форма называется UserForm1, а ProgressBar — ProgressBar1, то код будет примерно такой:

Sub ShowProgressBar() Dim lAllCnt As Long Dim rc As Range ‘кол-во ячеек в выделенной области lAllCnt = Selection.Count ‘показываем форму прогресс-бара UserForm1.Show UserForm1.ProgressBar1.Min = 1 UserForm1.ProgressBar1.Max = lAllCnt ‘цикл по всем ячейкам в выделенной области For Each rc In Selection ‘прибавляем 1 при каждом шаге UserForm1.ProgressBar1.Value = UserForm1.ProgressBar1.Value + 1 DoEvents ‘чтобы форма перерисовывалась Next ‘закрываем форму Unload UserForm1 End Sub

Как использовать эту форму и коды
Первоначально надо скачать файл, приложенный к статье, и в свой проект перенести форму frmStatusBar и модуль mCustomProgressBarModule.
Далее просто внедряем нужные строки в свои коды с циклами:

  • До начала цикла необходимо вызывать процедуру инициализации формы:
    Call Show_PrBar_Or_No(lAllCnt, «Обрабатываю данные. «)
    первым аргументом задается общее кол-во обрабатываемых элементов, а вторым заголовок формы. Если второй аргумент не указан, то по умолчанию будет показан заголовок «Выполнение. «. Так же внутри кодов есть кусок кода, отвечающий за минимальное кол-во элементов к обработке. По умолчанию задано 10. Это значит, что если обрабатывается менее 10 ячеек, то форма прогресс-бара показана не будет. Нужно для случаев, когда производятся разные действия над ячейками, но неизвестно сколько их будет. Но зато известно, что с ними будет делать код. Часто для кол-ва ячеек менее 100 нет смысла отображать прогресс выполнения, т.к. это и так секундное дело.
    Чтобы изменить минимальное кол-во достаточно в строке bShowBar = (lCnt > 10) заменить 10 на нужное число.
  • Далее в каждом проходе цикла вызвать перерисовку формы под новое значение цикла:
    If bShowBar Then Call MyProgresBar
  • и в конце не забыть закрыть форму, чтобы не висела:
    If bShowBar Then Unload frmStatusBar

Пример применения формы:

Sub Test_ProgressForm() Dim lr As Long Dim lAllCnt As Long ‘кол-во итераций lAllCnt = 10000 ‘инициализируем форму прогресс-бара Call Show_PrBar_Or_No(lAllCnt, «Обрабатываю данные. «) ‘сам цикл For lr = 1 To lAllCnt If bShowBar Then Call MyProgresBar Next ‘закрываем форму, если она была показана If bShowBar Then Unload frmStatusBar End Sub

Так же все описанные примеры и коды можно найти в приложенном файле:
Скачать пример:

Tips_ShowProgressBar.xls (79,0 KiB, 3 833 скачиваний)

Статья помогла? Поделись ссылкой с друзьями!

Поиск по меткам

Поделитесь своим мнением

Комментарии, не имеющие отношения к комментируемой статье, могут быть удалены без уведомления и объяснения причин. Если есть вопрос по личной проблеме — добро пожаловать на Форум

Источник:
http://www.excel-vba.ru/chto-umeet-excel/otobrazit-process-vypolneniya/

Excel vba прогресс бар

Создание прогресс-бара выполнения макроса (Макросы/Sub)

​Смотрите также​​ ‘показывать’ в Application.StatusBar​
​ прорисовывать элементы с​ в и Delphi,​Прогресс бар ?​
​ Dim pi As​
​Application.Calculation = xlCalculationManual​
​ инете представлено достаточно​
​Удалите одну -​
​:=False, Transpose:=False​
​ Excel.Workbook​Alex_ST, 23.12.2016 в​
​ ChrW(9633))​ в первом посте)?​
​ String(11 — p​Application.StatusBar = False​
​UserForm1.Show​
​Viper25​alex_gearbox​
​ использованием манифеста винды.​ это не проблема,​
​Может я чего-то​
​ New ProgressIndicator ‘​
​For i =​
​ много вариаций создания​ и все заработает​
​Workbooks(Month + «_TEMP.xlsx»).Close​
​Set Gorod =​
​ 14:08, в сообщении​
​DoEvents​
​Alex_ST​
​ 10, ChrW(8700))​
​End Sub​

​UserForm1.Label1.Width = 1​​: Здравствуйте.​: А я сделал​
​blanks​
​ тока как мне​
​ не понимаю.. Но​ создаём новый прогресс-бар​ 10 To 109​
​ Progressbar, но как​Viper25​
​Application.ScreenUpdating = True​
​ ThisWorkbook​
​ № 9 ()​Next​
​: Это точно. Я​Application.StatusBar = «Выполнено:​
​Sub test2()​For i =​
​Нужно создать прогресс-бар​
​ ProgressBar в StatusBar-е​
​: Как в ескселе​
​ это окно «вклеить»​

​ какой смысл в​​ pi.Show «Подождите, работает​​If Cells(i, 1).Value​​ его прописать? В​: Увы. Что я​Application.CutCopyMode = True​

​’Вставляем таблицу 1​​ 200?’200px’:»+(this.scrollHeight+5)+’px’);»>Спасибо, Слава.​’очищаем статус-бар от​ отходил от компа​ » & p​

​For i =​​ 1 To 100​ для наглядности работы​ Excel-я. На API-шных​
​ сделать пргресс бар​ в файл Экселевский,​ прогресс баре, если​ ​ макрос» ‘ отбражаем​
​ = «» Then​ идеале хотелось, чтобы​
​ не так сделал?​Application.DisplayAlerts = True​
​Dim filenameTEMP As​Udik​ значений после выполнения​ и не успел​ & «% «​ 1 To 10000​
​UserForm1.Label1.Width = Int(i​
​ макроса.​
​ вызовах. Могу прислать.​
​ по типу как​
​ если это возможно.​
​ отключено обновление экрана?​ индикатор ‘ код​
​ Rows(i).RowHeight = 0​ Progressbar выглядел аналогично​
​Спасибо.​End Sub​ String​: ага, увидел​Application.StatusBar = False​ сам ответить.​ & S: DoEvents​
​p = i​
​ * j)​
​Нашел такой пример.​
​Если кому интересно:​
​ копирование файла,​
​И можно ли​Лина​
​ макроса Application.ScreenUpdating =​’For Each cc​ с тем, который​Starbirst​Function GetFolderPath(Optional ByVal​filenameTEMP = myPath​Viper25​End Sub​
​Спасибо, Слава.​Next​ 100​For k =​
​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub Progress()​
​http://j-walk.com/ss/excel/tips/tip34.htm​
​т.е. движущиеся по​
​ остановить выполнение макроса.​
​: Вот файл​ False Range(«B22».Select Selection.AutoFill​
​ In [B10:B109].Columns​ появляется при нажатии​: Доброго времени суток!​ title As String​ + «» +​:​
​взял тут, там​Alex_ST​Application.StatusBar = False​Application.StatusBar = «Выполнено:​
​ 1 To 100000​
​’​
​-=Dj=-​
​ мере выполнения кода​
​Alex77755​Sanja​
​ Destination:=Range(«B2200», Type:=xlFillDefault Range(«B2200».Select​’cc.EntireColumn.Hidden = cc.Text​ на кнопку PDF.​ Ребята, окажите, пожалуйста,​ = «Выберите папку»,​ Month + «_TEMP.xlsx»​
​SLAVICK​ достаточно много вариантов​: Вызов своих процедур​End Sub​
​ » & p​
​Next k​
​’ Progress Bar​ ​: Здравствуйте! помогите с​

​ квадратики. ​​: Нет в стандартном​: А Вы все​

​ Range(«B201201».Select Selection.AutoFill Destination:=Range(«B201400»,​​ = «»​ Особо в макросах​ помощь! Во вложенном​ Optional ByVal initialPath​n = n​, спасибо.​ и с ЮзерФорм​ вставляйте между DoEvents​Sub test5()​

​ & «% «​​DoEvents​’​ прогресс баром (можно​vlth​

​ — кто мешает​​ по инструкции сделали?​ Type:=xlFillDefault Range(«B201400».Select Range(«E2».Select​’Next​ не волоку. Спасибо​
​ файле имеется кнопочка​

​ As String =​​ + 1 /​Viper25​ тоже​

​ и Next​​For i =​ & String(p ​Next​Dim intIndex As​

​ и статус бар).​​: Щёлкни правой клавишей​

​ нажать кнопочку?​​ Если прогрессбар именно​
​ ActiveCell.FormulaR1C1 = «1»​Next​ всем отозвавшимся!​
​ «С К Р​
​ «P:ФинДирОтделКонсолидацииБюджет») As String​ 2: p =​
​:​SLAVICK​
​Udik​ 1 To 10000​ 10 + 1,​
​End Sub​
​ Integer​У меня есть​
​ по панели ‘элементы​Для остановки процесса​ , то:​ Selection.AutoFill Destination:=Range(«E2:E400», Type:=xlFillDefault​Application.Calculation = xlCalculationAutomatic​Starbirst​ Ы Т Ь​Dim PS As​ 2 * n​SLAVICK​
​: для конкретного файла​
​: У меня лично​
​p = i​ ChrW(10000 + p​
​Viper25​
​Dim sngPercent As​
​ большой макрос, записанный​ управления’:​ в тело поставить​в Вашем файле​

​ Range(«E2:E400».Select Range(«C1».Select ‘Dim​​Application.ScreenUpdating = True​: Прилагаю отредактированный файл.​ П У С​
​ String: PS =​Application.StatusBar = «Выполнено:​, по Вашему примеру​ — нужно добавить​
​ не получается ничего​ 100: S​ 2))​:​ Single​

​ макрорекордером, выполняющий последовательные​​->Additional Controls. ->Microsoft ProgressBar​​ DoEvents и проверку​​ их нет​​ rng As Range​​End Sub​Формуляр​
​ Т Ы Е​ Application.PathSeparator​ » & n​
​ создал макрос, который​
​ 4е раза строки:​
​ показать в статусбаре​
​ = String(p ​DoEvents​
​Udik​
​Dim intMax As​
​ действия больше минуты.​
​ Control​​ глобальной переменной.​Лина​ With ThisWorkbook.Worksheets(«раскрой двп».Range(«C:C»​Формуляр​

​: Честно говоря, код​​ Я Ч Е​

​ и в ActiveX​​отвечать​ .FindNext() Loop While​Моих познаний Excel,​Application.Calculation = xlCalculationManual​
​ столбец B в​ .InitialFileName = initialPath​:=False, Transpose:=False​
​ еще один блок​
​ «% » &​
​ больше всего нравится​Next​

​ 100: S​​ процедуры.​DoEvents​
​ я находил не​

Progressbar к существующему макросу (Макросы/Sub)

​(‘фоновую’) сделать постоянной​​ есть ProgressBar 6.0(SP4)​?​ Not Rng Is​ не говоря уже​. ​ диапазоне , если​If .Show <>​Workbooks(Month + «_TEMP.xlsx»).Close​ «‘Вставляем таблицу 2″,​ String(p, ChrW(8700)): DoEvents​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub StatusBar3()​Application.StatusBar = False​ = «»: For​Alex_ST​’————————​ подходят)​ ширины, а шириной​ и ProgressBar 5.0(SP2)​Ama​ Nothing End If​ про макросы, недостаточно,​Application.ScreenUpdating = True​ в списке нет​ -1 Then Exit​’Вставляем таблицу 2​ макрос ругается.​SLAVICK​Dim lr As​End Sub​ j = 10102​: Вообще-то очень удобно​’ Your code​nilem​ другой​ какой выбрать. Просто​: Доброе время суток. ​ End With For​ потому понять, что​Application.Calculation = xlCalculationAutomatic​ данных (элемент управления​ Function​Dim filenameTEMP As​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub SBOR()​: так​ Long​Обсуждалось на Планете​ To 10102 +​ прогресс в статус-баре​

​необходимо управлять программно.​​ я ее буду​ Есть файл экселевский,​ Each cell In​
​ такое цикл, как​работать будет, наверняка,​ «список» для выбора​
​GetFolderPath = .SelectedItems(1)​
​ String​
​Application.ScreenUpdating = False​
​ScreenUpdating​
​Dim lAllCnt As​
​Udik​ p 10:​
​ показывать.​’————————​
​-=Dj=-​ Цвет фона надписей,​ тестить на работе​
​ с VBA. В​ Sheets(«раскрой двп».Range(«A2200» cell.Formula​ его задать, мне​ быстрее.​
​ формы в текущем​
​If Not Right(GetFolderPath,​
​filenameTEMP = myPath​Application.CutCopyMode = False​
​, и​
​ Long ‘кол-во итераций​
​: Так обычно обновления​
​ S = S​Вот у меня​
​Sleep 100​, привет​ само-собой, должен быть​
​ а там XP​ котором создаются листы​
​ = cell.Value Next​ достаточно сложно понять.​
​Может и прогрес-бар​
​ файле) . В​
​ 1) = PS​
​ + «» +​
​Application.DisplayAlerts = False​

Читайте также  Создание интерактивных тестов в MS Excel, Образовательная социальная сеть

​DisplayStatusBar​​Const lMaxQuad As​ экрана отрубают​ & ChrW(j): Next​
​ в заначке лежит​

​Next​​может лучше статус-бар?​ ​ разным.​ а у меня​ с данными с​ cell pi.Hide ‘​ Я брал разные​ не понадобится. ​ представленной таблице работа​ Then GetFolderPath =​ Month + «_TEMP.xlsx»​’задаем путь к​- это разные​ Long = 20​SLAVICK​Application.StatusBar = «Выполнено:​

VBA Прогресс бар

​ несколько примеров:​​End Sub​Просто вставьте в​Получаем ‘непрерывный’ (без​
​ Win7.​ помощью макроса. Хочу​ закрываем индикатор’ End​ макросы, пытался что-то​PS: Объявлять переменную​ макроса не занимает​ GetFolderPath & PS​n = n​ данным​ вещи.​ ‘сколько квадратов выводить​: Обновление экрана со​ » & p​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub test1()​Но не получается.​ нужных местах в​ квадратиков-сегментов) Progress Bar.​А DoEvents куда​ при выполнении вывести​ Sub​ изобрести — так​ в цикле тоже​ много времени, однако​End With​ + 1 /​Dim myPath As​Конечно если вы​lAllCnt = 10000​ статус баром не​ & «% «​For i =​Помогите, плиз.​ коде​Удачи!​ вставлять? В исполняемый​

​ окно с ProgressBar-ом​​The_Prist​ и получился макрос,​ как-то не принято.​ в настоящей таблице,​End Function​ 2: p =​ String​

​ его спрятали, то​​For lr =​ связано — действительно​
​ & S: DoEvents​
​ 1 To 10000​Спасибо.​Application.StatusBar = «Происходит этап​S_Isa​ макрос?​

​ чтобы показывало степень​​: Лина, читать код​

​ который я применял​​А внутренний цикл​ там, где помимо​SLAVICK​ 2 * n​
​myPath = GetFolderPath​ и не увидите.:​

​ 1 To lAllCnt​​ самый удобный способ​Next​

​p = i​​Udik​ №1″‘ следующий -​: А может вполне​​analyst​​ выполнения макроса, а​

ProgressBar в VBA

​ совершенно неудобно. Сами​​ по сей день.​ по одному столбц​ столбцов A, B,​: так Вы же​Application.StatusBar = «Выполнено:​’Задаем часть имени​Вот см так:​Application.StatusBar = «Выполнено:​ — статусбар. и​Application.StatusBar = False​ 100​: ну вот пример​ этап № 2.​ достаточно StatusBar?​: Можно здесь глянуть:​ так же хочу​ гляньте. Исправьте, пожалуйста,​
​ Спасибо большое!​ B никакого эффекта​ и С имеются​ смотрите на что​ » & n​ файла — номер​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Public Sub d()​
​ » & Int(100​ не нужно никаких​

​End Sub​​Application.StatusBar = «Выполнено:​ простенький​ 3 и т.д.​
​И ну его​Уведомление в процессе​ добавить кнопку остановки​ применив теги кода.​
​Лина​ не даёт.​

​ формулы в других​​ он ругается, и​ * 100 &​ месяца​Application.ScreenUpdating = 0​ * lr /​ юзерформ. Код работает​Sub test4()​ » & p​200?’200px’:»+(this.scrollHeight+5)+’px’);»>​а в конце​ к лешему лишние​ выполнения макроса​
​ выполнения. Трабл в​ Это кнопочка чуть​: Доброго времени суток.​

​И что остаётся?​​ столбцах, требует значительного​
​ что пишет.​ «% » &​

​Dim Month As​​Application.StatusBar = «111111:​ lAllCnt) & «%»​ сразу одинаково у​For i =​
​ & «% «​Public Sub test()​КодApplication.StatusBar = «»​

Создание графического прогрессбара в Excel

​ формы!​​Ama​ том что в​ выше поля, где​ Уважаемые знатоки нужна​
​Код200?’200px’:»+(this.scrollHeight+5)+’px’);»>Public Sub Скрыть()​ времени. Каким образом​У Вас дважды​

​ String(p, ChrW(8700)): DoEvents​​ String​ » ‘:DoEvents​ & String(CLng(lMaxQuad *​
​ всех.​ 1 To 10000​
​ & String(p ​Dim i As​-=Dj=-​А отражение ‘прогресса’​
​: С этим разобрался.​ стандартном наборе элементов​ набираете сообщение.​
​ ваша помощь.​Dim i As​ можно отобразить процесс​
​ в дном макросе​Workbooks.Open Filename:=filenameTEMP, UpdateLinks:=False​Month = Application.InputBox(«Введите​Application.ScreenUpdating = 1​
​ lr / lAllCnt),​Viper25​
​p = i​

​ 10 + 1,​​ Integer, j As​:​
​ вполне можно сформировать​ благодарю. В макросе​ в VBA ProgressBara​
​Alexander88​Не получается прилепить​ Integer​ работы макроса? Как​ повторяется строка:​Workbooks(Month + «_TEMP.xlsx»).Worksheets(«2»).Range(«A2:C10»).Copy​

​ номер месяца», Type:=2)​​Application.StatusBar = False​ ChrW(9632)) & String(lMaxQuad​: Подскажите, как прогресс-бар​ 100: S​

Прогресс бар выполнения макроса без цикла (Макросы/Sub)

​nilem​​ в текстовой переменной​ обрабатывал глобальную переменную​ нету.​
​: Приложите файл-пример, помогут​ к прогресс бару​Dim cc​ добавить к макросу​
​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Dim filenameTEMP As String​Gorod.Worksheets(«ALL»).Range(«A12:C20»).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,​’Задаем имя отчета​
​End Sub​ — CLng(lMaxQuad *​ внедрить в мой​ = String(p ​DoEvents​j = UserForm1.Width​

​, такой вариант подойдет,​​ которую в нужные​​ .​​Можно окно создать​
​ быстрее​
​ макрос, выдает ошибку.​Application.ScreenUpdating = False​ простейший Progressbar? В​
​а это недопустимо.​ SkipBlanks _​Dim Gorod As​Цитата​
​ lr / lAllCnt),​
​ файл (в примере​

​ 10, ChrW(10152)) &​​Next​​ / 100​​ спасибо)​ моменты в алгоритме​

Источник:
http://my-excel.ru/vba/excel-vba-progress-bar.html

Прогресс бар в статус баре

1. Введение

Редкая серьезная программа обходится без прогресс-бара — чрезвычайно полезного элемента управления. Его назначение — показать пользователю, что приложение работает, а не зависло.

В VB есть стандарный компонент ProgressBar. Применять его достаточно просто:

  • подключить к проекту компонент «Microsoft Windows Common Controls» (существует несколько версий);
  • дизайнером разместить прогресс-бар;
  • установить свойства «Min» и «Max»;
  • в коде приложениия (в нужном месте) устанавливать свойство «Value» (оно должно находиться в интервале [Min,Max]. При этом в линейке прогесс-бара будет отрисовано нужное к-во «квадратиков».

Так в чем же проблема? А вот в чем: к сожалению, этот прогресс-бар невозможно поместить в контейнер (самым распространенным из которых является статус-бар — обычно это область, располагающаяся внизу окна). Есть, правда, один способ для решения этой проблемы:

  • размещаем прогресс-бар на форме, установив его свойство «Align» в нуль (константа vbAlignNone). При этом прогресс-бар может иметь любые координаты;
  • делаем прогресс-бар невидимым (Visible=False);
  • размещаем на форме статус-бар с несколькими панелями. Решаем, в какой панели будем отображать прогресс-бар.
  • когда прогресс-бар понадобится, вычисляем координаты нужной панели и устанавливаем у нашего прогесс-бара (пока невидимого) свойства «Left», «Top», «Width» и «Height» так, чтобы прогресс-бар «вписался» в нужную панель;
  • делаем прогресс-бар видимым;
  • пользуемся прогресс-баром как обычно;
  • когда прогресс-бар больше не нужен — снова делаем его невидимым.

Способ, как видите, достаточно прост. К недосткам его можно отнести низкую эстетичность — панель для отображения прогресс-бара должна быть достаточно длинной, иначе «квадратики» будут выглядет не очень приглядно. Кроме того, цвет «квадратиков» нельзя менять (по крайней мере, я не знаю, как).

Как-то мне в руки попал известный пример «Прогресс-бар в системном трее». Я подумал: а неплохо было бы организовать прогресс-бар в статус баре в подобном же графическом стиле. Предлагаемая статья как раз об этом.

2. Основная идея

Мы сделаем прогресс-бар в выбираемой панели статус-бара, используя графические функции Windows. Эту же идею мы применим при конструировании прогресс-бара для использования в Excel.

Суть можно сформулировать очень просто: мы будем рисовать в нужной панельки статус-бара прямоугольник, ширина которого характеризует ход выполнения процесса. Одновременно в центре панельки будем показывать процент выполнения. Это будет выглядеть примерно так:

На мой взгляд, вид такого прогесс-бара симпатичнее стандартного (при условии, что цвета основных частей прогресс-бара может выбирать разработчик).

3. Приступаем к реализации

А, собственно, какие проблемы? Для рисования прямоугольника есть оператор Line, а для вывода текста — Print. Увы! Эти операторы применимы к форме или к PictureBox. У статус-бара таких методов нет. Что же делать? Можно, конечно, как было описано выше, разместить невидимый PictureBox на форме, а в нужный момент наложить его на выбранную панельку. Желающие могут это проделать, а мы пойдем другим путем: воспользуемся графическим интерфейсом Windows (GDI).

Следующее далее описание ни в коей мере не претендует на полноту; для желающих есть специальные (и очень объемные!) руководства. Автор пользовался «Библией API» Д.Эпплмана.

Базовым понятием графического интерфейса GDI является понятие контекста графического устройства. Контекст устройства можно сравнить с холстом художника — это то, на чем рисуют (наши коллеги-Дельфисты так его и называют «canvas» т.е. канва, холст). Все графические функции Windows требуют ссылки на какой-либо контекст. Как догадываются читатели, контекст — довольно сложная структура. Но нам не требуется проникновения в детали — достаточно получить ссылку на контекст. Visual Basic не позволят сделать это «в одно действие», нам придется сделать это самим.

Контекст можно получить для любого окна, при условии, что известен его хэндл (hwnd). Не у всех визуальных компонентов VB можно получить хэндл окна. К счастью, у статус-бара свойство hwnd обеспечено. Теперь, чтобы получить контекст устройства, достаточно вызвать функцию GetDC. Вот ее описание:

Здесь StatusBar — это статус-бар, расположенный на форме проекта; hwnd — хэндл его окна.

Идеология использования контекстов такова:

  • получаем контекст;
  • сохраняем его;
  • рисуем в контексте все необходимое;
  • восстаналиваем исходный контекст.

Для сохранения контекста служит вызов SaveDC:

Значение переменной iDc (результат, возвращаемый функцией) не следует изменять — он понадобится при восстановлении контекста.

Функцию SaveDc нужно, разумеется, предварительно объявить:

Для восстановления контекста служит функция RestoreDc. Обращение к ней выглядит так:

А вот объявление этой функции:

Итак, «тасовать холсты» мы научились. Займемся рисованием.

Художник рисует кистью. Пользователь Windows GDI — тоже. Кисть — это еще одно базовое понятие GDI. Кисть необходимо создать. Мы будем использовать простейшую кисть — она оставляет сплошной след. Вот как создается такая кисть:

Здесь Color& — цвет кисти (может быть сформирован функцией RGR(RR&,GG&,BB&) или QBcolor(n%). Естественно, функцию CreateSolidBrush нужно предварительно описать:

Чтобы нарисовать прямоугольник служит функция Rectangle. Вот ее описание:

Как и говорилось выше, первый параметр — это ссылка на контекст устройства («холст»). Четыре остальных параметра интуитивно понятны — это координаты левого верхнего и правого нижнего угла прямоугольника. Но где же ссылка на кисть? Ее нет. потому что ее нужно выбрать заранее. Это делает функция SelectObject:

Первый параметр — снова ссылка на контекст устройства, а второй — ссылка на кисть (то, что возвращает CreateSolidBrush). Когда кисть создана и выбрана, можно вызвать функцию Rectangle и рисовать прямоугольники.

Поскольку нам предстоит не только рисовать прямоугольники, но и выводить текст (процент выполнения), придется познакомиться с тем, как это делает Windows. Для вывода текста предназначена функция DrawText:

первый параметр — ссылка на контекст, второй параметр — это строка, которую мы хотим вывести, третий — длина строки (имейте в виду, что длина строки должна быть длинным целым). Четвертый параметр задает прямоугольник, в котором будет размещаться текст. Это переменная пользовательского типа RECT:

(Left, Top) — левая верхняя вершина, (Right, Bottom) — правая нижняя.

Параметр wFormat задает положение текста в прямоугольнике. Мы будем использовать вывод по центру:

А чем же задается цвет текста? Цветом кисти? Нет, кисти к тексту никакого отношения не имеют. Для задания цвет текста служит специальная функция SetTextColor:

Про первый параметр я уже не говорю, а второй — это цвет выводимого текста. Текст выводится поверх старого содержимого «холста». Можно задать режим «взаимодействия» текста со старым содержимым. Нас вполне устроит режим вывода текста «как есть» без изменения. Чтобы обеспечить такой режим вывода, нужно вызвать функцию SetBkMode:

декларируется эта функция так:

Результат этой функции (a&) не используется. Второй параметр (единица) как раз и задает нужный режим вывода.

Если не вызвывать функцию SetBkMode, то текст будет выводиться так:

что, согласитесь, не очень симпатично.

Перед тем, как перейти к программе, я хотел бы сделать важное замечание. Оно касается единиц измерения.

Все графические функции Windows в качестве единицы измерения понимают только пикселы. А VB позволяет разработчикам использовать самые разные единицы измерения: твипы, пункты, сантиметры, миллиметры, дюймы. Перед обращением к графической функции все координатные параметры должны быть переведены в пикселы. Как это сделать? Не очень трудно.

Начнем с твипов. По определению, твип это (1/1440) дюйма (т.н. «логического дюйма»; подробности — у Д.Эпплмана). Объект Screen в VB имеет два полезных метода:

Первая возвращает количество твипов на пиксел по горизонтали для Вашей видео-системы, вторая — соответственно количество твипов на пиксел по вертикали.

Если мы хотим из твипов получить пикселы, достаточно воспользоваться одной из формул:

  • picX=TwipX/px — для горизонтали;
  • picY=TwipY/py — для вертикали.

Здесь TwipX, TwipY — горизонтальный и вертикальный размеры в твипах, а picX, picY — те же размеры в пикселах.

Теперь нам нетрудно «разделаться» и с другими единицами измерения:

Пункт — это (1/72) дюйма, т.е. пункт равен двадцати твипам. Поэтому для работы с пунктами формулы будут иметь вид:

Дюйм содержит 1440 твипов, поэтому для работы с дюймами формулы будут такие:

С дюймами и пунктами все ясно. Для сантиметров и миллиметров дело обстоит ненамного сложнее. Как известно, 1 дюйм=2.54 см. Поэтому для пересчета сантиметров в пикселы формулы будут такие:

Столь же легко решается проблема пересчета миллиметров в пикселы:

Visual Basic обеспечивает еще одну систему измерения координат — «Знаки». Это чуть более хитрая система. Для нее формулы перевода таковы:

При рисовании наших прямоугольников API-шными вызовами мы должны будем преобразовать все размеры в пикселы. Формулы перевода мы теперь знаем. Но как узнать, какую метрику использует разработчик (который будет пользоваться нашим прогресс-баром)? Заставлять его использовать только пикселы? Слишком жесткое ограничение. Сейчас мы его обойдем. Наш статус-бар, где будет располагаться прогресс-бар, находится на какой-то форме, верно? При этом он наследует ее метрику. А метрику формы задает ее свойство ScaleMode. Таким образом, величина

как раз то, что нам нужно:

Величина scMode- Метрика

Напомню, что Parent — это указатель на родительский объект. Для статус-бара это форма, на которой он расположен.

Вот, в принципе, и все, что нужно, чтобы реализовать заявленные идеи.

Теперь самое время обсудить интерфейс нашего прогресс-бара. На мой взгляд, лучше всего реализовать наш прогресс-бар в виде класса. Тогда статус-бар и номер панельки, в котором мы рисуем прогресс-бар, цвета всех основных элементов и, разумеется, Min,Max и Value будут свойствами. А отображение очередного состояния можно оформить как метод.

Использование класса оправдано еще и потому, что класс можно потом включить в ActiveX-Dll и распространять в виде библиотеки.

4. Промежуточные итоги

Ниже приводится полный текст класса. Для подключения его к Вашему проекту, создайте в нем пустой модуль класса, переименуйте в clsPBar, и вставьте в него приведенный ниже код.

В этом классе собраны воедино все идеи, высказанные выше.

Если Вы внимательно анализировали код класса, то наверняка обратили на две внутренние (закрытые) переменные dxCurr и dxLast. Назначение их следующее. Предположим, что наш глобальный цикл, выполнение которого мы хотим визуализировать, выполняется несколько сот тысяч раз, а каждый «виток» выполняется очень быстро. Если вставить обращение к методу ShowProgress в такой цикл, то перерисовка прогресс-бара тоже будет выполняться на каждом витке. При этом возможно, что новое положение закрашенного прямоугольника не будет отличаться от предыдущего. Зачем же его (да, кстати, и текст в центре) перерисовывать? Кроме «отъедания» ресурсов и мигания такая перерисовка ничего не дает. Вот для предотвращения этой ненужной перерисовки и служат переменные dxCurr и dxLast. Если при очередном обращении к ShowProgress dxCurr=dxLast, то рисование обходится.

Читайте также  Трехмерные диаграммы (поверхности и изолинии) в EXCEL

Как пользоваться этим классом? Очень просто.

Разместите на форме статус-бар с двумя или более панельками. Решите, в какой панельке будет прогресс-бар. Когда прогресс-бар понадобится, пишем:

В качестве приложения к этой статье Вы можете скачать пример простого приложения, в котором используется описанный прогресс-бар.

5. Беда! Утечка памяти!

Пару лет назад, когда я создал этот «шедевр», со мной произошла неприятность. Отладив (как мне казалось) класс, я включил его в реальный проект и передал на тестирование. Тестирование ошибок не обнаружило, и программа была передана эксплуатационникам. Сначала все было хорошо. Но через несколько дней мне пожаловались, что при длительной работе моя программа завешивает компьютер. Помогает только перезагрузка. Поскольку проект без прогресс-бара исправно работал и не вызывал проблем, подозрение пало на прогресс-бар. Я быстренько воспроизвел ситуацию, о которой толковали эксплуатационники, и убедился, что при отключении прогресс-бара программа работает четко, а с прогресс-баром через некоторое время виснет. В чем же дело? Оказалось — в том, что я невнимательно читал Д.Эпплмана: созданные кисти нужно уничтожать при уничтожении объекта. Никто за нас это делать не будет!

Если приведенный выше код поместить в объемлющий цикл и выполнить пару тысяч раз — зависание почти неминуемо. Если запустить индикатор системных ресурсов, то отчетливо видно, как они стремительно «утекают». Ситуация эта, кстати, по-английски называется «memory leak» — «утечка памяти».

Чтобы уничтожить кисть нужно воспользоваться API-вызовом DeleteObject:

А вот как эта функция декларируется:

Код терминирования класса должен быть на самом деле таким:

Каюсь перед читателем! Я нарочно включил в тест класса не вполне корректный код терминирования чтобы продемонстрировать собственную (поучительную!) ошибку и сделать соответствующие выводы.

А пример-приложение содержит правильный класс. Он утечки памяти не вызывает.

6. А как быть с Excel?

Во введении я обещал сделать прогресс-бар и для использовании в VBA (применительно к Excel). В чем-то ситуация здесь проще, а в чем-то сложнее.

Для получения ссылки на контекст нужно получить хэндл окна, где мы хотим рисовать. При работе в VB это хэндл окна статус-бара, расположенного на форме. В Excel добраться до хэндла окна статус-бара затруднительно (хотя, вероятно, возможно). Я решил поступить так: размещать линейку прогресс-бара в центре главного окна. Хэндл главного окна Excel можно найти с помощью API-вызова FindWindow:

Этот вызов ищет окно по заголовку. У Excel заголовок — «XLMAIN». Естественно, что функция FindWindow должна быть продекларирована:

Функция Prepare теперь принимает вид:

А в остальном класс такой-же, как и для VB, за исключением того, что все размеры только в пикселах, и не нужен пересчет. Перед выводом прогресс-бара рекомендую установить Application.ScreenUpdating=False, а после завершения — вернуть Application.ScreenUpdating=True.

Открывая книгу PBtest.xls, Вы, естественно, должны включить макросы (иначе пример работать не будет!) Для запуска щелкните в главном меню по пункту «Прогресс-бар». Остальное, надеюсь, ясно.

Вы можете скачать готовые примеры на VB и VBA.

Источник:
http://www.codenet.ru/progr/vbasic/Progress-Status-Bar/

Excel vba прогресс бар

Создание прогресс-бара выполнения макроса (Макросы/Sub)

​Смотрите также​​ ‘показывать’ в Application.StatusBar​
​ прорисовывать элементы с​ в и Delphi,​Прогресс бар ?​
​ Dim pi As​
​Application.Calculation = xlCalculationManual​
​ инете представлено достаточно​
​Удалите одну -​
​:=False, Transpose:=False​
​ Excel.Workbook​Alex_ST, 23.12.2016 в​
​ ChrW(9633))​ в первом посте)?​
​ String(11 — p​Application.StatusBar = False​
​UserForm1.Show​
​Viper25​alex_gearbox​
​ использованием манифеста винды.​ это не проблема,​
​Может я чего-то​
​ New ProgressIndicator ‘​
​For i =​
​ много вариаций создания​ и все заработает​
​Workbooks(Month + «_TEMP.xlsx»).Close​
​Set Gorod =​
​ 14:08, в сообщении​
​DoEvents​
​Alex_ST​
​ 10, ChrW(8700))​
​End Sub​

​UserForm1.Label1.Width = 1​​: Здравствуйте.​: А я сделал​
​blanks​
​ тока как мне​
​ не понимаю.. Но​ создаём новый прогресс-бар​ 10 To 109​
​ Progressbar, но как​Viper25​
​Application.ScreenUpdating = True​
​ ThisWorkbook​
​ № 9 ()​Next​
​: Это точно. Я​Application.StatusBar = «Выполнено:​
​Sub test2()​For i =​
​Нужно создать прогресс-бар​
​ ProgressBar в StatusBar-е​
​: Как в ескселе​
​ это окно «вклеить»​

​ какой смысл в​​ pi.Show «Подождите, работает​​If Cells(i, 1).Value​​ его прописать? В​: Увы. Что я​Application.CutCopyMode = True​

​’Вставляем таблицу 1​​ 200?’200px’:»+(this.scrollHeight+5)+’px’);»>Спасибо, Слава.​’очищаем статус-бар от​ отходил от компа​ » & p​

​For i =​​ 1 To 100​ для наглядности работы​ Excel-я. На API-шных​
​ сделать пргресс бар​ в файл Экселевский,​ прогресс баре, если​ ​ макрос» ‘ отбражаем​
​ = «» Then​ идеале хотелось, чтобы​
​ не так сделал?​Application.DisplayAlerts = True​
​Dim filenameTEMP As​Udik​ значений после выполнения​ и не успел​ & «% «​ 1 To 10000​
​UserForm1.Label1.Width = Int(i​
​ макроса.​
​ вызовах. Могу прислать.​
​ по типу как​
​ если это возможно.​
​ отключено обновление экрана?​ индикатор ‘ код​
​ Rows(i).RowHeight = 0​ Progressbar выглядел аналогично​
​Спасибо.​End Sub​ String​: ага, увидел​Application.StatusBar = False​ сам ответить.​ & S: DoEvents​
​p = i​
​ * j)​
​Нашел такой пример.​
​Если кому интересно:​
​ копирование файла,​
​И можно ли​Лина​
​ макроса Application.ScreenUpdating =​’For Each cc​ с тем, который​Starbirst​Function GetFolderPath(Optional ByVal​filenameTEMP = myPath​Viper25​End Sub​
​Спасибо, Слава.​Next​ 100​For k =​
​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub Progress()​
​http://j-walk.com/ss/excel/tips/tip34.htm​
​т.е. движущиеся по​
​ остановить выполнение макроса.​
​: Вот файл​ False Range(«B22».Select Selection.AutoFill​
​ In [B10:B109].Columns​ появляется при нажатии​: Доброго времени суток!​ title As String​ + «» +​:​
​взял тут, там​Alex_ST​Application.StatusBar = False​Application.StatusBar = «Выполнено:​
​ 1 To 100000​
​’​
​-=Dj=-​
​ мере выполнения кода​
​Alex77755​Sanja​
​ Destination:=Range(«B2200», Type:=xlFillDefault Range(«B2200».Select​’cc.EntireColumn.Hidden = cc.Text​ на кнопку PDF.​ Ребята, окажите, пожалуйста,​ = «Выберите папку»,​ Month + «_TEMP.xlsx»​
​SLAVICK​ достаточно много вариантов​: Вызов своих процедур​End Sub​
​ » & p​
​Next k​
​’ Progress Bar​ ​: Здравствуйте! помогите с​

​ квадратики. ​​: Нет в стандартном​: А Вы все​

​ Range(«B201201».Select Selection.AutoFill Destination:=Range(«B201400»,​​ = «»​ Особо в макросах​ помощь! Во вложенном​ Optional ByVal initialPath​n = n​, спасибо.​ и с ЮзерФорм​ вставляйте между DoEvents​Sub test5()​

​ & «% «​​DoEvents​’​ прогресс баром (можно​vlth​

​ — кто мешает​​ по инструкции сделали?​ Type:=xlFillDefault Range(«B201400».Select Range(«E2».Select​’Next​ не волоку. Спасибо​
​ файле имеется кнопочка​

​ As String =​​ + 1 /​Viper25​ тоже​

​ и Next​​For i =​ & String(p ​Next​Dim intIndex As​

​ и статус бар).​​: Щёлкни правой клавишей​

​ нажать кнопочку?​​ Если прогрессбар именно​
​ ActiveCell.FormulaR1C1 = «1»​Next​ всем отозвавшимся!​
​ «С К Р​
​ «P:ФинДирОтделКонсолидацииБюджет») As String​ 2: p =​
​:​SLAVICK​
​Udik​ 1 To 10000​ 10 + 1,​
​End Sub​
​ Integer​У меня есть​
​ по панели ‘элементы​Для остановки процесса​ , то:​ Selection.AutoFill Destination:=Range(«E2:E400», Type:=xlFillDefault​Application.Calculation = xlCalculationAutomatic​Starbirst​ Ы Т Ь​Dim PS As​ 2 * n​SLAVICK​
​: для конкретного файла​
​: У меня лично​
​p = i​ ChrW(10000 + p​
​Viper25​
​Dim sngPercent As​
​ большой макрос, записанный​ управления’:​ в тело поставить​в Вашем файле​

​ Range(«E2:E400».Select Range(«C1».Select ‘Dim​​Application.ScreenUpdating = True​: Прилагаю отредактированный файл.​ П У С​
​ String: PS =​Application.StatusBar = «Выполнено:​, по Вашему примеру​ — нужно добавить​
​ не получается ничего​ 100: S​ 2))​:​ Single​

​ макрорекордером, выполняющий последовательные​​->Additional Controls. ->Microsoft ProgressBar​​ DoEvents и проверку​​ их нет​​ rng As Range​​End Sub​Формуляр​
​ Т Ы Е​ Application.PathSeparator​ » & n​
​ создал макрос, который​
​ 4е раза строки:​
​ показать в статусбаре​
​ = String(p ​DoEvents​
​Udik​
​Dim intMax As​
​ действия больше минуты.​
​ Control​​ глобальной переменной.​Лина​ With ThisWorkbook.Worksheets(«раскрой двп».Range(«C:C»​Формуляр​

​: Честно говоря, код​​ Я Ч Е​

​ и в ActiveX​​отвечать​ .FindNext() Loop While​Моих познаний Excel,​Application.Calculation = xlCalculationManual​
​ столбец B в​ .InitialFileName = initialPath​:=False, Transpose:=False​
​ еще один блок​
​ «% » &​
​ больше всего нравится​Next​

​ 100: S​​ процедуры.​DoEvents​
​ я находил не​

Progressbar к существующему макросу (Макросы/Sub)

​(‘фоновую’) сделать постоянной​​ есть ProgressBar 6.0(SP4)​?​ Not Rng Is​ не говоря уже​. ​ диапазоне , если​If .Show <>​Workbooks(Month + «_TEMP.xlsx»).Close​ «‘Вставляем таблицу 2″,​ String(p, ChrW(8700)): DoEvents​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub StatusBar3()​Application.StatusBar = False​ = «»: For​Alex_ST​’————————​ подходят)​ ширины, а шириной​ и ProgressBar 5.0(SP2)​Ama​ Nothing End If​ про макросы, недостаточно,​Application.ScreenUpdating = True​ в списке нет​ -1 Then Exit​’Вставляем таблицу 2​ макрос ругается.​SLAVICK​Dim lr As​End Sub​ j = 10102​: Вообще-то очень удобно​’ Your code​nilem​ другой​ какой выбрать. Просто​: Доброе время суток. ​ End With For​ потому понять, что​Application.Calculation = xlCalculationAutomatic​ данных (элемент управления​ Function​Dim filenameTEMP As​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub SBOR()​: так​ Long​Обсуждалось на Планете​ To 10102 +​ прогресс в статус-баре​

​необходимо управлять программно.​​ я ее буду​ Есть файл экселевский,​ Each cell In​
​ такое цикл, как​работать будет, наверняка,​ «список» для выбора​
​GetFolderPath = .SelectedItems(1)​
​ String​
​Application.ScreenUpdating = False​
​ScreenUpdating​
​Dim lAllCnt As​
​Udik​ p 10:​
​ показывать.​’————————​
​-=Dj=-​ Цвет фона надписей,​ тестить на работе​
​ с VBA. В​ Sheets(«раскрой двп».Range(«A2200» cell.Formula​ его задать, мне​ быстрее.​
​ формы в текущем​
​If Not Right(GetFolderPath,​
​filenameTEMP = myPath​Application.CutCopyMode = False​
​, и​
​ Long ‘кол-во итераций​
​: Так обычно обновления​
​ S = S​Вот у меня​
​Sleep 100​, привет​ само-собой, должен быть​
​ а там XP​ котором создаются листы​
​ = cell.Value Next​ достаточно сложно понять.​
​Может и прогрес-бар​
​ файле) . В​
​ 1) = PS​
​ + «» +​
​Application.DisplayAlerts = False​

​DisplayStatusBar​​Const lMaxQuad As​ экрана отрубают​ & ChrW(j): Next​
​ в заначке лежит​

​Next​​может лучше статус-бар?​ ​ разным.​ а у меня​ с данными с​ cell pi.Hide ‘​ Я брал разные​ не понадобится. ​ представленной таблице работа​ Then GetFolderPath =​ Month + «_TEMP.xlsx»​’задаем путь к​- это разные​ Long = 20​SLAVICK​Application.StatusBar = «Выполнено:​

VBA Прогресс бар

​ несколько примеров:​​End Sub​Просто вставьте в​Получаем ‘непрерывный’ (без​
​ Win7.​ помощью макроса. Хочу​ закрываем индикатор’ End​ макросы, пытался что-то​PS: Объявлять переменную​ макроса не занимает​ GetFolderPath & PS​n = n​ данным​ вещи.​ ‘сколько квадратов выводить​: Обновление экрана со​ » & p​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub test1()​Но не получается.​ нужных местах в​ квадратиков-сегментов) Progress Bar.​А DoEvents куда​ при выполнении вывести​ Sub​ изобрести — так​ в цикле тоже​ много времени, однако​End With​ + 1 /​Dim myPath As​Конечно если вы​lAllCnt = 10000​ статус баром не​ & «% «​For i =​Помогите, плиз.​ коде​Удачи!​ вставлять? В исполняемый​

​ окно с ProgressBar-ом​​The_Prist​ и получился макрос,​ как-то не принято.​ в настоящей таблице,​End Function​ 2: p =​ String​

​ его спрятали, то​​For lr =​ связано — действительно​
​ & S: DoEvents​
​ 1 To 10000​Спасибо.​Application.StatusBar = «Происходит этап​S_Isa​ макрос?​

​ чтобы показывало степень​​: Лина, читать код​

​ который я применял​​А внутренний цикл​ там, где помимо​SLAVICK​ 2 * n​
​myPath = GetFolderPath​ и не увидите.:​

​ 1 To lAllCnt​​ самый удобный способ​Next​

​p = i​​Udik​ №1″‘ следующий -​: А может вполне​​analyst​​ выполнения макроса, а​

ProgressBar в VBA

​ совершенно неудобно. Сами​​ по сей день.​ по одному столбц​ столбцов A, B,​: так Вы же​Application.StatusBar = «Выполнено:​’Задаем часть имени​Вот см так:​Application.StatusBar = «Выполнено:​ — статусбар. и​Application.StatusBar = False​ 100​: ну вот пример​ этап № 2.​ достаточно StatusBar?​: Можно здесь глянуть:​ так же хочу​ гляньте. Исправьте, пожалуйста,​
​ Спасибо большое!​ B никакого эффекта​ и С имеются​ смотрите на что​ » & n​ файла — номер​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Public Sub d()​
​ » & Int(100​ не нужно никаких​

​End Sub​​Application.StatusBar = «Выполнено:​ простенький​ 3 и т.д.​
​И ну его​Уведомление в процессе​ добавить кнопку остановки​ применив теги кода.​
​Лина​ не даёт.​

​ формулы в других​​ он ругается, и​ * 100 &​ месяца​Application.ScreenUpdating = 0​ * lr /​ юзерформ. Код работает​Sub test4()​ » & p​200?’200px’:»+(this.scrollHeight+5)+’px’);»>​а в конце​ к лешему лишние​ выполнения макроса​
​ выполнения. Трабл в​ Это кнопочка чуть​: Доброго времени суток.​

​И что остаётся?​​ столбцах, требует значительного​
​ что пишет.​ «% » &​

​Dim Month As​​Application.StatusBar = «111111:​ lAllCnt) & «%»​ сразу одинаково у​For i =​
​ & «% «​Public Sub test()​КодApplication.StatusBar = «»​

Создание графического прогрессбара в Excel

​ формы!​​Ama​ том что в​ выше поля, где​ Уважаемые знатоки нужна​
​Код200?’200px’:»+(this.scrollHeight+5)+’px’);»>Public Sub Скрыть()​ времени. Каким образом​У Вас дважды​

​ String(p, ChrW(8700)): DoEvents​​ String​ » ‘:DoEvents​ & String(CLng(lMaxQuad *​
​ всех.​ 1 To 10000​
​ & String(p ​Dim i As​-=Dj=-​А отражение ‘прогресса’​
​: С этим разобрался.​ стандартном наборе элементов​ набираете сообщение.​
​ ваша помощь.​Dim i As​ можно отобразить процесс​
​ в дном макросе​Workbooks.Open Filename:=filenameTEMP, UpdateLinks:=False​Month = Application.InputBox(«Введите​Application.ScreenUpdating = 1​
​ lr / lAllCnt),​Viper25​
​p = i​

​ 10 + 1,​​ Integer, j As​:​
​ вполне можно сформировать​ благодарю. В макросе​ в VBA ProgressBara​
​Alexander88​Не получается прилепить​ Integer​ работы макроса? Как​ повторяется строка:​Workbooks(Month + «_TEMP.xlsx»).Worksheets(«2»).Range(«A2:C10»).Copy​

​ номер месяца», Type:=2)​​Application.StatusBar = False​ ChrW(9632)) & String(lMaxQuad​: Подскажите, как прогресс-бар​ 100: S​

Прогресс бар выполнения макроса без цикла (Макросы/Sub)

​nilem​​ в текстовой переменной​ обрабатывал глобальную переменную​ нету.​
​: Приложите файл-пример, помогут​ к прогресс бару​Dim cc​ добавить к макросу​
​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Dim filenameTEMP As String​Gorod.Worksheets(«ALL»).Range(«A12:C20»).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,​’Задаем имя отчета​
​End Sub​ — CLng(lMaxQuad *​ внедрить в мой​ = String(p ​DoEvents​j = UserForm1.Width​

​, такой вариант подойдет,​​ которую в нужные​​ .​​Можно окно создать​
​ быстрее​
​ макрос, выдает ошибку.​Application.ScreenUpdating = False​ простейший Progressbar? В​
​а это недопустимо.​ SkipBlanks _​Dim Gorod As​Цитата​
​ lr / lAllCnt),​
​ файл (в примере​

​ 10, ChrW(10152)) &​​Next​​ / 100​​ спасибо)​ моменты в алгоритме​

Источник:
http://my-excel.ru/vba/excel-vba-progress-bar.html