Имя: Пароль:
1C
 
Из любой нетипизированной ТЗ сделать типизированную (для запроса)
0 Прохожий
 
11.09.23
07:18
Я так понимаю такое требование в параметрах запроса есть ,а ништяка такого еще нет?
Но как быть если данное попадается НЕОПРЕДЕЛЕНО?
1 Прохожий
 
11.09.23
07:19
&НаСервере
Функция ПолучитьТипизированнуюТаблицу(ТекТаблица)
    
    Ответ = Новый ТаблицаЗначений;
    Для Каждого Колонка из ТекТаблица.Колонки Цикл
        
        СписокТипов = Новый Массив;
        
        Для Каждого Тип из Колонка.ТипЗначения.Типы() Цикл
            Если Тип = Тип("Null") Тогда
                Продолжить;
            КонецЕсли;
            
            Попытка
                ОписаниеТипа = Новый ОписаниеТипов(Строка(Тип));
                ОписаниеТипа = Строка(Тип);
            Исключение
                ОписаниеТипа = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
                ОписаниеТипа = СтрЗаменить(ОписаниеТипа, "Справочник.", "СправочникСсылка.");
                ОписаниеТипа = СтрЗаменить(ОписаниеТипа, "Документ.", "ДокументСсылка.");
                ОписаниеТипа = СтрЗаменить(ОписаниеТипа, "Перечисление.", "ПеречислениеСсылка.");
            КонецПопытки;
            СписокТипов.Добавить(Тип(ОписаниеТипа));
        КонецЦикла;
        //Если СписокТипов.Количество() = 0 Тогда
        //    СписокТипов.Добавить(Тип("Неопределено"));    
        //КонецЕсли;
        ОписаниеСоставногоТипа = Новый ОписаниеТипов(СписокТипов);
        Ответ.Колонки.Добавить(Колонка.Имя, ОписаниеСоставногоТипа);
    КонецЦикла;
    
    Для Каждого Стр из ТекТаблица Цикл
        ЗаполнитьЗначенияСвойств(Ответ.Добавить(), Стр);    
    КонецЦикла;

    Возврат Ответ;
    
КонецФункции

&НаСервере
Процедура ВыполнитьНаСервере()
    
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    НЕОПРЕДЕЛЕНО КАК П1,
        |    3 КАК П2
        |ПОМЕСТИТЬ ВТ
        |
        |ОБЪЕДИНИТЬ ВСЕ
        |
        |ВЫБРАТЬ
        |    НЕОПРЕДЕЛЕНО,
        |    6";
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Запрос2 = Новый Запрос;
    Запрос2.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
    
    Запрос2.Текст =
        "ВЫБРАТЬ
        |    ВТ.П1 КАК П1,
        |    ВТ.П2 КАК П2
        |ИЗ ВТ КАК ВТ";
    ТЗ = Запрос2.Выполнить().Выгрузить();
    ТЗ2 = ПолучитьТипизированнуюТаблицу(ТЗ);
    
    Запрос3 = Новый Запрос;
    Запрос3.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
    Запрос3.УстановитьПараметр("ТЗ2",ТЗ2);
    Запрос3.Текст =
        "ВЫБРАТЬ
        |    ВТ2.П1 КАК П1,
        |    ВТ2.П2 КАК П2
        |ПОМЕСТИТЬ ВТ2
        |ИЗ &ТЗ2 КАК ВТ2
        |
        | ;
        |
        |ВЫБРАТЬ
        |    ВТ.П1 КАК П1,
        |    ВТ.П2 КАК П2
        |ИЗ ВТ КАК ВТ
        |
        |ОБЪЕДИНИТЬ ВСЕ
        |
        |ВЫБРАТЬ
        |    ВТ2.П1,
        |    ВТ2.П2
        |ИЗ ВТ2 КАК ВТ2";
    
    ТЗ3 = Запрос3.Выполнить().Выгрузить();
    
    
    
КонецПроцедуры

&НаКлиенте
Процедура Да(Команда)
    ВыполнитьНаСервере();
КонецПроцедуры
2 Прохожий
 
11.09.23
07:19
{(2, 2)}: Тип не может быть выбран в запросе
<<?>>ВТ2.П1 КАК П1,
{ВнешнийОтчет.ТестНеопределено.Форма.ФормаОтчета.Форма(94)}:    ТЗ3 = Запрос3.Выполнить().Выгрузить();
{ВнешнийОтчет.ТестНеопределено.Форма.ФормаОтчета.Форма(102)}:    ВыполнитьНаСервере();

по причине:
{(2, 2)}: Тип не может быть выбран в запросе
<<?>>ВТ2.П1 КАК П1,
3 Прохожий
 
11.09.23
07:19
Куда звонить, кому писать?
4 Прохожий
 
11.09.23
07:21
В другой ветке меня послали этим путем Два менеджера временных таблиц в одном запросе но если в колонке стоит неопределено, то у нее нет типа.
5 Мимохожий Однако
 
11.09.23
08:24
В чём великий смысл делать неопределенный тип?
6 Garykom
 
11.09.23
08:36
(0) Если в исходных данных Неопределено - это ошибка, отфильтруй или замени

Имхо ТС дурью мается
Как и с двумя МВТ в одном запросе
7 Прохожий
 
11.09.23
08:37
(5) ЕстьNULL(Чтото, Неопределено). Есть другие предложения для составных типов и т.п.?
8 Прохожий
 
11.09.23
08:38
(6) Это и есть две мвт в одном запросе. Костыли я уже сделал, все работает.
9 Прохожий
 
11.09.23
08:38
Меня этот пример интересует
10 Garykom
 
11.09.23
08:38
(7) ВЫРАЗИТЬ
11 Прохожий
 
11.09.23
08:39
(10) Во что?
12 Garykom
 
11.09.23
08:39
Когда ТЗ правильно получена из запроса - она уже типизированная
13 Garykom
 
11.09.23
08:40
(11) В пустой тип например
Твоя запросы виртуальные в вакууме, откуда знать
14 Прохожий
 
11.09.23
08:41
(12) Нет. Если неопределено, то нет типизации.
15 Garykom
 
11.09.23
08:41
Имхо если у тебя две МВТ - делаются два запроса с каждой, только на нужные данные
Результаты в ТЗ в третий запрос или кодом
16 Прохожий
 
11.09.23
08:42
(13) Пустой тип чего? Составной тип
17 Garykom
 
11.09.23
08:43
(14) Ты понимаешь что каждое поле должно иметь какой то смысл?
Либо это простой тип (число, строка, дата) или ссылочный из метаданных
И те и те имеют пустые значения
18 Garykom
 
11.09.23
08:43
(16) Все составные типы в запросах надо выражать в отдельные поля
19 Прохожий
 
11.09.23
08:43
(15) То есть предлагаешь обе прогнать через выгрузку- загрузку через ТЗ просто чтобы косяки платформы избежать? Я одну МВТ выгружаю и загружаю в запрос со второй МВТ.
20 Прохожий
 
11.09.23
08:44
Во второй МВТ есть таблица с колонкой типа неопределено, но загрузить первую параметром нельзя если даже явно назначить тип неопределено в описании типов
21 Garykom
 
11.09.23
08:45
(19) это уже на практике смотреть как лучше
но какой смысл портить своими данными имеющиеся МВТ?
22 Прохожий
 
11.09.23
08:46
(18) Это выдумки и общие пожелания. Есть конкретный пример, поле равно Неопределено. Удалось подружить только костылями. Сделал список исключений и в тексте запроса вместо "Таблица6, Поле8 как Поле8" подсовываем "Неопределено как Поле8". Только костылями
23 Прохожий
 
11.09.23
08:47
А точнее """"" КАК Поле8", и в ПолучитьТипизированнуюТаблицу тоже:
24 Garykom
 
11.09.23
08:47
(20) каким образом там ее получили? какой ее смысл? она точно нужна или можно ее тупо исключить при выгрузке?
25 Прохожий
 
11.09.23
08:47
Если СписокТипов.Количество() = 0 Тогда
    СписокТипов.Добавить(Тип("Строка"));    
КонецЕсли;
26 Garykom
 
11.09.23
08:48
Имхо ты какой то хренью страдаешь вместо решения задачи
27 Прохожий
 
11.09.23
08:48
Но это критично для последующего алгоритма, там ожидается Неопределено, а не пустая строка
28 Прохожий
 
11.09.23
08:48
(26) Задача подружить то что есть
29 Прохожий
 
11.09.23
08:49
Эта хрень называется деньги.
30 Прохожий
 
11.09.23
08:51
(24) Нельзя, следующая обработка ее ждет, пришлось костылем дописывать в запрос колонку.
31 Garykom
 
11.09.23
08:52
ты пытаешься в готовый код подсунуть результат из двух других мест?
вместо того чтобы переписать все и сделать нормально?
32 Прохожий
 
11.09.23
08:55
(31) Мне делать больше нечего. Так люди годами кастомы писали и никто не знает где чего и сколько. Кончай детский сад. "Переписать все". Есть реальный вопрос. Загрузка Неопределено с ТЗ не работает. Видимо, ни у кого решений нет. Жаль, будем жить на костылях для случая Неопределено.
33 Прохожий
 
11.09.23
08:56
Клиент ещё не заработал лишний миллиард долларов на развитие и не готов заплатить мне за "переписать все".
34 ptiz
 
11.09.23
09:03
(0) "НЕОПРЕДЕЛЕНО" прекрасно живет в запросах.
35 Garykom
 
11.09.23
09:10
(34) Передать ТЗ (с Неопределено внутри) как параметр в запрос не выходит
36 Garykom
 
11.09.23
09:10
(35)+ Точнее передать то можно, выбрать это поле где внутри есть Неопределено не получается чтобы в ВТ засунуть
37 Прохожий
 
11.09.23
09:15
(34) Прогони пример (1)
38 Garykom
 
11.09.23
09:32
Имхо все же (15)
В текстах запросах получения данных в ТЗ или обработкой самой ТЗ заменить все Неопределено на некое свое значение
Например ЕСТЬNULL(Неопределено, "НЕОПРДЕЛЕНО")

Затем сделать обратную замену когда из ТЗ через ВЫБОР

Изврат конечно еще тот:

    ТекстЗапроса =  
    "ВЫБРАТЬ
    |    ЕСТЬNULL(НЕОПРЕДЕЛЕНО, ""НЕОПРЕДЕЛЕНО"") КАК Поле1";
    Запрос = Новый Запрос(ТекстЗапроса);
    ТЗ1 = Запрос.Выполнить().Выгрузить();
    
    ТекстЗапроса =
    "ВЫБРАТЬ
    |    ТЗ1.Поле1 КАК Поле1
    |ПОМЕСТИТЬ ВТ1Врем
    |ИЗ
    |    &ТЗ КАК ТЗ1
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВЫБОР
    |        КОГДА ВТ1Врем.Поле1 = ""НЕОПРЕДЕЛЕНО""
    |            ТОГДА НЕОПРЕДЕЛЕНО
    |    КОНЕЦ КАК Поле1
    |ПОМЕСТИТЬ ВТ1
    |ИЗ
    |    ВТ1Врем КАК ВТ1Врем
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТ1.Поле1 КАК Поле1
    |ИЗ
    |    ВТ1 КАК ВТ1";
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("ТЗ", ТЗ1);
    
    ТЗ2 = Запрос.Выполнить().Выгрузить();
39 Прохожий
 
11.09.23
09:40
(38) Да я чуть иначе сделал, уже работает. Я негодую что без граблей никак. Хотя это гарантирует наши зарплаты, конечно...
40 Мимохожий Однако
 
11.09.23
10:10
ОФФ(39)"Юпитер, ты гневаешься, значить ты не прав" )) ИМХО, нервничать не профессионально
41 Прохожий
 
11.09.23
10:55
Ага. Недоделанные платформы - верх профессионализма.
"Писать надо по хитренькому" (с) Руководитель крупного разработчика 1С, не скажу кто
42 AlexeyKh
 
11.09.23
11:55
что бы типизировать значение Неопределено, я немного по другому делаю
вот рабочая функция которая типизирует ТЗ и возвращает ее в виде строки внутренней
можете вырезать цикл типизации, попробовать в своем примере.

проверял в консоли запросов работает

&НаСервере
Функция КомандаРезультатВСтрокуНаСервере()
    лкТЗ = РезультатТЗ.Выгрузить();    
    //Типизируем ТЗ, если есть данные
    Если лкТЗ.Количество() > 0 Тогда
        лкДанные = лкТЗ[0];//первая строка источник данных
        лкНов = Новый ТаблицаЗначений;
        Для каждого лкКол Из лкТЗ.Колонки Цикл  
            лкТипы    = Новый Массив;            
            лкТип    = ТипЗнч(лкДанные[лкКол.Имя]);
            Если лкТип = Тип("Строка") Тогда
                //если просто Строка, получается неограниченной, добавляем Квалификатор
                лкОписание = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(1024, ДопустимаяДлина.Переменная));
                лкНов.Колонки.Добавить(лкКол.Имя, лкОписание);
            ИначеЕсли лкТип = Тип("Неопределено") Тогда
                лкТипы.Добавить(Тип("Булево"));
                лкТипы.Добавить(Тип("Число"));
                лкНов.Колонки.Добавить(лкКол.Имя,Новый ОписаниеТипов(лкТипы));
            Иначе    
                лкТипы.Добавить(лкТип);
                лкНов.Колонки.Добавить(лкКол.Имя,Новый ОписаниеТипов(лкТипы));
            КонецЕсли;
        КонецЦикла;
        
        //перекидываем данные в типизированную ТЗ
        Для каждого лкСтр Из лкТЗ Цикл
            ЗаполнитьЗначенияСвойств(лкНов.Добавить(), лкСтр);
        КонецЦикла;
        лкТЗ = лкНов;
    КонецЕсли;
    
    Возврат ЗначениеВСтрокуВнутр(лкТЗ);
    
КонецФункции
43 Прохожий
 
11.09.23
12:04
Благодарю, чуть позже попробую. Сейчас уже другая задача.
44 AlexeyKh
 
11.09.23
15:15
допустим с колонкой со значение Неопределено, задача как-то решается (см.пример выше)

а вот как типизировать в ТЗ колонку со значением Null ?  
(вот что бы как раз и значение Null осталось и в запрос такую ТЗ в виде параметра можно было передать?)
у меня пока не получается...
45 Garykom
 
11.09.23
15:25
(44) точно также как в (38) только для NULL использовать соединение со специально созданной ВТ с NULL внутри
46 ptiz
 
11.09.23
16:23
(35) Не знаю, что у вас не выходит
https://disk.yandex.ru/i/URNvnoZfUeD3xg
47 Garykom
 
11.09.23
16:28
(46) добавь

НовСтр = ТЗ.Добавить();
НовСтр.Колонка1 = Неопределено;

и попробуй запусти
48 Garykom
 
11.09.23
16:30
(46) У ТС проблема что он не хочет разбираться какие там у него типы внутри ВТ
Из которых он данные берет а там упс и НЕОПРЕДЕЛЕНО внутри

посмотри мой код в (38) как пример
да можно типизировать и заполнить вместо Неопределено дефолтными значениями для простых и пустыми ссылками для ссылочных типов
но ТС это влом - и вполне его понимаю
49 Garykom
 
11.09.23
16:33
(48)+ в (38) я ТЗ заполняю через запрос
ТекстЗапроса =  
"ВЫБРАТЬ
|    ЕСТЬNULL(НЕОПРЕДЕЛЕНО, ""НЕОПРЕДЕЛЕНО"") КАК Поле1";
Запрос = Новый Запрос(ТекстЗапроса);
ТЗ1 = Запрос.Выполнить().Выгрузить();

А можно же просто
ТекстЗапроса =  
"ВЫБРАТЬ
|    НЕОПРЕДЕЛЕНО КАК Поле1"; // будет ошибка потом
Запрос = Новый Запрос(ТекстЗапроса);
ТЗ1 = Запрос.Выполнить().Выгрузить();
50 ptiz
 
11.09.23
17:03
(47) Всё также работает. При добавлении пустой строки там и так уже Неопределено (видно по результату запроса).
51 Garykom
 
11.09.23
17:38
(50) У тебя пустое значение составного типа vs Неопределено без типа
ТС я сразу предложил типизировать все свои неопределено но ему влом
52 Прохожий
 
11.09.23
18:29
Радикально проще способ умозрительный: Выбрать все интересующие ВТ в ТЗ из МВТ1, вторым запросом дополнить все ТЗ интересующими МВТ2, типизировать и загрузить в результирующую МВТ. И не надо в запросе к ТЗ из МВТ1 прибавлять МВТ2 через ОБЪЕДИНИТЬ ВСЕ. И с типами проблем не будет.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой