При проведении регламентной операции «Закрытие месяца» (в частности, во время выполнения расчета торговой наценки по проданным товарам в комплексных конфигурациях, таких как УТП или УПП) пользователи и разработчики часто сталкиваются с крайне неприятной ошибкой платформы «1С:Предприятие»: Ошибка обработки представления "РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты: Поле не найдено (Субконто2)". Проблема коварна тем, что в предыдущие периоды закрытие месяца могло проходить абсолютно штатно, без каких-либо сбоев.
В этой статье мы подробно разберем, почему возникает эта ошибка с точки зрения внутренних механизмов платформы 1С, как на это влияют пользовательские настройки и какими способами можно навсегда решить эту проблему.
Для того чтобы понять природу ошибки, проанализируем поведение платформы «1С:Предприятие» при работе с виртуальными таблицами регистра бухгалтерии, такими как Остатки, Обороты или ОстаткиИОбороты. Построение динамической схемы полей этих таблиц напрямую зависит от использования параметра «Субконто» (в текстах запросов он часто называется &ВидыСубконто).
Существует два сценария работы платформы:
Субконто1, Субконто2 и Субконто3 формируются в схеме запроса всегда (исходя из максимально возможного количества субконто на счетах в системе, обычно до 3). Если у какого-то счета аналитик меньше, запрос все равно выполнится успешно, просто в «отсутствующих» колонках вернется значение Неопределено или NULL. Именно поэтому в консоли запросов у автора темы запрос отрабатывал корректно, когда параметр &ВидыСубконто очищался.Если в фильтр запроса попадает счет, у которого фактически на текущий момент настроено меньше субконто, чем ожидается (например, только одно субконто вместо трех), то на выходе пересечения массивов платформа сформирует в схеме виртуальной таблицы только поле Субконто1. Поля Субконто2 в структуре таблицы физически не будет существовать. Любая попытка обратиться к нему в секциях ВЫБРАТЬ, ГДЕ или в условиях соединения ПО... мгновенно вызовет аварийное завершение запроса с ошибкой Поле не найдено "Субконто2".
Алгоритм расчета торговой наценки анализирует остатки и обороты по двум ключевым счетам:
Запрос пытается соединить данные этих таблиц по аналитике. В параметрах виртуальной таблицы при этом жестко передается массив видов субконто, формируемый программно:
ВидыСубконто = Новый Массив;
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады);
Если РазделятьПоПартиям Тогда
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Партии);
КонецЕсли;
Если в системе по какой-то причине на счетах розничного учета или наценки пропало второе субконто (например, Склады), пересечение переданного массива с настройками счета даст только одно совпадение — Номенклатура. Платформа создаст виртуальную таблицу только с полем Субконто1, а обращение к Субконто2 при соединении таблиц вызовет ошибку.
Рассмотрим подробнее три основные практические причины, почему это происходит, даже если раньше все работало без сбоев.
Самая распространенная причина в практике ведения учета. Бухгалтер или администратор системы мог зайти в настройки параметров учета и случайно или намеренно снять флаг «Вести складской учет» (или отключить суммовой учет по складам), либо отключить «Партионный учет».
При отключении этих констант система автоматически программно снимает соответствующие виды субконто (Склады, Партии) со счетов учета ТМЦ. На счете остается только одно активное субконто — Номенклатура. Как результат — при следующем расчете наценки падает ошибка, так как платформа больше не видит второго субконто на счетах.
Иногда пользователи с административными правами вручную вносят корректировки в План счетов (в режиме «1С:Предприятие»). Например, они могли зайти в карточку счета 42.02 (или аналогичного счета наценки) и удалить оттуда предопределенное субконто (например, «Склады» или «Ставки НДС»), посчитав его лишним. Это мгновенно ломает логику типовых запросов закрытия месяца.
При обновлении нетиповых или сильно измененных конфигураций могут некорректно перенестись свойства предопределенных счетов. Флаги ведения субконто на субсчетах учета товаров в рознице или торговой наценки могут сброситься к дефолтным значениям, если обновление выполнялось без должного контроля сопоставления объектов.
---
Рассмотрим два основных пути решения проблемы: пользовательский (настройка параметров системы без изменения кода) и программный (для разработчиков, если конфигурация кастомизирована).
Проанализируем ситуацию и проверим ключевые настройки системы по шагам:
Перейдите в меню «Предприятие» -> «Настройка параметров учета» (или аналогичный раздел настроек вашей конфигурации). Перейдите на вкладку «Запасы». Убедитесь, что установлены флаги ведения складского учета и партионного учета (если ваша схема предполагает расчет себестоимости по партиям). Если флаги были сняты, верните их на место.
Откройте План счетов хозрасчетный. Найдите счета, которые участвуют в расчете торговой наценки (обычно это субсчета счетов 28 «Товары» и 285 «Торговая наценка» для Украины, либо 41 и 42 для РФ). Проверьте состав субконто на этих счетах.
Например, на счете учета наценки и на счете учета товаров в рознице обязательно должны быть сопоставимые виды субконто. Как минимум: Номенклатура (Субконто 1) и Склады (Субконто 2). Если субконто Склады отсутствует, добавьте его вручную в карточке счета в плане счетов.
Если вы столкнулись с этой ошибкой в доработанной конфигурации или во внешней обработке закрытия месяца, и при этом бизнес-логика допускает отсутствие некоторых аналитик на счетах, вы можете исправить сам запрос. Рассмотрим два способа изменения кода.
Самый простой способ избежать жесткого контроля метаданных платформой — не передавать массив видов субконто в параметры виртуальной таблицы ОстаткиИОбороты. Если убрать этот параметр, платформа перейдет на позиционную схему формирования полей, и в виртуальной таблице гарантированно будут присутствовать поля Субконто1, Субконто2 и Субконто3 (со значениями NULL для отсутствующих аналитик).
Посмотрим на пример изменения параметров в коде запроса:
// БЫЛО (вызывало ошибку при отсутствии субконто на счетах):
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Номенклатура,
| ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Склад,
| ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаОстатка
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачПериода, &КонПериода, , , &СчетаУчета, &ВидыСубконто, ) КАК ХозрасчетныйОстаткиИОбороты";
// СТАЛО (убираем &ВидыСубконто из параметров виртуальной таблицы):
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Номенклатура,
| ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Склад,
| ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаОстатка
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачПериода, &КонПериода, , , &СчетаУчета, , ) КАК ХозрасчетныйОстаткиИОбороты";
Важное примечание: При отказе от параметра видов субконто необходимо быть абсолютно уверенным, что на всех анализируемых счетах порядок следования субконто одинаков (например, везде первым идет Номенклатура, вторым — Склады). В противном случае позиционное сопоставление полей вернет некорректные данные.
Более надежный профессиональный подход — программно анализировать структуру субконто конкретного счета перед выполнением запроса и динамически формировать текст обращения к полям таблицы. Рассмотрим пример реализации:
// Проверяем количество субконто на счете торговой наценки
СчетТН = ПланыСчетов.Хозрасчетный.ТорговаяНаценка;
КоличествоСубконтоТН = СчетТН.ВидыСубконто.Количество();
ТекстСубконто2 = "НЕОПРЕДЕЛЕНО";
Если КоличествоСубконтоТН > 1 Тогда
// Если на счете больше одного субконто, мы можем безопасно обращаться к полю Субконто2
ТекстСубконто2 = "ХозрасчетныйОстаткиИОбороты.Субконто2";
КонецЕсли;
Запрос.Текст = СтрЗаменить(Запрос.Текст, "[ПолеСубконто2]", ТекстСубконто2);
Этот способ гарантирует, что запрос никогда не упадет с ошибкой «Поле не найдено», даже если состав субконто на счетах учета будет регулярно меняться пользователями в процессе работы с базой данных.