← Назад к вопросам

Автозаполнение документа по выбранным параметрам

2.0 Middle🔥 141 комментариев
#Стандарты разработки#Формы и интерфейс

Условие

Доработайте документ "ПриобретениеТоваровУслуг" — добавьте кнопку заполнения табличной части по выбранным параметрам.

Параметры заполнения:

  • Дата
  • Организация
  • Склад

При нажатии кнопки "Заполнить" табличная часть должна автоматически заполниться товарами, которые были закуплены ранее по указанным параметрам (из предыдущих документов поступления).

Логика заполнения

  1. Найти последний документ поступления с такими же параметрами
  2. Скопировать номенклатуру, количество и цены из найденного документа

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение

Для автозаполнения документа нужно добавить кнопку на форму и обработчик в модуль формы документа.

Часть 1: Добавление кнопки на форму

В конструкторе формы документа "ПриобретениеТоваровУслуг":

// На форме в структуре элементов добавляем:
// Командная кнопка "ЗаполнитьПоПредыдущему"
// Текст: "Заполнить по предыдущему"
// Расположение: над таблицей Товары

Часть 2: Обработчик нажатия кнопки (в модуле формы)

&НаКлиенте
Процедура ЗаполнитьПоПредыдущемуНажатие(Кнопка)
    // Проверяем, выбраны ли параметры заполнения
    Если НЕ ЗначениеЗаполнено(Объект.Дата) Тогда
        Сообщить("Укажите дату");
        Возврат;
    КонецЕсли;
    
    Если НЕ ЗначениеЗаполнено(Объект.Организация) Тогда
        Сообщить("Укажите организацию");
        Возврат;
    КонецЕсли;
    
    Если НЕ ЗначениеЗаполнено(Объект.Склад) Тогда
        Сообщить("Укажите склад");
        Возврат;
    КонецЕсли;
    
    // Очищаем текущую таблицу
    Объект.Товары.Очистить();
    
    // Вызываем серверную процедуру для поиска данных
    ЗаполнитьТаблицуПоСерверу();
КонецПроцедуры

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

Функция НайтиПоследнийДокументПоступления(Дата, Организация, Склад)
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("Дата", Дата);
    Запрос.УстановитьПараметр("Организация", Организация);
    Запрос.УстановитьПараметр("Склад", Склад);
    
    Запрос.Текст = 
    """ВЫБРАТЬ ПЕРВЫЕ 1
        Документы.Ссылка
    ИЗ
        Документ.ПоступлениеТоваров КАС Документы
    ГДЕ
        Документы.Организация = @Организация
        И Документы.Склад = @Склад
        И Документы.Дата <= @Дата
        И НЕ Документы.ПометкаУдаления
        И Документы.Проведено
    ПОРЯДОКПО
        Документы.Дата УБЫВ,
        Документы.Номер УБЫВ
    """;
    
    Результат = Запрос.Выполнить();
    
    Если Результат.Пусто() Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    
    Возврат Выборка.Ссылка.ПолучитьОбъект();
КонецФункции

Часть 3: Улучшенная версия с пользовательским выбором

Если нужно предоставить выбор из нескольких найденных документов:

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

&НаКлиенте
Процедура ПроцедураПриЗавершении(РезультатДиалога, ДополнительныеПараметры) Экспорт
    Если РезультатДиалога = Неопределено Тогда
        Возврат; // Пользователь отменил выбор
    КонецЕсли;
    
    ЗаполнитьТаблицуИзДокумента(РезультатДиалога);
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьТаблицуИзДокумента(ДокументСсылка)
    ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
    
    Объект.Товары.Очистить();
    
    Для Каждого СтрокаИсточника Из ДокументОбъект.Товары Цикл
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Номенклатура = СтрокаИсточника.Номенклатура;
        НоваяСтрока.Количество = СтрокаИсточника.Количество;
        НоваяСтрока.ЕдиницаИзмерения = СтрокаИсточника.ЕдиницаИзмерения;
        НоваяСтрока.Цена = СтрокаИсточника.Цена;
        НоваяСтрока.Сумма = СтрокаИсточника.Сумма;
    КонецЦикла;
    
    Сообщить("Заполнено " + Объект.Товары.Количество() + " товаров");
КонецПроцедуры

Часть 4: Версия с фильтром по дате последних N дней

Если нужна более гибкая логика:

Функция НайтиПоследниеДокументы(Организация, Склад, ДнейНазад = 30)
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("Организация", Организация);
    Запрос.УстановитьПараметр("Склад", Склад);
    Запрос.УстановитьПараметр("ДатаОт", ТекущаяДата() - 86400 * ДнейНазад);
    
    Запрос.Текст = 
    """ВЫБРАТЬ
        Документы.Ссылка,
        Документы.Дата,
        Документы.Номер
    ИЗ
        Документ.ПоступлениеТоваров КАС Документы
    ГДЕ
        Документы.Организация = @Организация
        И Документы.Склад = @Склад
        И Документы.Дата >= @ДатаОт
        И НЕ Документы.ПометкаУдаления
        И Документы.Проведено
    ПОРЯДОКПО
        Документы.Дата УБЫВ,
        Документы.Номер УБЫВ
    """;
    
    Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

Ключевые моменты:

Разделение логики:

  • Клиентские процедуры для UI (&НаКлиенте)
  • Серверные процедуры для работы с данными (&НаСервере)
  • Проверка заполнения параметров обязательна

Поиск документов:

  • Используем ПЕРВЫЕ 1 для быстрого получения последнего
  • Сортируем по дате (убывание) и номеру
  • Проверяем, что документ проведён

Копирование данных:

  • Копируем только нужные реквизиты
  • Цену можно взять как есть или пересчитать
  • Количество копируется как есть

Обработка ошибок:

  • Проверяем заполнение обязательных параметров
  • Информируем пользователя о результатах
  • Предусматриваем вариант, если документов не найдено

Производительность:

  • Запрос использует индексы по Организации и Дате
  • Получаем один документ, а не весь список
  • ПолучитьОбъект() вызываем только один раз