При автоматизации бизнес-процессов в 1С:Бухгалтерия предприятия 3.0 часто возникает задача программного создания документов, в частности — «Счета на оплату покупателю». Начинающие разработчики часто сталкиваются с трудностями при заполнении реквизитов, чьи имена в метаданных не совпадают с заголовками на форме. Рассмотрим подробнее, как правильно работать с реквизитами Банковский счет и Оплата до, чтобы данные корректно сохранялись и отображались в системе.
Первая сложность, с которой мы сталкиваемся — это поиск нужного реквизита. На форме документа мы видим поле «Банковский счет», однако в структуре метаданных документа СчетНаОплатуПокупателю этот реквизит называется СтруктурнаяЕдиница. Это стандартное наименование для многих документов в конфигурациях на базе БСП, где под структурной единицей может подразумеваться как расчетный счет, так и касса.
Разберем типичную ошибку: попытку назначить счет через объект организации. Проанализируем код: часто программисты пытаются изменить основной счет в карточке организации вместо того, чтобы указать счет в самом документе. Правильный подход заключается в прямой записи ссылки в реквизит документа.
Рассмотрим пример правильного заполнения банковского счета:
// Создаем новый объект документа
НовыйДок = Документы.СчетНаОплатуПокупателю.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
НовыйДок.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701010101");
// Вариант 1: Установка основного счета организации
НовыйДок.СтруктурнаяЕдиница = НовыйДок.Организация.ОсновнойБанковскийСчет;
// Вариант 2: Поиск конкретного счета по наименованию (с учетом владельца)
ИмяСчета = "Основной (рублевый)";
НовыйДок.СтруктурнаяЕдиница = Справочники.БанковскиеСчета.НайтиПоНаименованию(ИмяСчета, Ложь, , НовыйДок.Организация);
Важный нюанс: при поиске счета методом НайтиПоНаименованию всегда указывайте владельца (организацию). В базе может быть несколько счетов с названием «Основной», принадлежащих разным юридическим лицам. Если не указать владельца, система может подставить счет чужой организации, что приведет к ошибкам при проведении или печати.
Ситуация с реквизитом «Оплата до» еще интереснее. В современных версиях «Бухгалтерии 3.0» этот реквизит в метаданных называется ДатаОплаты. Однако, если вы просто создадите документ программно, это поле может остаться пустым, так как в типовом решении оно часто вычисляется динамически или заполняется при изменении договора.
Выясним причину, по которой дата может не заполняться. Срок оплаты в 1С зависит от нескольких уровней настроек:
СрокОплатыСчетовПокупателю.Чтобы программно рассчитать дату оплаты так, как это делает система, мы рекомендуем использовать типовые механизмы. Посмотрим на пример кода, который учитывает общие настройки системы:
// Получаем количество дней отсрочки из констант
СрокОтсрочки = Константы.СрокОплатыСчетовПокупателю.Получить();
// Если константа заполнена, прибавляем дни к дате счета
Если СрокОтсрочки > 0 Тогда
// Обратите внимание: для учета рабочих дней используются специальные функции
НовыйДок.ДатаОплаты = НовыйДок.Дата + (СрокОтсрочки * 86400);
КонецЕсли;
Для более точного расчета, учитывающего производственный календарь и настройки договора, лучше использовать функции общего модуля ОбщегоНазначенияБПВызовСервера (если они доступны в вашей версии конфигурации) или аналогичные методы из модуля менеджера документа.
Вместо того чтобы вручную прописывать каждый реквизит, проанализируем возможность использования стандартного механизма заполнения. В 1С:Предприятии 8.3 для большинства документов реализован метод Заполнить(), который вызывает процедуру ОбработкаЗаполнения в модуле объекта.
Рассмотрим, как это упрощает жизнь программисту:
НовыйДок = Документы.СчетНаОплатуПокупателю.СоздатьДокумент();
// Заполняем основные реквизиты, от которых зависят остальные
НовыйДок.Дата = ТекущаяДата();
НовыйДок.Организация = Справочники.Организации.НайтиПоНаименованию("Наша фирма");
НовыйДок.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("Покупатель");
НовыйДок.ДоговорКонтрагента = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию("Основной", Ложь, , НовыйДок.Контрагент);
// Вызываем стандартное заполнение по правилам системы
// Это позволит автоматически подтянуть основной счет организации и рассчитать дату оплаты
НовыйДок.Заполнить(Неопределено);
// Если после автоматического заполнения нужно переопределить счет:
НовыйДок.СтруктурнаяЕдиница = Справочники.БанковскиеСчета.НайтиПоНаименованию("Валютный счет", Ложь, , НовыйДок.Организация);
Разберем ситуацию, когда банковский счет вроде бы назначен в коде, но при открытии документа или его записи поле оказывается пустым. В 1С:Бухгалтерия 3.0 жестко контролируется соответствие валюты банковского счета и валюты самого документа.
Если НовыйДок.ВалютаДокумента установлена как «USD», а в НовыйДок.СтруктурнаяЕдиница вы пытаетесь записать ссылку на рублевый счет, система (или логика формы при открытии) может очистить это значение. Поэтому перед присвоением всегда проверяйте:
Подытожим все вышесказанное и составим надежный алгоритм создания документа:
СоздатьДокумент().Организация, Контрагент и ДоговорКонтрагента.Заполнить() для инициализации типовых значений.СтруктурнаяЕдиница (если основной счет организации нас не устраивает).ДатаОплаты (если срок должен отличаться от стандартного).Товары и вызываем пересчет сумм.Запись или Проведение.Соблюдение этого порядка гарантирует, что все скрытые механизмы платформы отработают корректно, и ваш программно созданный счет ничем не будет отличаться от введенного вручную бухгалтером.