Відображення індикатора поточного стану за допомогою VBA

Раніше я розглянув методи створення користувацьких форм і основи роботи з ними (якщо ви ніколи не працювали з формами користувача, рекомендую для початку прочитати вказану замітку). У цій замітці показано використання індикатора поточного стану – графічного «вимірника», який відображає поточний стан виконуваної задачі, наприклад, працюючого макросу.[1]

поточного

Мал. 1. У вікні UserForm відображається процес виконання макросу

Завантажити нотатку у форматі Word або pdf, приклади в архіві

Ми розглянемо три методи створення індикаторів поточного стану:

  • Макрос, який запускається поза діалогового вікна UserForm (окремий індикатор поточного стану).
  • Макрос, який запускається з діалогового вікна UserForm. При цьому у діалоговому вікні UserForm використовується елемент керування MultiPage для відображення індикатора поточного стану, доки виконується інший макрос.
  • Макрос, який запускається з діалогового вікна UserForm. Висота діалогового вікна UserForm збільшується, а індикатор поточного стану відображається в нижній частині вікна.

Якщо використовується індикатор поточного стану, необхідно знати, наскільки завершено поточне завдання. Способи отримання цієї інформації різняться залежно від типу макросу, що виконується. Наприклад, якщо макрос записує дані в осередки (і кількість таких осередків відомо), то залишається створити код, який підраховуватиме відсоткове відношення кількості осередків, що містять дані. Навіть якщо неможливо точно оцінити, наскільки далеко «зайшов» макрос, користувачеві цікаво буде дізнатися, що макрос ще виконується і Excel не завис.

Відображення індикатора поточного стану у рядку стану вікна

Простийспосіб відображення ходу виконання макросу - використання рядка стану Excel. Його перевага – простота реалізації. Недоліком же є те, що більшість користувачів не звикли відстежувати інформацію, яка відображається в рядку стану вікна, оскільки воліють переглядати її в окремому вікні.

Для відображення повідомлення у рядку стану використовується наступний оператор:

Application.StatusBar = "Будь ласка, зачекайте..."

Можна оновлювати рядок стану у процесі виконання макросу. Наприклад, якщо в макросі використовується змінна Pet, яка представляє стан завдання, можна створити код, який періодично виконуватиме наступний оператор:

Application.StatusBar = "Виконання…" &Pet& % завершено

Після завершення макросу потрібно повернути рядок стану до попереднього вигляду. Для цього використовується наступний оператор:

Якщо рядок стану не повернуто до попереднього вигляду, продовжує відображатись завершальне повідомлення. Пам'ятайте, що індикатор поточного стану уповільнює виконання макросу, оскільки оновлення індикатора потребує додаткового використання системних ресурсів. Якщо швидкодія макросу понад усе, від використання індикатора поточного стану краще відмовитись.

Створення окремого індикатора поточного стану

Такий індикатор не ініціалізується шляхом відображення форми UserForm. Наступний макрос очищає робочий лист і записує 20 тисяч випадкових чисел в діапазон осередків (див. також файл progress indicatorl.xlsm).

Після невеликої зміни макросу (описаного у наступному розділі) діалогове вікно UserForm відображає індикатор процесу виконання макросу (рис. 1).

Створення діалогового вікна UserForm, що включає індикатор поточногостану

Виконайте такі кроки:

  1. Вставте нове діалогове вікно UserForm і змініть значення властивості Caption на ході виконання процесу.
  2. Додайте елемент керування Frame і назвіть йому ім'я FrameProgress.
  3. Додайте елемент керування Label до складу елемента керування Frame та призначте йому ім'я LabelProgress. Видаліть заголовок цього елемента керування, а також зробіть його фон червоним (за допомогою властивості BackColor). На даний момент розміри та розташування цього елемента керування не важливі.
  4. Додайте ще один елемент керування Label над елементом керування Frame, за допомогою якого ви описуватимете те, що відбувається (необов'язково). У нашому прикладі за допомогою цього елемента керування додається напис "Хід виконання процесу".
  5. Налаштуйте діалогове вікно UserForm та елементи керування таким чином, щоб вони виглядали як на рис. 2.

поточного

Мал. 2. Вікно форми UserForm може відігравати роль індикатора ходу виконання процесу

Можна змінити тип форматування елементів керування. Наприклад, властивість SpecialEffect елемента Frame таким чином, щоб останній став «утиснутим».

Створення процедур обробки подій. Важливо, щоб процедура автоматично запускалася під час відображення діалогового вікна UserForm. Один із варіантів передбачає використання події Initialize. Але ця подія виникає до того, як діалогове вікно відображається на екрані, тому такий варіант не підходить. З іншого боку, подія Activate виникає в той момент, коли діалогове вікно UserForm відображається на екрані, тому можна зупинитися на його використанні.

Вставте таку процедуру у модуль коду діалогового вікна UserForm. Ця процедура лише викликаєпроцедуру GenerateRandomNumbers, коли діалогове вікно UserForm відображається на екрані. Процедура GenerateRandomNumbers, яка зберігається в модулі коду VBA, є фактичним макросом, який працюватиме, доки на екрані відображається індикатор поточного стану.

GenerateRandomNumber має додатковий модуль, який відстежує поточний стан, зберігаючи відповідні відомості в змінній PctDone.

Процедура GenerateRandomNumbers включає два цикли. У внутрішньому циклі викликається процедура UpdateProgress, яка приймає лише один аргумент (змінна PctDone, яка «відповідальна» за відображення процесу виконання макросу). Ця змінна може набувати значення від 0 до 100.

Створення процедури запуску. Для відображення діалогового вікна UserForm введіть наступний код модуль VBA.

Можна зробити так, щоб рядок стану відповідав поточній темі робочої книги. Для цього до процедури ShowUserForm додайте наступний оператор.

. LabelProgress.BackColor = ActiveWorkbook.Theme. _ ThemeColorScheme.Colors(msoThemeAccentl)

При виконанні процедури ShowUserForm ширина об'єкта Label встановлюється рівною 0. Після цього викликається метод Show об'єкта UserForm1, що призводить до відображення діалогового вікна UserForm (відіграє роль індикатора поточного стану). Коли діалогове вікно UserForm відображається на екрані, викликається подія Activate, яка призводить до виконання процедури GenerateRandomNurabers. Процедура GenerateRandomNumbers включає код, який викликає процедуру UpdateProgress при кожній зміні змінної лічильника циклу r. Зауважте, що процедура UpdateProgress використовує метод Repaint об'єкта UserForm. Якби цього оператора не було, зображення нана екрані не оновлювалося б. Перед завершенням процедури GenerateRandomNumbers її останній оператор вивантажує діалогове вікно UserForm із пам'яті.

Для того щоб модифікувати цю методику, необхідно розібратися, як визначається відсоток завершення завдання, що виконується. Після цього значення стану завдання можна буде надавати змінній PctDone. Визначення цієї величини здійснюється у різний спосіб залежно від докладання. Якщо код виконується в циклі (як у даному прикладі), обчислення відсотка виконання є порівняно нескладним. Якщо ж код виконується над циклі, визначення стану виконання відбувається у різних точках коду.

Відображення відомостей про поточний стан за допомогою елемента керування MultiPage

У попередньому прикладі макрос запускався не з діалогового вікна UserForm. У багатьох випадках макрос, що довго виконується, можна змусити «піти зі сцени», клацнувши мишею на кнопці ОК в діалоговому вікні UserForm. У цьому розділі буде описаний найкращий спосіб, використання якого можливе при наступних припущеннях:

  • проект завершено та налагоджено;
  • у проекті використовується діалогове вікно UserForm (без елемента управління MultiPage) для запуску макросу, що довго виконується;
  • існує метод оцінки ступеня завершення завдання.

Як і попередньому прикладі, в робочий лист вводяться випадкові числа. Відмінність полягає в тому, що в додатку міститься діалогове вікно UserForm, в якому користувач визначається кількість рядків і стовпців для введення випадкових чисел (рис. 3; див. також файл progress indicator2.xlsm).

відображення

Мал. 3. Користувач визначає кількість рядків та стовпців, в які вводяться випадкові числа

Зміна діалогового вікна. На цьому етапіпередбачається, що діалогове вікно UserForm вже налаштовано. Нам залишилося додати елемент керування MultiPage. Перша сторінка елемента керування MultiPage міститиме всі початкові елементи керування. На другій сторінці розміщені елементи керування, які використовуються для відображення індикатора стану. Коли макрос почне виконуватися, у коді VBA значення властивості Value елемента керування MultiPage зміниться. У результаті буде приховано вихідні елементи керування та відображено елементи керування, які використовуються для створення індикатора поточного стану.

Першим кроком буде додавання елемента керування MultiPage у діалогове вікно UserForm. Після цього необхідно перемістити всі існуючі в діалоговому вікні UserForm елементи керування першу сторінку елемента керування MultiPage. Потім слід активізувати другу сторінку елемента управління MultiPage та налаштувати її так, щоб вона виглядала, як показано на рис. 4. У цьому випадку використовується та ж комбінація елементів керування, що й у попередньому прикладі.

  1. Додайте елемент керування Frame, надавши йому ім'я FrameProgress.
  2. Додайте елемент керування Label до складу елемента керування Frame, надавши йому ім'я LabelProgress. Видаліть заголовок цього елемента керування, а також зробіть його фоновий колір червоним.
  3. Додайте ще один елемент керування Label, що описує суть того, що відбувається (необов'язково).
  4. Активізуйте елемент керування MultiPage в цілому (а не окрему вкладку), а властивості Style надайте значення 2 – fmTabStyleNone. (Це призведе до приховання всіх вкладок.) Можливо, доведеться змінити розмір елемента керування MultiPage, щоб врахувати приховані вкладки.

відображення

Мал. 4. Друга вкладка елементауправління MultiPage, яка застосовується для відображення індикатора поточного стану

Найпростіший спосіб виділення елемента управління MultiPage, коли вкладки приховані, - вибір його в списку, що розкривається, який знаходиться у вікні Properties (підкреслено червоною лінією на рис. 4). Для вибору певної сторінки вкажіть величину властивості Value для елемента MultiPage: 0 - Page1, 1 - Page2 і т.д.

Вставлення процедури UpdateProgress. Вставте наступну процедуру в модуль коду діалогового вікна UserForm.