Как в 1С реализовать ввод произвольного текста в поле «Склад» без изменения типа реквизита

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

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

Анализ ситуации и постановка задачи

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

Основные подходы к решению:

  1. Использование «теневого» реквизита для хранения строки.
  2. Виртуальное поле на форме с программной обработкой записи.
  3. Применение механизма дополнительных реквизитов (БСП).
  4. Использование предопределенного элемента-заглушки.

Решение 1: Подмена реквизитов на управляемой форме

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

Рассмотрим алгоритм реализации по шагам:

  1. Добавим в документ новый реквизит СкладНаименованиеСтрока с типом Строка (100). Он будет реально хранить текст в базе.
  2. На управляемой форме документа создадим реквизит формы (не путать с реквизитом объекта!) СкладДляФормы с составным типом: СправочникСсылка.Склады и Строка.
  3. Разместим СкладДляФормы на месте стандартного поля склада.

Теперь проанализируем программную логику в модуле формы. Нам нужно обеспечить связку при открытии и сохранении документа.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Если ссылка на склад заполнена, показываем её, иначе — текст
    Если ЗначениеЗаполнено(Объект.Склад) Тогда
        СкладДляФормы = Объект.Склад;
    Иначе
        СкладДляФормы = Объект.СкладНаименованиеСтрока;
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // Распределяем данные из виртуального поля в реальные реквизиты
    Если ТипЗнч(СкладДляФормы) = Тип("Строка") Тогда
        ТекущийОбъект.СкладНаименованиеСтрока = СкладДляФормы;
        // Чтобы не ломать логику проведения, можно очистить ссылку 
        // или заполнить её «Складом по умолчанию»
        ТекущийОбъект.Склад = Справочники.Склады.ПустаяСсылка(); 
    Иначе
        ТекущийОбъект.Склад = СкладДляФормы;
        ТекущийОбъект.СкладНаименованиеСтрока = "";
    КонецЕсли;
КонецПроцедуры

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

Решение 2: Использование «виртуального» склада и комментария

Если задача пользователя — просто видеть правильное название в печатной форме, мы можем предложить более простой путь, не требующий создания новых реквизитов в метаданных (если это критично). Проанализируем ситуацию: пользователь может выбрать в поле склад значение «Прочие склады» (созданный нами элемент справочника), а в стандартном поле Комментарий написать уточнение.

Для реализации этого подхода выполним следующее:

  1. Создадим в справочнике Склады элемент с наименованием "Ввод вручную" или "Прочие".
  2. В модуле менеджера документа или в обработке печати изменим логику вывода.

Посмотрим на пример кода для модификации печатной формы:


// В процедуре формирования печатной формы
ПредставлениеСклада = "";
Если Объект.Склад = Справочники.Склады.НайтиПоНаименованию("Прочие") Тогда
    // Если выбран спец-склад, берем название из комментария или доп. реквизита
    ПредставлениеСклада = Объект.Комментарий; 
Иначе
    ПредставлениеСклада = СокрЛП(Объект.Склад.Наименование);
КонецЕсли;
ОбластьМакета.Параметры.СкладНазвание = ПредставлениеСклада;

Этот метод — самый безопасный для системы. Он не раздувает базу данных, не меняет структуру индексов SQL и гарантирует, что при обмене данными (например, в Бухгалтерию) документ не «отвалится» из-за неверного типа данных.

Решение 3: Дополнительные реквизиты (механизм БСП)

Если ваша конфигурация использует «Библиотеку стандартных подсистем» (БСП), то лучшим решением будет использование механизма Дополнительных реквизитов. Проанализируем преимущества: вам не нужно менять конфигурацию в конфигураторе, всё настраивается в пользовательском режиме.

Выясним, как это работает:

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

Технические риски и последствия для базы данных

Рассмотрим подробнее, почему разработчики 1С так сопротивляются превращению ссылочных полей в строковые. Выясним причину через архитектуру хранения данных в SQL.

1. Структура таблиц SQL. При использовании составного типа данных (Ссылка + Строка) вместо одной колонки _Fld123RRef в базе SQL создаются три: _Fld123_TYPE (тип), _Fld123_RRef (идентификатор ссылки) и _Fld123_S (сама строка). Это увеличивает объем данных и замедляет выполнение запросов.

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

3. Сходимость данных. Проанализируем человеческий фактор. Пользователь напишет «Склад 1», «склад 1», «Склад №1» и «Склад 1 » (с пробелом). Для 1С это четыре разных склада. При попытке построить отчет вы получите «чехарду» данных, которую невозможно будет свести автоматически. Именно поэтому рекомендуется всегда настаивать на заведении элементов в справочнике.

Рекомендации для внедренца

Прежде чем приступать к кодингу, проведем «воспитательную беседу» с заказчиком. Важно объяснить, что 1С — это не печатная машинка, а система учета. Предложите пользователю альтернативу:

Таким образом, мы рассмотрели несколько путей решения задачи. Самым надежным является использование дополнительных реквизитов или подмена поля на форме с сохранением данных в отдельную строку. Это позволяет избежать «мусора» в аналитических отчетах и при этом дает пользователю необходимую свободу ввода.

← На главную