Имя: Пароль:
1C
1С v8
Помогите с СКД
🠗 (Pro-tone 10.06.2021 11:20)
,
0 WED
 
10.06.21
08:49
Нужно сделать отчет а-ля "Прайс-Лист" - иерархический список номенклатуры с ценой, которую рассчитывает функция общего модуля.
Внешнюю функцию в схеме компоновки внешнюю функцию использовать нельзя по двум причинам:
1. Функция возвращает структуру Цена+Валюта цены,
2. Несмотря на отбор по Номенклатуре, СКД сперва обрабатывает весь справочник номенклатуры (и почему-то по нескольку раз вызывает внешнюю функцию для каждой номенклатуры), а только потом накладывает отбор.

На данный я решил задачу в СКД отчета добавил НабораДанных вида Объект, а в в функции ПриКомпоновкеРезультата формирую конечную таблицу (Номенклатура, Цена, Валюта), но этот подход мне не нравится из-за того, что приходится перед выполнением своего запроса разбираться с отборами и другими настройками, которые сделал пользователь в отчете.

Вопрос:
Есть ли возможность при выполнении отчета, не своим запросом формировать таблицу номенлатуры с учетом пользовательских отборов и других настроек отчета, а получить её из СКД, чтобы добавить в эту таблицу свои данные (Цена+Валюта) и вывести результат?
1 toypaul
 
гуру
10.06.21
08:57
"Несмотря на отбор по Номенклатуре, СКД сперва обрабатывает весь справочник номенклатуры" кривой отбор. правильный отбор накладывается сразу в запросе
"и почему-то по нескольку раз вызывает внешнюю функцию для каждой номенклатуры" а как иначе-то?
2 ДенисЧ
 
10.06.21
08:59
Можно сделать две схемы. Одну для получения списка номенклатуры, вторую - для формирования отчёта.
3 toypaul
 
гуру
10.06.21
09:00
"Есть ли возможность при выполнении отчета, не своим запросом формировать таблицу номенлатуры с учетом пользовательских отборов" есть. недавно такой отчет сделал. делается это через две схемы. в первой схеме получаем таблицу базовую. во второй цепляем остальные данные
4 WED
 
10.06.21
09:04
(1)
"кривой отбор. правильный отбор накладывается сразу в запросе"
Каким образом в запросе в СКД я могу заранее сделать отбор, который напрямую зависит от настроек пользователя и непредсказуем? Отбора может не быть совсем, а может быть, например, по единице измерения номенклатуры.

"а как иначе-то?"
Объясните? Я вот не понимаю почему внешняя функция вызывается для каждой номенклатуры по 2 раза.

(2),(3) Пробовал так, но первая схема (запрос) выдает мне вообще всю номенклатуру без учета настроек и отборов пользователя.
В запросе отборов нет. Я где-то ошибся?
5 toypaul
 
гуру
10.06.21
09:16
1 - долго объяснять
2 - несколько раз для каждой. ну это перебор наверное зависит от схемы
3 - где-то ошибся. не передал отборы из основной схемы в базовую. никто же не говорил что будет просто
6 ДенисЧ
 
10.06.21
09:32
(4) "В запросе отборов нет. Я где-то ошибся?"
Сам ответил, сам спросил...
7 WED
 
10.06.21
09:54
(6) Я предположил :) Никогда в отчетах в запросе в схеме компоновки не делал отборы - они же автоматом накладываются в зависимости от настроек отчета пользователем. И как я понимаю, СКД делает выборку по всем данным, а только потом накладывает пользовательский отбор. Есть другой способ?
8 GreyK
 
10.06.21
10:11
(7) Это зависит от того как написан запрос и какие соединения в нем использованы.
9 WED
 
10.06.21
10:14
(7) Да куда-уж проще:

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Номенклатура,
    Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения

ИЗ
    Справочник.Номенклатура КАК Номенклатура
10 Pro-tone
 
10.06.21
10:26
Делается всё очень просто. Запрос должен состоять из обращения к двум таблицам - спр номенклатура и цены номенклатуры (вся либо срез последних в зависимости от нужд), левое соединение. Зачем там 2 схемы СКД я не понимаю...
11 WED
 
10.06.21
10:27
(10) Таблицы цен не существует. Цена рассчитывается по сложной формуле.
12 Pro-tone
 
10.06.21
10:32
(11) тогда добавляется вычисляемое поле, в выражении которого пишешь вызов функции общего модуля для расчета цены
13 WED
 
10.06.21
10:47
(12) Вы первый пост вообще не читали?
1. Функция расчета цены возвращает структуру с Ценой и Валютой цены. В вычисляемых полях нельзя использовать структуру.
2. СКД вызывает внешнюю функцию для каждой номенклатуры по несколько раз (минимум 2). Функция "тяжелая", а из-за того, что СКД сперва получает данные (и, соответственно, вызывает внешнюю функцию) для всего справочника, а лишь потом накладывает отборы, то это превращается в очень долгое ожидание даже для 1 номенклатуры.
14 Pro-tone
 
10.06.21
10:53
(13)
1. так перепишите чтоб возвращала цену
2. ставьте отбор на конкретную номенклатуру, включая запрет на вывод таблицы, в чем проблема?

если нужна таблица всей номенклатуры - делаете отдельный регистр цен номенклатуры, заполняется он (обновляется) регламентным фоновым заданием, допустим, раз в 5-10 минут робот ее перезаполняет фоном, а вы в свой отчет данные по ценам тащите из нее
15 Pro-tone
 
10.06.21
10:56
+ я уверен, что каждые 5-10 мин перезаполнять регистр цен это даже часто, можно фоновое стартовать при записи новой номенклатуры или изменения реквизитов при записи и по расписанию раз в час,два,три
16 WED
 
10.06.21
11:06
(14)(15)
1. Не перепишу, потому что, во-первых, цена формируется для каждой номенклатуры по весьма тяжелому алгоритму, учитывающему в том числе и валюту, а, во-вторых, Прайс мультивалютный, т.е. валюта для каждой номенклатуры своя, а не не одна на весь прайс. Поэтому функция возвращает и цену и валюту этой цены.
2. Заранее считать и хранить цены в регистре бессмысленно, т.к. цена рассчитывается по запросу в реальном времени и зависит от массы факторов (в том числе и от пользователя для которого эта цена считается). Цена может измениться в любую секунду и рассчитанная 5-10 минут назад уже неактуальна.

На этом, думаю, дискуссию можно прекратить. Через объединение наборов данных вопрос решается вполне приемлимо.
17 Pro-tone
 
10.06.21
11:14
1. неубедительно, а пересчет по курсу всегда можно сделать
2. тоже неубедительно

>>Через объединение наборов данных вопрос решается вполне приемлимо.
так медленное выполнение никуда ж не уйдет
18 1Сергей
 
10.06.21
11:27
(16) интересно у вас бизнес делается...
19 1Сергей
 
10.06.21
11:34
Приятель пишет о своей трудовой юности (конец 90-х):

«Когда-то давно из меня пытались сделать сэйла. Предлагалось продавать людЯм услуги по установке внешних антенн.
Я спросил, почем это стоит. Мне было сказано: тыща умножить на коэффициент крыши. Я спросил, что такое коэффициент крыши. Мне разъяснили, что если крыша сложная, то коэффициент может быть сильно больше единицы. А если простая, то может быть меньше единицы.

Тогда я поинтересовался, а как же узнать, сложная крыша или простая. И оказалось... если у клиента есть деньги, значит крыша у него сложная.

И вот читаю в новостях: "Tesla резко повышает цены на солнечные крыши из-за нового параметра "сложность крыши".»

https://bash.im/quote/465508
20 WED
 
10.06.21
11:45
(18) А шо поделать? Не мы такие, жизнь такая :)
(19) Ну что-то типа того, только еще есть коэффициенты "ветра", "солнца" и "настроения директора".

По делу:
Вопрос окончательно решён (без применения двух наборов данных) благодаря этому решению:
http://forum.infostart.ru/forum9/topic246390/message2490592/#message2490592

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

Длинно:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();    
    
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    НаборДанных = МакетКомпоновки.НаборыДанных.ВнутренниеДанные;
    
    Запрос = Новый Запрос(НаборДанных.Запрос);
    Для Каждого ПараметрЗапроса Из МакетКомпоновки.ЗначенияПараметров Цикл
        Запрос.УстановитьПараметр(ПараметрЗапроса.Имя, ПараметрЗапроса.Значение);
    КонецЦикла;
    
    ТЗ = Запрос.Выполнить().Выгрузить();
    
    ОбработкаРезультатаСКД(ТЗ);
    
    СвойстваНабора = Новый Структура("Имя,ИсточникДанных,Поля,Отбор");
    ЗаполнитьЗначенияСвойств(СвойстваНабора, НаборДанных);    
    МакетКомпоновки.НаборыДанных.Удалить(НаборДанных);
    
    НаборДанных = МакетКомпоновки.НаборыДанных.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных"));
    ЗаполнитьЗначенияСвойств(НаборДанных, СвойстваНабора);
    НаборДанных.ИмяОбъекта = "ТЗ";
    Для Каждого Поле Из СвойстваНабора.Поля Цикл
        НовоеПоле = НаборДанных.Поля.Добавить();
        ЗаполнитьЗначенияСвойств(НовоеПоле, Поле);
    КонецЦикла;
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, Новый Структура("ТЗ", ТЗ), ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Процедура ОбработкаРезультатаСКД(ТЗ)
    
    //Обрабатываем ТЗ как нам нравится

КонецПроцедуры
Пользователь не знает, чего он хочет, пока не увидит то, что он получил. Эдвард Йодан