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