При автоматизации бизнес-процессов в 1С часто возникает необходимость программно создавать и изменять данные, например, элементы справочника Контрагенты. Это может быть актуально при интеграции с другими системами, импорте данных или разработке собственных обработок. В этой статье мы подробно рассмотрим, как программно создать нового контрагента, заполнить его основные и дополнительные реквизиты, а также привязать к нему банковские счета, уделяя внимание деталям и возможным нюансам. При реализации таких задач разработчику часто помогает справочник по методам БСП, содержащий множество готовых примеров использования стандартных подсистем.
Мы будем работать с объектами платформы 1С:Предприятие 8.3, используя управляемые формы, что является современным стандартом разработки. Все примеры кода будем писать на встроенном языке 1С.
Первым шагом при программной работе с любым справочником является создание нового элемента или поиск существующего. Для создания нового элемента справочника Контрагенты мы используем менеджер справочника и его метод СоздатьЭлемент(). После создания объекта элемента мы можем заполнять его реквизиты. Не забываем, что после заполнения всех необходимых реквизитов, для сохранения данных в базу необходимо вызвать метод Записать().
Давайте рассмотрим базовый пример создания юридического лица и заполнения его основных реквизитов:
Функция СоздатьНовогоКонтрагента(Наименование, ИНН, КПП, ПолноеНаименование) Экспорт
// Проверим, возможно, контрагент с таким ИНН уже существует
СсылкаНаКонтрагента = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ИНН);
Если СсылкаНаКонтрагента.Пустая() Тогда
// Создаем новый элемент справочника "Контрагенты"
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = Наименование; // Краткое наименование
НовыйКонтрагент.ИНН = ИНН;
НовыйКонтрагент.КПП = КПП;
НовыйКонтрагент.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо; // Указываем, что это юридическое лицо
НовыйКонтрагент.ПолноеНаименование = ПолноеНаименование; // Полное наименование
Попытка
НовыйКонтрагент.Записать(); // Записываем нового контрагента в базу
Возврат НовыйКонтрагент.Ссылка;
Исключение
Сообщить("Ошибка при записи контрагента: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
Иначе
Сообщить("Контрагент с ИНН " + ИНН + " уже существует: " + СсылкаНаКонтрагента.Наименование);
Возврат СсылкаНаКонтрагента;
КонецЕсли;
КонецФункции
// Пример вызова функции:
// КонтрагентСсылка = СоздатьНовогоКонтрагента("Ромашка ООО", "1234567890", "123456789", "Общество с ограниченной ответственностью ""Ромашка""");
// Если КонтрагентСсылка <> Неопределено Тогда
// Сообщить("Создан/найден контрагент: " + КонтрагентСсылка.Наименование);
// КонецЕсли;
В этом примере мы не только создаем контрагента, но и добавляем проверку на его существование по ИНН. Это важный шаг для предотвращения дублирования данных. Если контрагент с таким ИНН уже есть, мы возвращаем ссылку на существующего, а не создаем нового. Обратите внимание на использование перечисления Перечисления.ЮрФизЛицо.ЮрЛицо для указания типа контрагента. Для физических лиц мы бы использовали Перечисления.ЮрФизЛицо.ФизЛицо.
Реквизит Наименование обычно используется для краткого представления контрагента в списках, тогда как ПолноеНаименование содержит полное официальное название, которое может использоваться в печатных формах документов. В некоторых конфигурациях ПолноеНаименование может формироваться автоматически на основе других реквизитов, но при программном создании мы обычно заполняем его явно.
Часто возникает ситуация, когда стандартных реквизитов справочника Контрагенты недостаточно для хранения всей необходимой информации. Для таких случаев в 1С предусмотрен механизм дополнительных реквизитов и сведений. Эти реквизиты являются динамическими и их состав может меняться пользователем в режиме 1С:Предприятие. Для программной работы с ними нам потребуется несколько иной подход.
Дополнительные реквизиты хранятся в специальной коллекции объекта, которая доступна через свойство ДополнительныеРеквизиты. Каждый дополнительный реквизит в этой коллекции имеет свойство Свойство (ссылка на элемент плана видов характеристик ДополнительныеРеквизитыИСведения, который определяет сам реквизит) и Значение (собственно, значение реквизита).
Мы можем установить значение дополнительного реквизита двумя способами:
Прежде чем установить значение, необходимо убедиться, что сам дополнительный реквизит (его "описание") существует в системе. Описания дополнительных реквизитов хранятся в плане видов характеристик ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.
Давайте рассмотрим пример заполнения дополнительного реквизита "ТипВзаимоотношений" для контрагента:
Процедура ЗаполнитьДополнительныеРеквизиты(СсылкаНаКонтрагента, ИмяДопРеквизита, ЗначениеДопРеквизита) Экспорт
Если СсылкаНаКонтрагента.Пустая() Тогда
Сообщить("Ссылка на контрагента не определена. Заполнение дополнительных реквизитов невозможно.");
Возврат;
КонецЕсли;
КонтрагентОбъект = СсылкаНаКонтрагента.ПолучитьОбъект();
// Шаг 1: Находим само описание дополнительного реквизита в ПланеВидовХарактеристик
// Это важно, чтобы гарантировать, что мы работаем с существующим реквизитом.
ОписаниеДопРеквизита = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию(ИмяДопРеквизита);
Если ОписаниеДопРеквизита.Пустая() Тогда
Сообщить("Дополнительный реквизит с именем '" + ИмяДопРеквизита + "' не найден в системе. Проверьте его наличие.");
Возврат;
КонецЕсли;
// Шаг 2: Устанавливаем значение дополнительного реквизита для объекта контрагента
// Вариант 1: Поиск по наименованию в коллекции ДополнительныеРеквизиты
ЭлементКоллекцииДопРеквизитов = КонтрагентОбъект.ДополнительныеРеквизиты.Найти(ОписаниеДопРеквизита, "Свойство");
Если ЭлементКоллекцииДопРеквизитов <> Неопределено Тогда
ЭлементКоллекцииДопРеквизитов.Значение = ЗначениеДопРеквизита;
Иначе
// Если реквизит еще не добавлен в коллекцию объекта (например, при создании нового объекта),
// его можно добавить вручную или через методы работы с наборами дополнительных реквизитов
// В типовых конфигурациях обычно используется ПолучитьНаборДополнительныхРеквизитов()
НаборДопРеквизитов = РегистрыСведений.ДополнительныеРеквизиты.СоздатьНаборЗаписей();
НаборДопРеквизитов.Отбор.Объект.Установить(СсылкаНаКонтрагента);
НаборДопРеквизитов.Прочитать();
НоваяЗапись = НаборДопРеквизитов.Добавить();
НоваяЗапись.Объект = СсылкаНаКонтрагента;
НоваяЗапись.Свойство = ОписаниеДопРеквизита;
НоваяЗапись.Значение = ЗначениеДопРеквизита;
Попытка
НаборДопРеквизитов.Записать();
Сообщить("Дополнительный реквизит '" + ИмяДопРеквизита + "' успешно установлен (через регистр).");
Исключение
Сообщить("Ошибка при записи дополнительного реквизита через регистр: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
// После модификации дополнительных реквизитов, необходимо записать сам объект Контрагента,
// если вы работали напрямую с его коллекцией, а не через РегистрСведений.
// Если работали через РегистрСведений.ДополнительныеРеквизиты, то объект Контрагента записывать не нужно.
Если ЭлементКоллекцииДопРеквизитов <> Неопределено Тогда
Попытка
КонтрагентОбъект.Записать();
Сообщить("Дополнительный реквизит '" + ИмяДопРеквизита + "' успешно установлен.");
Исключение
Сообщить("Ошибка при записи контрагента после установки дополнительного реквизита: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
// Пример вызова:
// КонтрагентСсылка = СоздатьНовогоКонтрагента("ТестКонтрагент", "1111111111", "222222222", "ООО Тестовый Контрагент");
// Если КонтрагентСсылка <> Неопределено Тогда
// ЗаполнитьДополнительныеРеквизиты(КонтрагентСсылка, "ТипВзаимоотношений", "Поставщик");
// КонецЕсли;
В этом более комплексном примере мы сначала находим сам элемент плана видов характеристик, соответствующий нашему дополнительному реквизиту. Это обеспечивает корректную работу, так как ДополнительныеРеквизиты объекта оперируют именно ссылками на этот план видов характеристик, а не просто строковыми наименованиями. Мы предусмотрели два пути: прямой доступ к коллекции (если реквизит уже есть) и добавление записи в регистр сведений ДополнительныеРеквизиты, который является основным местом хранения этих данных. Последний подход более универсален для новых реквизитов или при первом заполнении.
Банковские счета в 1С хранятся в отдельном справочнике БанковскиеСчета. Этот справочник является подчиненным справочнику Контрагенты, что означает, что каждый банковский счет должен принадлежать конкретному контрагенту (или организации). Для создания банковского счета нам потребуется ссылка на контрагента, которому он будет принадлежать, а также информация о банке. Правильное заполнение этих данных крайне важно, если вы планируете в дальнейшем использовать автоматизированную загрузку банковских выписок, особенно в случаях некорректного указания БИК банком.
Перед тем как создать банковский счет, мы должны убедиться, что банк, в котором открыт счет, существует в справочнике Банки. Если его нет, нам придется создать его программно. Справочник Банки часто заполняется автоматически или импортируется, но в некоторых случаях его может не быть.
Давайте сначала разберем, как найти существующий банк или создать новый, если он отсутствует:
Функция ПолучитьСсылкаНаБанк(БИК, НаименованиеБанка, КорреспондентскийСчет) Экспорт
// Ищем банк по БИК - это уникальный идентификатор банка
БанкСсылка = Справочники.Банки.НайтиПоРеквизиту("БИК", БИК);
Если БанкСсылка.Пустая() Тогда
Сообщить("Банк с БИК " + БИК + " не найден. Создаем новый.");
НовыйБанк = Справочники.Банки.СоздатьЭлемент();
НовыйБанк.Наименование = НаименованиеБанка;
НовыйБанк.БИК = БИК;
НовыйBank.КоррСчет = КорреспондентскийСчет;
// Могут быть и другие реквизиты, например, Город, Адрес и т.д.
// Заполняем по мере необходимости
Попытка
НовыйБанк.Записать();
Возврат НовыйБанк.Ссылка;
Исключение
Сообщить("Ошибка при записи нового банка: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
Иначе
Возврат БанкСсылка; // Банк уже существует, возвращаем его ссылку
КонецЕсли;
КонецФункции
// Пример вызова:
// СсылкаНаСберБанк = ПолучитьСсылкаНаБанк("044525225", "ПАО Сбербанк", "30101810400000000225");
// Если СсылкаНаСберБанк <> Неопределено Тогда
// Сообщить("Ссылка на банк: " + СсылкаНаСберБанк.Наименование);
// КонецЕсли;
Мы используем БИК (Банковский Идентификационный Код) как основной критерий для поиска банка, поскольку он является уникальным. Если банк не найден, мы создаем новый элемент, заполняем его базовые реквизиты и записываем. Важно заполнить Наименование, БИК и КоррСчет.
Теперь, когда у нас есть ссылка на контрагента и ссылка на банк, мы можем создать новый банковский счет. Основные реквизиты для заполнения: Владелец (ссылка на контрагента), НомерСчета, Банк (ссылка на элемент справочника Банки) и ВалютаДенежныхСредств.
Функция СоздатьБанковскийСчетКонтрагента(СсылкаНаКонтрагента, НомерСчета, БИКБанка, НаименованиеБанка, КоррСчетБанка, КодВалюты) Экспорт
Если СсылкаНаКонтрагента.Пустая() Тогда
Сообщить("Не указан владелец банковского счета (контрагент).");
Возврат Неопределено;
КонецЕсли;
// Шаг 1: Получаем ссылку на банк (создаем, если не существует)
СсылкаНаБанк = ПолучитьСсылкаНаБанк(БИКБанка, НаименованиеБанка, КоррСчетБанка);
Если СсылкаНаБанк = Неопределено Тогда
Сообщить("Не удалось получить ссылку на банк. Создание банковского счета невозможно.");
Возврат Неопределено;
КонецЕсли;
// Шаг 2: Находим или создаем элемент справочника "Валюты"
СсылкаНаВалюту = Справочники.Валюты.НайтиПоКоду(КодВалюты); // Например, "643" для рубля
Если СсылкаНаВалюту.Пустая() Тогда
Сообщить("Валюта с кодом '" + КодВалюты + "' не найдена. Создание банковского счета невозможно.");
Возврат Неопределено;
КонецЕсли;
// Проверим, возможно, счет с таким номером для этого контрагента уже существует
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| БанковскиеСчета.Ссылка
|ИЗ
| Справочник.БанковскиеСчета КАК БанковскиеСчета
|ГДЕ
| БанковскиеСчета.Владелец = &Владелец
| И БанковскиеСчета.НомерСчета = &НомерСчета";
Запрос.УстановитьПараметр("Владелец", СсылкаНаКонтрагента);
Запрос.УстановитьПараметр("НомерСчета", НомерСчета);
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Если РезультатЗапроса.Следующий() Тогда
Сообщить("Банковский счет с номером " + НомерСчета + " для контрагента " + СсылкаНаКонтрагента.Наименование + " уже существует.");
Возврат РезультатЗапроса.Ссылка;
КонецЕсли;
// Шаг 3: Создаем новый элемент справочника "БанковскиеСчета"
НовыйБанковскийСчет = Справочники.БанковскиеСчета.СоздатьЭлемент();
НовыйБанковскийСчет.Владелец = СсылкаНаКонтрагента; // Привязка к контрагенту
НовыйБанковскийСчет.НомерСчета = НомерСчета;
НовыйБанковскийСчет.Банк = СсылкаНаБанк; // Привязка к банку
НовыйБанковскийСчет.ВалютаДенежныхСредств = СсылкаНаВалюту;
НовыйБанковскийСчет.Наименование = "Счет №" + НомерСчета + " (" + НаименованиеБанка + ")"; // Произвольное наименование счета
Попытка
НовыйБанковскийСчет.Записать();
Возврат НовыйБанковскийСчет.Ссылка;
Исключение
Сообщить("Ошибка при записи банковского счета: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
// Пример использования всей цепочки:
// СсылкаНаКонтрагента = СоздатьНовогоКонтрагента("Торговая Компания ""Восток""", "9876543210", "987654321", "ООО ""Торговая Компания ""Восток""");
// Если СсылкаНаКонтрагента <> Неопределено Тогда
// Сообщить("Контрагент создан/найден: " + СсылкаНаКонтрагента.Наименование);
// ЗаполнитьДополнительныеРеквизиты(СсылкаНаКонтрагента, "ТипВзаимоотношений", "Клиент");
//
// СсылкаНаСчет = СоздатьБанковскийСчетКонтрагента(
// СсылкаНаКонтрагента,
// "40702810100000000001",
// "044525225", // БИК Сбербанка
// "ПАО Сбербанк",
// "30101810400000000225", // Корр. счет Сбербанка
// "643" // Код валюты для рубля
// );
// Если СсылкаНаСчет <> Неопределено Тогда
// Сообщить("Банковский счет создан/найден: " + СсылкаНаСчет.НомерСчета);
// КонецЕсли;
// КонецЕсли;
В этом блоке мы сначала получаем ссылки на банк и валюту, используя вспомогательную функцию для банка и метод НайтиПоКоду() для валюты. Мы также добавляем проверку на существование банковского счета по номеру для конкретного контрагента, чтобы избежать дублирования. Затем создаем новый элемент справочника БанковскиеСчета, присваиваем ему Владельца (нашего контрагента), НомерСчета, ссылку на Банк и ВалютуДенежныхСредств, после чего записываем.
В типовых конфигурациях 1С для каждого контрагента (или организации) может быть выбран основной банковский счет. Этот счет используется по умолчанию в документах, отчетах и при формировании платежных поручений. Наличие корректного основного счета позволяет в дальнейшем эффективно использовать журнал банка и кассы для оперативного анализа и реестра платежей.
Как правило, основной банковский счет устанавливается одним из двух способов:
ОсновнойБанковскийСчет непосредственно у объекта Контрагент (если такой реквизит реализован в вашей конфигурации).В современных конфигурациях 1С, таких как 1С:ERP, 1С:Комплексная автоматизация, 1С:Бухгалтерия, наличие заполненных реквизитов счетов крайне важно.
Давайте рассмотрим общий подход, который часто встречается, с помощью обращения к объекту контрагента:
Процедура УстановитьОсновнойБанковскийСчет(СсылкаНаКонтрагента, СсылкаНаБанковскийСчет) Экспорт
Если СсылкаНаКонтрагента.Пустая() Или СсылкаНаБанковскийСчет.Пустая() Тогда
Сообщить("Для установки основного банковского счета необходимо указать и контрагента, и банковский счет.");
Возврат;
КонецЕсли;
КонтрагентОбъект = СсылкаНаКонтрагента.ПолучитьОбъект();
// В некоторых конфигурациях может быть прямой реквизит ОсновнойБанковскийСчет
Попытка
КонтрагентОбъект.ОсновнойБанковскийСчет = СсылкаНаБанковскийСчет;
КонтрагентОбъект.Записать();
Сообщить("Основной банковский счет для контрагента '" + СсылкаНаКонтрагента.Наименование + "' успешно установлен.");
Исключение
Сообщить("Ошибка при установке основного банковского счета через прямой реквизит: " + ОписаниеОшибки() + ". Возможно, в данной конфигурации используется другой механизм (например, общие процедуры или регистры сведений).");
// Если прямой реквизит не работает, попробуем типовой механизм через общие модули
КонецПопытки;
КонецПроцедуры
// Пример вызова:
// УстановитьОсновнойБанковскийСчет(СсылкаНаКонтрагента, СсылкаНаСчет);
При программной работе с данными в 1С, помимо непосредственного написания кода, важно учитывать некоторые общие рекомендации, которые помогут сделать вашу разработку более надежной и поддерживаемой:
Попытка...Исключение при работе с потенциально ошибочными операциями. Это позволяет предотвращать крах программы и корректно информировать пользователя.
ОбменДанными.Загрузка = Истина перед записью каждого объекта для ускорения процесса.
Программное создание и управление контрагентами и связанными с ними данными в 1С — это мощный инструмент для автоматизации. Мы рассмотрели основные шаги и предоставили примеры кода, которые помогут вам в решении подобных задач. Помните, что детали реализации могут немного отличаться в зависимости от конкретной конфигурации 1С, но основные принципы остаются неизменными. Всегда обращайтесь к документации вашей конфигурации и используйте типовой функционал, где это возможно, для повышения надежности и снижения затрат на поддержку.