Проверка рентабельности по реализациям при проведении

06.06.15

Разработка - Механизмы типовых конфигураций

В моей практике программиста 1С встретилась интересная задача. При проведении документа "Реализации Товаров и Услуг" на предприятии проводилась проверка рентабельности в целом по документу. Необходимо делать проверку на рентабельность по каждой строке списка товаров. Предлагаю вам оценить решение задачи.

 

Работающий механизм контроля рентабельности по документам

  Итак, до меня на предприятии другой программист сделал следующее:

  • При проведении документа "Реализация Товаров и Услуг", делается проверка на рентабельность документа. Если документ в целом не рентабелен, то выводится сообщение.

В принципе адекватная мера для предприятия, основной деятельностью которого является оказание услуг по доставке. Ежели текущая доставка не рентабельна (изменились цены, условия доставки и др.), то при проведении пользователю об этом сообщается. Пользователь принимает решение об отмене услуги или изменении условий. Кроме того, на предприятии у менеджеров, обслуживающих клиентов есть целый набор отчетов для контроля всех аспектов заказа. Таким образом, сообщения при проведении отсекают ошибки связанные с изменением условий по сделке. Должен сообщить, что после разговора с клиентом, условия сделки могут много раз поменяться. На нее влияет множество факторов:

  • Расстояние перевозки. Время перевозки
  • Дорожные условия (может измениться погода, тогда изменятся расценки на перевозку)
  • Водитель может заболеть и придется нанимать другого водителя
  • Транспорт может не пройти осмотр (технические неисправности при осмотре)
  • И множество др. факторов

Таким образом, перед проведением программа последний раз проверяет корректность условий и себестоимость. Себестоимость упрощенно считается по регистрам "Продажи себестоимость", по партиям товаров. Таким образом, при изменении поставок цена может поменяться. Рентабельность считается по себестоимости и данным регистра "Продажи". Если себестоимость документа меньше 5% то выводится сообщение.

 

 

Такой механизм работал очень просто. В модуле объекта документа "РеализацияТоваровУслуг", в процедуре "ОбработкаПроведения", после записи движений документа был следующий код:

 

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

Запрос.УстановитьПараметр("Регистратор",Ссылка);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Количество()>0 тогда
    Результат.Следующий();
        Если Результат.Рентабельность < 5 тогда
            Сообщить("Рентабельность документа не превышает 5%! Текущая рентабельность: "+Строка(Формат(Результат.Рентабельность,"ЧЦ=15; ЧДЦ=2"))+"%!",СтатусСообщения.ОченьВажное);
        КонецЕсли;
КонецЕсли;

 

Обратите внимание что рентабельность в запросе считается непосредственно при подсчете итогов. Это адекватно ускоряет запрос. Сделано очень грамотно!  

В чем состоит моя задача?

  Необходимо изменить алгоритм так, чтобы при проведении рентабельность считалась по каждой строке текущего документа. Если в определенных строках рентабельность меньше 5%, то выводить сообщение по конкретной строке. Итак, Начнем с запуска режима 1с Предприятие.  

Преимущества использования консоли запросов в любой задаче Программиста 1с

  В 1с Предприятии запустим обработку "Консоль запросов". консоль позволяет конструировать и отлаживать запросы прямо в режиме 1с Предприятие, без Конфигуратора. Это очень полезно. Любые разработки я начинаю с тестирования данных с помощью запросов. Это позволяет решить сразу несколько задач:

  1. Получить выборки данных по интересующим меня критериям
  2. Отладить запрос, сделать его рабочим, выполняющим возложенную задачу
  3. Быть уверенным в работе запроса, что он получает нужные данные от Базы Данных.
  4. Быть уверенным, что в базе данных нужные данные содержатся. Бывает так, что запрос работает, а данных для него просто нет. Вот такие ситуации сразу отслеживаются.
  5. После отладки запроса его можно сразу применить в отчете, модуле, в конфигураторе.

Итак, я хочу посмотреть, количество и данные документов "Реализация Товаров и Услуг", в которых рентабельность меньше 5%. Берем готовый запрос из конфигуратора, из модуля документа.  

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

  Помещаем его в обработку "Консоль запросов". В запросе нет параметров, поэтому нет необходимости их устанавливать. Забыл сказать, что запрос из модуля я упростил, убрал условие

 

|ГДЕ
|	ПродажиОбороты.Регистратор = &Регистратор

 

Итак, смотрим на данные, которые запрос отобрал из БД:

 

   

 

Мы видим, что в выборке, в колонке "Рентабельность", есть строки в которых Рентабельность = 0 и Рентабельность < 0 Хммм. А я хочу увидеть документы, в которых Рентабельность > 0. Для этого я добавил в запрос условие Рентабельность > 0 и посмотрел результат:

 

 

Как раз те документы, которые я искал! При проведении таких документов должны выводиться сообщения, по условиям задачи! Таким образом, после изменений в проведении документа, я буду тестировать алгоритм на данных документах! Но надо будет обязательно проверить, что в других документах, где рентабельность > 5% - сообщение не должно выводиться. Ну что-ж, изменим условие запроса и получим выборку для тестирования:

 

 

При проведении таких документов, сообщение не должно выводиться.  

Внедрение алгоритма в 1с

  Итак, в модуле документа "Реализация Товаров и Услуг", заменим существовавший код на следующий:

 

// Лунегов П.В. +++
// До изменения:

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

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

// Лунегов П.В. ---

Запрос.УстановитьПараметр("Регистратор",Ссылка);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Количество()>0 тогда
    Пока Результат.Следующий() Цикл
        //Результат.Следующий();
        Если Результат.Рентабельность < 5 тогда
            //Сообщить("Рентабельность документа не превышает 5%! Текущая рентабельность: "+Строка(Формат(Результат.Рентабельность,"ЧЦ=15; ЧДЦ=2"))+"%!",СтатусСообщения.ОченьВажное);
            Сообщить("Рентабельность по номенклатуре "+Строка(Результат.НоменклатураНаименование)+" (код ="+Строка(Результат.НоменклатураКод)+
            ", артикул ="+Строка(Результат.НоменклатураАртикул)+") не превышает 5%! Текущая рентабельность: "+Строка(Формат(Результат.Рентабельность,"ЧЦ=15; ЧДЦ=2"))+"%!",СтатусСообщения.ОченьВажное);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

 

  После тестирования на контрольной выборке документов, я заключил, что полностью выполнил задачу. Перенес в рабочую базу мои изменения. Клиент остался доволен.   На этом пока все, счастливо!

проверка рентабельности при проведении рентабельность в реализации

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    121582    670    389    

710

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6279    30    mkalimulin    25    

49

Шаблоны новых объектов 1С для 1С:Бухгалтерии предприятия

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Платформа 1С v8.3 1С:Бухгалтерия 3.0 Бесплатно (free)

Используются для создания новых объектов в конфигурации, чтобы не забыть, что нужно сделать. Сделано на примере 1С:Бухгалтерия предприятия, в других конфигурациях могут быть другие, а могут быть и похожие объекты.

28.12.2023    4822    mrXoxot    11    

99

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5383    user1923546    26    

43

Ключи аналитик учета в ЕРП, КА, УТ

Механизмы типовых конфигураций Платформа 1С v8.3 1С:ERP Управление предприятием 2 Россия Управленческий учет Бесплатно (free)

Разбираемся, зачем в системе ЕРП созданы справочники: ключи аналитик учета, зачем созданы аналогичные по набору измерений регистры сведений. Какие проблемы они решают, какие создают новые и что с этим делать.

08.11.2023    7020    ids79    25    

74

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16163    skovpin_sa    14    

98

Структура запроса

Инструментарий разработчика Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Абонемент ($m)

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

1 стартмани

21.06.2023    5153    57    obmailok    35    

56
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. SnowManUU 11.06.15 09:36 Сейчас в теме
Это удобно если в расчет партий производится в момент проведения документов. У меня на предприятие партии рассчитываются регламентным заданием ночью. А так в целом неплохой вариант решения
2. quarion 08.02.16 22:06 Сейчас в теме
Спасибо! применил на своей базе, теперь менеджеры сразу предупреждены, что так нельзя торговать ))
Оставьте свое сообщение