Как программно заполнить счета учета при создании документа Поступление на расчетный счет в 1С

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

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

Когда пользователь создает документ интерактивно в интерфейсе (на форме), система автоматически подставляет нужные счета учета при выборе организации, контрагента или договора. Но при программном создании документа эти счета часто остаются пустыми. В этой статье мы подробно разберем, почему попытка вызвать стандартные процедуры формы из кода приводит к ошибкам, и как правильно решить эту задачу с помощью штатных механизмов типовых конфигураций 1С.

Давайте разберем эту тему шаг за шагом, проанализируем причины типовых ошибок и напишем надежный, соответствующий стандартам разработки 1С код.

---

Выясняем причину: почему возникает ошибка «Поле объекта не обнаружено»?

Рассмотрим ситуацию, в которую попал автор темы. Он попытался программно заполнить документ и, чтобы не прописывать счета учета вручную, решил вызвать процедуру, которая отрабатывает на форме при изменении организации:

ПоступлениеНаРасчетныйСчетФормы.ОрганизацияПриИзмененииСервер(ЭтотОбъект);

В результате система выдала ошибку: «Поле объекта не обнаружено (Организация)». Давайте разберемся, почему так произошло.

Дело в том, что в управляемом приложении 1С существует жесткое разделение между контекстом формы и контекстом объекта базы данных:

  1. Объект базы данных (типа ДокументОбъект) — это сам документ со всеми его реквизитами и табличными частями, существующий в оперативной памяти сервера или записанный в базу. У него нет визуального отображения.
  2. Форма документа (тип УправляемаяФорма) — это визуальный интерфейс, с которым взаимодействует пользователь. Основным реквизитом формы является Объект (тип ДанныеФормыСтруктура), который временно хранит данные документа для отображения на экране.

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


// Внутри общего модуля формы ожидает структуру формы:
ПараметрФорма.Объект.Организация

Когда разработчик программно создает документ через Документы.ПоступлениеНаРасчетныйСчет.СоздатьДокумент() и передает полученный объект в процедуру формы, система пытается прочитать свойство Поступление.Объект.Организация. Но у самого документа Поступление (который имеет тип ДокументОбъект) нет реквизита с именем Объект! У него реквизит Организация находится на самом верхнем уровне. Из-за этого несоответствия типов и возникает критическая ошибка «Поле объекта не обнаружено».

Пытаться вызывать клиентские или серверные методы формы из фонового задания или серверного модуля общего назначения — грубейшая архитектурная ошибка. Нам нужен другой, чисто серверный программный интерфейс.

---

Правильное решение: использование общего модуля СчетаУчетаВДокументах

В типовых конфигурациях «1С:Предприятие 8» (таких как «Бухгалтерия предприятия 3.0», «ERP Управление предприятием», «Комплексная автоматизация») вся бизнес-логика по определению счетов учета вынесена в специализированные общие модули. Нам не нужно изобретать велосипед или вручную копировать код из модулей форм.

Для заполнения счетов расчетов с контрагентами и счетов учета денежных средств предназначен общий серверный модуль СчетаУчетаВДокументах. Метод, который решит нашу задачу, называется Заполнить(). Он принимает объект документа, анализирует его реквизиты и автоматически заполняет все необходимые счета на основе правил, настроенных в регистре сведений «Счета учета расчетов с контрагентами».

Давайте посмотрим на пример правильного кода для программного создания и заполнения документа:


// Шаг 1. Создаем новый объект документа на сервере
НовыйДокумент = Документы.ПоступлениеНаРасчетныйСчет.СоздатьДокумент();

// Шаг 2. Заполняем основные реквизиты шапки
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.ВидОперации = Перечисления.ВидыОперацийПоступлениеДенежныхСредств.ОплатаПокупателя;
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("ПОУ");

// ВАЖНО: Счета расчетов зависят от контрагента и договора! 
// Обязательно заполняем их перед вызовом подстановки счетов.
НовыйДокумент.Контрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7701020304");
НовыйДокумент.ДоговорКонтрагента = Справочники.ДоговорыКонтрагентов.НайтиПоРеквизиту("Код", "00001", , НовыйДокумент.Контрагент);

// Заполняем банковский счет нашей организации
НовыйДокумент.СчетОрганизации = НовыйДокумент.Организация.ОсновнойБанковскийСчет;

// Шаг 3. Заполняем табличную часть (или Расшифровку платежа)
НоваяСтрока = НовыйДокумент.РасшифровкаПлатежа.Добавить();
НоваяСтрока.СпособПогашенияЗадолженности = Перечисления.СпособыПогашенияЗадолженности.Автоматически;
НоваяСтрока.СуммаПлатежа = 120000;

// Шаг 4. Подготавливаем параметры для автоматического заполнения счетов
// Создаем структуру отбора, чтобы указать, какие именно реквизиты нужно заполнять.
ПараметрыЗаполнения = Новый Структура;
// Истина — заполнить только пустые счета учета; Ложь — перезаписать даже ранее заполненные
ПараметрыЗаполнения.Вставить("НеЗаполненныеРеквизиты", Истина); 

// Шаг 5. Вызываем универсальный механизм автозаполнения счетов
СчетаУчетаВДокументах.Заполнить(НовыйДокумент, ПараметрыЗаполнения);

// Шаг 6. Записываем готовый документ в базу данных
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);

---

Как работает механизм автозаполнения счетов изнутри?

Рассмотрим подробнее, что происходит внутри системы при вызове метода СчетаУчетаВДокументах.Заполнить(). Это знание поможет вам избежать ошибок при отладке.

Когда мы передаем объект нашего документа в эту процедуру, алгоритм платформы выполняет следующие действия:

  1. Проверяет метаданные переданного объекта и определяет его тип (в данном случае ДокументСсылка.ПоступлениеНаРасчетныйСчет).
  2. Считывает значения ключевых полей, влияющих на счета учета: Организация, Контрагент, ДоговорКонтрагента, а также валюту расчетов по договору.
  3. Обращается к регистру сведений РегистрСведений.СчетаУчетаРасчетовСКонтрагентами. Этот регистр хранит правила подстановки счетов по приоритетам:
    • Высший приоритет: Индивидуальные настройки для конкретного договора контрагента.
    • Средний приоритет: Настройки для контрагента в целом (без привязки к конкретному договору) или группы контрагентов.
    • Общий приоритет: Общие настройки для конкретной организации или всей информационной базы.
  4. Программа ищет наиболее подходящую запись в регистре и находит значения для реквизитов СчетРасчетов (например, 62.01) и СчетАвансов (например, 62.02).
  5. Затем система определяет счет учета денежных средств на основе выбранного банковского счета организации (СчетОрганизации). Для рублевых счетов это обычно счет 51.
  6. Найденные значения автоматически записываются в соответствующие реквизиты табличной части или шапки документа.

---

Важные нюансы при программном заполнении документов

Чтобы программное создание документа работало стабильно и без ошибок, рекомендуем обратить внимание на следующие технические аспекты:

Применяя этот подход, вы сохраняете целостность бизнес-логики типовой конфигурации. Если бухгалтер решит изменить счета учета расчетов с каким-то крупным контрагентом в пользовательском интерфейсе, ваш программный код автоматически начнет использовать новые настройки без необходимости переписывать сам программный код.

← На главную