УТ 10.3 Контролируем остатки автоматически

Один из менеджеров довольно крупной торговой конторы стройматериалов озадачил сделать ему так, чтобы "Торговля" сама предупреждала его о минимальном остатке товара на складах, так как "я сам постоянно забываю смотреть отчеты по точкам заказам и остаткам товаров, много организационной работы".
Раньше немного занимался Delphi для души и немного для работы, сейчас же больше полугода работаю с 1С,
и первое, что мне пришло в голову это Таймер на главной форме с запросом проверяющем остатки и выдающим предупреждение.

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

Если в Delphi таймер, то подобие в 1с8 — это [b]ПодключитьОбработчикОжидания(«НаименованиеЗапускаемойПроцедуры», КоличествоСекунд, Однократно);[/b]

Итак, начнем!

 Открываем конфигуратор и в дереве конфигурации кликаем правой кнопкой по головному звену (Названию конфигурации) и в контекстном меню выбираем «Открыть модуль приложения»

В открывшемся модуле, в конце создаем процедуру под названием:

Процедура ПроверкаОстатков() Экспорт
//….

КонецПроцедуры

ПодключитьОбработчикОжидания(«ПроверкаОстатков», 30, Истина);

В данном коде мы создаем процедуру которая будет запускаться через заданное время, переодичность запуска указываем в методе формы ПодключитьОбработчикОжидания, а так же значение «Истина» указывает на то, что при запуске эта процедура будет отрабатывать один раз, по заданию начальника ; ).

Ну а теперь, как 1с узнает, что остатков то уже мало и пора кричать громко, чтобы все узнали.
Как и было предложено, я взял документ типовой конфигурации «Установка значений точки заказа»

Для сравнения будем использовать поле «ЗначениеТочкиЗаказа» одноименного РегистраСведений и сравнивать будем с остатками товаров из РегистраНакоплений ТоварыНаСкладах.
Чтобы не строить велосипед, запрос возьмем из отчета «Анализ точек заказа» и уберем немного кода 😉

Переносим запрос в тело программы и вот, что у меня получилось:

Процедура ПроверкаОстатков() Экспорт //Алекс

ПользовательСпр = Справочники.Пользователи.НайтиПоНаименованию(ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя);

Если ПользовательСпр.ВыводитьПредупреждения Тогда

Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| ВложенныйЗапрос2.Номенклатура КАК Номенклатура,
| ВложенныйЗапрос2.РАЗНИЦА КАК Разница
|ИЗ
| (ВЫБРАТЬ
| ВложенныйЗапрос.Номенклатура КАК Номенклатура,
| СУММА(ВложенныйЗапрос.ЗначениеТочкиЗаказа) КАК ЗначениеТочкиЗаказа,
| СУММА(ВложенныйЗапрос.КоличествоОстаток) КАК КоличествоОстаток,
| СУММА(ВложенныйЗапрос.КоличествоОстаток) — СУММА(ВложенныйЗапрос.ЗначениеТочкиЗаказа) КАК РАЗНИЦА
| ИЗ
| (ВЫБРАТЬ
| ЗначенияТочкиЗаказа.Номенклатура КАК Номенклатура,
| ЗначенияТочкиЗаказа.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ЗначенияТочкиЗаказа.ЗначениеТочкиЗаказа КАК ЗначениеТочкиЗаказа,
| 0 КАК КоличествоОстаток
| ИЗ
| РегистрСведений.ЗначенияТочкиЗаказа.СрезПоследних(&ДатаКон, {(Склад).* КАК Склад, (Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры, (СпособОпределенияЗначенияТочкиЗаказа) КАК СпособОпределенияЗначенияТочкиЗаказа}) КАК ЗначенияТочкиЗаказа
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Закупки.Обороты(, &ДатаКон, День, {(Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры}) КАК Закупки
| ПО (ЗначенияТочкиЗаказа.СпособОпределенияЗначенияТочкиЗаказа = ЗНАЧЕНИЕ(Перечисление.СпособыОпределенияЗначенияТочкиЗаказа.СреднийРазмерПартии))
| И ЗначенияТочкиЗаказа.Номенклатура = Закупки.Номенклатура
| И (ВЫБОР
| КОГДА ЗначенияТочкиЗаказа.ХарактеристикаНоменклатуры <> ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)
| ТОГДА ЗначенияТочкиЗаказа.ХарактеристикаНоменклатуры = Закупки.ХарактеристикаНоменклатуры
| ИНАЧЕ ИСТИНА
| КОНЕЦ)
| И (Закупки.Период МЕЖДУ НАЧАЛОПЕРИОДА(ЗначенияТочкиЗаказа.ДатаНач, ДЕНЬ) И КОНЕЦПЕРИОДА(ЗначенияТочкиЗаказа.ДатаКон, ДЕНЬ))
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(, &ДатаКон, День, {(Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры}) КАК Продажи
| ПО (ЗначенияТочкиЗаказа.СпособОпределенияЗначенияТочкиЗаказа = ЗНАЧЕНИЕ(Перечисление.СпособыОпределенияЗначенияТочкиЗаказа.ОптимальныйРазмерЗаказа))
| И ЗначенияТочкиЗаказа.Номенклатура = Продажи.Номенклатура
| И (ВЫБОР
| КОГДА ЗначенияТочкиЗаказа.ХарактеристикаНоменклатуры <> ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)
| ТОГДА ЗначенияТочкиЗаказа.ХарактеристикаНоменклатуры = Продажи.ХарактеристикаНоменклатуры
| ИНАЧЕ ИСТИНА
| КОНЕЦ)
| И (Продажи.Период МЕЖДУ НАЧАЛОПЕРИОДА(ЗначенияТочкиЗаказа.ДатаНач, ДЕНЬ) И КОНЕЦПЕРИОДА(ЗначенияТочкиЗаказа.ДатаКон, ДЕНЬ))
| ГДЕ
| ЗначенияТочкиЗаказа.СпособОпределенияЗначенияТочкиЗаказа <> ЗНАЧЕНИЕ(Перечисление.СпособыОпределенияЗначенияТочкиЗаказа.НеКонтролировать)
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ТоварыНаСкладах.Номенклатура,
| ТоварыНаСкладах.ХарактеристикаНоменклатуры,
| 0,
| ТоварыНаСкладах.КоличествоОстаток
| ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаКон, ) КАК ТоварыНаСкладах) КАК ВложенныйЗапрос
|
| СГРУППИРОВАТЬ ПО
| ВложенныйЗапрос.Номенклатура) КАК ВложенныйЗапрос2
|ГДЕ
| ВложенныйЗапрос2.РАЗНИЦА < 0" ; Запрос.УстановитьПараметр(«ДатаКон», ТекущаяДата()); РезультатЗапроса = Запрос.Выполнить().Выбрать();
Пока РезультатЗапроса.Следующий() Цикл

Наименование = РезультатЗапроса.Номенклатура;
Разница = РезультатЗапроса.Разница;
Сообщить(«Остаток меньше значения точки заказа » + Наименование + » Необходимо заказать » + Строка(Разница * (-1)) );

КонецЦикла
КонецЕсли;

КонецПроцедуры

ПодключитьОбработчикОжидания(«ПроверкаОстатков», 30, Истина);

ПользовательСпр = Справочники.Пользователи.НайтиПоНаименованию(ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя);

Здесь я получаю пользователя под которым работает менеджер это нужно для проверки, нужно ли данному пользователю выводить предупреждение или нет.
Для этого в справочник пользователей я добавил реквизит [b]ВыводитьПредупреждения[/b] и ниже проверяю

Если ПользовательСпр.ВыводитьПредупреждения Тогда

тогда выполняем запрос и выводм сообщение

Наименование = РезультатЗапроса.Номенклатура;
Разница = РезультатЗапроса.Разница;
Сообщить(«Остаток меньше значения точки заказа » + Наименование + » Необходимо заказать » + Строка(Разница * (-1)) );

Вот, что получается при входе в программу:

Спасибо, что прочли.
Возможно Вам это поможет, а может Вы уже сделали лучше 😉

4 Comments

  1. Damian

    Как по мне, то лучше оформить это внешним отчетом и посылать его параметром в строку запуска 1С. Зачем из-за такой мелочи конфигурацию с поддержки снимать? Тем более, что отчет покажет это красивее + расшифровки + разные другие плюшки 🙂

    А вот еще другая сторона медали: а если менеджер никогда не закрывает 1С? Закрыл окно терминала и пошел домой. Завтра пришел, подключился — 1С у него открыта, про минимальные остатки никто не информирует…

    Reply
  2. 1977

    Согласен.

    Reply
  3. Bublik2011

    Интересно, а можно-ли загрузить эдакий список товаров, который надо отслеживать остатки? Наверно было-бы решением для лентяев, нежелающих одинаковый товар с разными Номенклатура.Код объединять, решением. Задал массив товаров, количество и получаешь выдающее предупрждение.

    Reply
  4. Boudybuilder

    (3) Bublik2011, Всё можно!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *