Почему в запросе 1С субконто возвращает NULL, хотя в проводках оно заполнено?

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

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

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

---

Причина 1. Путаница между Налоговым и Хозрасчетным регистрами (Ошибка в коде)

Первое, на что необходимо обратить внимание при возникновении расхождений — это соответствие источников данных в запросе и в последующей обработке. Рассмотрим фрагмент кода, аналогичный тому, который часто приводит к недоумению:


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

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

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

Проанализируем эту ситуацию. В запросе получение данных происходит из виртуальной таблицы налогового регистра (РегистрБухгалтерии.Налоговый.Обороты). Именно в налоговом учете по конкретному счету субконто может отсутствовать (возвращается NULL), из-за чего документ-регистратор и попадает в выборку.

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

---

Причина 2. Порядок субконто: Запрос против Отладчика

Другая распространенная проблема кроется в понимании того, как платформа позиционирует субконто. В языке запросов поля Субконто1, Субконто2, Субконто3 жестко привязаны к порядку видов субконто, заданному для конкретного счета в Плане счетов конфигурации.

Выясним, как это работает на примере счета 10.10. Предположим, на нем настроены виды субконто в следующем порядке:

  1. Номенклатура
  2. Склады
  3. Партии

Если в запросе мы проверяем условие Субконто2 ЕСТЬ NULL, мы ожидаем увидеть отсутствие Склада. Однако в отладчике при просмотре коллекции Субконто объекта Проводка элементы могут отображаться не по номерам позиций в плане счетов, а по алфавиту названий видов субконто:

В этом случае разработчик визуально видит в отладчике, что "второе" по списку субконто (Партии) заполнено, тогда как в запросе проверялось поле Субконто2 (которое на уровне базы данных соответствует Складу). Чтобы избежать этой путаницы, рекомендуется использовать обращение к субконто в запросах через параметры или виртуальные таблицы с указанием конкретного вида субконто:


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

---

Причина 3. Удаление субконто из конфигурации и «фантомные» данные в БД

Рассмотрим более сложный сценарий: субконто было физически удалено из счета в Конфигураторе (или был удален сам вид субконто из конфигурации), но в режиме предприятия пользователи продолжают видеть его в некоторых отчетах или проводках.

Когда вы удаляете связь счета с видом субконто в Конфигураторе, платформа 1С перестает проецировать это субконто на позиционные поля виртуальных таблиц (Субконто1...Субконто3). В результате в любых запросах к виртуальным таблицам по этому смещению возвращается NULL.

При этом физические записи в СУБД (таблицы движений регистра бухгалтерии) автоматически не очищаются. В базе данных остаются так называемые "фантомные" или битые ссылки. Метод Прочитать() для набора записей считывает строки напрямую из физической таблицы движений, где эти "удаленные" субконто все еще записаны.

---

Как решить проблему и вернуть данные на место?

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

Вариант А. Перепроведение документов

Если субконто было удалено ошибочно, верните его настройки на счет в Конфигураторе. После этого самым простым и безопасным способом восстановить движения является перепроведение документов-регистраторов. При проведении модуль документа заново сформирует движения по актуальным правилам конфигурации, затерев старые некорректные записи.

Вариант Б. Проведение Тестирования и исправления (ТИИ)

Если перепроведение документов в закрытом периоде невозможно или нежелательно, воспользуйтесь встроенными утилитами платформы. Выполните тестирование и исправление информационной базы (обязательно на резервной копии!):

  1. Запустите базу в режиме Конфигуратора.
  2. Перейдите в меню Администрирование — Тестирование и исправление...
  3. Установите флаг «Проверка логической целостности» и «Реиндексация таблиц информационной базы».
  4. В блоке настройки обработки неработающих ссылок выберите «Очищать объекты» или «Создавать дефолтные» (в зависимости от вашей задачи).

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

Вариант В. Программная корректировка движений

В случаях, когда ТИИ не помогает, можно написать внешнюю обработку для точечной очистки или заполнения субконто без изменения других реквизитов проводки и без перепроведения документа. Рассмотрим пример кода:


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

Для Каждого Проводка Из Набор Цикл
    Если Проводка.СчетДт = ПланыСчетов.Хозрасчетный.ТоварыНаСкладах Тогда
        // Устанавливаем значение субконто напрямую по имени вида субконто
        Проводка.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады] = НужныйСклад;
    КонецЕсли;
КонецЦикла;

// Записываем набор с флагом ОбменДанными.Загрузка, чтобы обойти проверки проведения
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();

Использование свойства ОбменДанными.Загрузка = Истина позволяет перезаписать движения регистра напрямую, не вызывая повторное проведение документа и сохраняя неизменными остальные данные учета.

← На главную