При переносе доработок из основной конфигурации в расширение программисты часто сталкиваются с ситуацией, когда простые на первый взгляд изменения свойств метаданных не работают. Типичный пример — необходимость разрешить ввод отрицательных чисел для реквизита табличной части, у которого в типовом решении стоит флаг «Неотрицательное». Разберем подробно, почему это происходит и как правильно реализовать задачу, учитывая ограничения различных версий платформы 1С:Предприятие.
Первым делом проанализируем ситуацию, описанную в обращении. Основная сложность заключается в версии платформы (8.3.13) и установленном режиме совместимости (8.3.12). В экосистеме 1С режим совместимости определяет доступный функционал механизмов расширений. До версии 8.3.15 возможности по изменению типов данных и их квалификаторов в расширениях были крайне жесткими.
Свойство Неотрицательное не является просто визуальной «галкой» в интерфейсе. Это часть определения типа Число, входящая в состав его квалификаторов. Когда мы заимствуем реквизит в расширение, платформа ожидает, что описание типа в расширении будет полностью идентично описанию в основной конфигурации. В режиме совместимости 8.3.12 попытка изменить квалификатор (снять флаг Неотрицательное) воспринимается системой как конфликт типов. В результате, даже если вам удастся сохранить расширение, изменения либо не вступят в силу, либо приведут к ошибкам при обновлении конфигурации базы данных.
Рассмотрим ситуацию глубже, на уровне системы управления базами данных (СУБД). Когда в основной конфигурации у числового реквизита стоит признак Неотрицательное, платформа при создании таблиц в SQL может накладывать соответствующие ограничения. Физическая структура таблиц определяется основной конфигурацией. Расширение не всегда может динамически перестроить колонку в SQL-таблице, чтобы она начала принимать отрицательные значения, если «базовый» слой этого не предполагает.
Выясним причину, почему простые действия в форме не помогают: даже если вы программно разрешите ввод минуса в поле ввода, при попытке записи объекта сработает системная проверка типа данных. Платформа 1С перед записью в базу сверяет значения с метаданными основной конфигурации, и если там стоит жесткий запрет на отрицательные числа, данные будут либо обрезаны (минус пропадет), либо возникнет ошибка нарушения целостности.
Прежде чем переходить к сложным методам, убедимся, что расширение вообще работает корректно. Проанализируем настройки, упомянутые в обсуждении:
Активно. Без этого расширение просто не подгружается в сеанс пользователя.Безопасный режим. Если этот флаг стоит, расширение работает в ограниченном окружении.Если режим совместимости вашей конфигурации выше 8.3.15, вы можете попробовать изменить свойства непосредственно в расширении формы. Разберем по шагам, как это сделать:
Добавим форму документа в расширение. Найдем нужный элемент (поле ввода), связанный с реквизитом табличной части. Посмотрим в палитру свойств. Нас интересует раздел Параметры выбора или Ограничение типа. Попробуйте снять флаг Неотрицательное там. Однако, помните: этот метод сработает только в том случае, если сама база данных готова принять такое значение.
Поскольку в режиме совместимости 8.3.12 изменить тип заимствованного реквизита практически невозможно, рассмотрим самый надежный способ решения задачи — создание «параллельного» реквизита. Этот метод позволяет обойти ограничения платформы, не нарушая целостность основной конфигурации.
Шаг 1. Создание собственного реквизита.
В расширении найдем нужную табличную часть документа и добавим в нее новый реквизит, например, с именем Сумма_Расширение. Для этого реквизита сразу установим тип Число нужной длины и точности, и обязательно снимем галочку Неотрицательное.
Шаг 2. Подмена в интерфейсе.
Добавим форму документа в расширение. Выполним следующие действия:
Сумма.Видимость в значение Ложь (скроем его от пользователя).Сумма_Расширение и разместим его на месте старого поля. Для пользователя визуально ничего не изменится, кроме возможности вводить минус.Шаг 3. Синхронизация данных.
Теперь нам нужно обеспечить связь между нашим новым полем и логикой документа. Рассмотрим программную реализацию в модуле формы или модуля объекта (через расширение):
Проанализируем ситуацию: если типовые алгоритмы конфигурации (например, проведение документа) используют значение стандартного реквизита Сумма, нам нужно передавать туда данные из нашего расширенного реквизита. Но так как стандартный реквизит не принимает минус, нам придется адаптировать и логику расчетов.
Пример кода для синхронизации в модуле формы (событие ПриЧтенииНаСервере):
&НаСервере
Процедура Расш1_ПриЧтенииНаСервереПосле(ТекущийОбъект)
// Заполняем наши расширенные реквизиты данными из базы при открытии формы
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
СтрокаТЧ.Сумма_Расширение = СтрокаТЧ.Сумма;
КонецЦикла;
КонецПроцедуры
И пример обработки перед записью, чтобы сохранить данные:
&НаКлиенте
Процедура Расш1_ПередЗаписьюПеред(Отказ, ПараметрыЗаписи)
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
// Если значение положительное, можем продублировать в типовой реквизит
Если СтрокаТЧ.Сумма_Расширение >= 0 Тогда
СтрокаТЧ.Сумма = СтрокаТЧ.Сумма_Расширение;
Иначе
// Если отрицательное — в типовой пишем 0 или используем логику расширения
СтрокаТЧ.Сумма = 0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Разберем преимущества данного подхода. Во-первых, вы не вступаете в конфликт с ядром платформы 1С и требованиями режима совместимости 8.3.12. Во-вторых, вы гарантируете, что при обновлении типовой конфигурации ваши данные не «побьются», так как они хранятся в отдельной колонке, созданной расширением. СУБД корректно создаст новую колонку с разрешением отрицательных чисел, так как это новый объект метаданных, а не изменение существующего.
Важный нюанс: Если отрицательные значения должны участвовать в типовых движениях (например, по регистрам накопления), вам также потребуется расширить соответствующие модули проведения (ОбработкаПроведения), чтобы алгоритмы учитывали данные из Сумма_Расширение вместо стандартной Сумма.
Проанализировав проблему, мы пришли к выводу, что в режиме совместимости 8.3.12 прямое изменение свойства Неотрицательное у заимствованных объектов заблокировано на уровне платформы. Наиболее эффективным и безопасным методом является добавление собственного реквизита в расширение с последующей подменой элементов на форме. Это требует больше кода для синхронизации данных, но обеспечивает стабильную работу системы и корректное хранение отрицательных значений в базе данных.