Как программно создать и провести документ «Поступление товаров» по выбранной строке таблицы в управляемой форме 1С?

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

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

Особенности клиент-серверной архитектуры при работе со строками

Проанализируем контекст управляемой формы. Свойство Элементы.ИмяТаблицы.ТекущиеДанные доступно только на стороне клиента. Оно возвращает объект типа ДанныеФормыЭлементКоллекции, который нельзя напрямую передать в серверный метод без контекста. Поэтому правильная схема взаимодействия выглядит следующим образом:

  1. На клиенте получаем текущую строку через Элементы.ИмяТаблицы.ТекущиеДанные.
  2. Проверяем, что строка действительно выбрана.
  3. Формируем объект Структура и копируем в него нужные реквизиты (дату ТТН, номер ТТН, номенклатуру, количество, цену и другие показатели).
  4. Передаем структуру параметров на сервер в процедуру или функцию.
  5. На сервере создаем документ, заполняем реквизиты и проводим его.

Пошаговая реализация создания и проведения документа

Разберем по шагам создание процедуры-обработчика команды на клиенте и серверной функции записи документа. Обратите внимание на синтаксис платформы 1С:Предприятие 8: для создания нового объекта применяется метод Документы.ИмяДокумента.СоздатьДокумент() (метод СоздатьОбъект() использовался в платформе 1С 7.7 и в 1С 8.х приведет к ошибке).

Посмотрим на пример клиентского обработчика нажатия кнопки:


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

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

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


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

КонецФункции

Важные правила и нюансы проведения

  1. Обработка исключений: Проведение документа всегда следует оборачивать в конструкцию Попытка ... Исключение. В конфигурациях при проведении могут срабатывать модули проверки заполнения, контроля остатков, валютных курсов или взаиморасчетов. Если документ не может быть проведен, система вызовет исключение, и пользователь получит понятное оповещение.
  2. Транзакционность: Вызов Записать(РежимЗаписиДокумента.Проведение) автоматически открывает неявную транзакцию. Если на этапе проведения возникнет ошибка, изменения по документу и его движениям не зафиксируются в базе данных.
  3. Расчет сумм и НДС: При фоновом заполнении документа события формы не срабатывают. Если в документе требуется рассчитать ставки НДС или сумму по строке, все расчеты необходимо выполнять программно до вызова метода Записать().

Альтернативный вариант: открытие предзаполненной формы

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


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

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

← На главную