В процессе разработки собственной конфигурации на платформе 1С:Предприятие 8.3 часто возникает задача автоматизации ввода данных. Типичный пример — создание документа Оприходование товаров на основании проведенной инвентаризации. Мы разберем, как правильно связать эти объекты, чтобы упростить работу пользователя и исключить ошибки ручного ввода.
Для решения этой задачи нам потребуется задействовать несколько механизмов платформы: механизм ввода на основании, работу с запросами и обработку событий формы. Рассмотрим каждый этап подробно.
Первым делом проанализируем самый правильный с точки зрения архитектуры 1С способ — использование стандартного обработчика ОбработкаЗаполнения. Этот метод срабатывает, когда пользователь нажимает кнопку «Создать на основании» или когда документ создается программно с передачей основания.
Разберем алгоритм действий в конфигураторе:
ОприходованиеТоваров.ИнвентаризацияТоваров (или наоборот, в оприходовании укажем инвентаризацию как основание).Посмотрим на пример кода, который должен появиться в модуле объекта ОприходованиеТоваров. Важно помнить, что в оприходование должны попадать только те позиции, по которым выявлен излишек (фактическое количество больше учетного).
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ИнвентаризацияТоваров") Тогда
// Заполняем реквизиты шапки
ЭтотОбъект.Склад = ДанныеЗаполнения.Склад;
ЭтотОбъект.Организация = ДанныеЗаполнения.Организация;
ЭтотОбъект.ДокументОснование = ДанныеЗаполнения;
// Очищаем табличную часть перед заполнением
ЭтотОбъект.Товары.Очистить();
// Используем запрос для получения только излишков
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ИнвентаризацияТоваровТовары.Номенклатура КАК Номенклатура,
| ИнвентаризацияТоваровТовары.Количество - ИнвентаризацияТоваровТовары.КоличествоУчет КАК КоличествоИзлишек,
| ИнвентаризацияТоваровТовары.Цена КАК Цена
|ИЗ
| Документ.ИнвентаризацияТоваров.Товары КАК ИнвентаризацияТоваровТовары
|ГДЕ
| ИнвентаризацияТоваровТовары.Ссылка = &Ссылка
| И ИнвентаризацияТоваровТовары.Количество > ИнвентаризацияТоваровТовары.КоличествоУчет";
Запрос.УстановитьПараметр("Ссылка", ДанныеЗаполнения);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НоваяСтрока = ЭтотОбъект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВыборкаДетальныеЗаписи);
НоваяСтрока.Количество = ВыборкаДетальныеЗаписи.КоличествоИзлишек;
// Рассчитываем сумму, если в ТЧ есть соответствующая колонка
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Иногда пользователю удобнее сначала создать пустой документ Оприходование товаров, а затем в поле «Инвентаризация» выбрать нужный акт. В этом случае механизм «Ввода на основании» не сработает автоматически, и нам нужно прописать логику в модуле формы.
Проанализируем ситуацию: нам нужно отследить изменение реквизита в шапке. Для этого создадим событие ПриИзменении для поля выбора акта инвентаризации.
Разберем по шагам создание этого обработчика:
Инвентаризация.Рассмотрим пример кода в модуле формы:
&НаКлиенте
Процедура ИнвентаризацияПриИзменении(Элемент)
// Вызываем серверную процедуру для заполнения данных
ЗаполнитьПоИнвентаризацииНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоИнвентаризацииНаСервере()
// Проверяем, выбрано ли основание
Если Объект.Инвентаризация.Пустая() Тогда
Возврат;
КонецЕсли;
// Получаем объект из ссылки для доступа к его данным (или используем запрос)
ДокОснование = Объект.Инвентаризация;
// Переносим склад, если он заполнен в акте
Если ЗначениеЗаполнено(ДокОснование.Склад) Тогда
Объект.Склад = ДокОснование.Склад;
КонецЕсли;
// Очищаем товары
Объект.Товары.Очистить();
// Для примера используем простой перебор, хотя запрос эффективнее
Для Каждого СтрокаОснования Из ДокОснование.Товары Цикл
Если СтрокаОснования.Количество > СтрокаОснования.КоличествоУчет Тогда
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = СтрокаОснования.Номенклатура;
НоваяСтрока.Количество = СтрокаОснования.Количество - СтрокаОснования.КоличествоУчет;
НоваяСтрока.Цена = СтрокаОснования.Цена;
// Вызываем пересчет сумм, если это предусмотрено в вашей конфигурации
РассчитатьСуммуСтроки(НоваяСтрока);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Выясним причину, по которой профессиональные разработчики предпочитают метод ЗаполнитьЗначенияСвойств. Представьте, что в вашей табличной части не 3 колонки, а 20 (серия, срок годности, характеристика, единица измерения и т.д.). Прописывать каждую строку вручную — долго и чревато ошибками при опечатках.
Функция ЗаполнитьЗначенияСвойств(Получатель, Источник) автоматически сопоставляет имена реквизитов. Если в акте инвентаризации колонка называется Номенклатура и в оприходовании она называется так же, данные будут скопированы одной строкой кода. Это значительно повышает читаемость и надежность вашего кода.
При разработке алгоритма оприходования следует учитывать несколько критически важных моментов, которые часто упускают малоопытные программисты:
Основание.Проведен = Истина).ЦеныНоменклатуры.Оприходовании строго соответствует складу из Инвентаризации, иначе возникнет пересортица между складами.Проанализировав вышеописанные подходы, мы видим, что автоматизация заполнения — это не просто копирование строк, а осмысленный перенос данных с соблюдением бизнес-логики предприятия. Использование запросов для фильтрации излишков и стандартных механизмов платформы позволит вам создать качественный и быстрый инструмент для пользователей.