Как в 1С 8.3 реализовать интерактивный календарь для расписания клиники?

Программист 1С v8.3 (Управляемые формы) Сфера услуг, туризм и социальный сектор
← На главную

Разработка интерактивного календаря для планирования записей — одна из наиболее частых задач при автоматизации медицинских центров, стоматологий, салонов красоты или автосервисов. Пользователям необходим удобный, быстрый и отзывчивый интерфейс, где можно буквально в один клик перетащить запись к другому врачу, изменить время приема или быстро оценить загрузку кабинетов. В этой статье мы подробно разберем, как решить эту задачу в среде 1С:Предприятие 8.3 (Управляемые формы), проанализируем штатные возможности платформы и альтернативные веб-технологии.

Вариант 1. Использование встроенного объекта платформы «Планировщик»

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

Рассмотрим по шагам, как настроить встроенный Планировщик на управляемой форме:

  1. Создание реквизита формы: Добавим на управляемую форму новый реквизит с типом данных Планировщик. Перетащим его на панель элементов формы, чтобы он отобразился на экране.
  2. Настройка временной шкалы: При создании формы нам необходимо программно задать параметры отображения сетки времени. Укажем шаг планирования и рабочий интервал.
  3. Добавление измерений: Измерения — это сущности, в разрезе которых строится график (например, «Врачи», «Кабинеты» или «Оборудование»).
  4. Заполнение данными: Программным запросом выберем данные о существующих записях из базы данных и заполним элементы планировщика.

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Задаем интервал отображения (например, текущий рабочий день)
	Элементы.КалендарьРасписания.ТекущийПериодОтображенияНачало = НачалоДня(ТекущаяДата());
	Элементы.КалендарьРасписания.ТекущийПериодОтображенияКонец = КонецДня(ТекущаяДата());
	
	// Настраиваем шкалу времени с шагом в 30 минут
	Элементы.КалендарьРасписания.ШкалаВремени.Элементы.Очистить();
	НовыйЭлементШкалы = Элементы.КалендарьРасписания.ШкалаВремени.Элементы.Добавить();
	НовыйЭлементШкалы.ЕдиницаВремени = ЕдиницаВремени.Минута;
	НовыйЭлементШкалы.Кратность = 30;
	
	// Настраиваем рабочий интервал (например, с 08:00 до 20:00)
	КалендарьРасписания.РабочееВремяНачало = '00010101080000';
	КалендарьРасписания.РабочееВремяКонец = '00010101200000';
	
	// Вызываем заполнение измерений (например, список врачей)
	ЗаполнитьИзмеренияПланировщика();
	
	// Загружаем записи из базы данных
	ОбновитьРасписаниеНаСервере();
	
КонецПроцедуры

Теперь разберем, как добавить в планировщик колонки врачей. Измерения позволяют группировать календарную сетку вертикально или горизонтально:


&НаСервере
Процедура ЗаполнитьИзмеренияПланировщика()
	
	// Очищаем старые измерения
	КалендарьРасписания.Измерения.Очистить();
	
	// Создаем новое измерение "Врачи"
	ИзмерениеВрачи = КалендарьРасписания.Измерения.Добавить("Врач");
	
	// Заполняем измерение элементами справочника "Сотрудники"
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Сотрудники.Ссылка КАК Ссылка,
		|	Сотрудники.Наименование КАК Наименование
		|ИЗ
		|	Справочник.Сотрудники КАК Сотрудники
		|ГДЕ
		|	НЕ Сотрудники.ПометкаУдаления";
	
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	Пока Выборка.Следующий() Цикл
		ЗначениеИзмерения = ИзмерениеВрачи.Значения.Добавить(Выборка.Ссылка, Выборка.Наименование);
	КонецЦикла;
	
КонецПроцедуры

Для вывода самих записей на сетку календаря используется коллекция Элементы объекта Планировщик. Рассмотрим пример заполнения элементами:


&НаСервере
Процедура ОбновитьРасписаниеНаСервере()
	
	КалендарьРасписания.Элементы.Очистить();
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ЗаписьНаПрием.Ссылка КАК Ссылка,
		|	ЗаписьНаПрием.Пациент.Наименование КАК ПациентНаименование,
		|	ЗаписьНаПрием.Врач КАК Врач,
		|	ЗаписьНаПрием.ДатаНачала КАК ДатаНачала,
		|	ЗаписьНаПрием.ДатаОкончания КАК ДатаОкончания
		|ИЗ
		|	Документ.ЗаписьНаПрием КАК ЗаписьНаПрием
		|ГДЕ
		|	ЗаписьНаПрием.Проведен";
	
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	Пока Выборка.Следующий() Цикл
		
		// Создаем элемент планировщика с указанием времени начала и окончания
		НоваяЗапись = КалендарьРасписания.Элементы.Добавить(Выборка.ДатаНачала, Выборка.ДатаОкончания);
		НоваяЗапись.Текст = Выборка.ПациентНаименование;
		
		// Привязываем элемент к измерению "Врач"
		НоваяЗапись.ЗначенияИзмерений.Вставить("Врач", Выборка.Врач);
		
		// Сохраняем ссылку на документ для последующей интерактивной работы
		НоваяЗапись.КлючСвязи = Выборка.Ссылка;
		
	КонецЦикла;
	
КонецПроцедуры

Штатный планировщик полностью поддерживает технологию Drag-and-Drop. Пользователь может перетаскивать записи мышкой, менять их длительность, растягивая границы блоков. Чтобы обработать эти изменения и сохранить их в базе данных, нам нужно использовать интерактивные события элемента формы, такие как ПриИзмененииЭлемента.

Ограничения штатного планировщика: Несмотря на простоту внедрения, встроенный объект имеет ряд «подводных камней». В реальных медицинских центрах крайне важна детальная визуализация: индикаторы оплаты, статусы явки (опоздал, подтвердил, в кабинете), иконки типов приемов, группировки по кабинетам с контролем занятости оборудования. Настроить настолько сложный графический интерфейс средствами стандартного планировщика 1С бывает крайне сложно или вовсе невозможно из-за жестких ограничений платформенного рендеринга.

Вариант 2. Интеграция JavaScript-библиотек через «Поле HTML-документа»

Если визуальные требования заказчика выходят за рамки возможностей стандартного планировщика, лучшим решением будет интеграция профессиональных JavaScript-календарей (например, FullCalendar.js или DHTMLX Scheduler) непосредственно в форму 1С.

Благодаря переходу современных версий платформы 1С 8.3 на современный движок рендеринга WebKit, мы получили полноценный доступ к современным стандартам веб-верстки. Схема взаимодействия строится на обмене данными между 1С и JavaScript через объект ПолеHTMLДокумента.

Рассмотрим по шагам архитектуру такого решения:

  1. Создание HTML-шаблона: В конфигурации создается макет с типом «Текстовый документ». В этот макет помещается HTML-код страницы, стили CSS и файлы JS-библиотек (их можно хранить локально в макетах, чтобы расписание работало даже без интернет-подключения).
  2. Выгрузка данных из 1С в JS: 1С выбирает информацию о записях, преобразует её в формат JSON и отправляет в JavaScript-функцию инициализации календаря.
  3. Обратная связь из JS в 1С: При перетаскивании карточки или клике в календаре JavaScript перехватывает событие и передает параметры (ID записи, новое время, новый врач) обратно на сторону 1С для записи в информационную базу.

Проанализируем пример передачи данных в JS-библиотеку из 1С. Для сериализации данных в формат JSON воспользуемся встроенными средствами платформы:


&НаСервере
Функция ПолучитьДанныеЗаписейВФорматеJSON()
	
	МассивЗаписей = Новый Массив;
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Запись.Ссылка КАК ID,
		|	Запись.Пациент.Наименование КАК Title,
		|	Запись.ДатаНачала КАК StartDate,
		|	Запись.ДатаОкончания КАК EndDate,
		|	Запись.Врач КАК ResourceId
		|ИЗ
		|	Документ.ЗаписьНаПрием КАК Запись";
	
	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();
	
	Пока Выборка.Следующий() Цикл
		
		СтруктураЗаписи = Новый Структура;
		СтруктураЗаписи.Вставить("id", Строка(Выборка.ID.УникальныйИдентификатор()));
		СтруктураЗаписи.Вставить("title", Выборка.Title);
		// Форматируем даты в стандарт ISO для JavaScript
		СтруктураЗаписи.Вставить("start", Формат(Выборка.StartDate, "ДФ=yyyy-MM-ddTHH:mm:ss"));
		СтруктураЗаписи.Вставить("end", Формат(Выборка.EndDate, "ДФ=yyyy-MM-ddTHH:mm:ss"));
		СтруктураЗаписи.Вставить("resourceId", Строка(Выборка.ResourceId.УникальныйИдентификатор()));
		
		МассивЗаписей.Добавить(СтруктураЗаписи);
		
	КонецЦикла;
	
	// Сериализация в строку JSON
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, МассивЗаписей);
	СтрокаJSON = ЗаписьJSON.Закрыть();
	
	Возврат СтрокаJSON;
	
КонецФункции

Передадим полученную JSON-строку в наше поле HTML-документа на клиенте:


&НаКлиенте
Процедура ОбновитьКалендарьНаФорме()
	
	ДанныеJSON = ПолучитьДанныеЗаписейВФорматеJSON();
	
	// Вызов JavaScript-функции, определенной внутри нашего HTML-шаблона
	Элементы.ПолеКалендаря.Документ.defaultView.loadAppointments(ДанныеJSON);
	
КонецПроцедуры

Для реализации обратной связи (из веб-интерфейса обратно в базу данных 1С) используется механизм обработки событий. В коде JavaScript при перетаскивании события (например, событие eventDrop в FullCalendar) вызывается специальный внутренний метод 1С:


// Пример JavaScript кода внутри HTML-макета
calendar.on('eventDrop', function(info) {
    var eventData = {
        id: info.event.id,
        newStart: info.event.start.toISOString(),
        newEnd: info.event.end.toISOString(),
        newResource: info.event.getResources()[0] ? info.event.getResources()[0].id : ""
    };
    
    // Передаем данные в 1С
    window.external.ВызватьСобытие1С("ИзменениеЗаписи", JSON.stringify(eventData));
});

В модуле управляемой формы 1С нам достаточно настроить событие ПриНажатии (или специализированный обработчик ожидания событий) для элемента ПолеHTMLДокумента, чтобы перехватить переданные параметры, выполнить необходимые проверки прав доступа и занятости оборудования на сервере, а затем перезаписать документ.

Вариант 3. Реализация через «Табличный документ» — стоит ли использовать?

В старых конфигурациях 1С (особенно на обычных формах) расписания часто строили на базе обычного ТабличногоДокумента. Ячейки таблицы программно объединялись, раскрашивались, а текст выводился в области макета.

Рассмотрим, почему этот подход сегодня считается устаревшим:

Использовать ТабличныйДокумент для интерактивных календарей в современных конфигурациях крайне не рекомендуется. Его область применения сейчас — это исключительно печатные формы расписания врачей на день или неделю.

Резюме и рекомендации

Выбор конкретного технического решения полностью зависит от требований вашего проекта:

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

Если же вы разрабатываете тиражное решение для клиник, где интерфейс расписания является главным рабочим местом администратора (АРМ) и требует максимального удобства, интеграции с внешними сервисами, отображения сложных статусов и иконок — выбирайте связку Поле HTML-документа + FullCalendar.js. Этот подход потребует от вас базовых знаний HTML, CSS и JavaScript, но взамен предоставит неограниченные возможности по кастомизации интерфейса.

← На главную