При работе с регистром бухгалтерии "Хозрасчетный" в 1С:Предприятии 8.3 часто возникает необходимость программно получить значения субконто, привязанных к проводкам. Однако, разработчики сталкиваются с тем, что стандартные реквизиты типа "Субконто1", "Субконто2", "Субконто3" (и аналогичные) видны в конфигураторе, но не отображаются в конструкторе запросов к основной таблице самого регистра. Давайте подробно разберем, почему так происходит и какие существуют эффективные методы для доступа к этим данным.
Прежде всего, давайте выясним, почему стандартные реквизиты субконто, хотя и видны в конфигураторе, не отображаются в конструкторе запросов при обращении к основной таблице регистра бухгалтерии Хозрасчетный. Суть кроется в архитектуре хранения данных и механизмах работы платформы 1С:Предприятие.
Исторически, и на более ранних версиях платформы (до 8.3.15), субконто хранились не напрямую в основной таблице движений регистра бухгалтерии (например, РегистрБухгалтерии.Хозрасчетный), а в отдельных вспомогательных таблицах (например, РегистрБухгалтерии.Хозрасчетный.Субконто). Платформа самостоятельно управляла этими связями, объединяя данные из разных таблиц при необходимости. Поэтому прямой запрос к основной таблице не мог "видеть" поля субконто, так как их там физически не было.
Начиная с платформы 8.3.15, структура хранения регистра бухгалтерии изменилась. Теперь субконто могут записываться непосредственно в основную таблицу движений Хозрасчетный. Для этого было добавлено 24 поля для хранения субконто, по 12 для дебета и кредита (СубконтоДт1...СубконтоДт12 и СубконтоКт1...СубконтоКт12). Это изменение привело к увеличению объема хранимых данных, но в некоторых случаях ускорило получение данных, так как платформа могла напрямую читать информацию о субконто из основной таблицы. По сути, "виртуальная" таблица ДвиженияДтКт (или ее аналоги) для новых движений стала более приближенной к реальной физической таблице.
Однако, критически важно понимать: несмотря на изменения в физическом хранении, для прикладного разработчика "виртуальная таблица" не является физически существующей таблицей в базе данных в традиционном смысле. Это скорее механизм, который платформа использует для формирования сложного запроса, объединяющего данные из различных физических таблиц (основные движения, данные субконто, итоги) в единый результат. Когда мы обращаемся к виртуальной таблице, платформа "транслирует" наш запрос в более сложный SQL-запрос, который корректно извлекает и связывает все необходимые данные. Именно поэтому конструктор запросов к основной таблице регистра не предлагает поля субконто напрямую, а предлагает это делать через специальные механизмы.
Наиболее распространенный, гибкий и рекомендуемый способ получения полной информации о проводках, включая значения субконто, – это использование специальной виртуальной таблицы ДвиженияССубконто. Эта таблица специально предназначена для того, чтобы предоставить разработчику все данные проводки в одном "снимке", включая аналитику.
Виртуальная таблица ДвиженияССубконто (или ХозрасчетныйДвиженияССубконто для конкретного регистра бухгалтерии Хозрасчетный) автоматически соединяет данные основной таблицы движений регистра бухгалтерии с соответствующими значениями субконто. Таким образом, мы получаем полную картину проводки со всеми необходимыми аналитическими разрезами.
Давайте рассмотрим пример запроса, который демонстрирует, как использовать эту виртуальную таблицу для получения необходимых данных:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйДвиженияССубконто.Период КАК Период,
| ХозрасчетныйДвиженияССубконто.Организация,
| ХозрасчетныйДвиженияССубконто.Регистратор,
| ХозрасчетныйДвиженияССубконто.Активность,
| ХозрасчетныйДвиженияССубконто.СчетДт,
| ХозрасчетныйДвиженияССубконто.СубконтоДт1,
| ХозрасчетныйДвиженияССубконто.СубконтоДт2,
| ХозрасчетныйДвиженияССубконто.СубконтоДт3,
| ХозрасчетныйДвиженияССубконто.СчетКт,
| ХозрасчетныйДвиженияССубконто.СубконтоКт1,
| ХозрасчетныйДвиженияССубконто.СубконтоКт2,
| ХозрасчетныйДвиженияССубконто.СубконтоКт3,
| ХозрасчетныйДвиженияССубконто.Сумма,
| ХозрасчетныйДвиженияССубконто.КоличествоДт,
| ХозрасчетныйДвиженияССубконто.КоличествоКт
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК ХозрасчетныйДвиженияССубконто
|ГДЕ
| ХозрасчетныйДвиженияССубконто.Период МЕЖДУ &ДатаНач И &ДатаКон
| И ХозрасчетныйДвиженияССубконто.Активность = ИСТИНА
| И ХозрасчетныйДвиженияССубконто.СчетДт = &СчетДт";
Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("СчетДт", ПланыСчетов.Хозрасчетный.НайтиПоКоду("60"));
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить("Период: " + Выборка.Период
+ ", Организация: " + Выборка.Организация
+ ", СчетДт: " + Выборка.СчетДт
+ ", СубконтоДт1: " + Выборка.СубконтоДт1);
КонецЦикла;
Разберем ключевые моменты этого подхода:
РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто. Это сообщает платформе, что нам нужна полная информация о движениях регистра Хозрасчетный, включая все его измерения, ресурсы и, конечно же, субконто.СубконтоДт1, СубконтоДт2, СубконтоДт3 (и аналогичные для кредитовой стороны: СубконтоКт1, СубконтоКт2, СубконтоКт3). Эти поля уже содержат ссылки на конкретные значения видов характеристик, которые являются значениями субконто.ДвиженияССубконто можно использовать такие параметры, как Период, Счет, Субконто, КорСубконто и другие. Важно отметить, что параметры Субконто и КорСубконто принимают не значения субконто (например, "Контрагент 1"), а виды субконто (например, ПланыВидовХарактеристик.ВидыСубконто.Контрагенты) или массив таких видов. Для отбора по конкретным значениям субконто (например, по конкретному контрагенту) используются параметры "Условие" в секции ГДЕ, как показано в примере выше с СчетДт = &СчетДт.ДвиженияССубконто могут попадать как активные, так и неактивные записи. Поэтому при формировании запросов, как правило, рекомендуется добавлять условие на Активность = ИСТИНА, чтобы получать только актуальные проводки.Этот подход является универсальным и широко используется для построения разнообразных отчетов (таких как "Карточка счета", "Отчет по проводкам") и заполнения экранных форм, отображающих проводки.
В некоторых случаях, если вам требуется получить субконто для конкретной записи регистра, или вы итерируете по набору записей регистра бухгалтерии, можно использовать программный подход, обращаясь к свойствам объекта ЗаписьРегистра без непосредственного запроса к виртуальной таблице. Этот метод особенно полезен, когда логика получения субконто может зависеть от вида счета, и вы хотите динамически обрабатывать каждый вид аналитики.
Рассмотрим пример кода, который демонстрирует, как получить все субконто для каждой проводки в наборе записей регистра:
// Пусть у нас есть некий документ, движения которого мы хотим проанализировать
// Например, это может быть ссылка на документ "Поступление (акты, накладные)"
// ТвойДокумент = Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру("000000001", Дата("20230101"));
// Для примера, возьмем произвольный документ
ТвойДокумент = РегистрыБухгалтерии.Хозрасчетный.НайтиПоНомерДокумента("000000001", Дата("20230101"), Метаданные.Документы.ПоступлениеТоваровУслуг.ПолноеИмя); // Пример получения ссылки на документ
Если ТвойДокумент = Неопределено Тогда
Сообщить("Документ не найден.");
Возврат;
КонецЕсли;
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ТвойДокумент);
НаборЗаписей.Прочитать(); // Обязательно прочитать записи после установки отбора
Для Каждого ЗаписьРегистра Из НаборЗаписей Цикл
Сообщить("Проводка: " + ЗаписьРегистра.СчетДт + " - " + ЗаписьРегистра.СчетКт + ", Сумма: " + ЗаписьРегистра.Сумма);
// Получаем субконто по дебетовому счету
Для Каждого Субконто Из ЗаписьРегистра.СчетДт.ВидыСубконто Цикл
НазваниеВидаСубконто = Субконто.ВидСубконто.ИмяПредопределенныхДанных; // Имя вида субконто (например, "Контрагенты")
ЗначениеСубконто = ЗаписьРегистра.СубконтоДт[Субконто.ВидСубконто];
Если ЗначениеСубконто <> Неопределено Тогда
Сообщить(" Дт Субконто (" + НазваниеВидаСубконто + "): " + Строка(ЗначениеСубконто));
КонецЕсли;
КонецЦикла;
// Получаем субконто по кредитовому счету
Для Каждого Субконто Из ЗаписьРегистра.СчетКт.ВидыСубконто Цикл
НазваниеВидаСубконто = Субконто.ВидСубконто.ИмяПредопределенныхДанных;
ЗначениеСубконто = ЗаписьРегистра.СубконтоКт[Субконто.ВидСубконто];
Если ЗначениеСубконто <> Неопределено Тогда
Сообщить(" Кт Субконто (" + НазваниеВидаСубконто + "): " + Строка(ЗначениеСубконто));
КонецЕсли;
КонецЦикла;
КонецЦикла;
Объясняем шаги этого программного метода:
НаборЗаписей для регистра бухгалтерии Хозрасчетный с помощью метода РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей(). Этот объект позволяет нам работать с коллекцией записей регистра.НаборЗаписей. В данном примере отбор установлен по регистратору (документу), что позволяет нам получить все проводки, сделанные конкретным документом. Вы можете установить любой другой необходимый отбор.Прочитать(). Этот метод выполняет запрос к базе данных и заполняет объект НаборЗаписей данными в соответствии с установленным отбором. Без этого шага НаборЗаписей будет пуст.ЗаписьРегистра в заполненном НаборЗаписей. Каждая ЗаписьРегистра представляет собой одну бухгалтерскую проводку.ЗаписьРегистра мы можем получить доступ к дебетовому счету (ЗаписьРегистра.СчетДт) и кредитовому счету (ЗаписьРегистра.СчетКт). У каждого объекта ПланСчетовСсылка.Хозрасчетный (представляющего счет) есть коллекция ВидыСубконто. Эта коллекция содержит информацию о том, какие виды аналитики (например, "Контрагенты", "Договоры") привязаны к данному счету.ВидыСубконто, мы можем получить конкретное значение субконто для текущей проводки. Это делается путем обращения к коллекции СубконтоДт или СубконтоКт объекта ЗаписьРегистра, используя в качестве индекса объект ВидСубконто (например, ЗаписьРегистра.СубконтоДт[Субконто.ВидСубконто]).Этот метод особенно полезен, когда вы работаете с отдельными проводками или когда вам нужна динамическая обработка субконто, которая зависит от настройки конкретного счета. Например, если на счете 60.01 первое субконто – это контрагент, а на счете 62.01 – тоже контрагент, но на счете 90.01 – номенклатурная группа, этот подход позволяет гибко определить, какие субконто существуют для текущего счета, и получить их значения. Количество полей СубконтоДт<N> и СубконтоКт<N>, доступных для использования, определяется в плане счетов в свойстве "Максимальное количество субконто". Установка ненулевого значения в этом свойстве активирует соответствующие стандартные реквизиты.
Как мы видим, доступ к субконто регистра бухгалтерии Хозрасчетный в 1С:Предприятии 8.3 не вызывает сложностей, если понимать основные механизмы платформы. Вы можете использовать один из двух основных подходов:
ДвиженияССубконто: Это наиболее мощный и гибкий способ для построения отчетов и получения большого объема данных, где платформа самостоятельно выполняет все необходимые соединения.НаборЗаписей и ЗаписьРегистра: Этот метод удобен для работы с отдельными проводками, когда требуется динамически определить и обработать субконто в зависимости от привязки к счету.Выбор конкретного метода зависит от вашей задачи. Понимание особенностей хранения данных и принципов работы виртуальных таблиц значительно упрощает работу с таким сложным, но крайне важным и мощным объектом конфигурации, как регистр бухгалтерии.