Как автоматически создавать элементы справочника при записи и правильно получать данные из табличной части в 1С?

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

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

Автоматическое создание объекта справочника программным способом

Рассмотрим ситуацию, когда при записи элемента одного справочника нам необходимо создать элемент в другом справочнике и заполнить его данными. Проанализируем два основных способа реализации этой задачи, которые обсуждались в рамках учебного примера.

Способ 1: Прямое заполнение реквизитов

Этот метод заключается в ручном создании объекта и последовательном присвоении значений его реквизитам. Разберем пример кода, который можно разместить в обработчике события записи:


НовыйОбъект = Справочники.Справочник1.СоздатьЭлемент();
НовыйОбъект.Наименование = "Автоматически созданный элемент";
НовыйОбъект.Комментарий = "Создано из другой формы";
// Здесь можно заполнить другие реквизиты
НовыйОбъект.Записать();

Способ 2: Использование метода Заполнить()

Более профессиональным подходом считается использование механизма ОбработкаЗаполнения. Это позволяет инкапсулировать логику внутри самого создаваемого объекта. Выясним, как это работает: мы передаем в объект структуру данных, а объект сам решает, как их распределить.


ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("Наименование", "Тестовое имя");
ПараметрыЗаполнения.Вставить("Цена", 100);

НовыйОбъект = Справочники.Справочник1.СоздатьЭлемент();
НовыйОбъект.Заполнить(ПараметрыЗаполнения);
НовыйОбъект.Записать();

Где лучше разместить код создания: в форме или в модуле объекта?

Выбор места для размещения кода крайне важен для стабильности программы. Проанализируем два варианта:

  1. В модуле формы (событие ПриЗаписи на сервере): Это удобно, если логика создания зависит от действий пользователя в интерфейсе. Однако, если объект будет записан программно (не через форму), этот код не сработает.
  2. В модуле объекта (событие ПередЗаписью или ПриЗаписи): Это более надежный вариант. Код сработает всегда, как бы ни записывался объект. Важный нюанс: Чтобы не создавать дубли при каждом редактировании, используйте проверку ЭтоНовый().

Рассмотрим пример в модуле объекта:


Процедура ПередЗаписью(Отказ)
    Если ЭтоНовый() Тогда
        // Код создания связанного объекта
    КонецЕсли;
КонецПроцедуры

Разбор ошибки «Поле объекта не обнаружено (ТекущиеДанные)»

Одной из самых частых ошибок при работе с управляемыми формами является неправильное обращение к строкам табличной части. Посмотрим на причину возникновения ошибки в коде Элементы.ТекущиеДанные.Подарок.

Проблема заключается в том, что ТекущиеДанные — это свойство не всей коллекции Элементы, а конкретного элемента формы, являющегося Таблицей. Выясним правильный алгоритм обращения:

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

Правильный вариант кода будет выглядеть так:

ДанныеСтроки = Элементы.ИмяВашейТаблицы.ТекущиеДанные;

Важно: Всегда проверяйте результат на пустое значение, так как если в таблице не выбрана ни одна строка, программа выдаст ошибку:


ДанныеСтроки = Элементы.Товары.ТекущиеДанные;
Если ДанныеСтроки <> Неопределено Тогда
    ВыбранныйПодарок = ДанныеСтроки.Подарок;
КонецЕсли;

Оптимизация получения данных через серверные вызовы

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

Разберем по шагам реализацию в модуле формы:

  1. Создаем клиентскую процедуру ПриИзменении для элемента табличной части.
  2. Вызываем серверную функцию для получения цены из базы данных.
  3. Используем директиву &НаСервереБезКонтекста для ускорения работы, так как нам не нужно передавать всю форму на сервер.

&НаКлиенте
Процедура ТоварыПодарокПриИзменении(Элемент)
    СтрокаТаблицы = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТаблицы <> Неопределено Тогда
        // Вызываем сервер для получения цены
        СтрокаТаблицы.Цена = ПолучитьЦенуПодаркаНаСервере(СтрокаТаблицы.Подарок);
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьЦенуПодаркаНаСервере(СсылкаНаПодарок)
    // Возвращаем цену прямо из реквизита справочника
    Возврат СсылкаНаПодарок.ЦенаПокупки;
КонецФункции

Полезные советы по работе с Синтаксис-помощником

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

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

← На главную