Как исправить ошибку «не задано значение параметра» в динамическом списке 1С?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке и доработке форм подбора, списков документов или справочников с использованием произвольного запроса в динамическом списке разработчики часто сталкиваются с ошибкой: «Ошибка при исполнении запроса набора данных по причине: не задано значение параметра». В консоли запросов такой текст может отрабатывать без ошибок, но при открытии управляемой формы интерфейс падает в исключение.

Разберем причины такого поведения платформы 1С:Предприятие 8.3 и рассмотрим способы правильной передачи параметров в динамический список.

Проанализируем типовую структуру запроса динамического списка, вызывающую подобную проблему:


ВЫБРАТЬ
	СправочникНоменклатура.Ссылка КАК Ссылка,
	СправочникНоменклатура.Наименование КАК Наименование,
	СправочникНоменклатура.Артикул КАК Артикул,
	ЕСТЬNULL(ОстаткиНаСкладе.КоличествоОстаток, 0) КАК КоличествоОстаток
ИЗ
	Справочник.Номенклатура КАК СправочникНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(
		{(&ДатаОстаткиЦены)},
		Счет В (&СписокСчетов),
		{(&ВидыСубконто)},
		Организация В (&СписокОрганизаций)
	) КАК ОстаткиНаСкладе
	ПО СправочникНоменклатура.Ссылка = ОстаткиНаСкладе.Субконто1
ГДЕ
	НЕ СправочникНоменклатура.ЭтоГруппа

Причины возникновения ошибки

Динамический список работает на базе механизма системы компоновки данных (СКД). Выясним основные причины ошибки исполнения запроса:

  1. Обязательные параметры без синтаксиса расширения СКД (фигурных скобок): если параметр виртуальной таблицы или условие ГДЕ записаны напрямую (например, Счет В (&СписокСчетов) или Организация В (&СписокОрганизаций)), платформа считает такие параметры строго обязательными. Если к моменту первого считывания данных их значения не переданы, СКД аварийно прерывает выполнение запроса.
  2. Неверный момент инициализации параметров: чтение первой порции данных динамического списка происходит при первичной отрисовке формы. Если параметры списка инициализируются в обработчике ПриОткрытии на клиенте или по кнопкам интерфейса, список пытается запросить данные на сервере раньше, чем клиентский код успевает передать значения.
  3. Параметры виртуальных таблиц регистров: для виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.Остатки параметры порядка субконто (&ВидыСубконто) и счетов требуют обязательного или явно определенного типа данных, иначе обращение к Субконто1 или Субконто2 приводит к ошибке.

Способ 1. Инициализация параметров в обработчике ПриСозданииНаСервере

Основное правило работы с динамическим списком — передавать все обязательные параметры на этапе инициализации формы на сервере. Рассмотрим правильный порядок действий:

Создадим функцию для расчета или получения списка счетов и заполним параметры списка в обработчике ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Формируем массив или список счетов
	СписокСчетов = Новый Массив;
	СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.Товары);
	СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.ГотоваяПродукция);
	
	// Заполняем список организаций
	СписокОрганизаций = Новый Массив;
	Если ЗначениеЗаполнено(Параметры.Организация) Тогда
		СписокОрганизаций.Добавить(Параметры.Организация);
	КонецЕсли;
	
	// Устанавливаем параметры динамического списка
	Список.Параметры.УстановитьЗначениеПараметра("СписокСчетов", СписокСчетов);
	Список.Параметры.УстановитьЗначениеПараметра("СписокОрганизаций", СписокОрганизаций);
	Список.Параметры.УстановитьЗначениеПараметра("ДатаОстаткиЦены", ТекущаяДатаСеанса());
	
КонецПроцедуры

Метод УстановитьЗначениеПараметра не только присваивает значение, но и автоматически устанавливает признак Использование = Истина для соответствующего параметра в коллекции Список.Параметры.

Способ 2. Использование синтаксиса расширения языка запросов СКД

Разберем, как сделать параметры динамического списка необязательными. Для этого используем фигурные скобки {}. Если параметр обернут в фигурные скобки, СКД включает условие в итоговый SQL-запрос только тогда, когда параметр явно заполнен и включен.

Посмотрим на пример адаптации текста запроса:


ВЫБРАТЬ
	СправочникНоменклатура.Ссылка КАК Ссылка,
	СправочникНоменклатура.Наименование КАК Наименование,
	ЕСТЬNULL(ОстаткиНаСкладе.КоличествоОстаток, 0) КАК КоличествоОстаток
ИЗ
	Справочник.Номенклатура КАК СправочникНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(
		{(&ДатаОстаткиЦены)},
		{(Счет В (&СписокСчетов))},
		{(&ВидыСубконто)},
		{(Организация В (&СписокОрганизаций))}
	) КАК ОстаткиНаСкладе
	ПО СправочникНоменклатура.Ссылка = ОстаткиНаСкладе.Субконто1
ГДЕ
	НЕ СправочникНоменклатура.ЭтоГруппа

Благодаря конструкциям {(Счет В (&СписокСчетов))} и {(Организация В (&СписокОрганизаций))}, если параметры не переданы при открытии формы, запрос не упадет с ошибкой — платформа просто рассчитает остатки без отбора по этим полям.

Способ 3. Динамическое обновление параметров на клиенте

Если в процессе работы с формой пользователь меняет организацию, дату или состав счетов, параметры динамического списка необходимо обновлять программно. Рассмотрим клиентскую процедуру обновления:


&НаКлиенте
Процедура ОбновитьСписокНоменклатуры()
	
	Список.Параметры.УстановитьЗначениеПараметра("ДатаОстаткиЦены", Объект.Дата);
	Список.Параметры.УстановитьЗначениеПараметра("СписокОрганизаций", Объект.Организация);
	
	// При необходимости отключаем параметр
	Если НЕ ЗначениеЗаполнено(Объект.Организация) Тогда
		ЭлементПараметра = Список.Параметры.Элементы.Найти("СписокОрганизаций");
		Если ЭлементПараметра <> Неопределено Тогда
			ЭлементПараметра.Использование = Ложь;
		КонецЕсли;
	КонецЕсли;
	
	// Принудительно обновляем данные в таблице формы
	Элементы.Список.Обновить();
	
КонецПроцедуры

Важные рекомендации при работе с остатками в динамических списках

  1. Не передавайте пустые коллекции: если в параметр с условием Счет В (&СписокСчетов) передать пустой массив, запрос вернет нулевые остатки либо сформирует некорректный план запроса. Всегда проверяйте количество элементов перед установкой параметра.
  2. Параметр даты: если в &ДатаОстаткиЦены передать пустую дату Дата(1, 1, 1), регистр бухгалтерии начнет расчет остатков на максимальную дату базы, что вызовет сильные зависания при открытии формы. Передавайте Неопределено (в фигурных скобках) или актуальную дату документа.
  3. Производительность: прямое соединение справочника с виртуальной таблицей остатков в динамическом списке создает существенную нагрузку на СУБД при скроллинге. Для высоконагруженных баз рекомендуется выводить остатки через событие ПриПолученииДанныхНаСервере только для отображаемых на экране строк.
← На главную