Почему выгрузка из 1С не видит документы за сегодняшний день и как это исправить

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

В процессе разработки и сопровождения самописных обработок для выгрузки данных во внешние системы (например, системы складского учета WMS или интернет-магазины) программисты часто сталкиваются с ситуацией, когда документы за текущий день не попадают в выборку. Это создает серьезные задержки в бизнес-процессах: склад не видит свежих заказов, а операторы вынуждены передавать данные вручную.

Рассмотрим детально причины возникновения этой проблемы на примере реального кейса, проанализируем программный код и найдем способы корректного получения данных «секунда в секунду».

Анализ механизма установки периода

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

Посмотрим на типичный некорректный пример:


НастройкаПериода.УстановитьПериод(Период.ДатаНачала, ?(Период.ДатаОкончания='0001-01-01', Период.ДатаОкончания, КонецДня(Период.ДатаОкончания)));

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

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


НастройкаПериода.УстановитьПериод(Период.ДатаНачала, ?(ЗначениеЗаполнено(Период.ДатаОкончания), КонецДня(Период.ДатаОкончания), КонецДня(ТекущаяДата())));

Использование функции КонецДня крайне важно, так как по умолчанию дата без указания времени воспринимается системой как 00:00:00 (начало дня). Если мы передадим в запрос дату «12.10.2023», то документы, созданные даже в одну секунду первого ночи этого же дня, могут не попасть в выборку.

Критическая ошибка: Внутреннее соединение с таблицей партий

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


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

Выясним причину, по которой ВНУТРЕННЕЕ СОЕДИНЕНИЕ (INNER JOIN) с таблицей ПартииТоваровНаСкладах обрезает данные текущего дня. Во многих типовых и доработанных конфигурациях (например, УТ 10.3, КА 1.1) используется механизм отложенного проведения по партиям.

Это означает следующее:

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

Результат: Если мы используем ВНУТРЕННЕЕ СОЕДИНЕНИЕ, то запрос вернет только те записи, которые есть в ОБЕИХ таблицах. Поскольку в таблице партий данных за сегодня еще нет, весь результат по сегодняшним документам просто отсекается. Чтобы этого избежать, необходимо использовать ЛЕВОЕ СОЕДИНЕНИЕ.

Ошибки в логике расчета количества

Рассмотрим еще один важный аспект — расчет поля «Количество». В исходном коде часто встречается странная конструкция в блоке ВЫБОР:


ВЫБОР
    КОГДА ТоварыНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)
        ТОГДА ЕСТЬNULL(ТоварыНаСкладахОбороты.КоличествоРасход, 0) + ЕСТЬNULL(ТоварыНаСкладахОбороты.КоличествоПриход, 0)
    ИНАЧЕ ЕСТЬNULL(ТоварыНаСкладахОбороты.КоличествоРасход, 0) + ЕСТЬNULL(ТоварыНаСкладахОбороты.КоличествоПриход, 0)
КОНЕЦ КАК Количество

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

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

Как правильно работать с границами периода в 1С

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

Пример правильной передачи параметров в запрос на языке 1С:


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

КонечнаяДата = ?(ЗначениеЗаполнено(Объект.ДатаОкончания), КонецДня(Объект.ДатаОкончания), КонецДня(ТекущаяДата()));

// Используем Границу для включения документов, попадающих на последнюю секунду
Запрос.УстановитьПараметр("Начало", НачалоДня(Объект.ДатаНачала));
Запрос.УстановитьПараметр("Конец", Новый Граница(КонечнаяДата, ВидГраницы.Включая));

Итоговые рекомендации по исправлению выгрузки

Подведем итоги и сформируем алгоритм исправления обработки выгрузки:

  1. Проверьте настройки периода: убедитесь, что дата окончания всегда приводится к КонецДня. Если выгрузка работает в автоматическом режиме, используйте ТекущаяДата() в качестве значения по умолчанию.
  2. Исправьте соединения в запросе: замените все ВНУТРЕННЕЕ СОЕДИНЕНИЕ на ЛЕВОЕ СОЕДИНЕНИЕ, если вы обращаетесь к вспомогательным регистрам (партии, затраты), которые могут заполняться не сразу.
  3. Пересмотрите логику выборки: старайтесь получать все необходимые данные из одной виртуальной таблицы (например, Обороты), не соединяя ее без крайней необходимости с основной физической таблицей регистра. Все нужные поля (Склад, Номенклатура) уже есть в измерениях виртуальной таблицы.
  4. Используйте объект Граница: это «золотой стандарт» разработки в 1С для исключения проблем с документами, созданными в 23:59:59.

Соблюдение этих правил позволит вашей системе интеграции работать стабильно, а данные в Biglit или любую другую внешнюю систему будут попадать мгновенно после проведения документов в 1С.

← На главную