Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
22 ноя 2024, 14:05

Проверка остатков на складе перед проведением

Автор Diakon, 15 мар 2012, 13:06

0 Пользователей и 1 гость просматривают эту тему.

Diakon

Добрый день. Начал изучать 1С 8.2
Вопрос такой. Мне в документе "Расходня накладная" перед списанием товара со склада надо проверять наличие доступного товара для списания. Ну чтоб при продаже скажем 10 ручек (при наличии на складе всего 5) документ не проводился и выдовалось сообщение о недостаче. Я написал через запрос получение остатков. И все работает если скажем я списываю эти ручки. Но если я списываю ручки и, скажем, книги (их на складе достаточно для списания) документ проводится. Потом в отчете я вижу что на складе осталось, например: -5 ручек и 10 книг. Подскажите где я ошибся и вообще насколько правильно такое решение которое использую я.

Процедура ОбработкаПроведения(Отказ, Режим)
   Движения.ТоварыНаСкладе.Записывать = Истина;
   Для Каждого ТекСтрокаРасходнаяНакладнаяТЧ Из РасходнаяНакладнаяТЧ Цикл
      Движение = Движения.ТоварыНаСкладе.Добавить();
      Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
      Движение.Период = Дата;
      Движение.Наименование = ТекСтрокаРасходнаяНакладнаяТЧ.Наименование;
      Движение.Количество = ТекСтрокаРасходнаяНакладнаяТЧ.Количество;
   КонецЦикла;
   
   Запрос = Новый Запрос(
    "ВЫБРАТЬ
    |   ТоварыНаСкладеОстатки.Наименование КАК НаименованиеПоРегистру,
    |   ТоварыНаСкладеОстатки.КоличествоОстаток КАК КоличествоПоРегистру,
    |   РасходнаяНакладнаяРасходнаяНакладнаяТЧ.Наименование КАК НаименованиеПоДок,
    |   РасходнаяНакладнаяРасходнаяНакладнаяТЧ.Количество КАК КоличествоПоДок
    |ИЗ
    |   РегистрНакопления.ТоварыНаСкладе.Остатки КАК ТоварыНаСкладеОстатки,
    |   Документ.РасходнаяНакладная.РасходнаяНакладнаяТЧ КАК РасходнаяНакладнаяРасходнаяНакладнаяТЧ
    |ГДЕ
    |   ТоварыНаСкладеОстатки.Наименование = РасходнаяНакладнаяРасходнаяНакладнаяТЧ.Наименование"
   );
    Результат = Запрос.Выполнить();
    ТабЗнач=Результат.Выбрать();
   Пока ТабЗнач.Следующий() Цикл
   СписываемоеКоличествоТовара = ТабЗнач.КоличествоПоРегистру - Движение.Количество;
      Если СписываемоеКоличествоТовара<0 Тогда
         Сообщить ("Товара: "+ТабЗнач.НаименованиеПоРегистру+" недостаточно на складе. Не хватает "+СписываемоеКоличествоТовара+"  единиц товара! Проведение отменено! ", СтатусСообщения.Важное);
         Отказ=Истина;
         Прервать;
      КонецЕсли;
   
   КонецЦикла;

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


Заранее спасибо!

cska-fanat-kz

Ошиблись во всем, чем тока можно!

1. Почитайте что нибудь про соединения таблиц в запросе. Намекну: вам понадобится левое соединение.
2. Условия накладываются в параметрах виртуальной таблицы а не в секции ГДЕ
3. Получение остатков надо ограничить списком номенклатуры из документа и получать на момент времени документа
4. Запрос получает ВСЕ табличные части ВСЕХ документов! надо добавить условие на ссылку текущего документа
5. Не учитываются дубли строк - т.е. если ваши ручки в ТЧ повторятся...
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

Klyacksa

Ну только в данном запросе все же правое соединение получается (по порядку следования таблиц).

И еще:
6. В регистрах/документах хранят не наименование строкой, а ссылку на справочник Номенклатура
7. Нужно отрабатывать на NULL все количественные показатели регистра, ибо если остаток товара 0, то записи в виртуальной таблице Остатки по такому товару не будет.
8. При перепроведении в запросе учтутся старые записи этого же документа, что даст совершенно кривые остатки. Например, на складе есть 10 ручек, наш документ списал 6. Мы спохватились, хотим списать все-таки 7  ручек. Вот в таком случае остаток мы получим не 10, как хотелось бы, а 4. Соответственно, документ не проведется.
9. Условие, которые написано в разделе ГДЕ, по-хорошему уйдет в соединение таблиц. Ну и, конечно, условия на виртуальную таблицу надо бы написать. Нам же не нужно получать все-все остатки по всем-всем товарам, правда же? Нам достаточно получить остатки только по используемым нами товарам. (но это уже есть в п.2)
10. Не нужно при Отказе сразу прерывать цикл. Если Отказ=Истина, документ и так не проведется, зато сли в таб.части не хватает двух товаров - Ручек и Карандашей, в Вашем случае пользователь увидит только сообщение о Ручках. А ему нужно знать обо всех нехватках документа.
11. Ну и, наконец, мы в самом запросе можем получить только те товары, по которым нехватка, а затем уже проверять - если результат запроса пустой, то минусов нет. Для этого в запрос нужно передать таблицу (Товар,Количество) и поставить условие сравнения с реальным остатком.
xxx: Спасибо! Я бы загуглил, но ты интересней. Материшься. Злишься. Послать можешь...

Мысль - это оргазм мозга. Кто способен его испытать - получают истинное наслаждение, остальным приходится имитировать

cska-fanat-kz

Ну это то да.
Просто я уже привык: сперва брать ТЧ документа и СЛЕВА присоединять остатки ;)
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

cska-fanat-kz

п. 11 конечно немного по другому делается: записываются движения документа, затем считываются получившиеся остатки и отбираются ушедшие в минус...
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

Klyacksa

2cska-fanat-kz, зная твою любовь к новой методике, не думаю, что стОит сейчас спорить по поводу методик проведения ;)

Но соглашусь, что в данном случае "по-новому" было бы проще всего

2Diakon
Методика проведения "по-новому" появилась с платформой 8.2 и заключается в том, что мы в начале записываем движения документа, а потом смотрим - не ушли ли мы в минус. И если ушли, отменяем проведение.
xxx: Спасибо! Я бы загуглил, но ты интересней. Материшься. Злишься. Послать можешь...

Мысль - это оргазм мозга. Кто способен его испытать - получают истинное наслаждение, остальным приходится имитировать

Diakon

Процедура ОбработкаПроведения(Отказ, Режим)
   //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
   // Данный фрагмент построен конструктором.
   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!


   // регистр ТоварыНаСкладе Расход
   Движения.ТоварыНаСкладе.Записывать = Истина;
   Для Каждого ТекСтрокаРасходнаяНакладнаяТЧ Из РасходнаяНакладнаяТЧ Цикл
      Движение = Движения.ТоварыНаСкладе.Добавить();
      Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
      Движение.Период = Дата;
      Движение.Наименование = ТекСтрокаРасходнаяНакладнаяТЧ.Наименование;
      Движение.Количество = ТекСтрокаРасходнаяНакладнаяТЧ.Количество;
   КонецЦикла;
   
   Движения.Записать();   
   //проверяю есть ли отрицательные остатки на складе после движений. Если есть - отмена проведения
   //и сообщение о нехватке товаров
   Запрос = Новый Запрос("ВЫБРАТЬ
                         |   ТоварыНаСкладеОстатки.Наименование,
                         |   ТоварыНаСкладеОстатки.КоличествоОстаток
                         |ИЗ
                         |   РегистрНакопления.ТоварыНаСкладе.Остатки КАК ТоварыНаСкладеОстатки
                         |ГДЕ
                         |   ТоварыНаСкладеОстатки.КоличествоОстаток < 0"
   );
   Результат = Запрос.Выполнить();
   ТабЗнач=Результат.Выбрать();
   Пока ТабЗнач.Следующий() Цикл
      
      СписываемоеКоличествоТовара = Движение.Количество - ТабЗнач.КоличествоОстаток;
      Сообщить ("Товара: "+ТабЗнач.Наименование+" недостаточно на складе. Не хватает "+СписываемоеКоличествоТовара+"  единиц товара! Проведение отменено! ", СтатусСообщения.Важное);
          Отказ=Истина;
      
   КонецЦикла;


   //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
КонецПроцедуры

Так?

Klyacksa

Вы получаете остатки по всем-всем товарам, а достаточно получать только по тем, которые есть в документе.
xxx: Спасибо! Я бы загуглил, но ты интересней. Материшься. Злишься. Послать можешь...

Мысль - это оргазм мозга. Кто способен его испытать - получают истинное наслаждение, остальным приходится имитировать

cska-fanat-kz

Хоть и опередили - не стал удалять ))

Уже лучше )

Только остатки надо получать не по всей номенклатуре, а только по той, что есть в ТЧ документа.
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

cska-fanat-kz

И количество нехватки вычисляется неправильно!
Движение.Количество - не меняется!
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск