Почему не сохраняются реквизиты документа "Приходный кассовый ордер" при его программном создании в 1С:ERP?

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

Начнем с анализа типичной ситуации, с которой сталкиваются разработчики при программном создании документов в системе 1С, в частности, такого важного документа как "Приходный кассовый ордер" (ПКО) в конфигурации 1С:ERP. Мы рассмотрим проблему, когда, казалось бы, все необходимые реквизиты заполнены в объекте документа перед его записью, но после сохранения документа эти реквизиты оказываются пустыми. Давайте разберемся, в чем здесь может быть причина и как корректно решить эту задачу.

Проблема: не сохраняются реквизиты "шапки" документа ПКО

Представьте ситуацию: вы разрабатываете обработку в 1С:ERP, которая должна программно формировать документы "Приходный кассовый ордер". В процессе создания документа вы тщательно заполняете его основные реквизиты, такие как ОбъектРасчетов и СтатьяДвиженияДенежныхСредств. Используя отладчик, вы убеждаетесь, что перед вызовом метода Записать() или Записать(РежимЗаписиДокумента.Проведение) эти реквизиты содержат корректные значения. Однако, открыв документ после его записи, вы обнаруживаете, что эти поля пусты. В чем же дело? Почему система "забывает" те значения, которые вы так старательно ей передавали? Эта ситуация встречается достаточно часто и является одной из ключевых особенностей работы с документами в 1С, особенно в сложных конфигурациях, таких как 1С:ERP Управление предприятием. Давайте выясним, почему так происходит и как правильно организовать заполнение данных.

Особенности структуры документов в 1С: реквизиты "шапки" и табличные части

Для полного понимания проблемы, нам необходимо глубже рассмотреть, как устроено хранение данных в документах 1С. В большинстве документов можно выделить два основных типа реквизитов:

  1. Реквизиты "шапки" документа. Эти реквизиты предназначены для хранения информации, которая является общей для всего документа. К ним относятся, например, дата и номер документа, организация, контрагент, сумма по документу в целом и так далее. Эти данные обычно хранятся в основной таблице документа в базе данных.
  2. Табличные части. Это списки однотипных данных, которые относятся к одному документу. Примерами могут служить список товаров и услуг в реализации, состав бригады в наряде или, как в нашем случае с ПКО, детализация платежа. Информация из табличных частей хранится в отдельных, подчиненных таблицах, которые связаны с основной таблицей документа.

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

Логика работы документа "Приходный кассовый ордер" в 1С:ERP

В конфигурации 1С:ERP, как и во многих других современных решениях, документ "Приходный кассовый ордер" имеет свою специфическую логику обработки. Несмотря на то, что на форме документа могут присутствовать поля, дублирующие реквизиты "шапки" (например, для ОбъектРасчетов или СтатьяДвиженияДенежныхСредств), или может казаться, что эти поля должны заполняться напрямую, внутренняя логика проведения документа и механизмы подсистем (таких как Взаиморасчеты, Казначейство, Учет денежных средств) зачастую ожидают ключевые данные именно в табличной части. Для документа ПКО в 1С:ERP такой ключевой табличной частью является РасшифровкаПлатежа. Именно в этой табличной части хранится детализация поступивших денежных средств: от кого, за что, по какому договору, с какой статьей движения денежных средств и т.д. Система спроектирована таким образом, что при проведении документа она в первую очередь обращается к данным из этой табличной части для формирования движений по регистрам и корректного отражения операций в учете. Значения, напрямую установленные в реквизитах "шапки", могут быть просто проигнорированы, перезаписаны или не учтены, если они не продублированы или не являются основными для заполнения в соответствующей табличной части.

Причина "потери" реквизитов: почему данные не сохраняются?

Теперь, когда мы понимаем структуру документов и логику ПКО, причина "потери" реквизитов становится очевидной. Если вы заполняете ОбъектРасчетов и СтатьяДвиженияДенежныхСредств только напрямую в объекте документа ПриходныйКассовыйОрдер (как реквизиты "шапки"), но система ожидает эти данные в строке табличной части РасшифровкаПлатежа, то после записи документа эти значения могут не сохраниться. Система при проведении или записи документа будет брать данные именно из табличной части для формирования движений по регистрам и корректного учета взаиморасчетов, движения денежных средств и прочего. Таким образом, заполнение табличной части РасшифровкаПлатежа является критически важным для того, чтобы эти ключевые реквизиты были сохранены и обработаны согласно логике конфигурации.

Решение проблемы: программное заполнение табличной части "РасшифровкаПлатежа"

Итак, решение проблемы заключается в корректном программном заполнении табличной части РасшифровкаПлатежа документа "Приходный кассовый ордер". Давайте рассмотрим подробный алгоритм и пример кода, который позволит нам успешно создавать ПКО с сохранением всех необходимых реквизитов.

Шаг 1: Создание нового документа "Приходный кассовый ордер"

Сначала мы создаем новый объект документа ПриходныйКассовыйОрдер и заполняем его базовые реквизиты "шапки", которые являются общими для всего документа.


// Создаем новый документ Приходный кассовый ордер
НовыйПКО = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();

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

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

Шаг 2: Добавление строки в табличную часть "РасшифровкаПлатежа"

Ключевым моментом является добавление новой строки в табличную часть РасшифровкаПлатежа и последующее заполнение необходимых реквизитов именно в этой строке.


// Добавляем новую строку в табличную часть "РасшифровкаПлатежа"
НоваяСтрока = НовыйПКО.РасшифровкаПлатежа.Добавить();

После выполнения этой операции переменная НоваяСтрока будет ссылаться на только что созданную строку табличной части, и мы можем приступить к заполнению ее реквизитов.

Шаг 3: Заполнение реквизитов в строке табличной части

Теперь мы заполняем те реквизиты, которые ранее пытались установить напрямую в "шапке" документа, но теперь делаем это в контексте строки табличной части. В вашем случае это ОбъектРасчетов и СтатьяДвиженияДенежныхСредств, а также другие важные для платежа поля, такие как Контрагент, ДоговорКонтрагента, Сумма. Предположим, у нас уже есть ссылки на необходимые справочники, созданные ранее, как было указано в исходном сообщении:


// Пример получения ссылок на необходимые объекты
// Допустим, мы ранее создали ДоговорКонтрагента и ОбъектРасчетов
// и получили ссылку на СтатьюДвиженияДенежныхСредств

// Пример создания элементов справочника (как в исходной задаче)
// В реальной обработке эти элементы могут быть найдены или созданы заранее.
Перем Контрагент, ДоговорКонтрагента, ОбъектРасчетов, СтатьяДДС;

Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("Клиент Программа"); 
Если Контрагент = Неопределено Тогда
    Контрагент = Справочники.Контрагенты.СоздатьЭлемент();
    Контрагент.Наименование = "Клиент Программа";
    Контрагент.ПолноеНаименование = "Клиент Программа для тестирования";
    Контрагент.Записать();
КонецЕсли;

ДоговорКонтрагента = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию("Основной договор с клиентом Программа");
Если ДоговорКонтрагента = Неопределено Тогда
    ДоговорКонтрагента = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
    ДоговорКонтрагента.Владелец = Контрагент;
    ДоговорКонтрагента.Наименование = "Основной договор с клиентом Программа";
    ДоговорКонтрагента.ТипНалогообложенияНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаНеОблагаетсяНДС;
    ДоговорКонтрагента.ПорядокРасчетов = Перечисления.ПорядокРасчетов.ПоДоговорамКонтрагентов;
    ДоговорКонтрагента.Записать();
КонецЕсли;

ОбъектРасчетов = Справочники.ОбъектыРасчетов.НайтиПоНаименованию(ДоговорКонтрагента.Наименование); // Часто Наименование ОбъектаРасчетов совпадает с Наименованием Договора
Если ОбъектРасчетов = Неопределено Тогда
    ОбъектРасчетов = Справочники.ОбъектыРасчетов.СоздатьЭлемент();
    ОбъектРасчетов.Наименование = ДоговорКонтрагента.Наименование; 
    ОбъектРасчетов.ДоговорКонтрагента = ДоговорКонтрагента;
    ОбъектРасчетов.Контрагент = Контрагент;
    // ... другие необходимые реквизиты для ОбъектаРасчетов
    ОбъектРасчетов.Записать();
КонецЕсли;

СтатьяДДС = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("Поступление оплаты от клиентов");
Если СтатьяДДС = Неопределено Тогда
    СтатьяДДС = Справочники.СтатьиДвиженияДенежныхСредств.СоздатьЭлемент();
    СтатьяДДС.Наименование = "Поступление оплаты от клиентов";
    СтатьяДДС.ВидДвиженияДенежныхСредств = Перечисления.ВидыДвиженийДенежныхСредств.Поступления;
    СтатьяДДС.Записать();
КонецЕсли;

// Теперь заполняем строку табличной части
НоваяСтрока.Контрагент = Контрагент;
НоваяСтрока.ДоговорКонтрагента = ДоговорКонтрагента;
НоваяСтрока.ОбъектРасчетов = ОбъектРасчетов; // Вот он, реквизит, который не сохранялся!
НоваяСтрока.СтатьяДвиженияДенежныхСредств = СтатьяДДС; // И этот!
НоваяСтрока.Сумма = НовыйПКО.СуммаДокумента; // Сумма по строке должна соответствовать сумме документа
// Можно также заполнить другие необходимые реквизиты строки, например:
// НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.БезНДС; // Или другую ставку
// НоваяСтрока.СуммаНДС = 0;
// НоваяСтрока.НазначениеПлатежа = "Оплата по договору №...";

Обратите внимание, что поля ОбъектРасчетов и СтатьяДвиженияДенежныхСредств теперь присваиваются именно строке табличной части РасшифровкаПлатежа. Это гарантирует их корректное сохранение и использование в логике документа.

Шаг 4: Запись и проведение документа

После того как все реквизиты "шапки" и табличных частей заполнены, мы можем записать или провести документ. Для ПКО чаще всего требуется именно проведение, чтобы сформировались движения по регистрам (Касса, Взаиморасчеты, ДвижениеДенежныхСредств).


// Записываем и проводим документ
Попытка
    НовыйПКО.Записать(РежимЗаписиДокумента.Проведение);
    Сообщить("Документ 'Приходный кассовый ордер' успешно создан и проведен. Номер: " + НовыйПКО.Номер);
Исключение
    Сообщить("Ошибка при создании/проведении документа: " + ОписаниеОшибки());
КонецПопытки;

Почему этот подход правильный и какие механизмы задействованы?

Мы с вами выяснили, что в 1С:ERP, в контексте таких документов, как "Приходный кассовый ордер", детализация платежа и, следовательно, такие ключевые реквизиты как ОбъектРасчетов и СтатьяДвиженияДенежныхСредств, ожидаются именно в табличной части РасшифровкаПлатежа. Давайте рассмотрим подробнее, почему это так и какие механизмы при этом задействованы:

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

Таким образом, всегда, когда мы работаем с документами, имеющими табличные части, критически важно понимать, какие данные являются "шапочными", а какие — "строковыми". Для таких документов, как "Приходный кассовый ордер", детализация платежа всегда будет относиться к строкам табличной части РасшифровкаПлатежа. Заполнение именно этих строк гарантирует корректную работу документа и сохранение всех необходимых реквизитов.

Надеемся, что этот подробный разбор поможет вам успешно создавать и проводить документы "Приходный кассовый ордер" в 1С:ERP и избежать распространенных ошибок при программной работе с документами, имеющими табличные части. Успехов в разработке!

← На главную