Как выбрать значение из ресурса регистра сведений в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Часто в процессе разработки возникает задача: необходимо сделать так, чтобы при нажатии на кнопку открывалась форма выбора определенного значения, которое хранится не в справочнике, а в ресурсе регистра сведений (РС). Например, у нас есть независимый непериодический регистр, где хранится строковый ресурс Тема, и нам нужно выбрать это значение для дальнейшего использования.

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

Особенности архитектуры регистра сведений

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

Выбрать стандартными средствами можно только конкретную ссылку. Запись регистра сведений представляет собой набор измерений, ресурсов и реквизитов. Наш ресурс Тема имеет примитивный тип данных (строка). Стандартные механизмы выбора 1С «из коробки» рассчитаны на ссылочные типы. Именно поэтому архитектурно самым правильным решением для хранения перечня тем, из которых пользователь должен делать выбор, является Справочник. Если же использование справочника жестко запрещено условиями задачи, нам придется программно обходить это ограничение.

Проанализируем два основных подхода к реализации выбора примитивного значения из регистра сведений.

Решение 1: Использование списка значений (Рекомендуемый подход)

Это самый правильный и частый способ в 1С для выбора примитивных значений (строк, чисел), хранящихся в регистрах. Нам вообще не нужно открывать форму списка самого регистра. Посмотрим на алгоритм действий:

  1. При нажатии на кнопку мы программно формируем запрос к первому регистру сведений. В запросе используем ключевое слово РАЗЛИЧНЫЕ, чтобы получить уникальные варианты ресурса, исключив возможные дубликаты.
  2. Обходим результат запроса и добавляем полученные строки в новый объект СписокЗначений.
  3. Вызываем метод списка значений ВыбратьЭлемент(). Пользователю откроется аккуратное диалоговое окно со списком всех доступных тем.
  4. Если пользователь выбрал значение, мы получаем выбранную строку и записываем её туда, куда нам нужно.

Этот способ избавляет от необходимости писать сложный код для форм и перехватывать оповещения.

Решение 2: Переопределение обработки выбора в форме списка регистра

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

Разберем этот вариант по шагам:

  1. В форме списка регистра сведений создаем обработчик события таблицы списка Выбор (срабатывает при двойном клике или нажатии Enter по строке).
  2. В обработчике обязательно устанавливаем СтандартнаяОбработка = Ложь, чтобы система не пыталась открыть саму запись регистра на редактирование.
  3. Получаем нужное значение из текущей выбранной строки и передаем его в систему через метод ОповеститьОВыборе.

Пример кода в модуле формы списка регистра:


Процедура РегистрСведенийСписокВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка) 
    Стр = Новый Структура; 
    Стр.Вставить("Тема", Элемент.ТекущиеДанные.Тема); 
    ОповеститьОВыборе(Стр); 
    СтандартнаяОбработка = Ложь; 
КонецПроцедуры

Затем в основной форме (откуда мы вызывали список) мы должны обработать событие ОбработкаВыбора. Именно туда придет наша структура со строкой, и там мы сможем её использовать.

Разбор ошибки «Значение не является значением объектного типа»

В процессе экспериментов с кодом разработчики часто сталкиваются с ошибкой:

«Значение не является значением объектного типа (Добавить)»

Посмотрим на пример кода, который вызывает такую ошибку:


Тема = Неопределено;
// ... код открытия формы ...
Для Каждого Эл Из ВыбранныйЭлемент.Тема Цикл 
    Стр = Тема.Добавить();
    Стр.Тема = Эл.Тема; 
КонецЦикла;

Проанализируем ситуацию: в коде переменная Тема инициализирована как Неопределено (а иногда инициализируют как пустую строку ""). Попытка вызвать метод .Добавить() у таких типов данных закономерно приводит к аварийному завершению. Метод Добавить() существует у коллекций значений, таких как ТаблицаЗначений, Массив или СписокЗначений. К примитивному типу или неопределенному значению ничего добавить нельзя.

Чтобы избежать этой ошибки, всегда следите за типизацией переменных и используйте встроенный отладчик (точки останова), чтобы проверять, какой именно тип имеет переменная перед вызовом её методов.

← На главную