При попытке программно установить отбор для ЖурналДокументов.Отбор или других списков, например,
ЭтаФорма.ЖурналДокументов.Отбор.Добавить("Контрагент", "Контрагент", "Контрагент")
Корнем проблемы является принципиальное различие в механизмах работы с отборами для списков объектов в обычных формах и в управляемых формах. В контексте платформы 1С:Предприятие 8.3, термин "динамический список" может интерпретироваться по-разному, что часто вводит в заблуждение.
ЖурналДокументов, СправочникСписок, ДокументСписок и т.д.)
В обычных формах мы часто имеем дело со списками, которые формируются динамически на основе данных из базы. Объекты типа ЖурналДокументов.Отбор, СправочникСписок.Отбор или ДокументСписок.Отбор представляют собой коллекции элементов отбора.
Суть проблемы: Для этих объектов (в обычных формах) метод Добавить() действительно не доступен. Об этом прямо говорится в синтакс-помощнике (СП): "Внимание! Метод не доступен для отбора динамических списков (свойство Отбор объектов СправочникСписок., ДокументСписок. и т.д.).".
Элементы отбора в таких списках, как правило, фиксированы и привязаны к существующим колонкам списка на форме. Мы не можем произвольно "добавить" новый элемент отбора, если для него нет соответствующей колонки или предопределенного свойства. Вместо добавления новых элементов, мы должны работать с уже существующими.
Решение для обычных форм: Использование метода Отбор.Найти()
Если нам необходимо установить отбор по какому-либо полю, например, по контрагенту, мы должны сначала убедиться, что для этого поля предусмотрена соответствующая колонка в журнале (списке). После этого мы можем найти существующий элемент отбора по имени поля и установить для него значение, а затем активировать его использование. Давайте посмотрим на пример:
// Предположим, мы хотим установить отбор по контрагенту в журнале документов
// Переменная МойКонтрагент содержит ссылку на нужного контрагента
// 1. Находим существующий элемент отбора по полю "Контрагент"
ЭлементОтбора = ЭтаФорма.ЖурналДокументов.Отбор.Найти("Контрагент");
// 2. Проверяем, был ли найден элемент отбора
Если ЭлементОтбора <> Неопределено Тогда
// 3. Устанавливаем значение отбора
ЭлементОтбора.Значение = МойКонтрагент;
// 4. Активируем использование отбора
ЭлементОтбора.Использование = Истина;
// 5. Обновляем список, чтобы изменения вступили в силу
// Для ЖурналаДокументов обычно достаточно установки значения,
// но в некоторых случаях может потребоваться явное Обновить()
// ЭтаФорма.ЭлементыФормы.ЖурналДокументов.Обновить(); // Если ЖурналДокументов является элементом формы
Иначе
Сообщить("Элемент отбора по контрагенту не найден в ЖурналеДокументов. Убедитесь, что соответствующая колонка присутствует.");
КонецЕсли;
Важно: Для успешного применения Отбор.Найти() соответствующий элемент отбора должен уже существовать в коллекции Отбор журнала/списка. Это означает, что он либо предопределен в конфигурации, либо был добавлен пользователем вручную через настройки списка.
ДинамическийСписок как объект)
В управляемых формах ситуация иная. Здесь ДинамическийСписок является полноценным объектом, и его свойство Отбор предоставляет гораздо более гибкие возможности. Мы можем программно добавлять элементы отбора, используя коллекцию Список.Отбор.Элементы.
Давайте рассмотрим различные подходы к программной установке отбора в динамическом списке управляемой формы.
Одним из наиболее чистых и рекомендуемых способов установить начальный отбор для динамического списка является передача параметров отбора при открытии формы. Мы формируем структуру, где ключи соответствуют именам полей, по которым хотим отбирать, а значения — данным для отбора. Этот механизм является частью расширения управляемой формы динамического списка.
// Пример: Открытие формы списка документов "Реализация товаров и услуг"
// с отбором по конкретному контрагенту
// 1. Определяем контрагента, по которому хотим отфильтровать
МойКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО \"Рога и Копыта\"");
Если МойКонтрагент <> Неопределено Тогда
// 2. Создаем структуру параметров отбора
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Контрагент", МойКонтрагент);
// 3. Создаем структуру параметров открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
// 4. Открываем форму списка, передавая параметры отбора
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", ПараметрыФормы);
Иначе
Сообщить("Контрагент не найден.");
КонецЕсли;
При таком подходе отбор будет применен до отображения формы пользователю, и он может быть виден в быстрых настройках или в настройках списка.
ПриСозданииНаСервере)
Если нам нужно установить отбор уже после того, как форма открыта (например, в обработчике события формы ПриСозданииНаСервере или по действию пользователя), мы можем программно добавить элементы отбора в коллекцию Список.Отбор.Элементы.
Для этого мы используем тип ЭлементОтбораКомпоновкиДанных и настраиваем его свойства: ЛевоеЗначение (поле, по которому отбираем), ВидСравнения, ПравоеЗначение (значение для сравнения) и Использование. Также можем указать РежимОтображения, чтобы контролировать видимость отбора для пользователя.
// Пример: Добавление отбора по контрагенту в динамический список
// в обработчике ПриСозданииНаСервере
// 1. Получаем ссылку на контрагента (или любой другой объект, по которому хотим отбирать)
МойКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО \"Мечта\"");
Если МойКонтрагент <> Неопределено Тогда
// 2. Создаем новый элемент отбора
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
// 3. Устанавливаем левое значение (поле списка)
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
// 4. Устанавливаем вид сравнения (например, "Равно")
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
// 5. Устанавливаем правое значение (значение, с которым сравниваем)
ЭлементОтбора.ПравоеЗначение = МойКонтрагент;
// 6. Активируем использование отбора
ЭлементОтбора.Использование = Истина;
// 7. Определяем режим отображения отбора для пользователя
// Возможные значения: Обычный, Скрытый, БыстрыйДоступ, Недоступный
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный;
Иначе
Сообщить("Контрагент для отбора не найден.");
КонецЕсли;
В типовых конфигурациях, основанных на БСП (например, 1С:ERP, 1С:КА, 1С:УТ), часто существуют вспомогательные функции, которые упрощают работу с динамическими списками. Одной из таких функций может быть ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(). Она позволяет более унифицированно добавлять или заменять элементы отбора, абстрагируясь от прямого создания ЭлементОтбораКомпоновкиДанных.
При использовании таких функций, разработчики полагаются на функциональность, предоставляемую БСП, что может быть более удобно и надежно в рамках типовых решений.
Если ваш динамический список построен на основе "произвольного запроса" (свойство Список.ПроизвольныйЗапрос = Истина), вы можете реализовать отбор, напрямую изменяя текст этого запроса, добавляя условия ГДЕ.
Этот метод дает максимальный контроль над запросом, но требует осторожности, чтобы не нарушить его структуру. Также необходимо использовать параметры запроса для безопасной передачи значений.
// Пример: Добавление отбора в текст запроса динамического списка
// в обработчике ПриСозданииНаСервере
// 1. Получаем ссылку на контрагента
МойКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО \"Партнер\"");
Если МойКонтрагент <> Неопределено Тогда
// 2. Проверяем, что список использует произвольный запрос
Если Список.ПроизвольныйЗапрос Тогда
// 3. Изменяем текст запроса, добавляя условие ГДЕ
Список.ТекстЗапроса = "ВЫБРАТЬ
| Документ.РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| Документ.РеализацияТоваровУслуг.Номер КАК Номер,
| Документ.РеализацияТоваровУслуг.Дата КАК Дата,
| Документ.РеализацияТоваровУслуг.Контрагент КАК Контрагент
|ИЗ
| Документ.РеализацияТоваровУслуг КАК ДокументРеализацияТоваровУслуг
|ГДЕ
| ДокументРеализацияТоваровУслуг.Контрагент = &МойКонтрагент";
// 4. Устанавливаем значение параметра запроса
Список.Параметры.Установить("МойКонтрагент", МойКонтрагент);
Иначе
Сообщить("Динамический список не использует произвольный запрос. Данный метод не применим.");
КонецЕсли;
Иначе
Сообщить("Контрагент для отбора не найден.");
КонецЕсли;
Этот метод следует применять с осторожностью, поскольку некорректное изменение запроса может привести к ошибкам в работе списка.
При работе с отборами в 1С всегда помните о следующих рекомендациях:
ЭтаФорма.ЖурналДокументов, то, скорее всего, это обычная форма.
СП (Синтакс-помощник) — ваш лучший друг. Он всегда укажет на доступность методов и свойств для конкретного объекта и режима работы.
Таким образом, хотя метод Отбор.Добавить() и недоступен для динамических списков в обычных формах, существуют эффективные альтернативные подходы как для обычных, так и для управляемых форм, позволяющие программно управлять отбором данных. Ключ к успеху — понимание архитектуры и особенностей платформы 1С.