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