При начале разработки в среде «1С:Предприятие» многие сталкиваются с путаницей в доступе к данным. Почему в форме документа можно написать Объект.Наименование, и это работает, а в форме списка аналогичная конструкция Список.Наименование вызывает ошибку? В чем разница между Элементы, ЭтаФорма и ТекущаяСтрока? Разберем эти вопросы подробно, разложим по полочкам теорию и рассмотрим практические примеры кода для решения этих задач.
Чтобы понять, как обратиться к данным, нужно сначала осознать, где мы находимся. В 1С существует две основные парадигмы работы с данными на клиенте:
Объект. Это "мутабельный" (изменяемый) контейнер данных.Список (обычно типа ДинамическийСписок). Это не данные как таковые, это — "окошко" в базу данных, результат запроса. Изучите также методы доработки динамических списков.Рассмотрим ситуацию, описанную в вопросе: почему нельзя обратиться через точку к списку?
Когда вы пишете Объект.Наименование в модуле формы документа, платформа обращается к реквизиту формы с именем "Объект", у которого есть свойство "Наименование". Это конкретная запись в памяти.
Когда вы пишете Список.Наименование в модуле формы списка, вы пытаетесь обратиться к реквизиту формы "Список". Но у типа ДинамическийСписок нет свойства "Наименование". Динамический список — это инструмент для отображения строк, это инструкция "как выбрать данные из БД" (проверить которую поможет управляемая консоль запросов), а не сама строка с данными. Как верно замечено в обсуждении, пытаться прочитать данные из самого слова "Список" — это как пытаться прочитать содержание главы из строки "Оглавление".
В форме списка мы не можем просто обратиться к переменной. Нам нужно узнать, на какой строке стоит курсор пользователя. Для этого мы должны использовать коллекцию Элементы.
Элементы — это коллекция всех визуальных компонентов формы (кнопок, таблиц, полей). Сама таблица, отображающая список, тоже является элементом формы (обычно с именем Список, но имя может быть любым, например ТаблицаТоваров).
Чтобы получить данные выделенной строки, используем свойство ТекущиеДанные элемента формы. Рассмотрим пример чтения данных:
&НаКлиенте
Процедура ПрочитатьДанныеИзСписка()
// Получаем текущие данные выделенной строки
// Элементы.Список - это обращение к таблице на форме
ТекДанные = Элементы.Список.ТекущиеДанные;
Если ТекДанные <> Неопределено Тогда
// Теперь мы можем читать колонки, которые есть в списке
Сообщить("Выбрана номенклатура: " + ТекДанные.Наименование);
Сообщить("Код: " + ТекДанные.Код);
КонецЕсли;
КонецПроцедуры
Важно понимать: через ТекущиеДанные мы получаем структуру, содержащую значения колонок, отображаемых в списке. Это данные только для чтения (в контексте списка). Если вы напишете ТекДанные.Наименование = "Новое имя", это визуально может сработать до обновления списка, но в базе данных ничего не изменится, так как Динамический Список не предназначен для прямой записи.
Так как список только "отображает" данные, чтобы внести изменения в конкретную строку (в объект базы данных), нам нужно выполнить следующую последовательность действий:
ПолучитьОбъект()).Рассмотрим пример реализации команды, которая меняет наименование у выделенного в списке элемента:
&НаКлиенте
Процедура ИзменитьВыделенныйЭлемент(Команда)
ТекДанные = Элементы.Список.ТекущиеДанные;
Если ТекДанные = Неопределено Тогда
Возврат; // Ничего не выделено
КонецЕсли;
// Вызываем серверную процедуру, передавая ссылку
// В динамическом списке обычно есть поле "Ссылка"
ИзменитьНаименованиеНаСервере(ТекДанные.Ссылка, "Новое название");
// Обновляем список, чтобы увидеть изменения
Элементы.Список.Обновить();
КонецПроцедуры
&НаСервере
Процедура ИзменитьНаименованиеНаСервере(СсылкаНаОбъект, НовоеИмя)
// Получаем объект для записи
ОбъектБД = СсылкаНаОбъект.ПолучитьОбъект();
// Блокируем объект от изменений другими пользователями
ОбъектБД.Заблокировать();
// Меняем данные
ОбъектБД.Наименование = НовоеИмя;
// Записываем в базу
ОбъектБД.Записать();
КонецПроцедуры
Автор вопроса также интересовался разницей между ключевыми понятиями. Давайте систематизируем их.
1. ЭтаФорма (ThisForm)
Это контекст текущего программного модуля формы. Через ЭтаФорма мы имеем доступ ко всем свойствам, методам, реквизитам и элементам данной формы. В управляемых формах (8.3) писать ЭтаФорма. часто избыточно. Например, вместо ЭтаФорма.Элементы можно писать просто Элементы. Однако использование ЭтаФорма полезно, когда нужно передать саму форму как параметр в другую процедуру.
2. Элементы (Items)
Это коллекция всех "визуальных кирпичиков" на экране. Кнопки, поля ввода, декорации, таблицы. Мы обращаемся к ним, когда хотим изменить внешний вид или поведение интерфейса. Например:
Элементы.ПолеКомментарий.Доступность = Ложь; — запрещаем редактирование поля.Элементы.Группа1.Видимость = Истина; — показываем группу.Элементы.Список.ТекущиеДанные — обращаемся к таблице, чтобы узнать, что выбрал пользователь.Важно не путать Элементы (интерфейс) и Реквизиты (данные). У Элемента нет значения данных, у него есть "ПутьКДанным".
3. ТекущаяСтрока (CurrentRow) vs ТекущиеДанные (CurrentData)
Здесь часто возникает путаница.
Элементы.Список.ТекущаяСтрока — возвращает идентификатор строки. В Динамическом списке это обычно Ссылка (или ключ записи регистра). В ТаблицеЗначений на форме это числовой идентификатор. Само по себе это свойство не дает доступа к колонкам (Наименованию, Коду и т.д.), оно просто указывает "кто" выбран.Элементы.Список.ТекущиеДанные — возвращает структуру с данными строки. Именно через это свойство мы читаем значения колонок (Наименование, Сумма, Дата), которые видим глазами в строке.Проанализируем итоговый алгоритм действий для разработчика, который хочет работать с данными в форме:
Объект (Объект.Клиент, Объект.Сумма) для чтения и записи.Элементы.ИмяВашегоСписка.ТекущиеДанные.ИмяКолонки.ТекущиеДанные.Ссылка, перейдите на сервер, получите объект методом ПолучитьОбъект() и запишите его.Понимание этой "таблично-объектной" модели, о которой упоминалось в обсуждении, является ключом к успешной разработке на платформе 1С.