Как заполнить реквизит неопределенного вида в форме списка справочника 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Проанализируем причины этой проблемы, рассмотрим внутренние ограничения платформы 1С 7.7 и разберем работающие способы реализации интерактивного выбора таких значений.

Выясним причину проблемы и ограничения платформы

Для понимания сути проблемы разберем по шагам, как платформа 1С 7.7 формирует таблицу формы списка:

  1. Инициализация редактора ячейки: когда колонка таблицы привязана к реквизиту типа «Неопределенный», платформа на этапе построения сетки не знает, какой элемент управления сопоставить ячейке (числовое поле, строку, маску даты или кнопку выбора ссылки). Пока значение пустое, режим редактирования ячейки штатно не активируется.
  2. Особенность метода ТекущийЭлемент(): частая ошибка разработчиков — попытка вызвать метод ТекущийЭлемент().НазначитьТип(...). В 1С 7.7 метод ТекущийЭлемент() возвращает ссылку на элемент базы данных, доступную исключительно для чтения. У ссылки отсутствуют методы модификации типа или записи.
  3. Ограничение метода НазначитьТип(): этот метод предназначен для объектов, созданных через СоздатьОбъект(), либо для элементов диалога в форме элемента справочника. При редактировании строки непосредственно в списке динамическая типизация ячейки «на лету» платформой не поддерживается в полном объеме.

Решение 1. Назначение типа при начале редактирования строки

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

Разберем по шагам реализацию этого механизма в модуле формы списка:


Процедура ПриНачалеРедактированияСтроки()
    // Проверяем, пустое ли значение реквизита
    Если ПустоеЗначение(ОбъектДляОбмена) = 1 Тогда
        Если ТипЗначенияСтр(ОбъектДляОбмена) = "" Тогда
            // Назначаем базовый тип, чтобы активировать кнопку выбора
            НазначитьТип("ОбъектДляОбмена", "Справочник");
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

После назначения типа платформа видит реквизит как ссылочный и отображает кнопку с тремя точками. Теперь перехватим стандартное событие нажатия кнопки выбора:


Процедура ПриНачалеВыбораЗначения(Идентификатор, ФСО)
    Перем Выбор;
    Если Идентификатор = "ОбъектДляОбмена" Тогда
        Меню = СоздатьОбъект("СписокЗначений");
        Меню.ДобавитьЗначение("Справочник");
        Меню.ДобавитьЗначение("Документ");
        
        Если Меню.ВыбратьЗначение(Выбор, "Выберите тип объекта") = 0 Тогда
            ФСО = 0; // Отменяем стандартную обработку выбора
            Возврат;
        КонецЕсли;
        
        // Уточняем тип реквизита перед дальнейшим открытием
        НазначитьТип("ОбъектДляОбмена", Выбор);
    КонецЕсли;
КонецПроцедуры

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

Решение 2. Перехват события через процедуру ПриВыбореСтроки()

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

Для этого используем предопределенную процедуру ПриВыбореСтроки(), метод Форма.ТекущаяКолонка() и запись через объект Справочник:


Процедура ПриВыбореСтроки()
    врКолонка = Форма.ТекущаяКолонка();
    
    // Проверяем, что пользователь кликнул именно по колонке нетипизированного объекта
    Если врКолонка = "ОбъектДляОбмена" Тогда
        СтатусВозврата(0); // Отменяем стандартное действие открытия элемента
        
        // Организуем поэтапный выбор
        СЗ_Типы = СоздатьОбъект("СписокЗначений");
        СЗ_Типы.ДобавитьЗначение("Справочник");
        СЗ_Типы.ДобавитьЗначение("Документ");
        
        ВыбранныйТип = "";
        Если СЗ_Типы.ВыбратьЗначение(ВыбранныйТип, "Выберите тип объекта") <> 1 Тогда
            Возврат;
        КонецЕсли;
        
        // Здесь открываем подбор конкретного вида и объекта
        // Например, для выбора конкретного справочника:
        СпрВыбор = СоздатьОбъект("Справочник.Номенклатура");
        Если СпрВыбор.Выбрать("Выберите позицию", "") = 1 Тогда
            // Записываем результат напрямую в базу данных через объект
            СпрОбъект = СоздатьОбъект("Справочник." + Вид());
            Если СпрОбъект.НайтиЭлемент(ТекущийЭлемент()) = 1 Тогда
                СпрОбъект.ОбъектДляОбмена = СпрВыбор.ТекущийЭлемент();
                СпрОбъект.Записать();
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Решение 3. Редактирование по отдельной экранной кнопке

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

В таком случае на панель формы списка выносится отдельная экранная кнопка (например, «Указать объект»). В формулу кнопки назначается процедура:

  1. Проверяем, что в списке позиционирована корректная строка: метод ПустоеЗначение(ТекущийЭлемент()) должен возвращать 0.
  2. Запрашиваем тип и вид метаданных через СписокЗначений.
  3. Открываем форму выбора объекта через функцию ОткрытьФорму() или подбор.
  4. Присваиваем выбранную ссылку реквизиту объекта через экземпляр СоздатьОбъект("Справочник..." ) и вызываем метод Записать().

Решение 4. Переключение режима на редактирование в диалоге

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

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

← На главную