Часто при работе с управляемыми формами в 1С возникает ситуация, когда мы пытаемся получить ссылку на документ из списка выделенных строк, а вместо ожидаемого объекта типа ДокументСсылка получаем что-то другое, например, идентификатор строки или структуру. Это мешает дальнейшей работе, например, созданию нового документа на основании выделенного. Давайте вместе разберемся, почему так происходит и как правильно решить эту задачу.
Проанализируем ситуацию. В управляемых формах, особенно при работе с элементом ДинамическийСписок, свойство ВыделенныеСтроки содержит массив не самих ссылок на объекты, а их идентификаторов. Это ключевой момент, который часто упускают из виду. Поэтому попытка напрямую присвоить элемент этого массива переменной, ожидающей ссылку, приводит к ошибке.
Конструкция вида:
// Неправильный подход!
СсылкаНаЗаявку = ВыделенныеСтроки[0];
// В переменной "СсылкаНаЗаявку" окажется не ссылка, а идентификатор
Это неверно, потому что платформа не знает, что этот идентификатор нужно преобразовать в ссылку на документ. Чтобы убедиться в этом, всегда полезно использовать отладчик и посмотреть, какой тип данных на самом деле содержится в элементе массива ВыделенныеСтроки[0].
Чтобы получить полные данные строки, включая нужную нам ссылку, необходимо использовать специальный метод элемента формы. Разберем по шагам, как это сделать.
Получаем массив идентификаторов выделенных строк. Это наш первый шаг, который мы уже знаем.
ВыделенныеСтроки = Элементы.Список.ВыделенныеСтроки;
Проверяем, что хотя бы одна строка выделена. Это хорошая практика, чтобы избежать ошибок.
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат; // Или выводим сообщение пользователю
КонецЕсли;
Используем метод ДанныеСтроки(). Этот метод принадлежит элементу формы (в нашем примере `Элементы.Список`) и принимает в качестве параметра идентификатор строки, который мы получили на первом шаге. В ответ он возвращает структуру с данными этой строки, где поля соответствуют колонкам списка.
Посмотрим на пример. Предположим, что в нашем динамическом списке основная колонка, содержащая ссылку на документ, называется "Ссылка".
// Получаем массив идентификаторов
ВыделенныеСтроки = Элементы.Список.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() > 0 Тогда
// Получаем идентификатор первой выделенной строки
ИдентификаторСтроки = ВыделенныеСтроки[0];
// С помощью метода ДанныеСтроки() получаем структуру данных
ДанныеВыделеннойСтроки = Элементы.Список.ДанныеСтроки(ИдентификаторСтроки);
// Теперь из структуры мы можем получить ссылку по имени колонки
СсылкаНаДокумент = ДанныеВыделеннойСтроки.Ссылка;
// Дальше можно работать с переменной "СсылкаНаДокумент"
КонецЕсли;
Если вам нужно получить данные из текущей активной строки (не обязательно выделенной), можно использовать свойство ТекущиеДанные элемента формы. Это еще проще:
// Этот способ подходит, если нужна только одна, текущая строка
ДанныеТекущейСтроки = Элементы.Список.ТекущиеДанные;
Если ДанныеТекущейСтроки <> Неопределено Тогда
СсылкаНаДокумент = ДанныеТекущейСтроки.Ссылка;
КонецЕсли;
Если ваша конечная цель — создать один документ на основе другого, то самым правильным и идеологически верным способом в 1С является использование механизма ввода на основании. Этот подход более универсален и не зависит от того, как именно вы получили ссылку на документ-основание.
Рассмотрим подробнее, как это реализовать программно в управляемой форме.
Получаем ссылку на документ-основание. Используем правильный метод, который мы разобрали в первом решении.
Формируем структуру параметров для открытия формы. Чтобы форма нового документа "поняла", что ее создают на основании чего-то, нужно передать ей ссылку на документ-основание в параметре с зарезервированным именем Основание.
Открываем форму нового документа. Для этого в тонком и веб-клиенте используется асинхронный метод ОткрытьФорму(). Важно помнить, что метод ПолучитьФорму() является синхронным и работает только в толстом клиенте или на сервере, поэтому его использование в клиентских процедурах управляемых форм часто приводит к ошибкам.
Посмотрим на итоговый пример кода для кнопки "Создать на основании":
&НаКлиенте
Процедура СоздатьНаОсновании(Команда)
// Шаг 1: Правильно получаем ссылку на документ-основание
ДанныеТекущейСтроки = Элементы.Список.ТекущиеДанные;
Если ДанныеТекущейСтроки = Неопределено Тогда
ПоказатьПредупреждение(,"Не выбрана строка для ввода на основании!");
Возврат;
КонецЕсли;
СсылкаНаОснование = ДанныеТекущейСтроки.Ссылка;
// Шаг 2: Формируем параметры для открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Основание", СсылкаНаОснование);
// Шаг 3: Открываем форму нового документа, передавая параметры
// Предположим, мы создаем документ "РеализацияТоваров" на основании "ЗаявкиПокупателя"
ОткрытьФорму("Документ.РеализацияТоваров.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
При таком вызове платформа автоматически запустит механизм заполнения нового документа на основании данных из документа, переданного в параметре Основание. Для этого, конечно, в модуле менеджера документа `РеализацияТоваров` должна быть настроена процедура ОбработкаЗаполнения.