Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

Во многих компаниях Excel остаётся основным инструментом для внутренних графиков, календарей и планирования.

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

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

Изначально я рассматривала вариант оставить Excel как основной интерфейс и просто «подтянуть» к нему автоматизацию: получать производственный календарь, забирать данные об отсутствиях из Битрикс24, использовать Power Query, макросы или внешний серверный скрипт.

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

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

Что это за приложение

Это внутреннее приложение для Битрикс24, которое ведёт годовой график сотрудников в табличном виде.

Снаружи оно похоже на большую таблицу, но внутри у него довольно много логики. В приложении можно:

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

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

Почему не подошёл обычный календарь

В какой-то момент может показаться, что для такой задачи достаточно стандартного календаря Битрикс24 или готового модуля учёта отсутствий.

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

Обычный календарь Битрикс24 не закрывал эту задачу по интерфейсу. Он хорошо подходит для событий, но не для плотного годового графика, где пользователи привыкли видеть всю структуру в табличном виде и быстро редактировать ячейки.

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

Но Excel оставался слабым местом там, где начиналась бизнес-логика.

Поэтому задача была не в том, чтобы «заменить Excel ради замены», а в том, чтобы сохранить его сильную сторону — привычный табличный сценарий — и убрать то, что в Excel приходилось держать вручную.

Как выглядел исходный процесс

До приложения график вели вручную в Excel. Каждый год это означало:

  • создать новый лист;
  • перенести производственный календарь;
  • отметить выходные и праздничные дни;
  • сверить отпуска и командировки с Битрикс24;
  • обновить список сотрудников;
  • поддерживать структуру таблицы, если кто-то увольнялся или менялся состав отдела.

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

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

Производственный календарь

Одна из основных причин делать отдельное приложение — автоматическое формирование календаря на год.

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

Если календаря на нужный год ещё нет, приложение обращается к сервису isdayoff.ru, получает данные по выходным и праздничным дням, сохраняет их в свою базу и дальше использует уже локальную копию.

Это сделано специально: приложение не должно зависеть от доступности внешнего API при каждом открытии графика. Если сервис временно недоступен, уже загруженные годы продолжают открываться из базы приложения.

В итоге новый год не нужно собирать вручную. Достаточно открыть его в приложении — календарная основа формируется автоматически.

Технологический стек

Приложение сделано как локальное приложение внутри Битрикс24: оно живёт в файловой структуре портала, подключает ядро Битрикс и работает в его окружении — с текущим пользователем, структурой компании, инфоблоками, модулем отсутствий и базой данных.

При установке install.php создаёт собственные таблицы приложения в базе Битрикс24. В них хранятся производственный календарь, ячейки графика, роли и права, настройки отображения, данные о присутствии пользователей и текущем редактировании ячеек. Повторный запуск установщика не сбрасывает уже настроенные права и данные.

Backend написан на PHP и работает с базой через стандартную обёртку Битрикс. Основная бизнес-логика остаётся на сервере: проверка прав, сохранение ячеек, импорт, экспорт, синхронизация отсутствий и обработка конфликтов.

Фронтенд сделан на обычном JavaScript и CSS, без отдельной сборки. Он отвечает за поведение таблицы: выделение диапазонов, копирование и вставку из Excel, протягивание значений, горячие клавиши, масштаб, блокировку редактируемых ячеек и обновления без перезагрузки.

Для обмена с сервером используется единый AJAX-диспетчер, а совместная работа реализована через long polling: приложение показывает, кто сейчас находится в графике, какие ячейки редактируются, и подтягивает изменения без ручного обновления страницы.

Фоновые операции вынесены в системный cron: периодическая синхронизация данных, обработка очереди изменений в отсутствиях Битрикс24 и проверка конфликтов между задачами и отпусками или командировками.

Для первичного формирования производственного календаря используется API сервиса isdayoff.ru.

Для импорта и экспорта Excel используется PhpSpreadsheet, а для уведомлений о конфликтах — интеграция с Yandex Messenger Bot API.

Какие модули и функции Битрикс24 использованы

Отдельно перечислю конкретные точки интеграции с ядром Битрикс24 — на случай, если кто-то будет делать похожее приложение и захочет ориентироваться не только на общие слова «интеграция с Битрикс24».

  • Bitrix\Main\UI\Extension::load(['main.core', 'ui.entity-selector']) — подключение стандартного UI-расширения для выбора сотрудников и подразделений. На нём построен интерфейс назначения ролей: пользователей и отделы можно выбирать штатным способом, без отдельного самописного справочника.
  • CUser::GetList() / CUser::GetByID() — получение списка сотрудников для графика, данных пользователей для панели прав и информации для экспорта в Excel.
  • CUser::GetUserGroup() и $USER->IsAdmin() — проверка, является ли пользователь администратором портала. Администраторам Битрикс24 выдаётся полный доступ к приложению без необходимости отдельно назначать им роль.
  • UF_DEPARTMENT — стандартное пользовательское поле с подразделениями сотрудника. Оно используется для построения списка сотрудников для отображения в графике отдела.
  • Инфоблок структуры компании — опция iblock_structure модуля intranet, методы CIBlockSection::GetList() и GetNavChain(). Эта часть нужна для работы с иерархией подразделений: если роль назначена на родительский отдел с опцией «включая дочерние подразделения», она должна действовать и на сотрудников вложенных отделов.
  • CModule::IncludeModule('intranet') + CIntranetUtils::GetAbsenceData() — стандартный способ получить отпуска, командировки и другие отсутствия сотрудников для первичной загрузки данных в график.
  • Инфоблок отсутствий — опция iblock_absence модуля intranet, метод CIBlockElement::GetList(). Прямой доступ к этим данным понадобился отдельно для обработки изменений и проверки конфликтов между отсутствиями и задачами.
  • События модуля iblock — OnAfterIBlockElementAdd, OnAfterIBlockElementUpdate, OnAfterIBlockElementDelete, зарегистрированные через RegisterModuleDependences(). На этих событиях построена реакция на создание, изменение и удаление отсутствий: обработчик не выполняет тяжёлую проверку сразу, а ставит отсутствие в очередь на последующую обработку через cron.
  • CFile::GetPath() по полю PERSONAL_PHOTO пользователя — получение аватарок для панели онлайн-пользователей и списка участников роли.
  • check_bitrix_sessid() — штатная защита Битрикс от CSRF. Проверка выполняется в общем AJAX-диспетчере перед выполнением действий, которые меняют данные.
  • COption — использовался для хранения выбранного списка отображаемых сотрудников между сессиями на раннем этапе. Позже эта настройка переехала в собственные таблицы приложения вместе с остальными пользовательскими настройками и правами.

Роли и панель управления правами

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

В ней можно создавать и редактировать роли, включать для каждой роли конкретные разрешения и назначать роль не только отдельному сотруднику, но и целому подразделению. Для выбора пользователей и отделов используется штатный механизм Битрикс24: приложение интегрировано с пользовательской структурой портала, поэтому администратору не нужно вручную вводить ID сотрудников или поддерживать отдельный список.

Это особенно важно для внутренних инструментов: структура команды меняется, люди переходят между отделами, появляются новые сотрудники. Если роль назначена подразделению, доступ автоматически соответствует организационной структуре, а не живёт отдельной ручной настройкой внутри приложения.

Из коробки создаются три роли, которые дальше можно менять:

  • Администратор — полный доступ: редактирование любых задач, создание и удаление, очистка года, импорт и экспорт, управление списком отображаемых сотрудников, ролями и правами.
  • Планировщик — просмотр графика, создание задач, редактирование и удаление только своих задач, экспорт. Чужие задачи менять нельзя.
  • Наблюдатель — только просмотр графика и экспорт, без права что-либо менять.

Отдельно можно включить право получать уведомления о конфликтах между задачами и отсутствиями. Это право не входит ни в одну роль по умолчанию: подписка на такие уведомления — осознанное решение конкретного человека или группы.

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

Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

Что отображается в графике

График построен как годовая таблица: по строкам — дни, по столбцам — сотрудники.

В ячейках могут отображаться:

  • рабочие дни с задачами;
  • выходные и праздники;
  • отпуска;
  • командировки;
  • конфликтные ячейки — когда задача и отсутствие пересеклись по датам;
  • пустые рабочие ячейки.
Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

Данные приходят из разных источников и должны быть согласованы между собой: производственный календарь, модуль отсутствий Битрикс24, вручную введённые задачи, список сотрудников и персональные настройки отображения конкретного пользователя.

Панель выбора сотрудников

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

Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

Это не ручная правка структуры таблицы, а обычный пользовательский интерфейс:

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

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

Масштаб и подстройка под экран

Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

В приложении несколько способов изменить отображение:

  • слайдер с шагом 5%;
  • ручной ввод точного значения процента;
  • кнопка подгонки по ширине окна.

Диапазон масштаба — от 50% до 130%.

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

Изменение ширины столбцов

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

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

Excel-подобная логика

Отдельно в приложении реализована Excel-подобная работа с таблицей — не полная замена Excel, а именно те сценарии, которые пользователи реально используют каждый день:

  • выделение одной ячейки, диапазона или нескольких столбцов;
  • копирование и вставка через системный буфер обмена;
  • вставка диапазона из настоящего Excel в график и обратно;
  • протягивание значений маркером заполнения;
  • перемещение по таблице с клавиатуры;
  • отмена и повтор действий с историей на 100 последних операций;
  • ввод текста прямо в выделенную ячейку без двойного клика.

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

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

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

Горячие клавиши

Для ускорения работы клавиатурное управление продумано отдельно.

Например, Delete очищает все выделенные ячейки сразу, а Backspace — только активную ячейку и сразу переводит её в режим редактирования, чтобы можно было тут же вписать новое значение. Это разное поведение, и оно сделано намеренно.

Из остального:

  • стрелки — перемещение по ячейкам, с Shift — расширение выделения;
  • Enter / Shift+Enter — переход на ячейку ниже или выше;
  • Tab / Shift+Tab — переход вправо или влево;
  • Escape — отмена редактирования или снятие выделения;
  • Ctrl+C / Ctrl+X / Ctrl+V — копирование, вырезание, вставка;
  • Ctrl+Z / Ctrl+Y — отмена и повтор;
  • Ctrl+A — выделить весь график.

Клавиши работают и на русской раскладке — это отдельно проверялось, чтобы Ctrl+Я срабатывал как Ctrl+Z.

Совместная работа в реальном времени

График может быть открыт сразу у нескольких пользователей, поэтому совместную работу пришлось продумывать отдельно.

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

Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

Кроме самой панели, реализованы механизмы защиты от параллельного редактирования:

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

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

Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

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

Интеграция с отсутствиями Битрикс24

Отпуска и командировки подтягиваются из Битрикс24 автоматически.

Здесь важно было не просто один раз загрузить данные, а поддерживать их актуальность. Если в Битрикс24 создаётся, изменяется или удаляется отсутствие, приложение должно понять, влияет ли это на график, появились ли конфликты и нужно ли отправить уведомление.

Проверка конфликтов вынесена в фоновые задачи. Обработчик события в Битрикс24 не делает тяжёлую работу прямо в момент сохранения отсутствия, а только ставит его в очередь на проверку. Дальше системный cron разбирает очередь, проверяет конкретное отсутствие и при необходимости отправляет уведомление.

Так сохранение отпуска или командировки в Битрикс24 не замедляется для пользователя, а приложение при этом всё равно реагирует на изменения.

Конфликты между задачами и отсутствиями

Конфликт возникает, когда на дату уже стоит задача, а потом на эту же дату оформляется отпуск или командировка.

Такая ячейка помечается как конфликтная, и при клике показывается подсказка: кто сотрудник, какая задача, какой тип отсутствия и период. Приложение сознательно не переносит задачу само — решение, что делать дальше, должно оставаться за человеком.

Как я сделала внутренний график занятости сотрудников в Битрикс24 вместо Excel, сохранив привычный формат работы

Отдельный важный сценарий — уведомления о конфликтах в Яндекс Мессенджер. Для этого я использовала Yandex Messenger Bot API: приложение формирует сообщение о найденном конфликте и отправляет его через бота тем пользователям, у которых есть соответствующее право.

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

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

Это оказалось полезным: так можно проверить логику на реальных данных и не разослать уведомления случайным людям.

Импорт и экспорт Excel

Импорт и экспорт Excel остались не как основной рабочий процесс, а как запасной сценарий. Если Битрикс24 временно недоступен или по какой-то причине нет возможности вести график прямо в приложении, данные можно выгрузить в Excel, поработать с ними локально, а затем загрузить обновлённый файл обратно.

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

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

Такое поведение осознанное. Основной сценарий — «выгрузили, отредактировали в Excel, загрузили обратно», а не частичное дополнение, где было бы неочевидно, что должно замениться, а что остаться.

Режимы открытия приложения

Приложение можно открыть тремя способами:

  • в отдельной вкладке браузера;
  • во фрейме внутри портала Битрикс24;
  • развёрнутым на весь экран в боковой панели Битрикс24.

Разворачивание на весь экран оказалось не такой простой кнопкой, как кажется. Битрикс24 при этом не показывает уже открытый экземпляр приложения, а полностью загружает его заново в отдельном окне. То есть это фактически второй независимый запуск приложения.

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

Перенос состояния в новое окно решился через sessionStorage. С обратным переносом при закрытии развёрнутого окна было сложнее: закрывающееся окно не всегда успевало само сохранить состояние, потому что Битрикс уничтожает iframe быстрее, чем браузер выполняет асинхронную проверку.

Рабочим оказался другой подход: окно, которое остаётся открытым, само читает состояние закрывающейся панели напрямую, пока та ещё жива. Это мелочь на первый взгляд, но именно такие детали определяют, будет ли инструментом удобно пользоваться каждый день.

Что пришлось предусмотреть

При разработке отдельно пришлось продумать:

  • автоматическое формирование производственного календаря;
  • хранение календаря, ячеек, ролей и настроек в собственных таблицах приложения;
  • гибкие роли и права доступа;
  • панель управления правами с назначением ролей сотрудникам и подразделениям Битрикс24;
  • синхронизацию с отсутствиями Битрикс24;
  • конфликты между задачами и отпусками или командировками;
  • уведомления о конфликтах через Yandex Messenger Bot API;
  • Excel-импорт и экспорт;
  • выбор и порядок отображаемых сотрудников;
  • масштаб и единую ширину столбцов;
  • горячие клавиши и массовое редактирование;
  • протягивание задач по строкам, столбцам и диапазонам без затирания выходных, отпусков и границ месяцев;
  • панель онлайн-пользователей;
  • совместную работу нескольких пользователей;
  • блокировку редактируемых ячеек;
  • защиту от перезаписи данных;
  • сохранение персональных настроек для разных режимов открытия.

Что изменилось после внедрения

После перехода от Excel к приложению график стало проще поддерживать и обновлять.

Больше не нужно каждый год собирать календарь вручную: производственный календарь формируется автоматически, а отсутствия сотрудников подтягиваются из Битрикс24. При этом сам формат остался привычным — это всё ещё табличный график с датами, сотрудниками и задачами.

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

Вывод

Снаружи проект выглядит как обычная большая таблица с датами и сотрудниками. Но внутри это полноценный инструмент с производственным календарём, ролями и правами, интеграцией с отсутствиями Битрикс24, проверкой конфликтов, Excel-подобным редактированием и совместной работой.

Главная задача была не просто заменить Excel и не сделать ещё один календарь. Нужно было сохранить привычный табличный формат, убрать ручную рутину вокруг него и перенести работу с графиком внутрь Битрикс24 так, чтобы пользователям не пришлось переучиваться заново.

3