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