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