Как избавиться от типа NULL в колонках результата запроса?
Добрый день.
Есть запрос:
В результате имею таблицу, в которой все колонки имеют составной тип, один из которых это NULL.
Для меня это критично, так как как я эту табличку сериализую, точнее должен сериализовать, но на этом этапе получаю ошибку из за типа NULL.
Можно ли переписать запрос так, что бы колонки была строго определенного типа?
Единственно, что пока приходит на ум, это создать ТЗ с такими же колонками с простым типом Строка/Белево и т.д. и просто в цикле заполнить эту ТЗ из выборки запроса. Но может есть более простой вариант?
Есть запрос:
"ВЫБРАТЬ
| ВЫРАЗИТЬ(ШтрихкодыИзменения.Штрихкод КАК СТРОКА(100)) КАК Штрихкод,
| ШтрихкодыИзменения.Владелец КАК Владелец_,
| ШтрихкодыИзменения.ТипШтрихкода КАК ТипШтрихкода,
| ШтрихкодыИзменения.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| Штрихкоды.Штрихкод ЕСТЬ NULL
| ИЛИ ШтрихкодыИзменения.Владелец ССЫЛКА Справочник.ФизическиеЛица
| И ТСДСотрудники.ФизЛицо ЕСТЬ NULL КАК Удаление
|ИЗ
| РегистрСведений.Штрихкоды.Изменения КАК ШтрихкодыИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды
| ПО ШтрихкодыИзменения.Штрихкод = Штрихкоды.Штрихкод
| И ШтрихкодыИзменения.Владелец = Штрихкоды.Владелец
| И ШтрихкодыИзменения.ТипШтрихкода = Штрихкоды.ТипШтрихкода
| И ШтрихкодыИзменения.ЕдиницаИзмерения = Штрихкоды.ЕдиницаИзмерения
| И ШтрихкодыИзменения.ХарактеристикаНоменклатуры = Штрихкоды.ХарактеристикаНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ ПланОбмена.ТСД.Сотрудники КАК ТСДСотрудники
| ПО ШтрихкодыИзменения.Узел = ТСДСотрудники.Ссылка
| И ШтрихкодыИзменения.Владелец = ТСДСотрудники.ФизЛицо
|ГДЕ
| ШтрихкодыИзменения.Узел = &Узел
| И (ШтрихкодыИзменения.Владелец ССЫЛКА Справочник.МестаХранения
| ИЛИ ШтрихкодыИзменения.Владелец ССЫЛКА Справочник.ФизическиеЛица
| ИЛИ ШтрихкодыИзменения.Владелец ССЫЛКА Справочник.Номенклатура)" ПоказатьВ результате имею таблицу, в которой все колонки имеют составной тип, один из которых это NULL.
Для меня это критично, так как как я эту табличку сериализую, точнее должен сериализовать, но на этом этапе получаю ошибку из за типа NULL.
Можно ли переписать запрос так, что бы колонки была строго определенного типа?
Единственно, что пока приходит на ум, это создать ТЗ с такими же колонками с простым типом Строка/Белево и т.д. и просто в цикле заполнить эту ТЗ из выборки запроса. Но может есть более простой вариант?
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) Вроде именно запросом на это никак не повлиять. Один из вариантов решения задачи, это удалить ненужную составляющую из типа колонки. Например, так:
Запрос = Новый Запрос;
Таблица = Запрос.Выполнить().Выгрузить();
ИсходныеКолонки = Новый Массив;
Для каждого Колонка Из Таблица.Колонки Цикл
ИсходныеКолонки.Добавить(Колонка);
КонецЦикла;
Для каждого Колонка Из ИсходныеКолонки Цикл
ИмяКолонки = Колонка.Имя;
ТипКолонки = Колонка.ТипЗначения;
Таблица.Колонки[ИмяКолонки].Имя = "Удалить" + ИмяКолонки;
Таблица.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ТипКолонки, , "NULL"));
Таблица.ЗагрузитьКолонку(Таблица.ВыгрузитьКолонку("Удалить"+ИмяКолонки), ИмяКолонки);
Таблица.Колонки.Удалить("Удалить" + ИмяКолонки);
КонецЦикла; Показать
(5) Пошел именно по этому пути, только код немного другой:
Результат=Запрос.Выполнить();
Выборка=Результат.Выбрать();
ТЗ=Новый ТаблицаЗначений;
Для Каждого Колонка из Результат.Колонки Цикл
ТЗ.Колонки.Добавить(Колонка.Имя,Новый ОписаниеТипов(Колонка.ТипЗначения,,"NULL"));
КонецЦикла;
Пока Выборка.Следующий() Цикл
Стр=ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(Стр,Выборка);
КонецЦикла; Показать
(1)
В каждом выбираемом поле ставь ВЫРАЗИТЬ(<нужное_поле> КАК <нужный_тип>)
Если всё равно останется проблема с NULL, то оберни <нужное_поле> в ЕСТЬNULL(<нужное_поле>, <пустая_ссылка_нужного_типа>)
Можно ли переписать запрос так, что бы колонки была строго определенного типа?
В каждом выбираемом поле ставь ВЫРАЗИТЬ(<нужное_поле> КАК <нужный_тип>)
Если всё равно останется проблема с NULL, то оберни <нужное_поле> в ЕСТЬNULL(<нужное_поле>, <пустая_ссылка_нужного_типа>)
(9) По запросу NULL будет только в правых таблицах, а выборка (кроме последнего поля) идёт из левой таблицы и там по причине соединения NULL не возникнет. Скорее всего в исходной левой таблице есть значения NULL изначально.
(1) По сути самого первого вопроса - есть ответ на ИТС (Сорри что поздно, но сам столкнулся)))):
При использовании запросов следует учитывать, что в результате запроса в колонках,
кроме типов значений исходных полей, могут присутствовать значения типа NULL.
Поэтому тип колонки таблицы значений, полученной из результата запроса,
не будет полностью соответствовать типу исходного поля таблицы, а будет дополнительно содержать тип NULL.
Иными словами Запрос.Выполнить().Выгрузить() - всегда добавляет к описанию типа возвращаемых колонок тип("NULL")
Это заложено платформой. И никак по-другому.
Сделал для себя процедуру, которая потом из таблицы "выбрасывает" этот NULL, может кому пригодится:
При использовании запросов следует учитывать, что в результате запроса в колонках,
кроме типов значений исходных полей, могут присутствовать значения типа NULL.
Поэтому тип колонки таблицы значений, полученной из результата запроса,
не будет полностью соответствовать типу исходного поля таблицы, а будет дополнительно содержать тип NULL.
Иными словами Запрос.Выполнить().Выгрузить() - всегда добавляет к описанию типа возвращаемых колонок тип("NULL")
Это заложено платформой. И никак по-другому.
Сделал для себя процедуру, которая потом из таблицы "выбрасывает" этот NULL, может кому пригодится:
Процедура ТаблицаЗначенийБезNull(ТаблицаЗначений, фИзменилиТаблицу = ЛОЖЬ) Экспорт
фИзменилиТаблицу = ЛОЖЬ;
чКрайний = ТаблицаЗначений.Колонки.Количество()-1;
Для чИндекс = 0 По чКрайний Цикл
ТипКолонки = ТаблицаЗначений.Колонки[чИндекс].ТипЗначения;
Если ТипКолонки.СодержитТип(Тип("Null")) Тогда
ИмяКолонки = ТаблицаЗначений.Колонки[чИндекс].Имя;
ЗагКолонки = ТаблицаЗначений.Колонки[чИндекс].Заголовок;
ШирКолонки = ТаблицаЗначений.Колонки[чИндекс].Ширина;
ЗнчКолонки = ТаблицаЗначений.ВыгрузитьКолонку(чИндекс);
ТипКолонки = Новый ОписаниеТипов(ТипКолонки,,"NULL"
,ТипКолонки.КвалификаторыЧисла
,ТипКолонки.КвалификаторыСтроки
,ТипКолонки.КвалификаторыДаты
,ТипКолонки.КвалификаторыДвоичныхДанных
);
ТаблицаЗначений.Колонки.Удалить(чИндекс);
ТаблицаЗначений.Колонки.Вставить(чИндекс,ИмяКолонки,ТипКолонки,ЗагКолонки,ШирКолонки);
ТаблицаЗначений.ЗагрузитьКолонку(ЗнчКолонки,чИндекс);
фИзменилиТаблицу = ИСТИНА;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Показать
(15)
Квалификаторы дополнительно передавать не нужно:
ТипКолонки = Новый ОписаниеТипов(ТипКолонки,,"NULL");
ТипКолонки = Новый ОписаниеТипов(ТипКолонки,,"NULL"
,ТипКолонки.КвалификаторыЧисла
,ТипКолонки.КвалификаторыСтроки
,ТипКолонки.КвалификаторыДаты
,ТипКолонки.КвалификаторыДвоичныхДанных
);
,ТипКолонки.КвалификаторыЧисла
,ТипКолонки.КвалификаторыСтроки
,ТипКолонки.КвалификаторыДаты
,ТипКолонки.КвалификаторыДвоичныхДанных
);
Квалификаторы дополнительно передавать не нужно:
ТипКолонки = Новый ОписаниеТипов(ТипКолонки,,"NULL");
(1) Привет из 2025,
все что тут писали коллеги к сути дела не имеет, особенно ответы с левым/внутренним соединением и ЕСТЬNULL(
кроме разве что (15) и ссылки ИТС
а именно:
"При использовании запросов следует учитывать, что в результате запроса в колонках, кроме типов значений исходных полей, могут присутствовать значения типа NULL."
Если вы используете .Выгрузить(), при чем не важно выгружаете из результата запроса или построителя запросов, в результате получите таблицу в колонках которых будет составной тип (null, + что-то что там было)
"Поэтому тип колонки таблицы значений, полученной из результата запроса, не будет полностью соответствовать типу исходного поля таблицы, а будет дополнительно содержать тип NULL."
Это просто особенность платформы, и именно при РезультатЗапроса.Выгрузить()
И действительно правильное решение проблемы, это не переписывать полученную в результате таблицу, а заменить РезультатЗапроса.Выгрузить() на РезультатЗапроса.Выбрать() и в выборке заполнить созданную ранее таблицу через ЗаполнитьЗначенияСвойств()
все что тут писали коллеги к сути дела не имеет, особенно ответы с левым/внутренним соединением и ЕСТЬNULL(
кроме разве что (15) и ссылки ИТС
а именно:
"При использовании запросов следует учитывать, что в результате запроса в колонках, кроме типов значений исходных полей, могут присутствовать значения типа NULL."
Если вы используете .Выгрузить(), при чем не важно выгружаете из результата запроса или построителя запросов, в результате получите таблицу в колонках которых будет составной тип (null, + что-то что там было)
"Поэтому тип колонки таблицы значений, полученной из результата запроса, не будет полностью соответствовать типу исходного поля таблицы, а будет дополнительно содержать тип NULL."
Это просто особенность платформы, и именно при РезультатЗапроса.Выгрузить()
И действительно правильное решение проблемы, это не переписывать полученную в результате таблицу, а заменить РезультатЗапроса.Выгрузить() на РезультатЗапроса.Выбрать() и в выборке заполнить созданную ранее таблицу через ЗаполнитьЗначенияСвойств()
ЕСТЬNULL(<Проверяемое выражение>, <Выражение замены>)
функция в запросе для проверки на null, если null то заменяет выражение
функция в запросе для проверки на null, если null то заменяет выражение
ЕСТЬNULL(<Проверяемое выражение>, <Выражение замены>)
Требуется указать в финальной части запроса, в процессе формирования подзапросов не соединенные записи будут давать NULL.
Требуется указать в финальной части запроса, в процессе формирования подзапросов не соединенные записи будут давать NULL.
В общем проблема решилась, не так как я ожидал но все же.
При сериализации 1С ругалась что не могла преобразовать NULL в тип Строка
У меня выгружалось 23К записей. Проверил по 100 раз, ни в одной нет значения NULL но в каждой колонке составной тип с NULL'ом - я на это и согрешил, о решил избавиться от этого типа NULL в колонках.
Избавился, табличка стала красивая, но выгружаться все равно не захотела.
Теперь ошибка при сериализации была другая, что невозможно к типу Строка привести значение : и указывала какое то "конячье" число из 26 символов. Решил поискать в базе такой штрихкод - а его нет.
Пришлось временно переписать выгрузку, сделал сериализацию построчно, что бы найти на какой товар назначен это тштрихкод и почему я его не могу найти.
В общем товар нашел, штрихкоды по нему нашел. Вижу штрихкод, на который ругается 1С. Копирую его в блокнот. и пытаюсь, из блокнота вставляю в строку поиска - не находит такой штрихкод.
Посимвольно сравнил 2 "одинаковых" штрихкода.
СУУУуу....а, вот оно, каким то макаром в середине штрихкода попал символ с кодом 29. Этот символ не отображается в 1С, но при выгрузке в XML выдает ошибку.
Так что тип колонку с NULL не причем, прост 1С не корректно материлась, наткнувшись на символ с кодом 29(↔)
Удалил штрихкод, и выгрузка возобновилась
При сериализации 1С ругалась что не могла преобразовать NULL в тип Строка
У меня выгружалось 23К записей. Проверил по 100 раз, ни в одной нет значения NULL но в каждой колонке составной тип с NULL'ом - я на это и согрешил, о решил избавиться от этого типа NULL в колонках.
Избавился, табличка стала красивая, но выгружаться все равно не захотела.
Теперь ошибка при сериализации была другая, что невозможно к типу Строка привести значение : и указывала какое то "конячье" число из 26 символов. Решил поискать в базе такой штрихкод - а его нет.
Пришлось временно переписать выгрузку, сделал сериализацию построчно, что бы найти на какой товар назначен это тштрихкод и почему я его не могу найти.
В общем товар нашел, штрихкоды по нему нашел. Вижу штрихкод, на который ругается 1С. Копирую его в блокнот. и пытаюсь, из блокнота вставляю в строку поиска - не находит такой штрихкод.
Посимвольно сравнил 2 "одинаковых" штрихкода.
СУУУуу....а, вот оно, каким то макаром в середине штрихкода попал символ с кодом 29. Этот символ не отображается в 1С, но при выгрузке в XML выдает ошибку.
Так что тип колонку с NULL не причем, прост 1С не корректно материлась, наткнувшись на символ с кодом 29(↔)
Удалил штрихкод, и выгрузка возобновилась
(12) О, знакомый символ 29 :)
Т.е. он не просто так ко мне попал. Печалька. придется перед сериализацией менять 29 на что то читабельно, а после десериализации это что то менять опять на символ 29.
Спасибо за ссылку. Но вот штрихкод из базы я уже удалил :(
Т.е. он не просто так ко мне попал. Печалька. придется перед сериализацией менять 29 на что то читабельно, а после десериализации это что то менять опять на символ 29.
Спасибо за ссылку. Но вот штрихкод из базы я уже удалил :(
Добрый день, я могу ошибаться, но в запросе можно сделать через виртуальную таблицу, а в условии ВТ_ поставить что-то
ГДЕ НЕ (КолонкаСnull Есть null)
ГДЕ НЕ (КолонкаСnull Есть null)
NULL появляется из-за левого соединение. Замени на Внутреннее соединение и тогда в выборке не будет записей с NULL унаследованных от левого соединения. По сути при использовании Внутреннего соединения мы компенсируем отсутствие в 1с конструкции НЕ ПсевдонимТаблицы.Поле ЕСТЬ NULL
А давайте мы не будем отвечать на ретротемы, а? Чета я сомневаюсь, что вопрос про ЕСТЬNULL от 20-го года в 24-м сохранил свою актуальность...
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот
