В организации проведена инвентаризация и для того чтобы оперативно начать работ с реальными остатками в базе УТ 11.0.9 все недостачи и излишки товара списаны на вспомогательный склад для дальнейших разбирательств. В организации понимают, что большинство проблем из-за пересортицы товаров. Необходимо написать обработку, которая по каталожному номеру номенклатуры и наиболее подходящей цене закупки из излишков и недостач подберет позиции в документ Пересортица товаров для того, чтобы «схлопнуть» их. Учет по характеристикам – не ведется.
Реализация
Конфигурация УТ 11.0.9.
На форме обработки необходимо указать:
• Склад – склад, на котором необходимо произвести все действия.
• Мин. длина артикула – число
• Мах процент отклонения цены
Табличная часть
• Номенклатура списываемая
• Номенклатура приходуемая
• Количество
По кнопке «Проанализировать пересортицу» необходимо табличную часть заполнить подобранным пересортом. Для этого надо найти все положительные остатки и каждой позиции попробовать подобрать позиции с отрицательными остатками. Анализировать регистр «Товары на складах».
Подбор должен осуществляться по артикулу постепенно укорачивая его с правой стороны. Например, остатки Товара 1 с артикулом 88764-91 являются пересортом Товара 2 (артикул 88764-23). Укорачивать можно только до указанного в обработке знака
Если подобрались одновременно несколько позиций, то берем в первую очередь ту позицию, у которой последняя закупочная цена наиболее приближена к позиции, которая в излишке.
В обработке по кнопке «Создать документ пересорта» должен создаться документ и заполниться его табличная часть.
(1) allgorhythm, это текст задания для соискателя в какой-то фирме в мск, они набирают удаленных кодеров, а это тестовое задание которое необходимо выполнить,
интересно, если вас возьмут, то вы так же будете решать реальные ТЗ?
(11) dj_serega, вам нужно готовое решение?
реализация - запрос в цикле, искать номенклатуру оператором Подобно по артикулу, с каждым циклом укорачивать артикул, дальше уже по заданию - если есть несколько позиций, то выбирать наиболее приближеннную по цене закупки, полученую пару товар списываемый - товар приходуемый скидывать в таб. часть, затем новый цикл за исключением позиций из таб. части,
повторять цикл пока не закончатся приходуемые или списываемые товары, или не найдено ни одного соответствия по артикулу,
нехрошо канеш что запрос в цикле, но порой без этого не обойтись
(14) artfa, (11) dj_serega, (2) Salavat, (8) AllexSoft, Был предложен такой вариант исполнения кода в обработке, но как сказали там* - ничего не показало :(
&НаКлиенте
Процедура ПроанализироватьПересортицу(Команда)
ПроанализироватьПересортицуНаСервере(Объект.Склад,Объект.МинДлинаАртикла,Объект.МаксПроцентРасхожденияЦены);
КонецПроцедуры
&НаСервере
Процедура ПроанализироватьПересортицуНаСервере(Склад,МинДлина,МаксПроцентРасхожденияЦены)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВложенныйЗапрос.Номенклатура КАК Номенклатура,
| ВложенныйЗапрос.Номенклатура.Артикул КАК Артикул,
| СУММА(ВложенныйЗапрос.Излишки) КАК Излишки,
| СУММА(ВложенныйЗапрос.Недостача) КАК Недостача
|ПОМЕСТИТЬ ВыборкаИзлишковНедостач
|ИЗ
| (ВЫБРАТЬ
| Излишки.ДокументОснование КАК ДОкументОснование,
| Излишки.Характеристика КАК Характеристика,
| Излишки.Номенклатура КАК Номенклатура,
| Излишки.КОформлениюАктовОстаток КАК Излишки,
| 0 КАК Недостача
| ИЗ
| РегистрНакопления.ТоварыКОформлениюИзлишковНедостач.Остатки КАК Излишки
| ГДЕ
| Излишки.Склад = &Склад
| И Излишки.КОформлениюАктовОстаток > 0
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| Недостача.ДокументОснование,
| Недостача.Характеристика,
| Недостача.Номенклатура,
| 0,
| Недостача.КОформлениюАктовОстаток
| ИЗ
| РегистрНакопления.ТоварыКОформлениюИзлишковНедостач.Остатки КАК Недостача
| ГДЕ
| Недостача.Склад = &Склад
| И Недостача.КОформлениюАктовОстаток < 0) КАК ВложенныйЗапрос
|
|СГРУППИРОВАТЬ ПО
| ВложенныйЗапрос.Номенклатура.Артикул,
| ВложенныйЗапрос.Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МАКСИМУМ(ЦеныНоменклатурыПоставщиков.Период) КАК Период,
| ВыборкаИзлишковНедостач.Номенклатура
|ПОМЕСТИТЬ ПоследнийПериод
|ИЗ
| ВыборкаИзлишковНедостач КАК ВыборкаИзлишковНедостач
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатурыПоставщиков КАК ЦеныНоменклатурыПоставщиков
| ПО ВыборкаИзлишковНедостач.Номенклатура = ЦеныНоменклатурыПоставщиков.Номенклатура
|ГДЕ
| ЦеныНоменклатурыПоставщиков.Период <= &Дата
|
|СГРУППИРОВАТЬ ПО
| ВыборкаИзлишковНедостач.Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МАКСИМУМ(ЦеныНоменклатурыПоставщиков.Цена) КАК Цена,
| ЦеныНоменклатурыПоставщиков.Период,
| ЦеныНоменклатурыПоставщиков.Номенклатура
|ПОМЕСТИТЬ КрайниеЦеныЗакупок
|ИЗ
| ПоследнийПериод КАК ПоследнийПериод
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатурыПоставщиков КАК ЦеныНоменклатурыПоставщиков
| ПО ПоследнийПериод.Период = ЦеныНоменклатурыПоставщиков.Период
| И ПоследнийПериод.Номенклатура = ЦеныНоменклатурыПоставщиков.Номенклатура
|ГДЕ
| ЦеныНоменклатурыПоставщиков.Цена > 0
| И НЕ ЦеныНоменклатурыПоставщиков.Цена ЕСТЬ NULL
|
|СГРУППИРОВАТЬ ПО
| ЦеныНоменклатурыПоставщиков.Период,
| ЦеныНоменклатурыПоставщиков.Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВыборкаИзлишковНедостач.Номенклатура,
| ВыборкаИзлишковНедостач.Артикул,
| ВыборкаИзлишковНедостач.Излишки,
| ВыборкаИзлишковНедостач.Недостача,
| КрайниеЦеныЗакупок.Цена
|ИЗ
| КрайниеЦеныЗакупок КАК КрайниеЦеныЗакупок
| ЛЕВОЕ СОЕДИНЕНИЕ ВыборкаИзлишковНедостач КАК ВыборкаИзлишковНедостач
| ПО (ВыборкаИзлишковНедостач.Номенклатура = КрайниеЦеныЗакупок.Номенклатура)";
Запрос.УстановитьПараметр("Склад", Склад);
Запрос.УстановитьПараметр("Дата",ТекущаяДата());
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
// Создаем таблицу с излишками товара
ТЗИзлишки = Новый ТаблицаЗначений;
ТЗИзлишки.Колонки.Добавить("Номенклатура");
ТЗИзлишки.Колонки.Добавить("Артикул");
ТЗИзлишки.Колонки.Добавить("Излишки");
ТЗИзлишки.Колонки.Добавить("Цена");
// Создаем таблицу с недостачей товара
ТЗНедостача = Новый ТаблицаЗначений;
ТЗНедостача.Колонки.Добавить("Номенклатура");
ТЗНедостача.Колонки.Добавить("Артикул");
ТЗНедостача.Колонки.Добавить("Недостача");
ТЗНедостача.Колонки.Добавить("Цена");
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Заполняем таблицы излишков и недостач
Если (ВыборкаДетальныеЗаписи.недостача < 0) и (ВыборкаДетальныеЗаписи.излишки > 0 ) Тогда
СтрокаИзлишки = ТЗИзлишки.Добавить();
СтрокаИзлишки.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
СтрокаИзлишки.Артикул = ВыборкаДетальныеЗаписи.Артикул;
СтрокаИзлишки.Излишки = ВыборкаДетальныеЗаписи.Излишки;
СтрокаИзлишки.Цена = ВыборкаДетальныеЗаписи.Цена;
СтрокаНедостача = ТЗНедостача.Добавить();
СтрокаНедостача.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
СтрокаНедостача.Артикул = ВыборкаДетальныеЗаписи.Артикул;
СтрокаНедостача.Недостача = ВыборкаДетальныеЗаписи.Недостача;
СтрокаНедостача.Цена = ВыборкаДетальныеЗаписи.Цена;
ИначеЕсли ВыборкаДетальныеЗаписи.Излишки > 0 Тогда
СтрокаИзлишки = ТЗИзлишки.Добавить();
СтрокаИзлишки.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
СтрокаИзлишки.Артикул = ВыборкаДетальныеЗаписи.Артикул;
СтрокаИзлишки.Излишки = ВыборкаДетальныеЗаписи.Излишки;
СтрокаИзлишки.Цена = ВыборкаДетальныеЗаписи.Цена;
// Заполняем таблицу недостач
ИначеЕсли ВыборкаДетальныеЗаписи.Недостача < 0 тогда
СтрокаНедостача = ТЗНедостача.Добавить();
СтрокаНедостача.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
СтрокаНедостача.Артикул = ВыборкаДетальныеЗаписи.Артикул;
СтрокаНедостача.Недостача = ВыборкаДетальныеЗаписи.Недостача;
СтрокаНедостача.Цена = ВыборкаДетальныеЗаписи.Цена;
КонецЕсли;
КонецЦикла;
ТЗИзлишки.Сортировать("Артикул ВОЗР");
ТЗНедостача.Сортировать("Артикул ВОЗР");
//Создаем таблицу пересортицы
ТЗРезультат = Новый ТаблицаЗначений;
ТЗРезультат.Колонки.Добавить("НоменклатураСписываемая", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗРезультат.Колонки.Добавить("АртикулСписываемая", Новый ОписаниеТипов("Строка"));
ТЗРезультат.Колонки.Добавить("ЦенаСписываемая",Новый ОписаниеТипов("Число"));
ТЗРезультат.Колонки.Добавить("НоменклатураПриходуемая",Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗРезультат.Колонки.Добавить("АртикулПриходуемая",Новый ОписаниеТипов("Строка"));
ТЗРезультат.Колонки.Добавить("РасхождениеЦены",Новый ОписаниеТипов("Число"));
ТЗРезультат.Колонки.Добавить("Количество",Новый ОписаниеТипов("Число"));
Для Каждого СтрокаИзлишки из ТЗИзлишки Цикл
АртикулИзлишки = СтрокаИзлишки.Артикул;
КоличествоСтрок = 0;
Для каждого СтрокаНедостача из ТЗНедостача Цикл
АртикулНедостача = СтрокаНедостача.Артикул;
// Пробуем товару в излишке подобрать товар с недостачей
Если АртикулИзлишки = АртикулНедостача Тогда
АртикулНедостача = СтрокаНедостача.Артикул;
СтрокаРезультат = ТЗРезультат.Добавить();
СтрокаРезультат.НоменклатураСписываемая = СтрокаИзлишки.Номенклатура;
СтрокаРезультат.АртикулСписываемая = СтрокаИзлишки.Артикул;
СтрокаРезультат.НоменклатураПриходуемая = СтрокаНедостача.Номенклатура;
СтрокаРезультат.АртикулПриходуемая = СтрокаНедостача.Артикул;
СтрокаРезультат.Количество = Мин(СтрокаИзлишки.Излишки,(-СтрокаНедостача.Недостача));
СтрокаРезультат.РасхождениеЦены = 100 - (Мин(СтрокаИзлишки.Цена,СтрокаНедостача.Цена)*100)/(Макс(СтрокаИзлишки.Цена,СтрокаНедостача.Цена));
КоличествоСтрок = ТЗРезультат.Количество()+1;
КонецЕсли;
КонецЦикла;
// Проверяем подобрались ли товары, если нет, то откусываем от артикула справа один знак
Если (КоличествоСтрок = 0) и (СтрДлина(АртикулИзлишки) <> МинДлина) Тогда
Пока СтрДлина(АртикулИзлишки)>МинДлина Цикл
УкороченныйАртикулИзлишки = Лев(АртикулИзлишки,СтрДлина(АртикулИзлишки)-1);
Для каждого СтрокаНедостача из ТЗНедостача Цикл
АртикулИзлишки = УкороченныйАртикулИзлишки;
АртикулНедостача = СтрокаНедостача.Артикул;
АртикулНедостача = Лев(АртикулНедостача,СтрДлина(АртикулНедостача)-1);
//проверяем совпадают ли артикулы по длине, если нет то приводим к одной длине
Если СтрДлина(АртикулИзлишки)<>СтрДлина(АртикулНедостача) Тогда
ДлинаАртикулИзлишки = СтрДлина(АртикулИзлишки);
ДлинаАртикулНедостача = СтрДлина(АртикулНедостача);
РазницаДлины = Макс(ДлинаАртикулИзлишки,ДлинаАртикулНедостача) - Мин(ДлинаАртикулИзлишки,ДлинаАртикулНедостача);
Если СтрДлина(АртикулИзлишки)>СтрДлина(АртикулНедостача) Тогда
АртикулИзлишки = Лев(АртикулИзлишки,(СтрДлина(АртикулИзлишки)-РазницаДлины));
Иначе
АртикулНедостача = Лев(АртикулНедостача, (СтрДлина(АртикулНедостача)-РазницаДлины));
КонецЕсли;
КонецЕсли;
// Пробуем товару в излишке подобрать товар с недостачей
Если АртикулИзлишки = АртикулНедостача Тогда
АртикулНедостача = СтрокаНедостача.Артикул;
СтрокаРезультат = ТЗРезультат.Добавить();
СтрокаРезультат.НоменклатураСписываемая = СтрокаИзлишки.Номенклатура;
СтрокаРезультат.АртикулСписываемая = СтрокаИзлишки.Артикул;
СтрокаРезультат.НоменклатураПриходуемая = СтрокаНедостача.Номенклатура;
СтрокаРезультат.АртикулПриходуемая = СтрокаНедостача.Артикул;
СтрокаРезультат.Количество = Мин(СтрокаИзлишки.Излишки,(-СтрокаНедостача.Недостача));
СтрокаРезультат.РасхождениеЦены =100- (Мин(СтрокаИзлишки.Цена,СтрокаНедостача.Цена)*100)/(Макс(СтрокаИзлишки.Цена,СтрокаНедостача.Цена));
КонецЕсли;
АртикулИзлишки = УкороченныйАртикулИзлишки;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
//Если подобрались одновременно несколько позиций, то берем в первую очередь ту позицию, у которой последняя закупочная цена наиболее приближена к позиции, которая в излишке.
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗРезультат.НоменклатураСписываемая,
| ТЗРезультат.АртикулСписываемая,
| ТЗРезультат.НоменклатураПриходуемая,
| ТЗРезультат.АртикулПриходуемая,
| ТЗРезультат.Количество,
| ТЗРезультат.РасхождениеЦены
|ПОМЕСТИТЬ ТЗРезультат
|ИЗ
| &ТЗРезультат КАК ТЗРезультат
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТЗРезультат.НоменклатураСписываемая,
| ТЗРезультат.НоменклатураПриходуемая,
| ТЗРезультат.Количество,
| Минимум(ТЗРезультат.РасхождениеЦены) КАК РасхождениеЦены
|ИЗ
| ТЗРезультат КАК ТЗРезультат
|ГДЕ
| ТЗРезультат.РасхождениеЦены < &МаксПроцентРасхождения
|
|СГРУППИРОВАТЬ ПО
| ТЗРезультат.НоменклатураСписываемая,
| ТЗРезультат.НоменклатураПриходуемая,
| ТЗРезультат.Количество
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ТЗРезультат";
Запрос.УстановитьПараметр("ТЗРезультат",ТЗРезультат);
Запрос.УстановитьПараметр("МаксПроцентРасхождения",МаксПроцентРасхожденияЦены);
Результат = Запрос.Выполнить();
ВыгрузкаПересортица = Результат.Выгрузить();
Пересортица.Загрузить(ВыгрузкаПересортица);
КонецПроцедуры
(16) Salavat, Отпадает, но существует, ибо сказали присылайте правильный обрабатейшен и все у Вас будет хорошо, в довесок кинули скрином, а возникает вопрос, какой он этот - правильный?
(20) artfa, (19) Salavat, (13) dj_serega, В общем смысл ошибки на скриншоте, я не понимаю причем тут проверка на значение "null", т.к. это другая ошибка, это такое представление отсутствия значения, а у меня, повторюсь - Обработка ничего не показала. Разные вещи, но у меня за компьютером, всё она показывает, и кино и мимино, и пересортицу то же.
Такие вот дела.
(27) allgorhythm, открыл. но я понял как настоящему программмеру - нужно проблему по буквам разложить, ок:
на радикале 800*500 (сравните с тем, что я говорил) - на нём я ничего не разберу.
здесь картинка - как-раз в размере 380*290 (примерно). на нём - я даже не пытаюсь, штото разобрать.
объясняю как делается скрин по человечески (для обычных людей):
выделяется область нужная на экране. и сохраняется 1:1 - параллельно обрезав лишнее.
в итоге получаем то, что видим мы сами (это я про Вас), а не штото.
(29) allgorhythm, наконецто.
но - теперь я не вижу на скрине
В общем смысл ошибки на скриншоте, я не понимаю причем тут проверка на значение "null", т.к. это другая ошибка, это такое представление отсутствия значения, а у меня, повторюсь - Обработка ничего не показала.
я тоже не понимаю - форма обработки и только.
пустое табличное поле. а данные какие есть?
что проверятьто? на что смотреть?
(30) Salavat, Есть задача описанная выше, есть процедура которая работает, *ну там написано как она работает, и есть ответный скрин, который я то же описал, вот сложите имеющиеся факты, и тогда мы поймем, что возможно, логика описана не верно, но нет, я проверил и подругому не знаю как - это возможно выполнить получив тот результат на который рассчитывает работодатель, по этому я выложил тут все за и против, программисты код понимают, если есть ко мне вопросы задавайте, т.к. я сам ну реально не понимаю как будет правильно, вот в чем дело.
(6) AllexSoft, Здравствуйте Алексей, вы писали что у Вас есть похожая обработка, если Вам не составит труда вышлите её мне пожалуйста на адрес "v.evtushenko@hotmail.com".
C уважением, Владимир.
37.
jobkostya1c_ERP
10022.09.14 21:20 Сейчас в теме
Тут затрагивали тему со стандартным помощником продаж, который сейчас коверкаю. И этот не работает. Раз уж начали тему, придется что-нибудь по данной обработке поглядеть. Чтоб задание сменили :)
(39) allgorhythm, (40) kostyaomsk, а оно вам надо? без работы хороший кодер никогда не останется, а делать эту обработку чтобы пройти тест работодателя - мне уже не надо, и так зашиваюсь на фрилансе
40.
jobkostya1c_ERP
10030.09.14 15:00 Сейчас в теме
Придется обработку сделать, которая генерирует бардак на складах :) И давайте тогда уже 11.1.7 релиз. Или бета-версию 11.1.9 т.к. на сайте 1С установочный демо есть)
Видимо, смотрят на оригинальность решения или считают раз потратил столько времени значит очень надо.
42.
jobkostya1c_ERP
10001.10.14 09:23 Сейчас в теме
Не для теста работодателя, а для теста УТ и прочих торговых последнего релиза. Мало ли какие обработчики могут зацепиться при программном создании документов. Наталкивает на идею еще одной разработки. Это я про моделирование ситуации до начала работы пересортицы. И такую вещь точно не нужно выкладывать. Она же вредоносная получается. Сначала запустят что попало, потом весь инфостарт запретят :)
allgorhythm, я не предлагаю, я только предполагаю возможные причины, почему обработка ничего не показала. А написать запрос можно, например, так:
Запрос = Новый Запрос;
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;