В процессе сопровождения и доработки конфигураций на платформе 1С:Предприятие 7.7 (например, «Торговля и Склад 7.7») разработчики нередко сталкиваются с необходимостью изменить или сбросить показатели регистра непосредственно из экранной формы справочника — например, обнулить баланс старой дисконтной карты при выдаче взамен нее новой. Рассмотрим особенности архитектуры платформы 7.7, выясним, почему прямая запись в регистр невозможна, и разберем корректные способы решения этой задачи.
Проанализируем базовый принцип работы регистров в платформе 7.7. В отличие от версии 8.x, где существуют независимые наборы записей и специализированные документы вроде корректировки записей регистров, в «семерке» действует строгое платформенное правило: запись движений в регистры возможна исключительно при проведении документа и только из предопределенной процедуры ОбработкаПроведения() в модуле документа.
У объектов типа Регистр в 1С 7.7 отсутствуют методы прямой модификации вроде Записать(). Механизм оперативного учета жестко завязан на понятиях точки актуальности (ТА) и таблицах итогов:
RA) и таблицы итогов (префикс RG).Таким образом, выполнить оператор вида «Регистр.Записать()» из модуля формы списка или элемента справочника невозможно в силу ограничений платформы.
Разберем классический, архитектурно правильный подход, который обеспечивает прозрачность учета и сохраняет целостность регистров. Создадим отдельный документ, фиксирующий факт хозяйственной операции (например, ЗаменаДисконтнойКарты).
В структуре документа предусмотрим реквизиты шапки:
СтараяКарта (тип: Справочник.ДисконтныеКарты);НоваяКарта (тип: Справочник.ДисконтныеКарты).Посмотрим на пример реализации модуля документа. В процедуре ОбработкаПроведения() считываем текущее сальдо со старой карты и переносим его на новую:
Процедура ОбработкаПроведения()
// Создаем объект регистра для получения актуального остатка
Рег = СоздатьОбъект("Регистр.ДисконтныеКарты");
Рег.УстановитьЗначениеФильтра("ДисконтнаяКарта", СтараяКарта);
ОстатокСуммы = Рег.СводныйОстаток(СтараяКарта, "Сумма");
Если ОстатокСуммы > 0 Тогда
// Списываем накопленный остаток со старой карты
ПривязкаСтроки(1);
Расход.ДисконтныеКарты(СтараяКарта, ОстатокСуммы);
// Зачисляем баланс на новую карту, если она указана
Если ПустоеЗначение(НоваяКарта) = 0 Тогда
Приход.ДисконтныеКарты(НоваяКарта, ОстатокСуммы);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратим внимание: для обнуления остатка в регистрах остатков выполняется движение Расход на сумму остатка (либо Приход с отрицательным знаком, если это предусмотрено учетной политикой). Важно понимать, что движение «Расход» само по себе уменьшает остаток, поэтому передавать в него сумму со знаком «минус» не требуется — передается положительное число текущего остатка.
Если пользователю неудобно открывать журналы документов и требуется выполнять операцию сразу из формы элемента или списка справочника, автоматизируем этот процесс. Сформируем и проведем документ полностью программно в фоновом режиме.
Разберем по шагам код вызова, который можно поместить в обработчик кнопки справочника:
Процедура ЗаменитьКартуНаНовую()
Если ПустоеЗначение(ВыбраннаяНоваяКарта) = 1 Тогда
Предупреждение("Не выбрана новая дисконтная карта!");
Возврат;
КонецЕсли;
// Создаем служебный документ в коде
Док = СоздатьОбъект("Документ.ЗаменаДисконтнойКарты");
Док.Новый();
Док.ДатаДок = ТекущаяДата();
Док.СтараяКарта = ТекущийЭлемент();
Док.НоваяКарта = ВыбраннаяНоваяКарта;
// Записываем документ и проводим его в режиме реального времени
Док.Записать();
// Флаг 1 означает оперативное проведение на Точку Актуальности (ТА)
Если Док.Провести(1) = 0 Тогда
Сообщить("Не удалось провести документ переноса остатка!", "!");
Иначе
Сообщить("Остаток успешно перенесен на новую карту.");
КонецЕсли;
КонецПроцедуры
Такой подход обеспечивает сохранение привычного для кассира или менеджера интерфейса без необходимости вручную заполнять документы, при этом база данных сохраняет строгую ссылочную целостность.
Проанализируем ситуации, когда манипуляций с движениями регистров можно полностью избежать:
Контрагенты или ФизическиеЛица), смена физического носителя не требует корректировки регистров. В этом случае в карточке новой дисконтной карты просто указывается тот же владелец, а старая карта помечается как заблокированная или удаляется. Все накопления автоматически сохраняются за покупателем.УстановитьРеквизит().