Сверка остатков 1С и WMS находит расхождения, а товар на месте. Откуда они берутся

21.09.26

Учетные задачи - Логистика, склад и ТМЦ

Кладовщик получает задачу: на складе проверки лежат две штуки. Идёт в зону, а там всё на месте и никакой задачи в складской системе нет. Так работала автоматическая сверка остатков между учётной и складской системами: разницу она переносила документом, а комментарий к этому документу восемь месяцев отправлял людей искать несуществующий ноль. Робота разобрали до кода. Обе сравниваемые величины оказались синтетическими: слева физический срез с вычетами по активности и окнами в 60 минут и 12 часов, справа учётный остаток на конец дня минус трёхчасовой хвост непроведённых ордеров. Порог срабатывания стоял в нуле, поэтому робот исправно оформлял собственный шум измерения: за 60 дней он сам создал 62,7% оборота технического склада, а 2 081 артикул из 2 102 приезжал туда и уезжал обратно. Внутри обе формулы, замер лага отгрузки, снятая гипотеза и честная граница данных.

Робот сверки остатков ходил по номенклатуре, сравнивал количество в учётной системе (ERP, Enterprise Resource Planning, система управления ресурсами предприятия) с количеством в складской (WMS, Warehouse Management System, система управления складом) и найденную разницу сам переносил документом на технический склад проверки. В комментарии к документу стояла строка "при нулевых остатках в WMS". Восемь месяцев её читали как показание прибора: склад отдал ноль, товар пропал, идите искать.

Подняли снимок конкретного запуска из журнала регистрации. Учётная система в момент запуска: 438. Складская: 436. Разница 2, перенесено 2. Нуля там не было никогда, и по этой позиции его не было ни разу.

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

 

Чья это боль

Такой робот стоит у многих, кто живёт на двух системах. Логика у всех примерно одна: регламентным заданием пробегаем по остаткам, находим расхождение, оформляем его документом, чтобы учёт не расходился с физикой. Дальше начинается быт: кладовщик получает задачу "на складе проверки две штуки", идёт в зону, а там всё на месте и никакой задачи в складской системе нет. Он приходит с вопросом "где потеря". Ему отвечают строкой из комментария: "в WMS был ноль". Он идёт искать ноль, которого не было.

Цена такой петли измеряется не этими двумя штуками. Она в том, что склад перестаёт верить документам, а разработчик получает регулярный поток обращений без единого воспроизводимого случая. Восемь месяцев разбора шли по ложному следу, хотя реальные числа лежали рядом: событие "Синхронизация остатков" в журнале регистрации пишет оба значения на момент запуска.

Вывод раздела: при жалобе на робота первым делом поднимаем его собственный протокол в журнале. Документ он породил уже потом, и как источник он вторичен.

 

Почему очевидное решение не работает

Очевидное решение звучит так: раз системы расходятся, чиним обмен. Ищем, где теряется движение, добавляем ретраи, сверяем очередь.

На этом проекте чинить было нечего. Обычный цикл "отбор - отгрузка - расходный ордер" оказался атомарным. Замерили лаг между физической отгрузкой в складской системе и появлением расходного ордера в учётной на пяти случаях подряд: 0, 0, 9, 13 и 1 секунда. Верхняя граница 13 секунд. Робот просыпается по расписанию регламентного задания, и его окно на порядки больше: попасть внутрь тринадцатисекундного разрыва можно, но регулярную разницу такой канал не даст.

То есть обмен работал. Расхождение бралось из другого места.

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

 

Первое: комментарий был константой

Строка "при нулевых остатках в WMS" стоит в коде процедуры, которая формирует перемещение. Она пишется на каждый документ независимо от того, какие числа робот увидел. Когда-то она описывала одну ветку логики, ветка изменилась, строка осталась.

Дальше сработала обычная человеческая механика: текст в документе выглядит как факт, потому что его написала программа. Программа же не врёт. Врёт наше предположение, что она формулирует по данным.

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

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

 

Второе: обе цифры робота - синтетика

Это главное. Робот сравнивал два числа, из которых ни одно не равно остатку своего регистра в моменте.

Складская сторона считалась так:

ОстатокWMS = россыпь(зона_1) + россыпь(зона_2) + содержимое_коробов
             - позиции из списка исключений

Список исключений выкидывал позицию целиком, если по ней:

  • была отгрузка в окне 60 минут (для закрытых заказов) или 12 часов (для открытых);
  • была приёмка младше 12 часов;
  • была корректировка младше 60 минут.

Учётная сторона считалась так:

ОстатокERP = остаток регистра на конец дня
             - непроведённые расходные ордера младше 3 часов

Почему формулы такие. Каждое исключение когда-то ставили под конкретную ложную тревогу: приходила жалоба "робот увёл товар, который в этот момент отбирали", и в код добавлялось окно. Логика понятная, вот только каждое окно делает величину чуть менее похожей на остаток и чуть более похожей на "остаток за вычетом того, что нас недавно ругали".

Два следствия, которые видны прямо из формул.

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

Второе: окна разной длины (60 минут против 12 часов в одной формуле) делают невозможным разбор инцидента по времени документа. Позиция не паркуется в момент причины. Она паркуется в первый тихий момент после волны активности, когда все окна исключений успели закрыться. Между событием и документом может лежать полсуток и любое количество чужих движений. Разбирать такой документ по времени бесполезно, и склад, который честно смотрит "что происходило в 14:20", не найдёт ничего.

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

 

Третье: порог стоял в нуле

При таких формулах разница между ними колеблется сама по себе. На быстрой позиции измеренный дрейф составил 2 единицы при остатке 438, это 0,46%. По второй позиции того же снимка разница была 4 (86 против 82) и разошлась двумя перемещениями, 1 и 3.

Порог срабатывания у робота был нулевой. Любая разница больше нуля превращалась в документ.

Отсюда тезис, который я готов защищать: автоматическая сверка двух учётных систем в первую очередь меряет собственную методику измерения, и её порог обязан быть больше шума этой методики. Если порог ноль, а формулы разные, вы построили генератор задач для склада. Он будет работать вечно, потому что источник у него бесконечный: сама разница определений.

Масштаб генерации на разобранном складе проверки за 60 дней:

Показатель Значение
Строк движений 9 372
Документов-регистраторов 2 061
Артикулов 2 102
Приход 15 879
Расход 15 490
Нетто +389
Оборот (приход + расход) 31 369

Из этого оборота 19 660 единиц, то есть 62,7%, создаёт напрямую сам робот сверки. И 2 081 артикул из 2 102 имеют и приход, и расход по этому складу: товар уезжает на проверку и возвращается обратно. Второй робот, пополнение канала, тянет позиции назад, и на горячих днях счёт взаимных перекидок идёт на десятки.

Нетто +389 единиц за два месяца при обороте 31 369 - это отношение примерно 1 к 80. Восемьдесят движений ради одного результата.

Вывод раздела: посчитайте по своему техническому складу долю движений, которую создаёт сам робот. Если она в районе половины оборота, склад работает на сверку, а не сверка на склад.

 

Гипотеза, которую пришлось снять

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

Замер лага её убил. 0, 0, 9, 13, 1 секунда - конвейер атомарен, разъезжаться там нечему. Версию сняли.

Осталось объяснить дрейф по дням, а он был. Нетто по дням за пять дней подряд:

День Учётная система Складская система
1 -31 -31
2 +50 +59
3 -13 -25
4 +60 +60
5 -10 -10
Сумма +56 +53

Первый, четвёртый и пятый день совпадают точно. Расходятся второй и третий, и суммарно за пять дней набегает 3 единицы.

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

Дальше самое неприятное для авторов исходного разбора. Робот вычитает непроведённые расходные ордера младше 3 часов, то есть компенсирует ровно тот канал, который и без него атомарен (0-13 секунд), и никак не компенсирует канал с реальным суточным сдвигом. Заплатка стоит мимо источника. Работает она при этом честно: три часа действительно гасят часть колебаний, только по совпадению.

Вывод раздела: если поправка стоит в коде давно и никто не помнит, под что её ставили, померьте канал, который она чинит. Есть шанс, что чинить там нечего.

 

Про арифметику, которую надо считать руками

Накопленные за пять дней +3 и припаркованные роботом +2 связаны базовым сдвигом в одну единицу. В рабочей записи разбора эта связка была записана как "+3 минус (-1) = +2", и она не сходится: три минус минус один это четыре. Числа по краям подтверждены независимо, оба верны, неверна была только запись перехода между ними: базовый сдвиг вычитается со знаком плюс, 3 - 1 = 2.

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

 

Честная граница: мгновенный срез задним числом здесь не воспроизводится

Тут начинается часть, которую обычно не пишут.

Фактический срез регистра по всем складам на момент запуска робота даёт 442 (165 + 3 + 10 + 110 + 154). Робот в ту же секунду записал 438. Разрыв 4 единицы. Он больше, чем найденная роботом разница, ради которой всё затевалось.

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

Причины, по которым в такой базе это в принципе нормально:

  • за один вечер прошло 670 допроведений документов прошлыми датами;
  • правка наборов записей и изменение количеств в табличных частях при перепроведении не журналируются вовсе;
  • регистр остатков складской системы журналируется не полностью: зона отбора опустошается молча, наблюдали исчезновение ячейки на 24 штуки без единого события в журнале;
  • replay журнала против живого состояния дал 240 против 214, расхождение 26 единиц;
  • номера документов переиспользуются примерно раз в год, поиск по номеру без фильтра по дате находит четыре разных документа.

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

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

 

Спящий дефект: процедура мутирует список, по которому же и считает

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

Не выстрелило только потому, что объект пересоздаётся на каждый запуск. Это не защита, это везение конкретной реализации: любой рефакторинг с кэшированием объекта включает дефект.

Проверяется механически. Ищем в процедуре расчёта все места, где в коллекцию параметров что-то добавляется, и смотрим, приходит эта коллекция снаружи или собирается локально. Приходит снаружи и модифицируется - дефект, независимо от того, срабатывает он сегодня.

Вывод раздела: список складов, по которому считается сверка, должен собираться заново внутри расчёта. Общий на весь цикл массив рано или поздно получит в себя результат самого расчёта.

 

Что с этим делать

Порядок такой.

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

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

Поднять порог выше шума методики. Как его выбрать: взять историю сверок за месяц, построить распределение модуля разницы по позициям и посмотреть, где начинается хвост. На разобранном складе дрейф на быстрых позициях был около 0,5%, а типовая срабатывавшая разница составляла 1-2 единицы при остатках в сотни.

Или, вместо порога, требовать повтора. Позиция паркуется, если разница держится два прогона подряд. Шум методики между прогонами меняется, реальная недостача остаётся.

Здесь же граница честности. Порог мы не подобрали на исторических данных. Рекомендация "от трёх единиц или два прогона подряд" выглядит разумной, но сколько реальных расхождений она пропустит, на этих данных не посчитано. Пока это гипотеза, требующая прогона по истории. Копировать её в свою конфигурацию как готовую цифру рано. Кто такой прогон сделает, тот и закроет вопрос по-настоящему.

Отдельно: категория "перемещения с другим комментарием" - 942 документа с нетто +1 584 единицы - осталась неразобранной по шаблонам. Это почти треть оборота технического склада, и что там внутри, честно говоря, неизвестно.

 

Открытый вопрос

Прямой ответ на исходный вопрос склада "где потеря": потери не было ни одной. Был прибор, который меряет сам себя, и строка-константа, которая восемь месяцев отправляла людей искать несуществующий ноль.

Мне интересно, насколько это общий случай. С каким порогом стоит сверка у вас, и мерил ли кто-нибудь распределение модуля разницы за месяц до того, как поставить этот порог? Если у вас порог ноль и склад при этом не жалуется, это тоже ответ, и мне он был бы полезен: значит формулы у вас сопоставимы, и интересно, как вы этого добились.

Снимок конкретного запуска, с которого начался весь разбор, лежит в журнале регистрации, и достать его руками из боевой базы за восемь месяцев тяжело. У нас это делает Журнал регистрации, свёрнутый для нейросети: события сворачиваются до строк с параметрами, и видно оба числа на момент прогона, а не пересказ в комментарии документа.

Другие наши инструменты диагностики 1С:

Вступайте в нашу телеграмм-группу Инфостарт

сверка остатков расхождение остатков WMS ERP склад проверки порог сверки ложные срабатывания регламентное задание журнал регистрации перемещение товаров шум измерения обмен данными технический склад инвентаризация аудит остатков

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Логистика, склад и ТМЦ 1С:Предприятие 8 Россия Платные (руб)

Подсистема автоматизированного управления складом AS WMS для конфигураций на платформе 1С 8. AS WMS – готовое решение для эффективного управления, хранения и учета на адресном складе. Внедрение системы AS WMS способствует быстрому отбору товара, ускорению инвентаризации, снижению зависимости от персонала, исключению пересорта. AS WMS встраивается в любую конфигурацию на платформе 1С 8 и работает как единая система без обменов. В учетной системе нет необходимости менять процессы под AS WMS (например, вводить ордерную схему), AS WMS использует стандартные документы по товародвижению вашей учетной системы.

50000 руб.

26.07.2023    13216    64    0    

14

Перенос данных 1C Взаиморасчеты Оптовая торговля Логистика, склад и ТМЦ Файловый обмен (TXT, XML, DBF), FTP Системный администратор Разработчик 1С:Предприятие 8 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Управленческий учет Платные (руб)

Можно проверить до покупки, оставьте заявку! Воспользовались более 268 компаний! Перенос данных из УТ 10.3 в УТ 11 | из УТ 10.3 в КА 2 | из УТ 10.3 в ERP. Решение для перехода с УТ 10.3. Можно перенести начальные остатки, нормативно-справочную информацию и все возможные документы. При выгрузке можно установить отбор по периоду, организациям и складам.

50200 руб.

24.04.2015    210089    180    253    

299

Обмен с ГосИС Логистика, склад и ТМЦ Разработчик Пользователь 1С:Предприятие 8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

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

6649 руб.

09.01.2024    20047    204    30    

185

Логистика, склад и ТМЦ Бухгалтер Пользователь 1С:Предприятие 8 Сельское хозяйство и рыболовство Строительство Горнодобывающая промышленность Розничная и сетевая торговля (FMCG) Транспорт, автопарки, такси Оптовая торговля, дистрибуция, логистика Лесное и деревообрабатывающее хозяйство Управленческий учет Платные (руб)

Позволяет автоматизировать процесс взвешивания ТМЦ в организациях, осуществляющих приемку и отгрузку различным транспортом, для ведения складского учета и контроля остатков на складах. Конфигурация позволяет фиксировать вес вручную, напрямую с весов, а также управлять дополнительным оборудованием и контролировать движение транспорта.

40000 руб.

24.03.2015    140060    355    118    

146
Для отправки сообщения требуется регистрация/авторизация