Olark Livehelp
ГлавнаяРегистрацияВход Все для комфортного обучения 1С Воскресенье, 20.05.2012, 07:17
  Публикации Приветствую Вас Гость | RSS

 
 
Главная » Статьи » Статьи по 1С

Новая методика контроля отрицательных остатков при проведении документов в системе 1С:Предприятие 8.2

Вводная ситуация.

Имеем конфигурацию с одним регистром накопления «ОстаткиТоваров», регистр имеет 2 измерения: «Номенклатура» и «Склад» и один ресурс «Количество». По регистру движения формируют 2 документа: «Приходная» и «Расходная». Справочники, реквизиты документов и типы данных надеюсь очевидны.

Про «Приходную» писать нечего, там просто формируются в «плюс» остатки. Про «Расходную поговорим подробнее. Для начала вспомним, как формировалась процедура проведения в 8.1.

Для начала мы получали запросом данные табличной части документа, группировали ее, чтобы исключить дубли строк, и соединяли с таблицей остатков регистра:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ

|     РасходнаяТовары.Номенклатура,

|     СУММА(РасходнаяТовары.Количество) КАК Количество

|ПОМЕСТИТЬ ДокТЧ

|ИЗ

|     Документ.Расходная.Товары КАК РасходнаяТовары

|ГДЕ

|     РасходнаяТовары.Ссылка = &Ссылка

|

|СГРУППИРОВАТЬ ПО

|     РасходнаяТовары.Номенклатура

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

|     ДокТЧ.Номенклатура,

|     ДокТЧ.Количество,

|     ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток,0) КАК Остаток

|ИЗ

|     ДокТЧ КАК ДокТЧ

|           ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(

|                       ,

|                       Склад = &Склад

|                            И Номенклатура В

|                                  (ВЫБРАТЬ

|                                        ДокТЧ.Номенклатура

|                                  ИЗ

|                                        ДокТЧ КАК ДокТЧ)) КАК ОстаткиТоваровОстатки

|           ПО ДокТЧ.Номенклатура = ОстаткиТоваровОстатки.Номенклатура";

Запрос.УстановитьПараметр("Склад", Склад);

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатЗапроса = Запрос.Выполнить();

Кроме этого данные табличной части документа мы использовали для дополнительного отбора при расчете виртуальной таблицы.

Обратите также внимание на функцию ЕСТЬNULL которую мы использовали для гарантии избавления от типа значения NULL в результате запроса. Остатки, которых на складе нет, не присоединятся в таблице документа, и мы поля с остатком заполним значением 0 (ноль).

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

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

      Если Выборка.Количество < Выборка.Остаток Тогда

            Сообщить("Не хватает товара " + Выборка.Номенклатура + ", из необходимых " + Выборка.Количество + " в наличие имеется только " + Выборка.Остаток;

            Отказ = Истина;

      КонецЕсли;

     

      Если Не Отказ Тогда

            Движение = Движения.ОстаткиТоваров.Добавить();

            Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

            Движение.Период = Дата;

            Движение.Номенклатура = Выборка.Номенклатура;

            Движение.Склад = Склад;

            Движение.Количество = Выборка.Количество;

КонецЕсли;

КонецЦикла; 

 

Вроде бы, куда уж проще и быстрее? Однако есть куда!

Разберем новую методику контроля остатоков.

Для начала получим сгруппированную табличную часть документа.

      Запрос = Новый Запрос;

      Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

      Запрос.Текст = "ВЫБРАТЬ

      |     РасходнаяТовары.Номенклатура,

      |     СУММА(РасходнаяТовары.Количество) КАК Количество

      |ПОМЕСТИТЬ ДокТЧ

      |ИЗ

      |     Документ.Расходная.Товары КАК РасходнаяТовары

      |ГДЕ

      |     РасходнаяТовары.Ссылка = &Ссылка

      |

      |СГРУППИРОВАТЬ ПО

      |     РасходнаяТовары.Номенклатура

      |;

      |

      |////////////////////////////////////////////////////////////////////////////////

      |ВЫБРАТЬ

      |     ДокТЧ.Номенклатура,

      |     ДокТЧ.Количество

      |ИЗ

      |     ДокТЧ КАК ДокТЧ";

      Запрос.УстановитьПараметр("Ссылка", Ссылка);

      РезультатЗапроса = Запрос.Выполнить();

 

Временная таблица ДокТЧ нам еще пригодится в дальнейшем, для ее использования мы подключили к запросу менеджер временных таблиц.

Далее сформируем движения по регистру.

Движения.ОстаткиТоваров.Записывать = Истина;

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

      Движение = Движения.ОстаткиТоваров.Добавить();

      Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

      Движение.Период = Дата;

      Движение.Номенклатура = Выборка.Номенклатура;

      Движение.Склад = Склад;

      Движение.Количество = Выборка.Количество;

КонецЦикла; 

Движения.Записать();

 

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

Движения записываем в регистр. Причем при записи движений я обращаюсь не к конкретному набору записей (Движения.ОстаткиТоваров.Записать()), а ко всей коллекции «Движения». Подобный вызов записи гарантирует запись данных в регистры в той последовательности, в которой они расположены на дереве метаданных, что в свою очередь резко уменьшает взаимные блокировки и как следствие ошибки DeadLock.

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

Запрос.Текст = "ВЫБРАТЬ

|     Номенклатура,

|     КоличествоОстаток КАК Остаток

|ИЗ

|     РегистрНакопления.ОстаткиТоваров.Остатки(

|                       ,

|                       Склад = &Склад

|                            И Номенклатура В

|                                  (ВЫБРАТЬ

|                                        ДокТЧ.Номенклатура

|                                  ИЗ

|                                        ДокТЧ КАК ДокТЧ)) 

|ГДЕ

|     КоличествоОстаток < 0";

 

Запрос.УстановитьПараметр("Склад", Склад);

РезультатЗапроса = Запрос.Выполнить();

 

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

Обратимся к результату запроса и известим пользователя о минусах на складе.

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = "Не хватает товара " + Выборка.Номенклатура + ", после проведения документа остаток составит " + Выборка.Остаток;

            Сообщение.Сообщить();

            Отказ = Истина;        

КонецЦикла; 

 

Вот собственно и вся новая методика контроля остатков. Перечислим плюсы этого метода:

·         Нет необходимости соединять в запросе таблицу документа и данными регистров

·         Не надо производить проверку на NULL

·         Нет необходимости получать излишние данные (остатки) для проведения документа. Ведь мы чаще все же записываем документ с правильными цифрами и он проводится, чем документы которые уводят остатки в минус.

Однако не стоит думать, что такая технология может быть применена повсеместно. На секунду задумайтесь, что в этой задаче необходимо еще и себестоимость рассчитать при списании, и Вы придете к выводу, что необходим «старый» метод контроля остатков.

Вот тут Вы можете скачать демобазу с разобранным примером.

Категория: Статьи по 1С | Добавил: GROOVY (11.06.2010)
Просмотров: 12755
Всего комментариев: 17
0  
15 maratimus   (06.12.2011 14:34)
А что будет, если в один и тот же момент будут проводиться 2 документа расхода , 1 будет делать отрицательные остатки, а другой нет, тогда проверку не пройдут оба документа, что неверно.
Неправильно также блокировать всю таблицу, иначе одновременно не смогут проводиться документы, что будет являться узким местом в системе. Мне кажется, это новая технология - полный бред. Исправьте меня, если я не прав. Спасибо за внимание.

0  
16 GROOVY   (06.12.2011 15:39)
Про блокировки в статье нет вообще ни слова.
Если 2 сеанса будут параллельно списывать один и тот же товар, то они выстроятся в транзакционную очередь и не смогут проводится параллельно. Однако, еще раз подчеркну: в примере блокировок нет!
В контексте вышесказанного могу констатировать: Ваш комментарий полный бредни о чем.

0  
17 maratimus   (07.12.2011 14:48)
Да я и не утверждаю, что в вашем примере есть блокировки, я просто констатировал факт, который был как вариант решения у меня на уме, но как я понял, с ваших слов, платформа автоматически контролирует записи у регистров накоплений и никакие управляемые блокировки не нужны, но тогда согласно http://v8.1c.ru/overview/datalockcontrol.htm это возможно только под одну систему БД IBM DB2, а для файловой, postge sql и oracle блокировка идет на уровне таблиц, вот я это как раз имел в виду.
То есть, если в системе одновременно работает много пользователей(например 10000), то при попытке провести документ, система будет выдавать сообщение типа ошибка блокировки и ничего более, а при старой технологии(т.к. данные на чтение не блокируются - "Read Committed") могло выдаваться сообщение о том, что товара по такой-то строчке не хватает, и пользователь уже созванивался с заказчиком и т.д. и не тратил драгоценное время на ожидание...

0  
14 loky30   (13.09.2011 14:15)
Кто может выложить базу с правильной реализацией этого метода. На примерах быстрей доходит.

0  
13 gazelkin23   (08.03.2011 22:18)
Просто отличный ответ на вопрос.........................
Я вот подумал, что для взятия запроса("правильного") которого одного хватит на все проведение, возможно прицепить движения этого документа(с нужным знаком). И все что оперативное, что нет сработает ровно, ведь при записи новых движений старые исчезнут.

Внимание вопрос??? сколько баллов снимут за этот метод
и сколько за тот что используется в УПП 1.3 ??? confused


0  
12 gazelkin23   (27.02.2011 10:14)
Так может как в УПП удалить все движения в начале процедуры обработки проведения и действовать как в 8.1. ????? Подскажите пожалуйста у меня сдача на специалиста 24.03.2011.

0  
11 USER1C   (24.01.2011 15:06)
"Перечислим плюсы этого метода:
· Нет необходимости соединять в запросе таблицу документа и данными регистров
· Не надо производить проверку на NULL
· Нет необходимости получать излишние данные (остатки) для проведения документа."
В примере к книге М.Г. Радченко "Коротко о главном" блокировки и расчет остатков применяются только при оперативном проведении (а как же не оперативное?). При этом теряются указанные преимущества:
· соединяются в запросе таблица документа и данными регистров
· производится проверка на NULL
· получаются данные (остатки) для проведения документа
· используются два относительно простых запроса вместо одного
· вместо того, чтобы стереть старые движения, прочитать данные, проверить на возможность проведения, заблокировать, записать движения используется более долгий алгоритм издевательства над базой: заблокировать, стереть старые движения, записать движения, прочитать данные, проверить на возможность проведения, если не получилось - стереть все движения по документу. ЗДОРОВО!
При этом, в данной книге, на этом сайте в статье и на других сайтах с аналогичной статьей - ни где не учтено или хотя бы разъяснено - как обрабатывать данные при не оперативном проведении. Сказки о том, что это свершившийся факт и проверяли при отпуске товара глазами и пальцем - в реальном учете просто бред, а на экзамене - снижение оценки.
Напомню требования к экзамену:
Если при проведении документа используются каким-то образом данные, считываемые из регистров, обязательно требуется предусмотреть получение таких данных на момент проведения документа. СНИЖЕНИЕ ОЦЕНКИ НА 1,0 БАЛЛ.
Использование неправильных или упрощенных алгоритмов при расчете значений ресурсов регистра. СНИЖЕНИЕ ОЦЕНКИ НА 0,5 - 2,0 БАЛЛОВ.
Отсутствие в решении проверок на правильное заполнение ресурсов регистра, приводящее, например, к появлению отрицательных остатков товаров на складе. Наличие отрицательных значений ресурсов регистра допустимо, только если об этом явно сказано в задании или следует из логики учетной схемы, не противоречащей ситуации, возникающей в реальной практике ведения учета. СНИЖЕНИЕ ОЦЕНКИ НА 1,0 - 2,0 БАЛЛОВ.
Ну и сколько может остаться баллов?
А как же рассчитывать себестоимость товара для списания? По новой схеме: стереть старые движения, рассчитать себестоимость из уверенности, что товара хватит, заблокировать, записать движения, прочитать данные, проверить на возможность проведения, если не получилось - стереть все движения по документу. Не естественно, но выполнимо.
Пожалуйста, покажите правильный (или хотя бы подходящий для сдачи экзамена) пример проведения по новой методике с учетом не оперативного проведения и расчетом себестоимости товара.

0  
8 palax   (10.09.2010 13:54)
МоментВремени почему не используется . когда делаем выборку из регистр остатков ОстаткиТоваров....?Опечатка?

0  
9 GROOVY   (10.09.2010 15:01)
Оперативное проведение отличается от не оперативного только
передачей момента проведения в параметр виртуальной таблицы.

Оперативное проведение отличается от не оперативного только передачей момента проведения в параметр виртуальной таблицы.

Оперативное проведение отличается от не оперативного только передачей момента проведения в параметр виртуальной таблицы.

Оперативное проведение отличается от не оперативного только передачей момента проведения в параметр виртуальной таблицы.


0  
5 ShAN   (16.08.2010 04:06)
Такой метод контрля остатков возможен только при оперативном проедении, но если пользователь внесет изменение прошлым периодом тогда он не сработает? Тогда придется писать 2а варианта оброботки контроля остатков для опер и неопер проведения??? зачем писать больше если "старый метод" более уникален??? Насколько сильно этот момент карается на экзамене?

0  
6 GROOVY   (17.08.2010 22:56)
Оперативное проведение отличается от не оперативного только передачей момента проведения в параметр виртуальной таблицы. О какой втором алгоритме Вы говорите?

0  
4 alice   (15.07.2010 13:28)
С самой методикой все, в принципе, понятно.
Не понятно вот только, как в экзаменационных задачах из условия понять, какую именно методику использовать нужно.

0  
1 Lostar   (18.06.2010 12:53)
При растёте себестоимости всё ещё веселее!

Ведь для того, чтобы проверить, что документ "хороший" нам достаточно проверить количественные остатки.
И это позволяет нам для разных задач (1.4 например) реализовывать разные проверки данных с меньшим количеством обращений к базе данных.

Записали количество - проверили нулевые остатки. Если всё ок, то ТОГДА считаем себестоимость и пишем все остальные регистры.

Запись или не запись регистров в 8.2 контролируется свойством Движения.ИмяРегистра.Записывать = Истина (это для программистов 8.1:)

ПС: А есть ли у Вас информация о том, что 1С рекомендует такой метод проверки остатков?


0  
2 DoctorRoza   (28.06.2010 21:35)
В книге М.Г. Радченко "Коротко о главном" стр. 321 абз. 2 именно такой новый метод описывает автор при проведении документов и проверки остатков. В принципе, учитывая авторитет Максима Григорьевича, то можно сказать, что да, 1С рекомендует использовать данный метод! smile

0  
3 Sanchez   (01.07.2010 14:09)
а почему у мгр'а при расчете себестоимости не устанавливается дата получения остатков в запросе, а считываются последние? при неоперативном проведении полный швах будет? говорят на экзамене за это тоже штрафуют на баллы wacko

0  
7 Бубузяка   (25.08.2010 15:44)
На экзамене, при неоперативном проведении, контроль остатков можно не выполнять (если это специально не оговаривается в задаче). Объясняете тем, что неоперативное проведение - регистрация свершившегося факта, т.е. контроль остатков, был выполнен визуальными средствами (глазками и пальцем) на складе при отгрузке.

0  
10 freefly   (08.10.2010 14:28)
А фраза "документы могут проводиться неоперативно" подпадает под определение "если это специально не оговаривается в задаче"? То есть, если есть фраза "документы могут проводиться неоперативно", то нужно выполнять контроль остатков при неоперативном проведении? Или необходимость выполнять контроль остатков при неоперативном проведении указывается как то конкретней? Может можно привести пример задачи с таким условием? А то чет в прострации какой то. wacko

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
 
 
Форма входа
Login:
Пароль:

Категории раздела
Видеоуроки по 1С [8]
Бесплатные видеоуроки для it-специалистов по работе с системой 1С:Предприятие
Статьи по 1С [8]
Статьи и методические материалы
Утилиты и полезности [5]
Утилиты, обработки и прочие мелочи делающие работу с системой 1С:Предприятие удобнее, да и не только с ней.

Поиск

Наш опрос
Внедряете 8.2?
Всего ответов: 1114

Сейчас на форуме
  • Результаты сдачи экз... (865)
  • Справочник список (3)
  • Задача 1.50 (3)
  • Задача 1.01 (200)
  • Общие вопросы по сда... (108)
  • Задача 2.12 (2)
  • Задача 2.10 (9)
  • Задача 2.8. Не могу... (16)
  • 2.20 (53)
  • 2.16 (2)

  • Поиск

     

    Copyright Павел Чистов © 2012 | Хостинг от uCoz