Многие пользователи и администраторы систем на базе 1С:Розница 3.0 и 1С:УНФ 3.0 столкнулись с крайне неприятным поведением документа УстановкаЦен. Суть проблемы заключается в том, что при попытке отредактировать уже проведенный документ или даже просто при просмотре его формы, внесенные вручную значения цен бесследно исчезают, заменяясь расчетами по формулам. Рассмотрим подробнее, почему это происходит, как устроена внутренняя логика программы и какие шаги необходимо предпринять, чтобы сохранить данные в целостности.
Проанализируем стандартный сценарий работы пользователя. Предположим, у нас есть вид цены «Розничная», который рассчитывается по формуле Закупочная * 1.2. При создании документа система предлагает цену 120 рублей. Однако бизнес-логика требует установить цену 125 рублей вручную. Пользователь вносит изменения, проводит документ, и в базе данных (в регистре сведений ЦеныНоменклатуры) фиксируется верное значение — 125 рублей.
Проблемы начинаются при повторном открытии этого же документа. Рассмотрим, что видит пользователь:
Выясним причину такого «невменяемого», на первый взгляд, поведения. Оно кроется в механизме динамического пересчета цен, который был значительно переработан в линейке 3.0.
В редакциях 3.0 разработчики стремились сделать форму максимально «живой». Система постоянно отслеживает зависимости. Если вид цены помечен как рассчитываемый по формуле, форма документа считает своим долгом актуализировать это значение при любом удобном случае. Проблема в том, что в ранних релизах (3.0.11, 3.0.12) алгоритм проверки «ручного ввода» работал некорректно.
В коде формы заложены обработчики событий, такие как ПриЧтенииНаСервере и ПриОткрытии. Проанализируем ситуацию: когда форма считывает данные из базы, она видит сохраненное число. Но затем срабатывает процедура визуализации, которая проверяет правила заполнения. Если система видит активную формулу, она инициирует фоновый пересчет, полагая, что данные в табличной части устарели относительно базовых цен.
Интересной особенностью конфигураций УНФ и Розница является порог в 50 строк. Посмотрим на логику работы серверных вызовов:
Это объясняет, почему на маленьких тестовых примерах ошибка воспроизводится всегда, а на больших реальных документах поведение кажется непредсказуемым.
Первым делом проанализируем версию вашей программы. Разработчики признали наличие проблемы в механизме фиксации ручных изменений. Начиная с релизов 3.0.13.х и выше, в логику работы формы были внесены исправления:
ЦенаИзмененаВручную = Истина.Если обновление по каким-то причинам невозможно, проанализируем программный способ решения. Можно создать расширение, которое будет блокировать автоматическое заполнение для уже проведенных документов. Рассмотрим пример логики, которую следует внедрить в модуль формы документа УстановкаЦен:
&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
// Блокируем обновление цен, если документ уже проведен
Если ТекущийОбъект.Проведен Тогда
ЭтаФорма.ТолькоПросмотр = Истина;
КонецЕсли;
КонецПроцедуры
Хотя полная блокировка формы (ТолькоПросмотр) — это радикальная мера, она гарантирует, что пользователь не испортит данные случайным переключением вкладок.
Посмотрим на рекомендации опытных пользователей, которые выработали безопасный алгоритм работы в условиях нестабильного поведения формы:
Ситуация осложняется, если документ создан на основании. В этом случае в структуре документа сохраняется ссылка на документ-основание (например, поступление). При открытии формы процедура ЗаполнитьПоОснованию может вызываться неявно для обновления данных о закупке. Если в «Приходной накладной» цена изменилась хотя бы на копейку, форма «Установки цен» решит, что всю таблицу нужно пересчитать заново. Постарайтесь избегать повторного перезаполнения по основанию, если вы уже внесли значительный объем ручных правок.
Резюмируем: Основная проблема заключается в конфликте между «умной» формой, стремящейся к актуальности, и потребностью пользователя в жесткой фиксации цен. Наилучшим выходом является переход на актуальные релизы (3.0.13+), где работа с флагами ручного изменения цен была доведена до рабочего состояния.