Как реализовать автозаполнение документа «Оприходование товаров» на основании «Инвентаризации»?

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

В процессе разработки собственной конфигурации на платформе 1С:Предприятие 8.3 часто возникает задача автоматизации ввода данных. Типичный пример — создание документа Оприходование товаров на основании проведенной инвентаризации. Мы разберем, как правильно связать эти объекты, чтобы упростить работу пользователя и исключить ошибки ручного ввода.

Для решения этой задачи нам потребуется задействовать несколько механизмов платформы: механизм ввода на основании, работу с запросами и обработку событий формы. Рассмотрим каждый этап подробно.

Механизм «Заполнение на основании» в модуле объекта

Первым делом проанализируем самый правильный с точки зрения архитектуры 1С способ — использование стандартного обработчика ОбработкаЗаполнения. Этот метод срабатывает, когда пользователь нажимает кнопку «Создать на основании» или когда документ создается программно с передачей основания.

Разберем алгоритм действий в конфигураторе:

  1. Откроем окно редактирования документа ОприходованиеТоваров.
  2. Перейдем на вкладку «Ввод на основании».
  3. В списке «Является основанием для» выберем ИнвентаризацияТоваров (или наоборот, в оприходовании укажем инвентаризацию как основание).
  4. Нажмем кнопку «Конструктор ввода на основании». Он поможет создать каркас процедуры, но логику отбора излишков нам придется дописать вручную.

Посмотрим на пример кода, который должен появиться в модуле объекта ОприходованиеТоваров. Важно помнить, что в оприходование должны попадать только те позиции, по которым выявлен излишек (фактическое количество больше учетного).


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

КонецПроцедуры

Реализация автозаполнения через форму документа

Иногда пользователю удобнее сначала создать пустой документ Оприходование товаров, а затем в поле «Инвентаризация» выбрать нужный акт. В этом случае механизм «Ввода на основании» не сработает автоматически, и нам нужно прописать логику в модуле формы.

Проанализируем ситуацию: нам нужно отследить изменение реквизита в шапке. Для этого создадим событие ПриИзменении для поля выбора акта инвентаризации.

Разберем по шагам создание этого обработчика:

  1. На форме документа выделим поле Инвентаризация.
  2. В панели свойств нажмем на лупу рядом с событием «ПриИзменении».
  3. Система предложит создать процедуру на клиенте и на сервере. Соглашаемся, так как работа с данными документа (запросы, обращение к базе) возможна только на сервере.

Рассмотрим пример кода в модуле формы:


&НаКлиенте
Процедура ИнвентаризацияПриИзменении(Элемент)
    // Вызываем серверную процедуру для заполнения данных
    ЗаполнитьПоИнвентаризацииНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПоИнвентаризацииНаСервере()
    
    // Проверяем, выбрано ли основание
    Если Объект.Инвентаризация.Пустая() Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем объект из ссылки для доступа к его данным (или используем запрос)
    ДокОснование = Объект.Инвентаризация;
    
    // Переносим склад, если он заполнен в акте
    Если ЗначениеЗаполнено(ДокОснование.Склад) Тогда
        Объект.Склад = ДокОснование.Склад;
    КонецЕсли;
    
    // Очищаем товары
    Объект.Товары.Очистить();
    
    // Для примера используем простой перебор, хотя запрос эффективнее
    Для Каждого СтрокаОснования Из ДокОснование.Товары Цикл
        
        Если СтрокаОснования.Количество > СтрокаОснования.КоличествоУчет Тогда
            
            НоваяСтрока = Объект.Товары.Добавить();
            НоваяСтрока.Номенклатура = СтрокаОснования.Номенклатура;
            НоваяСтрока.Количество = СтрокаОснования.Количество - СтрокаОснования.КоличествоУчет;
            НоваяСтрока.Цена = СтрокаОснования.Цена;
            
            // Вызываем пересчет сумм, если это предусмотрено в вашей конфигурации
            РассчитатьСуммуСтроки(НоваяСтрока);
            
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

Использование функции ЗаполнитьЗначенияСвойств

Выясним причину, по которой профессиональные разработчики предпочитают метод ЗаполнитьЗначенияСвойств. Представьте, что в вашей табличной части не 3 колонки, а 20 (серия, срок годности, характеристика, единица измерения и т.д.). Прописывать каждую строку вручную — долго и чревато ошибками при опечатках.

Функция ЗаполнитьЗначенияСвойств(Получатель, Источник) автоматически сопоставляет имена реквизитов. Если в акте инвентаризации колонка называется Номенклатура и в оприходовании она называется так же, данные будут скопированы одной строкой кода. Это значительно повышает читаемость и надежность вашего кода.

Бизнес-логика и важные нюансы

При разработке алгоритма оприходования следует учитывать несколько критически важных моментов, которые часто упускают малоопытные программисты:

Проанализировав вышеописанные подходы, мы видим, что автоматизация заполнения — это не просто копирование строк, а осмысленный перенос данных с соблюдением бизнес-логики предприятия. Использование запросов для фильтрации излишков и стандартных механизмов платформы позволит вам создать качественный и быстрый инструмент для пользователей.

← На главную