Как правильно получить остатки за минусом резервов в 1С 7.7 Торговля и склад

Программист 1С v7.7 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке выгрузок, обработок и отчетов в конфигурации «1С:Торговля и склад 7.7» нередко возникает задача рассчитать реальный свободный остаток номенклатуры на складе: Свободный остаток = Физический остаток - Резерв. Однако при написании прямого запроса ко встроенному языку запросов 1С 7.7 программисты часто сталкиваются с ситуацией, когда полученные цифры не сходятся со стандартными отчетами программы. Разберем по шагам, почему возникают расхождения и как правильно реализовать выборку данных.

Анализ типового запроса и причин расхождений

Посмотрим на пример запроса, который объединяет два регистра накопления — Регистр.ОстаткиТМЦ и Регистр.РезервыТМЦ:


ТекстЗапроса = 
"//{{ЗАПРОС(Сформировать)
|Без итогов;    
|Период С {НашаДата} по {НашаДата};
|Номенклатура = Регистр.ОстаткиТМЦ.Номенклатура, Регистр.РезервыТМЦ.Номенклатура;
|Склад = Регистр.ОстаткиТМЦ.Склад, Регистр.РезервыТМЦ.Склад;
|Количество = Регистр.ОстаткиТМЦ.Количество;                        
|Резерв = Регистр.РезервыТМЦ.Количество;
|Группировка Номенклатура упорядочить по Номенклатура.Код БЕЗ Групп; 
|Функция КоличествоКонОст = КонОст(Количество);
|Функция РезервКонОст = КонОст(Резерв);  
|Условие(Склад = ВыбСклад);
|";

Выясним основные причины, из-за которых результат такого запроса может отличаться от данных отчета «Остатки ТМЦ»:

  1. Единицы измерения и коэффициенты пересчета. В регистрах 1С 7.7 остатки хранятся исключительно в базовых единицах измерения (коэффициент = 1). В типовых отчетах выводятся данные с учетом выбранной единицы (основной или единицы отчета) путем деления на коэффициент: ПечКол = ПечКол / ТЗ.ПечЕд.Коэффициент. Если номенклатура ведется в упаковках или коробках, базовый остаток в штуках будет кратно больше.
  2. Особенности точки актуальности (ТА) и периода запроса. Конструкция Период С ... По ... рассчитывает остаток с учетом движений документов за указанный интервал. Если требуется срез на текущий момент (на ТА), указание периода может приводить к лишнему пересчету или некорректному учету документов, проведенных будущим числом.
  3. Дополнительные разрезы учета (Фирма, Заявка). Регистр РезервыТМЦ хранит остатки в разрезе фирмы и документа резервирования. Если при запросе не накладывается фильтр по конкретной фирме, суммируются резервы всех организаций базы данных.
  4. Отрицательные остатки («красные» резервы). Штатные отчеты могут маскировать или отдельно обрабатывать некорректно закрытые резервы, тогда как прямой запрос честно выдает отрицательные значения.

Способ 1. Использование типовых функций глобального модуля

Рассмотрим самый надежный способ получения корректных остатков. В типовой конфигурации «Торговля и склад 7.7» реализованы специальные функции, учитывающие все внутренние механизмы и настройки учета компании:

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

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

Способ 2. Получение итогов через объектную модель регистров

Проанализируем альтернативный вариант, который работает быстрее встроенного языка запросов при формировании данных на Точку Актуальности (ТА). Для этого обратимся к регистрам напрямую через метод ВыгрузитьИтоги():


// Создаем объекты регистров
РегОст = СоздатьОбъект("Регистр.ОстаткиТМЦ");
РегРез = СоздатьОбъект("Регистр.РезервыТМЦ");

// Устанавливаем фильтрацию по складу
РегОст.УстановитьЗначениеФильтра("Склад", ВыбСклад, 1);
РегРез.УстановитьЗначениеФильтра("Склад", ВыбСклад, 1);

// Выгружаем актуальные остатки в таблицы значений
ТЗ_Остатки = СоздатьОбъект("ТаблицаЗначений");
ТЗ_Резервы = СоздатьОбъект("ТаблицаЗначений");

РегОст.ВыгрузитьИтоги(ТЗ_Остатки, 1, 1);
РегРез.ВыгрузитьИтоги(ТЗ_Резервы, 1, 1);

После выгрузки объединим таблицы по номенклатуре в результирующую ТаблицаЗначений и рассчитаем свободный остаток:


ТЗ_Итог = СоздатьОбъект("ТаблицаЗначений");
ТЗ_Итог.НоваяКолонка("Номенклатура", "Справочник.Номенклатура");
ТЗ_Итог.НоваяКолонка("Остаток", "Число", 15, 3);
ТЗ_Итог.НоваяКолонка("Резерв", "Число", 15, 3);
ТЗ_Итог.НоваяКолонка("Свободно", "Число", 15, 3);

// Заполняем остатки
ТЗ_Остатки.ВыбратьСтроки();
Пока ТЗ_Остатки.ПолучитьСтроку() = 1 Цикл
    ТЗ_Итог.НоваяСтрока();
    ТЗ_Итог.Номенклатура = ТЗ_Остатки.Номенклатура;
    ТЗ_Итог.Остаток      = ТЗ_Остатки.Количество;
    ТЗ_Итог.Резерв       = 0;
    ТЗ_Итог.Свободно     = ТЗ_Остатки.Количество;
КонецЦикла;

// Вычитаем зарезервированные позиции
ТЗ_Резервы.ВыбратьСтроки();
Пока ТЗ_Резервы.ПолучитьСтроку() = 1 Цикл
    Стр = 0;
    Если ТЗ_Итог.НайтиЗначение(ТЗ_Резервы.Номенклатура, Стр, "Номенклатура") = 1 Тогда
        ТЗ_Итог.ПолучитьСтрокуПоНомеру(Стр);
        ТЗ_Итог.Резерв   = ТЗ_Резервы.Количество;
        ТЗ_Итог.Свободно = ТЗ_Итог.Остаток - ТЗ_Резервы.Количество;
    КонецЕсли;
КонецЦикла;

Способ 3. Заимствование логики из типового отчета «Остатки ТМЦ»

Если требуется получить данные с помощью встроенного объекта Запрос на произвольную дату в прошлом, наиболее правильный путь — открыть стандартный отчет ОстаткиТМЦ в конфигураторе и скопировать блок формирования текста запроса оттуда. Это позволит избежать ошибок при совместной обработке нескольких регистров и учесть все тонкости типовой конфигурации.

Важные рекомендации по устранению ошибок:

  1. Перед отладкой запросов выполните тестирование информационной базы через меню «Администрирование -> Тестирование и исправление ИБ» с включенным флагом «Пересчет итогов».
  2. Убедитесь, что в базе отсутствуют зависшие движения задним числом с помощью обработки восстановления последовательности документов.
  3. Всегда контролируйте единицы измерения номенклатуры при сравнении результатов выборки с экранными формами отчетов.
← На главную