Как правильно задать порядок и выполнить отбор по субконто в запросах к регистру бухгалтерии 1С?

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

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

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

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

Двойная роль параметра "Субконто" в запросах

Параметр Субконто выполняет две ключевые функции, которые мы разберем по шагам:

  1. Отбор итогов по видам субконто: Этот параметр позволяет выбрать данные только по тем видам субконто, которые вы явно перечислили в массиве.
  2. Упорядочивание видов субконто в результате запроса: Он явно задает, какой вид субконто будет соответствовать полям Субконто1, Субконто2 и т.д. в результирующей выборке. Это соответствие устанавливается независимо от того, в каком порядке они настроены на счете в конфигураторе или были изменены пользователем.

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

Как работает отбор по видам субконто

Когда вы передаете массив видов субконто в параметр Субконто, запрос будет работать по принципу логического "И" (пересечения). Это означает, что в выборку попадут только те счета, у которых присутствуют все перечисленные в массиве виды субконто. Если счет имеет меньше видов субконто, чем указано в массиве, или хотя бы один из указанных видов субконто на счете отсутствует, то данные по такому счету не попадут в выборку. Это очень важный момент, который часто вызывает путаницу.

Рассмотрим пример, приведенный в исходном сообщении:


ВЫБРАТЬ
    БИ.Счет КАК Счет,
    БИ.Субконто1 КАК Субконто1,
    БИ.Субконто2 КАК Субконто2,
    БИ.СуммаОборот КАК СуммаОборот
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Обороты(, , , , &ВС, , , ) КАК БИ;

// Где &ВС формируется следующим образом:
ВС = Новый Массив;
ВС.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);
ВС.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
ВС.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Подразделения);
ВС.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);
ВС.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтруктурныеЕдиницы);
Запрос.УстановитьПараметр("ВС", ВС);

В этом примере, если мы передадим в параметр &ВС массив, содержащий, скажем, пять видов субконто (Номенклатура, Контрагенты, Подразделения, Договоры, СтруктурныеЕдиницы), то в результат запроса попадут только те счета, которые имеют все эти пять видов субконто одновременно. Если у какого-либо счета есть только "Номенклатура" и "Контрагенты", то этот счет не будет включен в выборку, поскольку у него отсутствуют "Подразделения", "Договоры" и "СтруктурныеЕдиницы".

Таким образом, если вы формируете запрос с большим количеством видов субконто в массиве (например, десять), и ни один из ваших счетов не имеет все эти десять видов субконто одновременно, то результат запроса будет пустым. Это является прямым ответом на вопрос автора, который предполагал, что если счет имеет только два субконто, то они как-то "подстроятся" под первые элементы массива. Нет, отбор работает строго по принципу "все указанные". Для интерактивной отладки таких выборок и быстрой проверки параметров запроса подойдёт консоль запросов для 1С.

Как работает упорядочивание видов субконто

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

Вернемся к нашему примеру. Если в массиве &ВС мы сначала добавили ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура, а затем ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, то в результате запроса:

  1. Поле БИ.Субконто1 всегда будет содержать значение субконто типа "Номенклатура".
  2. Поле БИ.Субконто2 всегда будет содержать значение субконто типа "Контрагенты".

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

Если счет имеет, например, три вида субконто (Номенклатура, Контрагенты, Договоры), а в ваш массив &ВС вы передали только "Номенклатура" и "Контрагенты", то в полях Субконто1 и Субконто2 вы увидите "Номенклатуру" и "Контрагентов" соответственно. Вид субконто "Договоры" в этом случае не будет доступен через позиционное поле СубконтоN в соответствии с заданным массивом, поскольку он не был указан в массиве-параметре.

Таким образом, мы видим, что параметр Субконто не только фильтрует, но и "типизирует" поля СубконтоN в результате запроса, обеспечивая предсказуемость структуры выходных данных.

Рекомендации по использованию и лучшие практики

На основе вышеизложенного и опыта работы с платформой 1С, мы можем сформулировать следующие рекомендации:

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

Давайте еще раз посмотрим на пример кода, чтобы закрепить понимание:


// Предположим, у нас есть счета:
// 41.01: Субконто1 - Номенклатура, Субконто2 - Склады
// 60.01: Субконто1 - Контрагенты, Субконто2 - Договоры
// 44.01: Субконто1 - Подразделения

// Сценарий 1: Получить обороты по счетам, у которых есть Номенклатура и Склады.
// При этом в выборке Субконто1 должно быть Номенклатура, а Субконто2 - Склады.
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    БИ.Счет КАК Счет,
    |    БИ.Субконто1 КАК Номенклатура,
    |    БИ.Субконто2 КАК Склад,
    |    БИ.СуммаОборот КАК СуммаОборот
    |ИЗ
    |    РегистрБухгалтерии.Хозрасчетный.Обороты(, , , , &ВидыСубконто, , , ) КАК БИ";

МассивВидовСубконто = Новый Массив;
МассивВидовСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);
МассивВидовСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады);
Запрос.УстановитьПараметр("ВидыСубконто", МассивВидовСубконто);

// В результате мы получим данные только по счету 41.01,
// где Номенклатура будет в поле "Номенклатура", а Склад в поле "Склад".
// Счета 60.01 и 44.01 не попадут, т.к. у них нет обоих указанных видов субконто.

// Сценарий 2: Получить обороты по счетам, у которых есть только Контрагенты.
Запрос2 = Новый Запрос;
Запрос2.Текст = 
    "ВЫБРАТЬ
    |    БИ.Счет КАК Счет,
    |    БИ.Субконто1 КАК Контрагент,
    |    БИ.СуммаОборот КАК СуммаОборот
    |ИЗ
    |    РегистрБухгалтерии.Хозрасчетный.Обороты(, , , , &ВидыСубконто2, , , ) КАК БИ";

МассивВидовСубконто2 = Новый Массив;
МассивВидовСубконто2.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
Запрос2.УстановитьПараметр("ВидыСубконто2", МассивВидовСубконто2);

// В результате мы получим данные только по счету 60.01.
// Поле "Контрагент" будет содержать значение субконто типа "Контрагенты".
// Счет 41.01 не попадет, потому что у него нет вида субконто "Контрагенты".
// Счет 44.01 не попадет по той же причине.

// Сценарий 3: Массив с большим количеством видов субконто.
Запрос3 = Новый Запрос;
Запрос3.Текст = 
    "ВЫБРАТЬ
    |    БИ.Счет КАК Счет,
    |    БИ.Субконто1 КАК Номенклатура,
    |    БИ.Субконто2 КАК Контрагент,
    |    БИ.Субконто3 КАК Склад,
    |    БИ.СуммаОборот КАК СуммаОборот
    |ИЗ
    |    РегистрБухгалтерии.Хозрасчетный.Обороты(, , , , &ВидыСубконто3, , , ) КАК БИ";

МассивВидовСубконто3 = Новый Массив;
МассивВидовСубконто3.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);
МассивВидовСубконто3.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
МассивВидовСубконто3.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады);
Запрос3.УстановитьПараметр("ВидыСубконто3", МассивВидовСубконто3);

// Если ни один счет в базе не имеет одновременно Номенклатуру, Контрагентов и Склады,
// то Запрос3 вернет пустой результат.

Заключение

Таким образом, параметр Субконто в запросах к регистру бухгалтерии в 1С является мощным инструментом для управления как отбором данных, так и структурой выходных полей. Осознанное его использование позволяет нам создавать надежные, предсказуемые и, потенциально, более производительные запросы, что особенно важно при работе с комплексными задачами, такими как свертка базы или поддержание единообразия данных в распределенных информационных системах. Всегда помните о его двойной функции — фильтрации по принципу "И" и жестком упорядочивании полей СубконтоN.

← На главную