Начнем с анализа типичной ситуации, с которой сталкиваются разработчики при программном создании документов в системе 1С, в частности, такого важного документа как "Приходный кассовый ордер" (ПКО) в конфигурации 1С:ERP. Мы рассмотрим проблему, когда, казалось бы, все необходимые реквизиты заполнены в объекте документа перед его записью, но после сохранения документа эти реквизиты оказываются пустыми. Давайте разберемся, в чем здесь может быть причина и как корректно решить эту задачу.
Представьте ситуацию: вы разрабатываете обработку в 1С:ERP, которая должна программно формировать документы "Приходный кассовый ордер". В процессе создания документа вы тщательно заполняете его основные реквизиты, такие как ОбъектРасчетов и СтатьяДвиженияДенежныхСредств. Используя отладчик, вы убеждаетесь, что перед вызовом метода Записать() или Записать(РежимЗаписиДокумента.Проведение) эти реквизиты содержат корректные значения. Однако, открыв документ после его записи, вы обнаруживаете, что эти поля пусты. В чем же дело? Почему система "забывает" те значения, которые вы так старательно ей передавали?
Эта ситуация встречается достаточно часто и является одной из ключевых особенностей работы с документами в 1С, особенно в сложных конфигурациях, таких как 1С:ERP Управление предприятием. Давайте выясним, почему так происходит и как правильно организовать заполнение данных.
Для полного понимания проблемы, нам необходимо глубже рассмотреть, как устроено хранение данных в документах 1С. В большинстве документов можно выделить два основных типа реквизитов:
Когда объект документа считывается или записывается, система обращается ко всей информации, относящейся к этому объекту, из обеих таблиц, обеспечивая тем самым целостность и полноту данных.
В конфигурации 1С:ERP, как и во многих других современных решениях, документ "Приходный кассовый ордер" имеет свою специфическую логику обработки. Несмотря на то, что на форме документа могут присутствовать поля, дублирующие реквизиты "шапки" (например, для ОбъектРасчетов или СтатьяДвиженияДенежныхСредств), или может казаться, что эти поля должны заполняться напрямую, внутренняя логика проведения документа и механизмы подсистем (таких как Взаиморасчеты, Казначейство, Учет денежных средств) зачастую ожидают ключевые данные именно в табличной части.
Для документа ПКО в 1С:ERP такой ключевой табличной частью является РасшифровкаПлатежа. Именно в этой табличной части хранится детализация поступивших денежных средств: от кого, за что, по какому договору, с какой статьей движения денежных средств и т.д. Система спроектирована таким образом, что при проведении документа она в первую очередь обращается к данным из этой табличной части для формирования движений по регистрам и корректного отражения операций в учете. Значения, напрямую установленные в реквизитах "шапки", могут быть просто проигнорированы, перезаписаны или не учтены, если они не продублированы или не являются основными для заполнения в соответствующей табличной части.
Теперь, когда мы понимаем структуру документов и логику ПКО, причина "потери" реквизитов становится очевидной. Если вы заполняете ОбъектРасчетов и СтатьяДвиженияДенежныхСредств только напрямую в объекте документа ПриходныйКассовыйОрдер (как реквизиты "шапки"), но система ожидает эти данные в строке табличной части РасшифровкаПлатежа, то после записи документа эти значения могут не сохраниться. Система при проведении или записи документа будет брать данные именно из табличной части для формирования движений по регистрам и корректного учета взаиморасчетов, движения денежных средств и прочего. Таким образом, заполнение табличной части РасшифровкаПлатежа является критически важным для того, чтобы эти ключевые реквизиты были сохранены и обработаны согласно логике конфигурации.
Итак, решение проблемы заключается в корректном программном заполнении табличной части РасшифровкаПлатежа документа "Приходный кассовый ордер". Давайте рассмотрим подробный алгоритм и пример кода, который позволит нам успешно создавать ПКО с сохранением всех необходимых реквизитов.
Сначала мы создаем новый объект документа ПриходныйКассовыйОрдер и заполняем его базовые реквизиты "шапки", которые являются общими для всего документа.
// Создаем новый документ Приходный кассовый ордер
НовыйПКО = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();
// Заполняем основные реквизиты "шапки" документа
НовыйПКО.Дата = ТекущаяДата();
НовыйПКО.Организация = Справочники.Организации.НайтиПоНаименованию("Наша Организация"); // Замените на вашу организацию
НовыйПКО.Касса = Справочники.Кассы.НайтиПоНаименованию("Основная касса"); // Замените на вашу кассу
НовыйПКО.СуммаДокумента = 1000; // Пример суммы
НовыйПКО.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду("643"); // Российский рубль
НовыйПКО.ВидОперации = Перечисления.ВидыОперацийПоступленияДенежныхСредств.ОплатаОтКлиента;
Обратите внимание, что даже если в ВидОперации мы выбрали "ОплатаОтКлиента", это лишь определяет общий характер операции. Детализация, куда именно будет отнесена эта оплата (по какому договору, объекту расчетов, статье ДДС), должна быть указана в табличной части.
Ключевым моментом является добавление новой строки в табличную часть РасшифровкаПлатежа и последующее заполнение необходимых реквизитов именно в этой строке.
// Добавляем новую строку в табличную часть "РасшифровкаПлатежа"
НоваяСтрока = НовыйПКО.РасшифровкаПлатежа.Добавить();
После выполнения этой операции переменная НоваяСтрока будет ссылаться на только что созданную строку табличной части, и мы можем приступить к заполнению ее реквизитов.
Теперь мы заполняем те реквизиты, которые ранее пытались установить напрямую в "шапке" документа, но теперь делаем это в контексте строки табличной части. В вашем случае это ОбъектРасчетов и СтатьяДвиженияДенежныхСредств, а также другие важные для платежа поля, такие как Контрагент, ДоговорКонтрагента, Сумма.
Предположим, у нас уже есть ссылки на необходимые справочники, созданные ранее, как было указано в исходном сообщении:
ДоговорыКонтрагентов, содержащий нужные параметры (Тип налогообложения НДС, Порядок расчетов).ОбъектыРасчетов, соответствующий этому Договору.СтатьиДвиженияДенежныхСредств "Поступление оплаты от клиентов".
// Пример получения ссылок на необходимые объекты
// Допустим, мы ранее создали ДоговорКонтрагента и ОбъектРасчетов
// и получили ссылку на СтатьюДвиженияДенежныхСредств
// Пример создания элементов справочника (как в исходной задаче)
// В реальной обработке эти элементы могут быть найдены или созданы заранее.
Перем Контрагент, ДоговорКонтрагента, ОбъектРасчетов, СтатьяДДС;
Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("Клиент Программа");
Если Контрагент = Неопределено Тогда
Контрагент = Справочники.Контрагенты.СоздатьЭлемент();
Контрагент.Наименование = "Клиент Программа";
Контрагент.ПолноеНаименование = "Клиент Программа для тестирования";
Контрагент.Записать();
КонецЕсли;
ДоговорКонтрагента = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию("Основной договор с клиентом Программа");
Если ДоговорКонтрагента = Неопределено Тогда
ДоговорКонтрагента = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
ДоговорКонтрагента.Владелец = Контрагент;
ДоговорКонтрагента.Наименование = "Основной договор с клиентом Программа";
ДоговорКонтрагента.ТипНалогообложенияНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаНеОблагаетсяНДС;
ДоговорКонтрагента.ПорядокРасчетов = Перечисления.ПорядокРасчетов.ПоДоговорамКонтрагентов;
ДоговорКонтрагента.Записать();
КонецЕсли;
ОбъектРасчетов = Справочники.ОбъектыРасчетов.НайтиПоНаименованию(ДоговорКонтрагента.Наименование); // Часто Наименование ОбъектаРасчетов совпадает с Наименованием Договора
Если ОбъектРасчетов = Неопределено Тогда
ОбъектРасчетов = Справочники.ОбъектыРасчетов.СоздатьЭлемент();
ОбъектРасчетов.Наименование = ДоговорКонтрагента.Наименование;
ОбъектРасчетов.ДоговорКонтрагента = ДоговорКонтрагента;
ОбъектРасчетов.Контрагент = Контрагент;
// ... другие необходимые реквизиты для ОбъектаРасчетов
ОбъектРасчетов.Записать();
КонецЕсли;
СтатьяДДС = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("Поступление оплаты от клиентов");
Если СтатьяДДС = Неопределено Тогда
СтатьяДДС = Справочники.СтатьиДвиженияДенежныхСредств.СоздатьЭлемент();
СтатьяДДС.Наименование = "Поступление оплаты от клиентов";
СтатьяДДС.ВидДвиженияДенежныхСредств = Перечисления.ВидыДвиженийДенежныхСредств.Поступления;
СтатьяДДС.Записать();
КонецЕсли;
// Теперь заполняем строку табличной части
НоваяСтрока.Контрагент = Контрагент;
НоваяСтрока.ДоговорКонтрагента = ДоговорКонтрагента;
НоваяСтрока.ОбъектРасчетов = ОбъектРасчетов; // Вот он, реквизит, который не сохранялся!
НоваяСтрока.СтатьяДвиженияДенежныхСредств = СтатьяДДС; // И этот!
НоваяСтрока.Сумма = НовыйПКО.СуммаДокумента; // Сумма по строке должна соответствовать сумме документа
// Можно также заполнить другие необходимые реквизиты строки, например:
// НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.БезНДС; // Или другую ставку
// НоваяСтрока.СуммаНДС = 0;
// НоваяСтрока.НазначениеПлатежа = "Оплата по договору №...";
Обратите внимание, что поля ОбъектРасчетов и СтатьяДвиженияДенежныхСредств теперь присваиваются именно строке табличной части РасшифровкаПлатежа. Это гарантирует их корректное сохранение и использование в логике документа.
После того как все реквизиты "шапки" и табличных частей заполнены, мы можем записать или провести документ. Для ПКО чаще всего требуется именно проведение, чтобы сформировались движения по регистрам (Касса, Взаиморасчеты, ДвижениеДенежныхСредств).
// Записываем и проводим документ
Попытка
НовыйПКО.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ 'Приходный кассовый ордер' успешно создан и проведен. Номер: " + НовыйПКО.Номер);
Исключение
Сообщить("Ошибка при создании/проведении документа: " + ОписаниеОшибки());
КонецПопытки;
Мы с вами выяснили, что в 1С:ERP, в контексте таких документов, как "Приходный кассовый ордер", детализация платежа и, следовательно, такие ключевые реквизиты как ОбъектРасчетов и СтатьяДвиженияДенежныхСредств, ожидаются именно в табличной части РасшифровкаПлатежа. Давайте рассмотрим подробнее, почему это так и какие механизмы при этом задействованы:
РасчетыСКлиентами) и регистры учета денежных средств (например, ДенежныеСредства, ДвиженияДенежныхСредств) обычно имеют измерения, которые соответствуют Контрагенту, ДоговоруКонтрагента, ОбъектуРасчетов и СтатьеДвиженияДенежныхСредств. Если в документе несколько строк расшифровки, каждая из них может относиться к разным контрагентам, договорам или статьям ДДС, что требует отдельного движения по регистрам. Поэтому система берет данные именно из строк табличной части, чтобы сформировать корректные движения.РасшифровкаПлатежа. Например, одна общая сумма может быть получена от одного контрагента, но относиться к оплате по нескольким договорам или объектам расчетов, либо включать оплату за разные виды услуг, каждый из которых относится к своей статье движения денежных средств. Если бы эти реквизиты хранились только в "шапке", то такая детализация была бы невозможна.РасшифровкаПлатежа для хранения ключевых аналитических данных гарантирует, что документ будет правильно обработан всеми подсистемами, сформирует корректные движения и будет участвовать в отчетах.
Таким образом, всегда, когда мы работаем с документами, имеющими табличные части, критически важно понимать, какие данные являются "шапочными", а какие — "строковыми". Для таких документов, как "Приходный кассовый ордер", детализация платежа всегда будет относиться к строкам табличной части РасшифровкаПлатежа. Заполнение именно этих строк гарантирует корректную работу документа и сохранение всех необходимых реквизитов.
Надеемся, что этот подробный разбор поможет вам успешно создавать и проводить документы "Приходный кассовый ордер" в 1С:ERP и избежать распространенных ошибок при программной работе с документами, имеющими табличные части. Успехов в разработке!