Как я создал инструмент проектного управления.
Однажды я пришел на собеседование, на позицию «Руководитель проекта». Прошлись по основным требованиям и компетенциям — вопросов у директора не возникло. Тогда он спросил:
— Как ты относишься к работе в ночные часы?
— Нормально, если потом будет возможность выспаться. Хотя бы в выходные.
— Представь, что ты управляешь большим количеством проектов внедрения, каждый из которых длится до нескольких недель, и мы делим в них зону ответственности с заказчиком. Таких мини-проектов очень много, может быть несколько сотен в год, и большая их часть будет реализована в интервале 2-3 месяца. Какой из известных тебе инструментов ты бы использовал для эффективного управления в этом случае?
Исчерпывающего ответа я дать не мог, так как было слишком много неопределенности. Однако я сказал, что инструменты буду подбирать по ходу дела, в зависимости от проектных требований и прочих не обозначенных на интервью нюансов.
Это было в самом конце августа, а 1 сентябре я приступил к работе. 30 декабря был успешно завершен и документально закрыт первый этап федерального проекта. Более 300 площадок были оснащены необходимым оборудованием, на которое был установлен и настроен софт, площадки приняты заказчиком. Всего было выпущено 2 акта, проектная деятельность была организована в системе Yougile (на стороне заказчика), а учет я вел в эксель-файле, который умел подкрашивать статусы проектов (см. Листинг 2 кода ниже), содержал технические детали по площадкам и некоторую специфическую информацию. В моей команде было 10 инженеров, которые в несколько смен вводили площадки в эксплуатацию — в пике до пары десятков ежесуточно.
На следующий год ситуация осложнилась тем, что закрывать работы предстояло пообъектно, то есть на каждую площадку (в редких случаях — на две), предстояло выпускать отдельный акт выполненных работ по форме договора. Дополнительно потребовалось также производить внутренние файлы для бухгалтерии, для выставления счетов.
Т.к. пик работ приходился традиционно на вторую половину года, у меня было время, чтобы подготовиться: предстояло расширить таблицу с проектным статусом дополнительными полями и закладками с тем, чтобы приготовить ее к автогенерации документов. Также были составлены шаблоны закрывающих документов в формате «.doc», и внутренних форм для бухгалтерии — в формате «.xls». Далее предстояло самое интересное: т. к. я уже привык работать по ночам, а в весенне-летний период производственных задач со смещенным рабочим временем у меня практически не было, я за пределами рабочего дня приступил к созданию первой версии VBA-скрипта (v.1). Он собирал необходимые данные из таблички и раскладывал их в шаблоны документов. Через пару недель скрипт был составлен и отлажен на том небольшом количестве работ, которые мы вели, и моя рутина по формированию проектной документации на этом закончилась, практически так и не начавшись. Столь экзотический на первый взгляд выбор языка — VBA — я сделал исключительно по той причине, что он встроен в инструментарий MS Office. Мне не потребовалось никаких усилий и дополнительного обеспечения, чтобы внедрить автоматизацию у себя на машине. Только в конце года я осознал, насколько создание этого нехитрого инструмента оказалось необходимым и своевременным ходом, который по сути предопределил успех второго этапа нашего проекта в части его документального оформления.
Так как с течением времени наша работа усложнялась, появлялись дополнительные сущности и нюансы, а желание составлять или даже незначительно править вручную документы у меня не возникало, первая версия скрипта постоянно дорабатывалась, что было неудобно и довольно трудоемко, поскольку объем кода уже давно составлял несколько сотен строк. Пришло время для первого серьезного рефакторинга. В его ходе была полностью изменена архитектура. Из обычных модулей код был перенесен в класс-модули (отдаленный аналог классов в полноценных объектно-ориентированных языках программирования), в которых весь функционал был прозрачно разнесен на соответствующие функции. Теперь доработка скриптов под новые задачи пошла существенно быстрее. Так появился второй мажорный релиз продукта (v.2).
Этим развитие инструмента не ограничилось. Через некоторое время появилась еще одна версия (v.3) в которой были реализованы: автоматическое добавление реквизитов договора (в том числе стало возможным выбирать из списка подписантов), автонумерация актов, импорт заявок на работы и прочие удобные фичи. Поскольку автоматизация выпуска проектных документов практически исключила ошибки и кратно ускорила документооборот с нашим партнером и заказчиком, мне не составило труда согласовать с ним такую форму заявок на работы, которую не нужно было руками переносить в мой файл с проектным статусом - теперь это происходило автоматически при нажатии «секретной» комбинации кнопок. По определенным причинам, я не размещал на своих эксель-формах ни одной кнопки — все события генерировались либо с помощью комбинаций клавиш, либо двойным кликом по ключевым ячейкам, стилизованным под кнопки.
Так мы работали пол счастливых года, за которые я смог сосредоточить свои усилия и внимание на других проектных активностях, а также посвятить часть времени изучению продуктового подхода.
А потом случилось страшное: по независящим от нас причинам генеральный директор заказчика в одностороннем порядке инициировал изменение договорных отношений, существенно изменивших их внутреннюю структуру. Это повлекло «откат» всей завершенной к настоящему моменту работы, что требовало переоформления всех заактированных за полгода работ на фоне набирающего обороты проектного темпа.
К этому моменту у меня, правда, уже был помощник, обученный процессам и проектному инструменту, и способный не запутаться в стремительном разнонаправленном потоке документов.
К чему я так подробно писал про скрипт? Дело в том, что v.3 дала возможность в кратчайшие сроки (существенно быстрее, чем занял процесс подписания дополнительного соглашения к договору), адаптировать инструмент таким образом, чтобы он научился генерировать все необходимые документы в соответствии с описанными выше обстоятельствами, а также не запутаться со статусом довольного большого количества мини-проектов. Конец года также принес успех всем многочисленным участникам проекта, мы мужественно справились с неожиданно нахлынувшей на нас дополнительной лавиной документов и благодаря нашей прекрасной инженерной команде закрыли в срок изначально запланированные 400+ площадок, более половины из которых пришлось на последний квартал года.
Таким образом, одним из основных инструментов проектного управления, о котором меня на собеседовании спрашивал директор, стал небольшой набор обычных офисных документов: основной проектный файл в MS Excel, щедро обмазанный VBA-модулями, несколько шаблонов MS Word для генерации документов, а также шаблоны в MS Excel для выпуска внутренних заявок для бухгалтерии и «впитывания» заявок от заказчика в согласованной форме. Познее этот механизм был перенесен на другую часть проекта, связанную с разработкой программных модулей.
Проведенный анализ выявил следующие преимущества и недостатки инструмента:
Преимущества:
- колоссальное ускорение документооборота, обусловленное практически нулевым количеством ошибок, причем, в основном, теоретически возможные ошибки (в подавляющем большинстве, связанные с опечатками в адресе площадок) «подтягивались» из заявок заказчика и могли быть устранены только на его стороне;
- высвобождение существенного ресурса среднего уровня квалификации — нужно было не только выпускать огромное количество документов, но и не запутаться в них, я оцениваю этот ресурс минимум в 2 ШЕ в пик документооборота, длившегося более 4 месяцев;
- возможность быстро и гибко подстраиваться под изменяющиеся требования заказчика и проектное окружение, что находило отражение в сопутствующей документации;
- автоматизация выпуска проектной документации стоило компании 0 рублей, т.к. была полностью реализована на уже используемых продуктах MS Office, а написана скромным автором этой статьи, который довольно продолжительное время был единоличным руководителем всех внутренних и внешних проектов компании.
Недостатки:
-
Так как основной файл, составляющий инструмент, имел расширение
.xlsm, его хранение не поддерживалось обычными многопользовательскими системами документооборота (например, MS SharePoint), что привело к необходимости системным администраторам кастомизировать под проектную команду дополнительные средства одновременного доступа и организовать нам специальную сетевую папку на сервере — не то, чтобы это сложно или сильно небезопасно, но тем не менее в некоторых компаниях я бы столкнулся с серьезными проблемами в таком случае; - система управления проектом оказалась отчасти однопользовательской: вносить изменения в единицу времени мог только один человек, однако при этом остальные пользователи все же могли в режиме «только для чтения» генерировать документы. Поэтому я этот минус тоже считаю не существенным, по крайней мере в данном конкретном случае.
Этот класс-модуль заполняет шаблон документа. Функция Fillпоследовательно вызывает
несколько вложенных функций для заполнения соответствующего раздела документа. Чтобы нарастить функционал, достаточно в этом
модуле лишь дописать соответствующую функцию и вызвать ее в Fill. Отладка в этом случае будет быстрой и комфортной.
Этот листинг эксель-объекта (одна из вкладок рабочего документа) представляет собой бработчик события изменения данных на вкладке таблицы. Если меняется поле статуса, то соответсвующая строка подкрашивается в соответствии с заданным форматом. В моем случае все форматы жестко зашиты в код, но ничто не мешает вынести настройки формата в отдельную сервисную вкладку и брать их оттуда. Как проектный менеджер я очень люблю использовать подобный подход в статусных (и не только) документах.
В коде выше показан запуск обработчика события на двойной клик. Если клик произошел на определенном мной столбце, то из соответствующей ячейке строки начнет собираться информация для последующей автогенерации документа с предварительным созданием всех необходимых сущностей, после чего создается файл с Актом выполненных работ по выбранной площадке.
Данный код демонстрирует, как устроен класс-модуль, собирающий из статусного файла всю необходимую
информацию для документа. Если для новой фичи требуется не только заполнять новые поля шаблона, но и собирать для этого
дополнительные данные, логика внесения изменений в код аналогична описанной для Листинга 1:
нужно добавить функционал в новой процедуре, которую необходимо назвать, начиная с Collect[Something],
и вызывать ее в общей функции Collect. На случай, если функционал потребуется отключить, потребуется просто
закомментировать одну строчку кода.
.doc.
Перед тем, как заполнить документ, его, очевидно, надо создать. Именно этот процесс представлен в
листинге выше. Отмечу, что наибольшее количество ошибок, не связанных с разработкой, а обусловленных именно
эксплуатацией и неправильной настройкой системы встречаются и обрабатываются здесь. К ним я отношу: обращение к несуществующему
файлу, попытка открыть или записать в уже открытый файл и т.п. Именно в этом фрагменте можно обнаружить самую большую плотность
кода обработки ошибок. Как можно заметить, мы не создаем файл с нуля, а копируем его из шаблона (встроенная функция
FileCopy) и в последствии заполняем данными из нашего коллектора.
В этом фрагменте происходит то же самое, что и в предыдущем листинге,
разница лишь в том, что в данном случае из шаблона создается .xls документ.
В последнем представленном листинге я хотел показать на самом низком уровне абстракции, как происходит заполнение документа, в данном случае речь идет о заявке в формате «xls», шаблон которой мы скопировали в предыдущем листинге. Т.к. в последней версии своего инструмента я еще добавил подобие changelog'а на последней вкладке Excel-файла, я также решил снабжать комментариями новые участки кода — интерпретатор подсвечивает их на картинке зеленым. В данном случае, как видно, я по запросу бухгалтерии изменил , логику расчета НДС. При этом, чтобы вернуть все обратно, достаточно раскомментировать одну строчку и закомментировать другую.
Модули с VBA-скриптом распределены следующим образом:
- 9 эксель-объектов (закладок) с обработчиками и собственным кодом;
-
2 обычных модуля: один из них,
Money, я позаимствовал в интернете и немного улучшил, посмкольку это оказалось существенно бстрее, чем писать и отлаживать достаточно объемный код с ветвистой логикой преобразования сумму в рублях из чисел в слова; второй модуль реализует импорт заявок на работы — я писал об этой новой полезной фиче, когда рассказывал о тех удобствах, которые содержала v.3 инструмента; - 3 класс-модуля (по 3 поколения в каждом):
- ComDataCollector – для сбора данных из статусного файла;
- ComDocParser – для заполнения шаблонов генерируемых документов;
- ComDocConfig – для управления конфигурациями и настройкой системы.
Поколения класс-модулей отражают мажорную версионность изменений. Отчасти благодаря такому лайфхаку
я не стал прибегать к инструментам систем контроля версий, а пошел таким спорным путем. Дело в том, что хранить VBA-скрипты
отдельно от файла с данными в Гитлабе, представлялось мне весьма неудобным, а держать целиком .xlsm файл в
репозитории я был не мог из соображений конфиденциальности. Такой подход себя очень хорошо оправдал, в особенности когда
одновременно приходилось исправлять акты по старой форме и генерить их по новой в процессе перехода на изменившиеся договорные
рельсы, о чем я также писал выше.