Как исправить ошибку Недопустимое значение параметра при получении расшифровки в СКД

Программист 1С v8.3 (Управляемые формы)
← На главную

При разработке отчетов на базе Системы компоновки данных (СКД) одной из самых частых задач является обработка двойного щелчка мыши по ячейке. Мы хотим не просто открыть стандартную расшифровку, а программно получить значение конкретного поля или связанные с ним данные (например, ссылку на документ или справочник). Однако на этом этапе программисты часто сталкиваются с ошибкой: «Ошибка при вызове метода контекста (Получить): Недопустимое значение параметра (параметр номер '1')». Проанализируем, почему это происходит, и разберем правильный алгоритм работы с расшифровкой.

Выясняем причину ошибки

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

Поля = Данные.Элементы.Получить(Расшифровка).ПолучитьПоля();

Причина ошибки кроется в том, как именно был инициализирован объект Данные. В коде автора мы видим следующее:


&наСервере
Функция ПолучитьРасшифровкуНаСервере(Расшифровка)
  ДанныеРасшифровкиСКД = Новый ДанныеРасшифровкиКомпоновкиДанных;
  ДанныеРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровкиСКД, УникальныйИдентификатор);
  Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
  // ... попытка получить элемент
КонецФункции

Проанализируем этот фрагмент. Ключевая проблема здесь — использование конструктора Новый ДанныеРасшифровкиКомпоновкиДанных. Создавая объект таким образом, вы получаете абсолютно пустой контейнер. В нем нет ни элементов, ни настроек, ни связей с теми данными, которые пользователь видит на экране в табличном документе. Когда вы передаете в метод Получить() идентификатор (например, число 17), система ищет элемент с этим индексом в пустой коллекции и, закономерно, выдает ошибку «Недопустимое значение параметра», так как элемента с таким номером не существует.

Для корректной работы нам нужно не создавать новый объект, а обратиться к тому, который был сформирован системой в момент генерации отчета.

Разберем по шагам правильный алгоритм

Чтобы программно обработать расшифровку в управляемых формах, необходимо использовать адрес во временном хранилище, где СКД сохраняет структуру отчета. Рассмотрим, как это реализовано в платформе 1С 8.3.

Шаг 1. Получение адреса данных расшифровки.

В управляемой форме отчета существует стандартный реквизит (обычно он так и называется — ДанныеРасшифровки), имеющий тип Строка. В этом реквизите хранится уникальный адрес. Нам нужно передать этот адрес в нашу серверную функцию вместе с идентификатором самой расшифровки.

Шаг 2. Правильный вызов на клиенте.

Модифицируем процедуру обработки расшифровки, чтобы она передавала адрес данных:


&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь; // Отключаем стандартное окно расшифровки
    
    // Передаем идентификатор и АДРЕС данных расшифровки
    РезультатОбработки = ПолучитьРасшифровкуНаСервере(Расшифровка, ДанныеРасшифровки);
    
    // Выводим результат пользователю
    Сообщить("Вы нажали на поле: " + РезультатОбработки.НаименованиеПоля);
    Сообщить("Значение: " + Строка(РезультатОбработки.ЗначениеПоля));
КонецПроцедуры

Шаг 3. Реализация серверной логики.

Теперь перепишем серверную функцию так, чтобы она извлекала реальные данные из временного хранилища:


&НаСервере
Функция ПолучитьРасшифровкуНаСервере(Идентификатор, АдресХранилища)
    // Извлекаем существующий объект данных расшифровки
    Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
    
    // Получаем элемент расшифровки по идентификатору
    Элемент = Данные.Элементы.Получить(Идентификатор);
    
    Если ТипЗнч(Элемент) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
        // Если кликнули по значению (полю)
        Поля = Элемент.ПолучитьПоля();
        Если Поля.Количество() > 0 Тогда
            СтруктураРезультат = Новый Структура;
            СтруктураРезультат.Вставить("НаименованиеПоля", Поля[0].Поле);
            СтруктураРезультат.Вставить("ЗначениеПоля", Поля[0].Значение);
            Возврат СтруктураРезультат;
        КонецЕсли;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Проанализируем типы элементов расшифровки

Важно понимать, что переменная Расшифровка (идентификатор) может указывать на разные типы объектов в коллекции Элементы. Если мы не будем проверять тип, код может вызвать исключение в других ситуациях (например, при клике на группировку).

  1. ЭлементРасшифровкиКомпоновкиДанныхПоля: Этот объект создается, когда пользователь нажимает на конкретное значение в детальных записях или ресурсах. Только у него есть метод ПолучитьПоля().
  2. ЭлементРасшифровкиКомпоновкиДанныхГруппировка: Этот объект соответствует строкам-группировкам. Чтобы получить данные из него, нужно использовать метод ПолучитьИерархию() или анализировать родителей элемента.

Для надежности кода всегда проверяйте тип полученного элемента с помощью функции ТипЗнч(), как показано в примере выше.

Как получить значение соседнего поля (например, Ссылку)?

Часто в отчете выводится артикул или код, а нам при клике нужно получить Ссылка на объект, даже если эта ссылка не выведена в отдельной колонке. Рассмотрим, как это сделать правильно, не прибегая к перебору индексов в цикле.

Если поле добавлено в «Поля расшифровки» в настройках СКД или просто присутствует в наборе данных текущей группировки, оно будет доступно в коллекции полей элемента расшифровки. Проверим все доступные поля в текущей ячейке:


Для Каждого ТекущееПоле Из Поля Цикл
    Если ТекущееПоле.Поле = "Ссылка" Тогда
        НужнаяСсылка = ТекущееПоле.Значение;
        Прервать;
    КонецЕсли;
КонецЦикла;

Если же поле Ссылка находится на уровень выше (в родительской группировке), необходимо двигаться вверх по иерархии расшифровки. Для этого у элемента расшифровки есть метод ПолучитьРодителей(). Это гораздо эффективнее и правильнее, чем пытаться угадывать идентификатор соседа путем вычитания единицы из индекса (индексТекущегоЭлемента - 1), так как индексы в СКД не гарантируют строгую последовательность строк таблицы.

Резюме

Чтобы избежать ошибки «Недопустимое значение параметра» при программной работе с СКД, запомните три правила:

  1. Никогда не создавайте Новый ДанныеРасшифровкиКомпоновкиДанных в обработчике. Используйте адрес из реквизита формы.
  2. Всегда проверяйте тип элемента, полученного из коллекции Данные.Элементы.
  3. Передавайте данные между клиентом и сервером через временное хранилище, используя УникальныйИдентификатор формы для управления временем жизни данных.

Соблюдение этой структуры позволит вам создавать интерактивные и отказоустойчивые отчеты, корректно реагирующие на действия пользователя.

← На главную