Приветствуем вас! Сегодня мы с вами погрузимся в одну из распространенных проблем, с которой сталкиваются разработчики на платформе 1С:Предприятие – некорректная работа отбора в
ТаблицаЗначений
Представим типовую ситуацию: мы получаем данные из запроса в
ТаблицаЗначений
ТаблицаЗначений
Рассмотрим пример из практики, когда в запросе было выбрано поле, например,
РасчетыСКлиентами.ОбъектРасчетов
ЗаказКлиента
Справочник.ОбъектыРасчетов
Как это выяснить? Мы можем использовать отладчик. Установите точку останова после выполнения запроса и выгрузки данных в
ТаблицаЗначений
Выборка.ЗаказКлиента
ТаблицаЗначений
ТипЗнч()
ДокументСсылка.ЗаказКлиента
СправочникСсылка.ОбъектыРасчетов
Если мы выяснили, что поле в запросе возвращает не тот тип, который нам нужен для отбора, решение достаточно простое – необходимо скорректировать запрос. В нашем примере с
РасчетыСКлиентами.ОбъектРасчетов
ЗаказКлиента
Объект
Давайте посмотрим на пример такого изменения в тексте запроса:
ВЫБРАТЬ
РасчетыСКлиентами.ОбъектРасчетов.Объект КАК ЗаказКлиента,
// Другие поля...
ИЗ
РегистрНакопления.РасчетыСКлиентами КАК РасчетыСКлиентами
// Условия отбора...
В этом случае, добавив
.Объект
ОбъектРасчетов
ОбъектРасчетов
ОбъектРасчетов
Документ.ЗаказКлиента
ОбъектРасчетов.Объект
ДокументСсылка.ЗаказКлиента
Хотя колонки
ТаблицаЗначений
Неопределено
Мы можем добавить колонку с определенным типом, используя метод
Колонки.Добавить()
ОписаниеТипов
// Создаем новую ТаблицуЗначений
ПеременнаяТЗ = Новый ТаблицаЗначений;
// Добавляем колонку "НомерЗаказа" строкового типа
ПеременнаяТЗ.Колонки.Добавить("НомерЗаказа", Новый ОписаниеТипов("Строка"));
// Добавляем колонку "Сумма" числового типа
ПеременнаяТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
// Добавляем колонку "ЗаказКлиента" ссылочного типа на документ ЗаказКлиента
ПеременнаяТЗ.Колонки.Добавить("ЗаказКлиента", Новый ОписаниеТипов("ДокументСсылка.ЗаказКлиента"));
Такой подход делает нашу
ТаблицаЗначений
Давайте проанализируем другие распространенные ситуации, когда типы данных могут мешать корректному отбору:
СправочникСсылка.ОбъектыРасчетов
ДокументСсылка.ЗаказКлиента
ДокументСсылка.ЗаказКлиента
ДокументСсылка.РеализацияТоваровУслуг
ВЫБОР КОГДА
NULL
NULL
NULL
NULL
ЕСТЬNULL()
NULL
Теперь рассмотрим, какими методами мы можем осуществлять отбор в
ТаблицаЗначений
Метод
НайтиСтроки()
Структура
Посмотрим на пример:
// Предположим, у нас есть ТаблицаЗначений ТЗ
// с колонками "Контрагент", "Сумма", "Договор"
// Создаем структуру для отбора
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Контрагент", СсылкаНаКонтрагента);
СтруктураОтбора.Вставить("Договор", СсылкаНаДоговор);
// Применяем отбор
НайденныеСтроки = ТЗ.НайтиСтроки(СтруктураОтбора);
Если НайденныеСтроки.Количество() > 0 Тогда
Для Каждого СтрокаТЗ Из НайденныеСтроки Цикл
Сообщить("Найденная строка: " + СтрокаТЗ.Сумма);
КонецЦикла;
Иначе
Сообщить("Строки по заданным условиям не найдены.");
КонецЕсли;
Перебор и копирование: Для более сложных условий отбора (например, "больше", "меньше", "в иерархии", "содержит часть строки", "не равно") часто используется ручной перебор строк исходной
ТаблицаЗначений
Пример такого подхода:
// Предположим, у нас есть ТаблицаЗначений ИсходнаяТЗ
// с колонками "Дата", "Сумма", "Статус"
ОтфильтрованнаяТЗ = Новый ТаблицаЗначений;
Для Каждого Колонка Из ИсходнаяТЗ.Колонки Цикл
ОтфильтрованнаяТЗ.Колонки.Добавить(Колонка.Имя, Колонка.ОписаниеТипов);
КонецЦикла;
Для Каждого СтрокаИсходнойТЗ Из ИсходнаяТЗ Цикл
// Пример сложного условия отбора:
// Сумма больше 1000 ИЛИ (Статус = "Оплачен" И Дата > НачалоМесяца(ТекущаяДата()))
Если СтрокаИсходнойТЗ.Сумма > 1000 ИЛИ
(СтрокаИсходнойТЗ.Статус = "Оплачен" И СтрокаИсходнойТЗ.Дата > НачалоМесяца(ТекущаяДата())) Тогда
ОтфильтрованнаяТЗ.Добавить().Заполнить(СтрокаИсходнойТЗ);
КонецЕсли;
КонецЦикла;
Использование
ПостроителяЗапроса
ТаблицаЗначений
ПостроительЗапроса
ТаблицаЗначений
ПостроительЗапроса.Отбор.Добавить()
Давайте посмотрим, как это реализовать:
// Предположим, у нас есть ТаблицаЗначений ИсходнаяТЗ
// с колонками "Номенклатура", "Количество", "Склад"
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ИсходнаяТЗ);
// Добавляем поля, которые хотим получить в результате
ПостроительЗапроса.Поля.Добавить("Номенклатура");
ПостроительЗапроса.Поля.Добавить("Количество");
ПостроительЗапроса.Поля.Добавить("Склад");
// Устанавливаем условие отбора
ЭлементОтбора = ПостроительЗапроса.Отбор.Добавить("Номенклатура");
ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии;
ЭлементОтбора.Значение = СсылкаНаГруппуНоменклатуры; // Отбор по группе номенклатуры
ЭлементОтбора.Использование = Истина;
ЭлементОтбора2 = ПостроительЗапроса.Отбор.Добавить("Количество");
ЭлементОтбора2.ВидСравнения = ВидСравнения.Больше;
ЭлементОтбора2.Значение = 10;
ЭлементОтбора2.Использование = Истина;
// Выполняем запрос и получаем отфильтрованную ТаблицуЗначений
ОтфильтрованнаяТЗ = ПостроительЗапроса.Выполнить().Выгрузить();
Свойство
ОтборСтрок
ТаблицаЗначений
ОтборСтрок
ФиксированнуюСтруктуру
Пример использования в модуле формы:
// Предположим, у нас есть элемент формы ТаблицаНаФорме, источником данных которого является ТЗ
// и мы хотим отфильтровать ее по колонке "Статус" со значением "Активный"
СтруктураОтбораФормы = Новый Структура("Статус", "Активный");
Элементы.ТаблицаНаФорме.ОтборСтрок = Новый ФиксированнаяСтруктура(СтруктураОтбораФормы);
Этот способ удобен для динамического изменения отбора, видимого пользователю.
Помимо проблем с типами, мы можем столкнуться и с другими сложностями:
"Ошибка отображения типов: Отсутствует отображение для типа '{http://v8.1c.ru/8.1/data/core}ValueTable'": Эта ошибка может возникать при попытке передачи
ТаблицаЗначений
ValueTable
ТаблицаЗначений
ТаблицаЗначений
ОписаниеТипов
"Тип не может быть выбран в запросе": Помимо проблем с составными типами, эта ошибка также может указывать на несоответствие типов данных при сравнении или объединении полей в запросе (например, сравнение числового поля со строковым). Всегда проверяйте, что сравниваемые или объединяемые поля имеют совместимые типы. При необходимости используйте функции преобразования типов, такие как
СТРОКА()
ЧИСЛО()
ДАТА()
Для эффективной работы с отборами в
ТаблицаЗначений
ТаблицаЗначений