Как программно получить значения субконто регистра бухгалтерии "Хозрасчетный" в 1С:Предприятии 8.3?

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

При работе с регистром бухгалтерии "Хозрасчетный" в 1С:Предприятии 8.3 часто возникает необходимость программно получить значения субконто, привязанных к проводкам. Однако, разработчики сталкиваются с тем, что стандартные реквизиты типа "Субконто1", "Субконто2", "Субконто3" (и аналогичные) видны в конфигураторе, но не отображаются в конструкторе запросов к основной таблице самого регистра. Давайте подробно разберем, почему так происходит и какие существуют эффективные методы для доступа к этим данным.

Причины, по которым субконто не видны напрямую в конструкторе запросов к регистру

Прежде всего, давайте выясним, почему стандартные реквизиты субконто, хотя и видны в конфигураторе, не отображаются в конструкторе запросов при обращении к основной таблице регистра бухгалтерии Хозрасчетный. Суть кроется в архитектуре хранения данных и механизмах работы платформы 1С:Предприятие.

Исторически, и на более ранних версиях платформы (до 8.3.15), субконто хранились не напрямую в основной таблице движений регистра бухгалтерии (например, РегистрБухгалтерии.Хозрасчетный), а в отдельных вспомогательных таблицах (например, РегистрБухгалтерии.Хозрасчетный.Субконто). Платформа самостоятельно управляла этими связями, объединяя данные из разных таблиц при необходимости. Поэтому прямой запрос к основной таблице не мог "видеть" поля субконто, так как их там физически не было.

Начиная с платформы 8.3.15, структура хранения регистра бухгалтерии изменилась. Теперь субконто могут записываться непосредственно в основную таблицу движений Хозрасчетный. Для этого было добавлено 24 поля для хранения субконто, по 12 для дебета и кредита (СубконтоДт1...СубконтоДт12 и СубконтоКт1...СубконтоКт12). Это изменение привело к увеличению объема хранимых данных, но в некоторых случаях ускорило получение данных, так как платформа могла напрямую читать информацию о субконто из основной таблицы. По сути, "виртуальная" таблица ДвиженияДтКт (или ее аналоги) для новых движений стала более приближенной к реальной физической таблице.

Однако, критически важно понимать: несмотря на изменения в физическом хранении, для прикладного разработчика "виртуальная таблица" не является физически существующей таблицей в базе данных в традиционном смысле. Это скорее механизм, который платформа использует для формирования сложного запроса, объединяющего данные из различных физических таблиц (основные движения, данные субконто, итоги) в единый результат. Когда мы обращаемся к виртуальной таблице, платформа "транслирует" наш запрос в более сложный SQL-запрос, который корректно извлекает и связывает все необходимые данные. Именно поэтому конструктор запросов к основной таблице регистра не предлагает поля субконто напрямую, а предлагает это делать через специальные механизмы.

Способ 1: Получение субконто с помощью виртуальной таблицы "ДвиженияССубконто"

Наиболее распространенный, гибкий и рекомендуемый способ получения полной информации о проводках, включая значения субконто, – это использование специальной виртуальной таблицы ДвиженияССубконто. Эта таблица специально предназначена для того, чтобы предоставить разработчику все данные проводки в одном "снимке", включая аналитику.

Виртуальная таблица ДвиженияССубконто (или ХозрасчетныйДвиженияССубконто для конкретного регистра бухгалтерии Хозрасчетный) автоматически соединяет данные основной таблицы движений регистра бухгалтерии с соответствующими значениями субконто. Таким образом, мы получаем полную картину проводки со всеми необходимыми аналитическими разрезами.

Давайте рассмотрим пример запроса, который демонстрирует, как использовать эту виртуальную таблицу для получения необходимых данных:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
 | ХозрасчетныйДвиженияССубконто.Период КАК Период,
 | ХозрасчетныйДвиженияССубконто.Организация,
 | ХозрасчетныйДвиженияССубконто.Регистратор,
 | ХозрасчетныйДвиженияССубконто.Активность,
 | ХозрасчетныйДвиженияССубконто.СчетДт,
 | ХозрасчетныйДвиженияССубконто.СубконтоДт1,
 | ХозрасчетныйДвиженияССубконто.СубконтоДт2,
 | ХозрасчетныйДвиженияССубконто.СубконтоДт3,
 | ХозрасчетныйДвиженияССубконто.СчетКт,
 | ХозрасчетныйДвиженияССубконто.СубконтоКт1,
 | ХозрасчетныйДвиженияССубконто.СубконтоКт2,
 | ХозрасчетныйДвиженияССубконто.СубконтоКт3,
 | ХозрасчетныйДвиженияССубконто.Сумма,
 | ХозрасчетныйДвиженияССубконто.КоличествоДт,
 | ХозрасчетныйДвиженияССубконто.КоличествоКт
 |ИЗ
 | РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК ХозрасчетныйДвиженияССубконто
 |ГДЕ
 | ХозрасчетныйДвиженияССубконто.Период МЕЖДУ &ДатаНач И &ДатаКон
 | И ХозрасчетныйДвиженияССубконто.Активность = ИСТИНА
 | И ХозрасчетныйДвиженияССубконто.СчетДт = &СчетДт";

Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("СчетДт", ПланыСчетов.Хозрасчетный.НайтиПоКоду("60"));

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    Сообщить("Период: " + Выборка.Период 
            + ", Организация: " + Выборка.Организация 
            + ", СчетДт: " + Выборка.СчетДт 
            + ", СубконтоДт1: " + Выборка.СубконтоДт1);
КонецЦикла;

Разберем ключевые моменты этого подхода:

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

Этот подход является универсальным и широко используется для построения разнообразных отчетов (таких как "Карточка счета", "Отчет по проводкам") и заполнения экранных форм, отображающих проводки.

Способ 2: Программное получение субконто через объекты "НаборЗаписей" и "ЗаписьРегистра"

В некоторых случаях, если вам требуется получить субконто для конкретной записи регистра, или вы итерируете по набору записей регистра бухгалтерии, можно использовать программный подход, обращаясь к свойствам объекта ЗаписьРегистра без непосредственного запроса к виртуальной таблице. Этот метод особенно полезен, когда логика получения субконто может зависеть от вида счета, и вы хотите динамически обрабатывать каждый вид аналитики.

Рассмотрим пример кода, который демонстрирует, как получить все субконто для каждой проводки в наборе записей регистра:


// Пусть у нас есть некий документ, движения которого мы хотим проанализировать
// Например, это может быть ссылка на документ "Поступление (акты, накладные)"
// ТвойДокумент = Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру("000000001", Дата("20230101")); 
// Для примера, возьмем произвольный документ
ТвойДокумент = РегистрыБухгалтерии.Хозрасчетный.НайтиПоНомерДокумента("000000001", Дата("20230101"), Метаданные.Документы.ПоступлениеТоваровУслуг.ПолноеИмя); // Пример получения ссылки на документ

Если ТвойДокумент = Неопределено Тогда
    Сообщить("Документ не найден.");
    Возврат;
КонецЕсли;

НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ТвойДокумент);
НаборЗаписей.Прочитать(); // Обязательно прочитать записи после установки отбора

Для Каждого ЗаписьРегистра Из НаборЗаписей Цикл
    Сообщить("Проводка: " + ЗаписьРегистра.СчетДт + " - " + ЗаписьРегистра.СчетКт + ", Сумма: " + ЗаписьРегистра.Сумма);

    // Получаем субконто по дебетовому счету
    Для Каждого Субконто Из ЗаписьРегистра.СчетДт.ВидыСубконто Цикл
        НазваниеВидаСубконто = Субконто.ВидСубконто.ИмяПредопределенныхДанных; // Имя вида субконто (например, "Контрагенты")
        ЗначениеСубконто = ЗаписьРегистра.СубконтоДт[Субконто.ВидСубконто];
        Если ЗначениеСубконто <> Неопределено Тогда
            Сообщить("    Дт Субконто (" + НазваниеВидаСубконто + "): " + Строка(ЗначениеСубконто));
        КонецЕсли;
    КонецЦикла;

    // Получаем субконто по кредитовому счету
    Для Каждого Субконто Из ЗаписьРегистра.СчетКт.ВидыСубконто Цикл
        НазваниеВидаСубконто = Субконто.ВидСубконто.ИмяПредопределенныхДанных;
        ЗначениеСубконто = ЗаписьРегистра.СубконтоКт[Субконто.ВидСубконто];
        Если ЗначениеСубконто <> Неопределено Тогда
            Сообщить("    Кт Субконто (" + НазваниеВидаСубконто + "): " + Строка(ЗначениеСубконто));
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

Объясняем шаги этого программного метода:

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

Этот метод особенно полезен, когда вы работаете с отдельными проводками или когда вам нужна динамическая обработка субконто, которая зависит от настройки конкретного счета. Например, если на счете 60.01 первое субконто – это контрагент, а на счете 62.01 – тоже контрагент, но на счете 90.01 – номенклатурная группа, этот подход позволяет гибко определить, какие субконто существуют для текущего счета, и получить их значения. Количество полей СубконтоДт<N> и СубконтоКт<N>, доступных для использования, определяется в плане счетов в свойстве "Максимальное количество субконто". Установка ненулевого значения в этом свойстве активирует соответствующие стандартные реквизиты.

Заключение

Как мы видим, доступ к субконто регистра бухгалтерии Хозрасчетный в 1С:Предприятии 8.3 не вызывает сложностей, если понимать основные механизмы платформы. Вы можете использовать один из двух основных подходов:

  1. Запросы к виртуальной таблице ДвиженияССубконто: Это наиболее мощный и гибкий способ для построения отчетов и получения большого объема данных, где платформа самостоятельно выполняет все необходимые соединения.
  2. Программный доступ через объекты НаборЗаписей и ЗаписьРегистра: Этот метод удобен для работы с отдельными проводками, когда требуется динамически определить и обработать субконто в зависимости от привязки к счету.

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

← На главную