Нам предстоит решить интересную задачу по созданию интерактивного плана размещения квартир в конфигурации 1С 8. Этот план должен не только визуализировать расположение квартир в многоэтажном доме, но и обеспечивать динамическое взаимодействие: при наведении курсора на каждую квартиру должно появляться всплывающее сообщение, а при клике — создаваться определенный документ. Разберем возможные подходы и выберем наиболее подходящий для полноценной реализации всех требований.
Этот подход является наиболее гибким и мощным, позволяющим реализовать все заявленные требования к интерактивности. ПолеHTMLДокумента в 1С представляет собой встроенный браузер на движке Webkit, что открывает двери для использования полноценных веб-технологий: HTML, CSS и JavaScript.
Сам графический план этажа с изображением квартир удобно создавать в формате SVG (Scalable Vector Graphics). SVG — это векторный формат, который обладает рядом преимуществ: он масштабируется без потери качества, его можно редактировать как в графических редакторах (например, Inkscape, Adobe Illustrator), так и непосредственно в текстовом виде, что важно для программной генерации или изменения элементов.
<rect> или многоугольником <polygon>). Каждому такому элементу желательно присвоить уникальный идентификатор (атрибут id), который будет соответствовать идентификатору квартиры в базе 1С.ПолеHTMLДокумента. Это можно сделать различными способами:
ПолеHTMLДокумента.УстановитьТекст().ПолеHTMLДокумента.УстановитьДокумент().Для обработки событий наведения курсора и кликов нам понадобится JavaScript, который будет выполняться внутри ПолеHTMLДокумента.
Всплывающие подсказки (тултипы) при наведении на квартиру реализуем с помощью комбинации CSS и JavaScript. При наведении на SVG-элемент, соответствующий квартире, JavaScript может динамически изменять его стиль или отображать заранее подготовленный HTML-элемент с информацией.
Рассмотрим пример концептуального JS-кода, который может быть размещен в HTML-файле, загружаемом в ПолеHTMLДокумента:
<!-- HTML с SVG для плана -->
<svg width="800" height="600">
<!-- Пример квартиры -->
<rect x="50" y="50" width="100" height="80" fill="#f0f0f0" stroke="#333" class="apartment" data-apartment-id="КВ00001"></rect>
<text x="70" y="90" fill="#000">КВ1</text>
<!-- ... другие квартиры ... -->
</svg>
<div id="tooltip" style="position: absolute; display: none; background: #ffffcc; border: 1px solid #ccc; padding: 5px; z-index: 1000;"></div>
<script>
// Пример JS-кода для SVG-элементов
document.addEventListener('DOMContentLoaded', function() {
const apartments = document.querySelectorAll('.apartment'); // Предположим, у квартир есть класс 'apartment'
const tooltip = document.getElementById('tooltip');
apartments.forEach(apartment => {
apartment.addEventListener('mouseenter', function(event) {
// Получаем данные о квартире из атрибутов (например, data-apartment-id)
const apartmentId = this.dataset.apartmentId;
// В реальном приложении здесь могли бы быть AJAX-запросы к 1С
// или данные могли бы быть предварительно загружены в JS-переменную
const apartmentInfo = getApartmentInfo(apartmentId); // Функция получения данных
// Обновляем и отображаем всплывающую подсказку
tooltip.innerHTML = `<strong>Квартира №${apartmentInfo.number}</strong><br>
Этаж: ${apartmentInfo.floor}<br>
Площадь: ${apartmentInfo.area} м²<br>
Статус: ${apartmentInfo.status}`;
tooltip.style.display = 'block';
tooltip.style.left = (event.clientX + 10) + 'px';
tooltip.style.top = (event.clientY + 10) + 'px';
this.style.fill = '#ccffcc'; // Подсвечиваем квартиру при наведении
});
apartment.addEventListener('mouseleave', function() {
tooltip.style.display = 'none';
this.style.fill = '#f0f0f0'; // Возвращаем исходный цвет
});
});
// Функция-заглушка для получения данных о квартире (в реальном приложении данные берутся из 1С)
function getApartmentInfo(id) {
// Здесь можно было бы сделать вызов серверной функции 1С
// для получения актуальных данных по ID квартиры, например, через AJAX
// Для примера используем статические данные
const data = {
'КВ00001': { number: '1', floor: 1, area: 55, status: 'Свободна' },
'КВ00002': { number: '2', floor: 1, area: 70, status: 'Забронирована' }
// ... другие квартиры
};
return data[id] || { number: id, floor: '?', area: '?', status: 'Неизвестен' };
}
});
</script>
Самая интересная часть — это взаимодействие между JavaScript в браузере и кодом 1С. При клике на SVG-элемент (квартиру) нам необходимо передать информацию о ней в 1С, чтобы там создать соответствующий документ. Для этого используем механизм взаимодействия ПолеHTMLДокумента с контекстом 1С.
В JavaScript-коде мы можем вызвать метод ВнешниеФункции.ИмяВашейФункцииВ1С(параметры), где ВнешниеФункции — это специальный объект, через который 1С предоставляет свои методы в JavaScript-окружение.
Разберем по шагам, как настроить это взаимодействие:
ПолеHTMLДокумента: Создаем клиентскую процедуру, которая будет вызываться из JavaScript, и серверную процедуру, которая выполнит создание документа. Также важно зарегистрировать клиентскую процедуру для доступа из JavaScript.Пример кода в модуле формы 1С:
// В модуле формы, на клиенте
&НаСервере
Процедура ПриКвартиреКликНаСервере(ИД_КвартирыСтрока)
// Здесь можно получить объект квартиры по ИД_КвартирыСтрока
// Например, найти элемент справочника "Квартиры" по коду или наименованию
КвартираСсылка = Справочники.Квартиры.НайтиПоКоду(ИД_КвартирыСтрока);
Если КвартираСсылка.Пустая() Тогда
ЗаписьЖурналаРегистрации(
"ПланКвартир",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Не найдена квартира по идентификатору: " + ИД_КвартирыСтрока
);
Возврат;
КонецЕсли;
// Создаем новый документ, например, "ДоговорАренды"
НовыйДокумент = Документы.ДоговорыАренды.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Квартира = КвартираСсылка;
НовыйДокумент.Организация = Организация; // Пример заполнения
НовыйДокумент.Ответственный = Пользователи.ТекущийПользователь();
// ... заполнение других реквизитов ...
Попытка
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ '" + НовыйДокумент + "' успешно создан для квартиры " + ИД_КвартирыСтрока);
// Открываем форму созданного документа для дальнейшего заполнения
ФормаДокумента = НовыйДокумент.ПолучитьФорму();
ФормаДокумента.Открыть();
Исключение
ЗаписьЖурналаРегистрации(
"ПланКвартир",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Ошибка при создании документа для квартиры " + ИД_КвартирыСтрока + ": " + ОписаниеОшибки()
);
Сообщить("Не удалось создать документ: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
// Клиентская процедура, которая будет вызываться из JavaScript
&НаКлиенте
Процедура ПриКвартиреКлик(ИД_КвартирыСтрока)
// Вызов серверной процедуры.
// ИД_КвартирыСтрока будет передано из JavaScript.
ПриКвартиреКликНаСервере(ИД_КвартирыСтрока);
КонецПроцедуры
// В обработчике события "ПриСозданииНаСервере" или "ПриОткрытии" формы
// мы регистрируем клиентскую процедуру для доступа из JavaScript
&НаКлиенте
Процедура ПриСозданииНаСервере(Отказ)
// Инициализация данных для поля HTML
// ...
// После того как ПолеHTMLДокумента будет создано и загружено
// регистрируем нашу функцию для JavaScript
// Обращение к объекту parentWindow необходимо для Webkit в 1С
// Если в вашей версии 1С работает прямой доступ через Документ,
// можно попробовать `Элементы.ПолеHTMLДокумента.Документ.ВнешниеФункции`
Если Элементы.ПолеHTMLДокумента.Документ.parentWindow <> Неопределено Тогда
Элементы.ПолеHTMLДокумента.Документ.parentWindow.ВнешниеФункции.ПриКвартиреКлик = Новый ЗащищеннаяПроцедура("ПриКвартиреКлик");
Иначе
Сообщить("Не удалось зарегистрировать функцию 'ПриКвартиреКлик' для JavaScript. Проверьте версию платформы и настройки ПоляHTMLДокумента.");
КонецЕсли;
КонецПроцедуры
ПолеHTMLДокумента: Добавляем обработчик клика, который вызывает зарегистрированную функцию 1С.Пример кода в HTML/JS:
<!-- Внутри тега <script> вашего HTML-файла -->
document.addEventListener('DOMContentLoaded', function() {
const apartments = document.querySelectorAll('.apartment');
apartments.forEach(apartment => {
apartment.addEventListener('click', function(event) {
const apartmentId = this.dataset.apartmentId; // Получаем ID квартиры из data-атрибута
// Вызываем функцию 1С через объект ВнешниеФункции
// Обратите внимание на window.parentWindow - это часто необходимо в 1С
if (window.parentWindow && window.parentWindow.ВнешниеФункции && window.parentWindow.ВнешниеФункции.ПриКвартиреКлик) {
window.parentWindow.ВнешниеФункции.ПриКвартиреКлик(apartmentId);
} else if (window.ВнешниеФункции && window.ВнешниеФункции.ПриКвартиреКлик) { // Запасной вариант для некоторых сценариев
window.ВнешниеФункции.ПриКвартиреКлик(apartmentId);
} else {
console.error('Функция 1С ПриКвартиреКлик не найдена или недоступна в контексте JavaScript!');
alert('Ошибка: Не удалось связаться с 1С для создания документа.');
}
});
});
});
Критически важный момент: Точный способ регистрации и вызова внешних функций может немного отличаться в зависимости от версии платформы 1С и нюансов конфигурации. Всегда рекомендуется обращаться к официальной документации 1С по взаимодействию с ПолеHTMLДокумента. Также следует учитывать сериализацию данных, если передаются сложные объекты, а не простые строки.
Преимущества:
Недостатки:
ТабличныйДокумент — это более "родной" для 1С способ визуализации данных, который также может быть использован для отображения плана. Он проще в освоении для 1С-разработчиков, но имеет существенные ограничения в интерактивности.
Мы можем "нарисовать" план этажа, используя ячейки табличного документа. Каждой ячейке или группе ячеек можно задать границы, фон, текст, таким образом формируя изображение квартир. Это похоже на создание макета отчета.
ТабличныйДокумент.ПолеТабличногоДокумента и выводим в него заполненный макет.Для обработки кликов по "квартирам" в табличном документе используем событие ОбработкаРасшифровки элемента ПолеТабличногоДокумента.
Рассмотрим пример кода в модуле формы 1С:
// В модуле формы
Процедура ПолеТабличногоДокументаОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку, чтобы полностью контролировать поведение
Если ТипЗнч(Расшифровка) = Тип("Строка") Тогда
// Предполагаем, что расшифровка содержит ID квартиры
ИД_Квартиры = Расшифровка;
Сообщить("Кликнули по квартире с ID: " + ИД_Квартиры);
// Здесь вызываем серверную процедуру для создания документа
СоздатьДокументПоКвартире(ИД_Квартиры);
ИначеЕсли ТипЗнч(Расшифровка) = Тип("ПараметрыРасшифровкиКомпоновкиДанных") Тогда
// Если расшифровка пришла от СКД, работаем с ней по-другому
// Например, ищем нужный параметр
Для Каждого Параметр Из Расшифровка.Параметры Цикла
Если Параметр.Имя = "ИД_Квартиры" Тогда
ИД_Квартиры = Параметр.Значение;
Сообщить("Кликнули по квартире с ID (из СКД): " + ИД_Квартиры);
СоздатьДокументПоКвартире(ИД_Квартиры);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СоздатьДокументПоКвартире(ИД_Квартиры)
// Логика создания документа аналогична примеру с HTML-полем
КвартираСсылка = Справочники.Квартиры.НайтиПоКоду(ИД_Квартиры);
Если КвартираСсылка.Пустая() Тогда
ЗаписьЖурналаРегистрации(
"ПланКвартир",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Не найдена квартира по идентификатору: " + ИД_Квартиры
);
Возврат;
КонецЕсли;
НовыйДокумент = Документы.ДоговорыАренды.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Квартира = КвартираСсылка;
НовыйДокумент.Записать();
Сообщить("Документ создан для квартиры " + ИД_Квартиры);
ФормаДокумента = НовыйДокумент.ПолучитьФорму();
ФормаДокумента.Открыть();
КонецПроцедуры
Всплывающие подсказки: Реализация всплывающих подсказок при наведении курсора в табличном документе значительно сложнее или вовсе невозможна стандартными средствами без использования низкоуровневых механизмов или внешних компонентов, что противоречит простоте этого подхода.
Преимущества:
Недостатки:
1С:Предприятие предлагает объект ГрафическаяСхема, который обычно используется для визуализации бизнес-процессов или блок-схем. Теоретически его можно приспособить для отрисовки плана.
Мы можем создавать элементы (прямоугольники, текст) на графической схеме, представляющие квартиры. Схема может быть сохранена в виде файла *.grs или храниться в базе данных как двоичные данные.
Однако, ГрафическаяСхема имеет очень ограниченные возможности по интерактивности. Стандартные средства не позволяют легко реализовать всплывающие подсказки при наведении или сложные обработчики кликов с передачей данных для создания документов на уровне отдельных графических элементов "квартир". Этот инструмент более подходит для статической визуализации или управления потоками, чем для сложной интерактивной карты.
Как было отмечено на форуме, для задач, которые "не 1С-ные", часто более правильным и менее трудоемким решением является использование специализированного стороннего программного обеспечения или онлайн-сервисов. Существуют планировщики квартир, CAD-системы или графические редакторы, которые могут создавать детальные и интерактивные планы.
Интеграция с 1С в этом случае будет происходить через API (интерфейсы программирования приложений), если таковые предоставляются сторонними системами. 1С может отправлять или получать данные, а пользователь будет взаимодействовать с планом во внешней программе/сервисе.
Преимущества:
Недостатки:
Существуют типовые и отраслевые решения 1С, которые демонстрируют похожий функционал, что подтверждает принципиальную возможность реализации таких задач:
Исходя из требований к всплывающим сообщениям при наведении и созданию документов по клику, наиболее подходящим и функциональным подходом является использование ПоляHTMLДокумента в сочетании с SVG и JavaScript. Этот метод предоставляет максимальную гибкость и интерактивность, хотя и требует дополнительных компетенций в веб-разработке.
Если интерактивность ограничена только кликами, а внешний вид плана может быть упрощен, то ТабличныйДокумент может быть более быстрым в реализации, но с существенными компромиссами в пользовательском опыте, особенно отсутствием всплывающих подсказок при наведении.
ГрафическаяСхема наименее подходит для данной задачи из-за ограниченной интерактивности и возможностей по визуализации сложного плана.
В конечном итоге, выбор зависит от конкретных требований к детализации, бюджету на разработку и доступных компетенций команды. Для полноценной реализации всех запрошенных возможностей рекомендуем углубиться в изучение взаимодействия 1С с JavaScript через ПолеHTMLДокумента. Мы рекомендуем также рассмотреть опыт уже существующих отраслевых решений 1С, которые используют схожие подходы.