Розробка додатків vba в excel

Створення програми, яка здійснює контроль
за використанням компонентів проектів

Тут ми акцентуємо вашу увагу на деякі інші питання створення закінчених додатків на базі Excel на прикладі ще однієї реальної програми.

В ході розробки різних додатків у вас накопичується все більше повторно використовуваних компонентів, і на контроль за ними йде досить багато часу. Наприклад, як визначити, який файл використовується в проекті OBJobAgent - SPREAD.VBX або його нова версія SSVBX25.VBX? Де використовується модуль OBORD32 - в проекті OBSuper або спільно з проектом AvailAgent? Подібних питань безліч.

Щоб полегшити управління повторно використовуваними компонентами, застосовуються сховища (репозитарії) вихідного коду, проте багато невеликі організації не працюють з ними. Як "спрощеного" рішення можна порекомендувати скористатися Excel 97 для формування зведених таблиць, в яких відображено використання компонентів в будь-яких проектах.

Файли проектів VB є звичайними ASCII-файли, що містять шляхи і імена файлів, з яких складається проект. До версії VB 3.0 включно опис проекту зберігалося в MAK-файлах і включало досить простий список імен компонентів (див. Лістинг 1). Починаючи з VB4, цей файл отримав розширення VBP, а склад і структура зберігається в ньому істотно змінилися (див. Лістинг 2).

Лістинг 1. Фрагмент типового MAK-файлу
в VB3 містить список компонентів проекту

Лістинг 2. Фрагмент типового VBP-файлу в VB5, що містить список компонентів проекту.

C: \ WINDOWS \ SYSTEM \ STDOLE2.TLB # Standard OLE Types

C: \ PROGRAM FILES \ COMMON FILES \ MICROSOFT SHARED \ DC: \ PROGRAM _

Ідея, яку ми збираємо втілити, полягає в наступному. Працюючи в Excel, ми будемо послідовно відкривати цікаві для нас файли проектів і формувати таблицю з усіма використовуваними в цих додатках компонентами, а потім на основі цієї інформації створимо підсумкову зведену таблицю (див. Рис. 1) Таке завдання може вирішуватися декількома способами. Наприклад, ви можете написати необхідні процедури на VB5 і викликати Excel в якості сервера ActiveX. Однак тут ми покажемо, як написати ці процедури в середовищі самого Excel, використовуючи VBA.

ПРИМІТКА. Нехай читачів не бентежить заголовок "Count of Файл" на рис.1. Ми спеціально хотіли продемонструвати можливі мовні проблеми, коли російськомовне додаток робиться в англійській версії офісного пакету - англійські слова в даному випадку формуються автоматично майстром створення зведених таблиць.

Створення своїх власних процедур

КРОК 1. Запустіть Excel, задайте ім'я нового проекту PivotVBP.xls і перейдіть в середу розробки VB (Alt + F11). Створіть там новий BAS-модуль (команда Insert | Module) і назвіть його також PivotVBP (в поле Name вікна Properties).

Тепер приступимо до написання коду процедур даного модуля (остаточний варіант коду наведено в лістингу 3). Зверніть увагу, що створювати нові процедури можна або використовуючи команду Insert | Procedure, або ввівши перший рядок заголовка процедури (Sub ІмяПроцедури) безпосередньо у вікні коду модуля.

Лістинг 3. Текст модуля коду PivotVBP.

Attribute VB_Name = "PivotVBP"

'Установка заголовків таблиці

'LoadProjectFile формує вихідну

'Таблицю компонентів і повертає результат

If LoadProjectFile Then 'є хоча б один проект

'Формування зведеної таблиці

If FileType $ <> "" Then 'заданий компонент

'Виділення імені файлу з повного

Call FileNameTest (FileN $, Path $, Filename $)

'Додати опис компонента (проект, тип, ім'я

'Файлу) в колекцію Files

Files.Add Array (Project $, FileType $, Filename $), txt $

Ми будемо писати код процедур за принципом "зверху-вниз" - класичного методу структурного програмування - від високого рівня компонентів до більш низького. Правильність такого підходу вже давно доведена - необхідно думати хоча б про колег-розробників, які будуть потім розбиратися в наших програмах, коригувати їх або використовувати в своїх проектах. Але, рухаючись "зверху-вниз", потрібно завжди пам'ятати про готових компонентах нижнього рівня, які будуть складати в значній мірі основу програми.

КРОК 2. Першою напишемо процедуру CreateVBProjCrossRef, яка є головним для всього нашого застосування. Вона спочатку встановлює заголовки, які будуть використовуватися в вихідної, а потім і у зведеній таблиці. Потім вона звертається до функції LoadProjectFile. в якій формується вихідна таблиця компонентів додатків. Якщо функція повертає значення True (Істина), то це означає, що така таблиця була створена хоча б для одного проекту. В цьому випадку викликається підпрограма, яка будує зведену таблицю.

КРОК 3. Процедура SetUpHeadings використовує об'єкт Selection активної в даний момент електронної таблиці, щоб привласнити назви стовпців. Зверніть увагу, що метод Offset застосовується для зміщення вправо при заповненні заголовків для другого і третього стовпців, а також для виділення комірки в першому стовпці першого ряду, розташованого під заголовками.

Досить звичайним контраргументи проти програмування "зверху-вниз" є судження про те, що це заважає поетапного проведення налагодження - додаток можна запустити на виконання тільки після написання всього коду. Однак така теза є невірним: насправді поетапна налагодження легко реалізується за допомогою використання різноманітних "заглушок" (порожніх або реалізованих в спрощеному варіанті процедур).

Нагадаємо також, що при роботі в середовищі VBA при запуску програми на виконання (Run / F5) управління передається компоненті (в даному випадку - процедурі), яка в даний момент знаходиться в активному вікні середовища. Так що перед тим, як натиснути F5, встановіть текстовий курсор в вікні коду на процедуру CreateVBProjCrossRef.

КРОК 4. Пишемо процедуру LoadProjectFile, ключову для всього проекту - формування вихідної таблиці компонентів. Вона працює в циклі, звертаючись до стандартного діалогового вікна для визначення імені існуючого файлу (рис. 2). З цією метою використовується метод GetOpenFilename об'єкта Application і розширення .MAK і .VBP для ідентифікації файлів проектів. Якщо користувач замість вибору файлу (кнопка Open) натискає Cancel, формування таблиці закінчується і функція повертає в зухвалу програму значення True або False залежно від того, чи був обраний хоча б один проект чи ні.

Тип вибраного файлу (MAK або VBP) можна визначити по розширенню його імені. Але ми тут робимо по-іншому: файл проекту відкривається і перевіряється наявність знака рівності в першому рядку (див. Листинги 1 і 2). Зверніть увагу, що в разі MAK-файлу необхідно встановити покажчик читання / запису всередині файлу в його початок, щоб врахувати перший рядок при формуванні списку компонентів.

Після цього викликається відповідна процедура - LoadMAK або LoadVBP, щоб завантажити інформацію з файлу проекту в колекцію Files, а потім помістити цю інформацію з колекції Files в електронну таблицю. Зверніть увагу, що перший цикл For. Next переглядає колекцію Files, а другий цикл For. Next - масив, що містить детальну інформацію для кожного файлу.

КРОК 5. Пишемо код процедур LoadMAK, LoadVBP і FilesAdd. Різниця між процедурами LoadMAK і LoadVBP полягає в тому, як ідентифікується тип компонента в рядках файлу опису проекту. У першому випадку це робиться за допомогою розширення імені файлу, у другому - за допомогою ключового слова на початку рядка. Обидві процедури використовують допоміжну підпрограму FilesAdd, в якій виробляється виділення короткого імені файлу і запису його опису в колекцію Files.

ВАЖЛИВЕ ЗАУВАЖЕННЯ. Для виконання деякий операцій при обробці рядків символьних файлів MAK і VBP ми використовували створені раніше процедури ParseString і FileNameTest, які застосовувалися в різних наших VB-додатках. Вони записані в модулях PARSESUB.BAS і INSTRREV.BAS, відповідно. Завантажити їх в створюване нами додаток в середовищі Excel / VBA можна за допомогою команди File | Import File, але при цьому слід мати на увазі дуже важливу обставину.

BAS-модуль, завантажений таким чином в Office / VBA (це відноситься і до Word, і до Excel), автоматично втрачає логічний зв'язок з відповідним BAS-файлом, збереженим на диску, і стає суто внутрішнім компонентом цього додатка. Це одне з істотних відмінностей логіки використання BAS-модулів в звичайному VB і VBA. У другому випадку (з яким ми маємо справу зараз, працюючи в Excel 97) зміни, зроблені в BAS-файлі, ніяк не впливають на стан завантаженого BAS-модуля і навпаки.

Відповідно, якщо ми хочемо в своїх майбутніх додатках використовувати якісь модулі, сформовані в VBA, то ми повинні записати їх на диск за допомогою спеціальної команди File | Export. Таким чином, заміна назв команд читання / запису модулів Add / Save на Import / Export насправді відображає відмінності в механізмі роботи з модулями.

Після завантаження модулів PARSESUB.BAS і INSTRREV.BAS ми побачимо, що в Excel / VBA вони отримали тривіальні імена Module1 і Module2. Така заміна імен видається правильним кроком, оскільки - повторимо ще раз - це вже інші компоненти, не пов'язані з батьківським файлами. В цьому плані варіант, реалізований в Word 97, коли імені внутрішнього модуля присвоюється ім'я вихідного файлу (строго кажучи навіть не ім'я файлу, а назва в першому рядку файлу Attribute VB_Name - якщо вона є), видається не дуже правильним, так як створює ілюзію однозначного відповідності між цими двома компонентами.

КРОК 6. З огляду на все це, після завантаження модулів PARSESUB.BAS і INSTRREV.BAS (команда File | Import File), які перетворяться в компоненти Module1 і Module2 нашого проекту, ми виконаємо наступні операції. Скопіюємо текст процедури ParseString з Module1 в Module (виділивши текст, а потім записавши його в буфер обміну і відновивши звідти). Потім видалимо Module1 (залишилися там процедури нам не знадобляться), а Module2 перейменуємо в Service (див. Лістинг 4).

Лістинг 4. Текст модуля коду Service

Attribute VB_Name = "Service"

Sub FileNameTest (PathFile $, Path $, File $)

'Вхід: PathFile $ - повне ім'я файлу

'Вихід: Path $ - ім'я каталогу

'File $ - ім'я файлу

pos2 - pos - Len (del $)))

ElseIf n> 1 Then

ParseString = "" 'n-ий елемент даних не знайдений

Створення зведеної таблиці

Приступаємо до створення процедури CreatePivotTable, яка формує зведену таблицю на основі вихідної таблиці компонентів. Як ми зараз переконаємося, програмний код цієї процедури досить невеликий, але писати його вручну - справа досить обтяжлива. Тому краще скористатися майстром Pivot Table Wizard, а потім модифікувати створений при цьому код в більш універсальний вид.

КРОК 8. Перейдемо в середу Excel так, щоб на екрані було видно створена нами вихідна електронна таблиця (рис. 3). Задамо режим запису дії за допомогою команди Tools | Macro | Record New Macro (на панелі Status Bar з'явиться слово Recording). Залишимо ім'я створюваної макрокоманди, пропонованої за замовчуванням. Потім командою Data | PivotTable Report запустимо Майстер створення зведених таблиць, який буде послідовно пропонувати виконати чотири операції за допомогою виведених їм діалогових вікон.

У першому вікні залишимо пропонований за замовчуванням варіант створення зведеної таблиці - Microsoft Excel list or database - і натиснемо кнопку Next (рис. 4). Наступний крок також пройдемо, нічого не змінюючи.

Третій крок - найважливіший: формування структури зведеної таблиці. На екрані з'явиться діалогове вікно із зображенням схеми таблиці (рис. 5).

З правого боку будуть намальовані три кнопки, які відповідають трьом колонкам поточної електронної таблиці. Як назв кнопок використовується вміст комірок першого рядка таблиці, яке інтерпретується як назви стовпців. Перетягуючи мишею назви правих кнопок, формуємо таблицю, зображену на рис. 6.

Для цього найменування "Проект" потрібно помістити в поле "COLUMN", "Тип" і "Файл" - в "ROW", а потім "Файл" - в "DATA".

Заключний, четвертий крок також пройдемо, нічого не змінюючи (буде використовуватися перемикач New worksheet) - натиснувши кнопку Finish. У нас з'явиться створена майстром зведена таблиця. Тепер зупинимо режим запису дії - Tools | Macro | Stop Recording.

КРОК 9. Повернемося в середу VBA. Там у вікні проектів ми побачимо, що у нас з'явився новий модуль, а в ньому - процедура приблизно такого вигляду:

ActiveSheet.PivotTableWizard SourceType: = xlDatabase, _

RowFields: = Array ( "Тип", "Файл"), _

Скопіюємо її в наш основний модуль PivotVBP, перейменуємо в CreatePivotTable, а модуль Module1 видалимо з проекту. У наведеному вище коді видно, що перший рядок використовує посилання на конкретний діапазон з 16 рядків. Щоб використовувати цю процедуру для будь-якого числа рядків, необхідно додати тільки два рядки коду для виділення комірки, розташованої вище на один рядок. При цьому ми будемо використовувати метод CurrentRegion об'єкта Selection для виділення суміжних рядків і стовпців. Необхідно також змінити аргумент SourceData = Selection у методу PivotTableWizard, щоб використовувати об'єкт Selection як діапазон. Результат нашої роботи приведений в лістингу 3.

КРОК 10. Переконаємося в працездатності нашого застосування. Запустимо на виконання процедуру CreateVBProjCrossRef. Потім, послідовно вибираючи файли у вікні "Завантажити файл VB-проекту", сформуйте вихідну таблицю компонентів. Завершіть операцію вибору файлів, натиснувши у вікні кнопку Cansel, і ви побачите зведену таблицю компонентів VB-проектів.

Записати будь-які інші процедури можна тільки в модулі коду. В даному проекті ми створили два таких модуля - PivotVBP і Service. Розподіляючи процедури між двома модулями, ми хотіли підкреслити специфіку підпрограм. У PivotVBP знаходяться процедури, написані саме в рамках створення цього додатка, і ми поки не бачимо потенційної можливості застосування будь-яких з них в інших проектах. А ось в модулі Service записані ті процедури, які ми взяли готовими з більш ранніх розробок.

Чи знаєте Ви, що, коли деякі дослідники, які намагаються примирити релятивізм і ефірну фізику, кажуть, наприклад, про те, що космос складається на 70% з "фізичного вакууму", а на 30% - з речовини і поля, то вони впадають в фундаментальне логічне протиріччя. Це протиріччя полягає в наступному.

НОВИНИ ФОРУМУ
Лицарі теорії ефіру