Имя: Пароль:
1C
1С v8
Скалярное произведение на Запросах и СКД
0 kittystark
 
29.10.22
00:04
задача из практической плоскости (уже решена)
перешла в разряд "Академических" - а как можно сделать по-другому?
так, для разминки мозга, а может кто из умных еще и новое оригинальное решение даст

формально задачу можно поставить так:
- есть некий регистр сведений "T1", наполненный кучей записей, с несколькими измерениями (ссылки на разные справочники) и числовыми ресурсами: A,B,C, ... ,Z (26 ресурсов, для представления полноты "тяжести проблемы")
- есть другая таблица "T2"с числовыми полями c1, c2, c3, ... , c26 - для простоты считаем, что пока одна запись в таблице

для выбранных записей регистра нужно в СКД посчитать  c1*A + c2*B + c3*C + ... + c26*Z
т.е. по сути ∑ ресурсы[i] * с[i]  - это скалярное произведение двух векторов: ресурсы • c

хотелось бы получить "более других", оригинальных и РАБОЧИХ решений

типа как в той задаче про измерение высоты башни и барометр:
насыпать гору из барометров высотой с башню, количество барометров поделить на их коэффициент сыпучести
1 kittystark
 
29.10.22
00:04
способ 1, запросом "в лоб":
ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>,
    c1*A + c2*B + c3*C + ... + c26*Z КАК Скаляр
ИЗ Т1,Т2
2 kittystark
 
29.10.22
00:05
способ 2, ресурсом СКД "в лоб":
c1*A + c2*B + c3*C + ... + c26*Z
3 kittystark
 
29.10.22
00:06
далее на ум приходит идея транспонировать ресурсы
способ 3, запросами

ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>, 1 КАК ID, А КАК Рес ИЗ T1
ПОМЕСТИТЬ ВТ1
ОБЪЕДИНИТЬ
ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>, 2, B ИЗ T1
ОБЪЕДИНИТЬ
ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>, 3, C ИЗ T1
...
ОБЪЕДИНИТЬ
ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>, 26, Z ИЗ T1;


ВЫБРАТЬ 1 КАК ID, C1 Как Коэфф ИЗ T2
ПОМЕСТИТЬ ВТ2
ОБЪЕДИНИТЬ
ВЫБРАТЬ 2, C2 ИЗ T2
ОБЪЕДИНИТЬ
ВЫБРАТЬ 3, C3 ИЗ T2
...
ОБЪЕДИНИТЬ
ВЫБРАТЬ 26, C26 ИЗ T2;

ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>, Сумма(ВТ1.Рес * ВТ2.Коэфф) КАК Скаляр
ИЗ ВТ1 ЛЕВОЕ СОЕДИНЕНИЕ ВТ2 ПО ВТ1.ID = ВТ2.ID
СГРУППИРОВАТЬ ПО <ПОЛЯ ИЗМЕРЕНИЙ>
4 kittystark
 
29.10.22
00:15
способ 4
транспонированную ВТ1 из способа выше можно сформировать и по-другому:
создать перед этим временную таблицу с натуральными числами 1..26 (запрос приводить не буду), далее

ВЫБРАТЬ <ПОЛЯ ИЗМЕРЕНИЙ>, НатЧисла.НПП,
выбор
когда НатЧисла.НПП = 1 тогда A
когда НатЧисла.НПП = 2 тогда B
когда НатЧисла.НПП = 1 тогда C
...
когда НатЧисла.НПП = 26 тогда Z
конец как Рес
ПОМЕСТИТЬ ВТ1
ИЗ НатЧисла, Т1;

далее как в сп.3
5 kittystark
 
29.10.22
00:19
и все бы хорошо, а если ресурсов не 26 а больше???
хочется не долбаться, вколачивая все ручками, а сделать изящно

кто-то скажет: надо формировать текст запроса программно, в цикле
может быть...
но как-то не то...
6 kittystark
 
29.10.22
00:24
способ 5
выгрузить Т1 и Т2 в две ТЗ,
для каждой строки в цикле пробежаться по колонкам - перемножаем, суммируем - профит
но нужно соответствие - каким колонкам что сопоставлять
7 kittystark
 
29.10.22
00:35
способ 6
без запроса, прочитать набор записей регистра сведений, выгрузить в ТЗ
обходя ее колонки - транспонирование ресурсов сделать добавлением новых строк в другую ТЗ_Два
ТЗ_Три - создаем добавлением новой строки на каждую колонку Т2, т.е. тоже транспонируем
потом запросом ТЗ_Два связать с ТЗ_Три по айди или даже номеру строки
8 kittystark
 
29.10.22
00:44
хочется воспользоваться выражением СКД ВычислитьВыражениеСГруппировкойТаблицаЗначений() со всякими там Сумма(Массив(ПолучитьЧасть( ТЗ, "1"))),
но очень смахивает на усложненный вариант способа 2
9 kittystark
 
29.10.22
00:51
способ 7
знаю, что можно воспользоваться выражением СКД "ГрупповаяОбработка",
прийдется функцию писать, и честно говоря, пока смутно себе представляю как ее написать
10 kittystark
 
29.10.22
01:07
все, доклад окончен... идеи кончились... пора идти спать

кто что сможет дельного добавить ?
(транспонирование в БД через реструктуризацию таблиц - не предлагать)
11 kittystark
 
31.10.22
10:42
апну
12 Kassern
 
31.10.22
10:52
(5) "и все бы хорошо, а если ресурсов не 26 а больше???
хочется не долбаться, вколачивая все ручками, а сделать изящно " - Вы можете текст запроса составлять динамически.
13 kittystark
 
31.10.22
10:56
(12) подробнее, пожалуйста
14 Kassern
 
31.10.22
11:01
(13) Да что тут подробнее?
Посмотрите как в типовых запросы собираются, те же упаковки добавляются в текст запроса в зависимости от условий.
15 kittystark
 
31.10.22
11:05
т.е.  Запрос.ТекстЗапроса = ... + ... и всякие там СтрЗаменить, СтрСоединить
16 Kassern
 
31.10.22
11:07
(15) Можете просто параметр сделать мол:
{НужноеПоле} КАК Рес
Далее просто СтрЗаменить {НужноеПоле} на собранную строку.
17 Kassern
 
31.10.22
11:08
А сборка этого поля у вас и будет динамической в зависимости от количества ресурсов
18 kittystark
 
31.10.22
11:14
ну да
или же программно поменять текст выражения ресурса СКД
по такому же образу и подобию
19 mikecool
 
31.10.22
11:17
(12) тогда уж не текст собирать, а использовать объектную схему запроса
20 kittystark
 
31.10.22
11:20
(19) вот сколько лет она существует (а уже, наверное под червонец будет)
все руки никак до нее не доходят

привычка что-ли дурацкая...
21 Kassern
 
31.10.22
11:21
(19) В типовых почему-то именно так подменяют текст запроса, а не через объектную схему собирают. Гляньте ПодборТоваровСервер модуль в УТ11, наверное и в ЕРП такой же есть. Там все через шаблоны и замены сделаны по примеру из (16)
22 kittystark
 
31.10.22
16:28
вообщем с заменой выражения РЕСУРСА СКД как в 18 - тоже работает
вот выдержки из рабочего кода:
КоллекцияРесурсовСКД    = СхемаКомпоновкиДанных.ПоляИтога;
РесурсСкаляр        = КоллекцияРесурсовСКД.Найти("Скаляр");
Компоненты         = новый Массив;

Для каждого Ресурс из КоллекцияРесурсовСКД цикл
    Если ПроверитьПоходящийЛиРеуср( Ресурс.ПутьКДанным ) тогда
        КодВторойМножитель = ПолучитьИмяВторогоМножителя( Ресурс.ПутьКДанным );
        Компоненты.Добавить( " Сумма(" + Ресурс.ПутьКДанным + " * выбор когда Код = """ + КодВторойМножитель + """ тогда Стоимость иначе 0 конец) " );
    КонецЕсли;
КонецЦикла;

РесурсСкаляр.Выражение     = СтрСоединить( Компоненты, Символы.ВК + " + ");

и этот дельфин одному городскому банку - наиболее симпатичен