При работе с типовыми и отраслевыми решениями 1С:Предприятие (например, 1С:Бухгалтерия предприятия 3.0 или 1С:Общепит) разработчики и администраторы часто сталкиваются с ситуацией, когда кнопка "Перезаполнить учетные количества и суммы" в документе Инвентаризация товаров на складе ведет себя не так, как ожидается: вместо обновления колонок учетных остатков она полностью очищает табличную часть и удаляет позиции, добавленные вручную.
Рассмотрим подробно, как по шагам отследить цепочку асинхронных вызовов в управляемых формах, включить отладку фоновых заданий и устранить некорректное поведение алгоритма.
Проанализируем исходный код команды формы. В современных конфигурациях на управляемых формах взаимодействие с пользователем происходит асинхронно через описания оповещений:
Процедура ПерезаполнитьУчетныеДанные(Команда)
Если Объект.Товары.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ТекстВопроса = НСтр("ru = 'Перезаполнить учетные количества и суммы? %ПредупреждениеОЗаписиДокумента%'");
ТекстВопроса = СтрЗаменить(ТекстВопроса, "%ПредупреждениеОЗаписиДокумента%",
?(Модифицированность, Символы.ПС + НСтр("ru='(Перед заполнением документ будет записан!)'"),
""));
Оповещение = Новый ОписаниеОповещения("ВопросПерезаполнитьУчетныеДанныеЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да, Заголовок);
КонецПроцедуры
Когда вы видите конструкцию Новый ОписаниеОповещения("ВопросПерезаполнитьУчетныеДанныеЗавершение", ЭтотОбъект), это значит, что при ответе пользователя на диалоговое окно платформа вызовет процедуру с именем ВопросПерезаполнитьУчетныеДанныеЗавершение, которая расположена в этом же модуле формы (так как второй параметр — ЭтотОбъект).
Найдем указанную процедуру в модуле формы. Внутри нее обычно находится обращение к серверу для запуска процедуры заполнения:
Процедура ЗаполнитьДокументНаКлиенте(НазваниеДействия)
Если ИспользуетсяОтложенноеПроведение Тогда
СтатусКорректировкиСтоимости = СтатусКорректировкиСтоимостиНоменклатуры(Объект.Организация, Объект.Дата);
ОпределитьНеобходимостьАктуализацииСебестоимости(НазваниеДействия, СтатусКорректировкиСтоимости);
Иначе
ЗаполнитьПоАктуальнымОстаткам(НазваниеДействия, Ложь);
КонецЕсли;
КонецПроцедуры
Очень часто длительные операции заполнения документов выносятся в фоновые задания с помощью общей библиотеки БСП. В коде это выглядит следующим образом:
Задание = ДлительныеОперации.ЗапуститьФоновоеЗаданиеСКонтекстомКлиента(ИмяЭкспортнойПроцедуры,
ПараметрыЭкспортнойПроцедуры, КлючЗадания, НаименованиеЗадания);
Если установить точку останова в вызываемой серверной процедуре (например, Документы.ИнвентаризацияТоваровНаСкладе.ЗаполнитьПоОстаткам), отладчик не остановится на ней по умолчанию, так как код выполняется в отдельном фоновом сеансе на сервере.
Для решения этой проблемы и перехвата выполнения кода настроим автоматическое подключение отладчика:
После включения этой опции точки останова в экспортных процедурах фоновых заданий начнут успешно срабатывать.
В ходе отладки серверной процедуры выборки остатков из регистров часто обнаруживается спорная логика обхода записей. Например, в отраслевых доработках может встречаться код следующего вида:
//+Общепит
// Пропустить группы. Группы в выборке есть при иерархической сортировке.
Если Выборка.КоличествоУчет = 0 И Выборка.СуммаДляЦены = 0 Тогда
Продолжить;
КонецЕсли;
//-Общепит
Суть проблемы: Разработчики доработки наложили условие пропуска строк с нулевым остатком без учета контекста операции. При действии "Перезаполнить учетные данные" необходимо обходить текущие строки документа и лишь обновлять расчетные колонки КоличествоУчет и СуммаУчет. Если же алгоритм выполняет полный перезапрос остатков и фильтрует нулевые значения, все вручную внесенные строки (у которых учетный остаток в системе равен нулю) отбрасываются и не попадают в итоговый результат.
Для восстановления корректной работы кнопки "Перезаполнить учетные количества и суммы" можно использовать несколько подходов:
Выборка.КоличествоУчет = 0 должна вычисляться только при первоначальном заполнении документа по остаткам (когда происходит полное формирование табличной части), но не при перезаполнении учетных сумм по существующим строкам.&Вместо или &ИзменениеИОбработка и реализовать корректное обновление колонок только для текущих строк табличной части Объект.Товары.