При работе с конфигурацией «Управление торговлей 10.3» программисты часто сталкиваются с ситуацией, когда прямой запрос к виртуальным таблицам остатков регистра накопления ПартииТоваровНаСкладах выдает результат, отличный от данных типовых отчетов (например, «Ведомость по партиям товаров на складах»). Это вызывает недоумение, особенно когда склады и периоды указаны верно. Проанализируем причины этой проблемы и разберем по шагам, как найти и устранить источник расхождений.
Первым делом выясним причину, связанную с тем, как 1С работает с данными. Типовые отчеты в УТ 10.3 строятся на основе виртуальных таблиц остатков. Если вы пишете запрос к физической таблице (таблице движений), вы можете получить некорректные данные, если не учтете флаг Активность. Записи в регистре могут быть деактивированы (например, при отмене проведения документа), но они физически остаются в базе. Виртуальные таблицы 1С автоматически отсекают неактивные записи, в то время как в прямом запросе к движениям это нужно указывать явно:
ГДЕ
РегистрНакопления.ПартииТоваровНаСкладах.Активность = ИСТИНА
Рассмотрим ситуацию с установкой периода. В 1С время 00:00:00 начала дня может трактоваться по-разному. Если документ был проведен ровно в 00:00:00 первого числа месяца, то обычный запрос на дату '20231001000000' может не включить этот документ, если не использовать объект Граница. Типовые отчеты практически всегда используют Граница(КонецПериода, ВидГраницы.Включая).
Если ваш запрос обращается к остаткам на НачалоПериода, убедитесь, что вы сравниваете «яблоки с яблоками». Проанализируем ситуацию: отчет может выводить остатки на 01.10.2023 00:00:00 включая движения этой секунды, а ваш запрос — исключая их. В этом случае данные разойдутся ровно на сумму движений, попавших в «нулевую» секунду.
Одной из самых частых причин расхождений в УТ 10.3 является настройка «Списывать партии при проведении документов». Посмотрим на логику работы программы: если эта галка в настройках параметров учета снята, то при проведении реализации товар списывается только из регистра ТоварыНаСкладах (количественно). Регистр ПартииТоваровНаСкладах остается без изменений до тех пор, пока не будет запущена обработка «Проведение по партиям».
В этом случае «Ведомость по товарам на складах» покажет актуальный остаток, а «Ведомость по партиям» — завышенный. Проверим актуальность партионных данных, взглянув на наличие документов в очереди на проведение по партиям (регистр сведений СписанныеТовары).
Выясним, не кроется ли ошибка в разрезах учета. Регистр ПартииТоваровНаСкладах имеет измерения ХарактеристикаНоменклатуры, СерияНоменклатуры и Качество. Разберем пример: если в запросе вы группируете данные только по Номенклатуре, а в базе есть остаток +10 по качеству «Новый» и -10 по качеству «Брак», запрос может показать 0. Однако отчет с детальными настройками выведет обе строки.
Важно помнить, что УТ 10.3 допускает (хоть это и считается ошибкой учета) возникновение отрицательных остатков по партиям. Это происходит, когда товар отгружается «в минус» или когда перепутаны серии в приходе и расходе.
Иногда проблема носит чисто технический характер — повреждение таблиц итогов. 1С хранит рассчитанные остатки в специальных таблицах для ускорения работы. Если в результате сбоя итоги «разъехались» с реальными движениями, запрос к виртуальной таблице остатков вернет неверное значение, хотя детальный отчет по движениям (если его сформировать за весь период жизни базы) может показать правду.
Для решения этой проблемы выполним следующие действия:
Эта процедура заставит систему полностью пересчитать все остатки на основе физических записей регистра. После этого сравним данные запроса и отчета снова.
Если вышеперечисленные методы не помогли, проанализируем ситуацию вручную. Рассмотрим алгоритм сверки:
Партии товаров на складах.Товары на складах.Чтобы избежать ошибок с границами периода в своем коде, используйте следующий подход при работе с запросом:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура,
| Остатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&МоментВремени, Номенклатура = &Номенклатура) КАК Остатки";
// Чтобы получить остатки НА НАЧАЛО дня, включая документы этой секунды:
ГраницаОстатков = Новый Граница(НачалоДня(ВыбДата), ВидГраницы.Включая);
Запрос.УстановитьПараметр("МоментВремени", ГраницаОстатков);
Запрос.УстановитьПараметр("Номенклатура", ВыбНоменклатура);
Использование Граница гарантирует, что ваш запрос будет видеть те же данные, что и стандартные отчеты, использующие аналогичные механизмы компоновки данных.