Как в 1С 7.7 создать справочник, состоящий только из групп

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе интеграции учётных систем 1С:Предприятие 7.7 с современными веб-сайтами и интернет-магазинами разработчики часто сталкиваются с архитектурным тупиком. Структура каталога товаров на сайте (в системах 1С-Битрикс, OpenCart, WooCommerce и др.) должна быть ориентирована на поисковое продвижение (SEO), удобство покупателей и маркетинговые категории. В то же время иерархия справочника Номенклатура в базе 1С построена по принципу складского учёта, удобства бухгалтерии или по поставщикам. Изменять рабочую структуру номенклатуры нельзя по внутренним причинам компании.

Отличным выходом из этой ситуации является создание альтернативного классификатора категорий. Для этого мы создаем вспомогательный справочник, который должен состоять исключительно из групп (папок), формирующих виртуальное дерево категорий сайта. К этим группам пользователи будут привязывать реальные товары. В этой статье мы подробно разберем, как технически реализовать справочник, в котором запрещено создавать элементы, а разрешено создавать только группы, и рассмотрим все сопутствующие проблемы платформы 1С 7.7.

Почему нельзя просто использовать стандартный справочник?

В платформе 1С:Предприятие 7.7 в конфигураторе нет стандартного флажка «Разрешить только группы». Мы можем легко запретить создание групп (задав количество уровней иерархии равным 1), но запретить создание элементов «из коробки» система не позволяет. Если оставить справочник как есть, пользователи неизбежно начнут путаться и создавать обычные элементы вместо папок-категорий, что нарушит логику выгрузки на сайт.

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

Шаг 1. Интерактивный запрет в модуле формы элемента

Первое, с чем сталкивается пользователь при попытке создать новый элемент справочника, — это открытие формы элемента. Мы можем перехватить это действие на самом раннем этапе с помощью предопределенной процедуры ВводНового().

Рассмотрим, как это сделать. Нам необходимо открыть конфигуратор, найти наш вспомогательный справочник (например, СтруктураСайта), зайти в свойства формы элемента и открыть её модуль. Впишем туда следующий код:


Процедура ВводНового(ИмяШаблона, ОбъектКопирования)
    Предупреждение("В данном справочнике разрешено создавать только группы (папки)!");
    СтатусВозврата(0);
    Возврат;
КонецПроцедуры

Выясним причину, почему это работает. Когда пользователь нажимает клавишу «Insert» или кнопку «Добавить элемент», система пытается создать новый элемент и инициализировать форму. Вызов функции СтатусВозврата(0) сообщает платформе 1С 7.7 о необходимости отменить текущее действие. В результате форма элемента даже не откроется, а пользователь получит понятное предупреждение.

Шаг 2. Отключение редактирования в списке

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

Чтобы исключить эту лазейку, выполним следующие действия в Конфигураторе:

  1. Откроем окно редактирования свойств нашего справочника.
  2. Перейдем на вкладку «Формы».
  3. Найдем параметр «Редактирование в списке» и снимем с него флажок (установим значение в «Форме»).

Теперь создание и редактирование любых объектов справочника будет происходить строго через диалоговые формы, что гарантирует вызов нашего обработчика ВводНового().

Шаг 3. Защита на уровне базы данных (Модуль справочника)

Ограничения на уровне экранных форм защищают базу данных только от интерактивных действий обычных пользователей. Но что делать, если в системе работают внешние обработки, механизмы загрузки данных из Excel или XML-файлов? Программный код вида Спр.Новый() не открывает формы, а значит, легко обойдет все наши запреты в модуле формы.

Для создания полноценной защиты («защиты от дурака» на уровне СУБД) нам необходимо перенести логику проверки в Модуль справочника. Этот модуль выполняется всегда при попытке записи объекта в базу данных, независимо от того, как именно происходит запись — интерактивно или программно.

Откроем Модуль справочника в конфигураторе и добавим предопределенную процедуру ПриЗаписи():


Процедура ПриЗаписи()
    // Проверяем, является ли записываемый объект элементом или группой
    Если ЭтоГруппа() = 0 Тогда
        Предупреждение("Критическая ошибка: Создание элементов в справочнике категорий запрещено на уровне СУБД!");
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
КонецПроцедуры

Проанализируем работу этого механизма. Метод ЭтоГруппа() возвращает 1, если записываемый объект является папкой (группой), и 0, если это конечный элемент. Если проверка определяет элемент, инструкция СтатусВозврата(0) отменяет транзакцию записи объекта в базу данных. Таким образом, ни один сторонний программный код не сможет засорить наш справочник ошибочными элементами.

Шаг 4. Настройка удобного выбора групп в интерфейсе

Когда мы успешно ограничили справочник только группами, возникает следующая практическая задача: как пользователи будут работать с этим справочником при связывании его с номенклатурой?

Допустим, в карточке товара (справочник Номенклатура) мы создали реквизит КатегорияСайта с типом ссылки на наш новый справочник. Когда пользователь нажмет кнопку выбора (три точки), откроется форма списка нашего справочника категорий. По умолчанию в 1С 7.7 двойной клик по группе не выбирает её, а просто открывает её содержимое (заходит внутрь папки).

Посмотрим, как переопределить это поведение платформы, чтобы сделать выбор папок удобным. Для этого откроем модуль формы списка нашего справочника (формы выбора) и в процедуре ПриОткрытии() пропишем специальную директиву:


Процедура ПриОткрытии()
    // Проверяем, открыта ли форма в режиме выбора значения
    Если Форма.РежимВыбора() = 1 Тогда
        // Разрешаем интерактивный выбор групп вместо захода внутрь
        ВыборГруппы(1);
    КонецЕсли;
КонецПроцедуры

Благодаря функции ВыборГруппы(1), платформа меняет поведение: теперь при двойном щелчке мыши по папке (или при нажатии клавиши Enter) группа будет сразу возвращаться в качестве выбранного значения в поле карточки номенклатуры.

Шаг 5. Обход проблемы «Черного запроса» 1С 7.7 при работе с пустыми группами

Создав справочник, полностью состоящий из групп, вы обязательно столкнетесь с фундаментальным ограничением встроенного языка запросов 1С 7.7. Стандартный механизм запросов платформы (так называемый «черный запрос») проектировался для бухгалтерских целей. Из-за этого встроенные запросы принципиально не выбирают пустые группы справочника (папки, внутри которых физически нет подчиненных элементов).

Если вы попытаетесь выгрузить структуру сайта через стандартный Запрос, он вернет пустой результат, так как в нашем справочнике по определению нет и не может быть элементов! Как решить эту проблему?

Решение А. Использование объектной модели (ВыбратьЭлементы)

Самый простой способ обойти это ограничение в файловом варианте базы данных (DBF) — отказаться от использования запросов и применить последовательный перебор элементов справочника через объектную модель. Для этого мы используем метод ВыбратьЭлементы() с параметром отключения иерархии:


Процедура ВыгрузитьСтруктуруСайта()
    Спр = СоздатьОбъект("Справочник.СтруктураСайта");
    
    // Передаем параметр 0, чтобы обходить справочник линейно, без учета вложенности
    Спр.ВыбратьЭлементы(0);
    
    Пока Спр.ПолучитьЭлемент() = 1 Цикл
        // Дополнительно страхуемся проверкой на группу
        Если Спр.ЭтоГруппа() = 1 Тогда
            КодКатегории = Спр.Код;
            НаименованиеКатегории = Спр.Наименование;
            РодительКатегории = Спр.Родитель;
            
            Сообщить("Экспорт категории: " + НаименованиеКатегории + " (Код: " + КодКатегории + ")");
            // Здесь пишем код записи в XML, JSON или отправки по API на сайт
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Рассмотрим подробнее данный подход. Передача нуля в метод ВыбратьЭлементы(0) заставляет систему сканировать таблицу справочника «плоским» списком. Это работает чрезвычайно быстро и гарантирует, что мы получим абсолютно все группы, даже если они созданы «на вырост» и пока не имеют привязанных товаров.

Решение Б. Прямой SQL-запрос (для SQL-версий баз данных)

Если ваша база данных 1С 7.7 работает на Microsoft SQL Server, либо если вы используете внешние компоненты класса 1С++, лучшим и наиболее производительным решением будет использование прямого SQL-запроса к таблице справочника.

В физических таблицах СУБД группы и элементы хранятся вместе, а признак группы определяется флагом в поле ISFOLDER. Прямой SQL-запрос полностью игнорирует внутренние ограничения логики «черных запросов» 1С. Пример написания такого запроса с использованием компоненты 1С++ выглядит следующим образом:


// Пример получения структуры папок через прямой SQL-запрос
Рекордсет = СоздатьОбъект("ODBCРекордсет");
ТекстЗапроса = "
|SELECT 
|    ID as [Ссылка $Справочник.СтруктураСайта],
|    DESCR as Наименование,
|    PARENTID as [Родитель $Справочник.StructureSaita]
|FROM 
|    $Справочник.СтруктураСайта
|WHERE 
|    ISFOLDER = 1
|";

ТаблицаКатегорий = Рекордсет.ВыполнитьИнструкцию(ТекстЗапроса);
// В результате мы получаем чистую таблицу значений со всеми группами

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

Альтернативный подход: Структура без создания нового справочника

Давайте проанализируем ситуацию: всегда ли оправдано создание отдельного справочника? Иногда это может усложнить поддержку информационной базы. Существует альтернативный вариант реализации множественной иерархии категорий без заведения нового объекта метаданных.

Мы можем использовать дополнительный реквизит внутри существующего справочника Номенклатура. Этот реквизит будет иметь тип «Справочник.Номенклатура» (самостоятельная ссылка на элемент этого же справочника), но при этом программно ограничиваться выбором только групп. Таким образом, каждый товар получит поле «Родитель для сайта», указывающее на виртуальную папку в едином справочнике номенклатуры. Это позволяет избежать дублирования объектов и заведения лишних сущностей в конфигурации.

Подведем итоги

Мы подробно разобрали задачу создания справочника только из групп в платформе 1С 7.7. Для реализации этой схемы нам потребовалось объединить несколько защитных механизмов:

Используя предложенные инструкции, вы сможете построить гибкую, отказоустойчивую архитектуру для интеграции вашей базы 1С:Предприятия 7.7 с любыми внешними веб-ресурсами и сервисами.

← На главную