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

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

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

Программное создание и привязка предопределенных элементов

Важно понимать, что мы не можем создать предопределенный элемент "с нуля" программно таким образом, чтобы он появился в конфигураторе. Предопределенное имя элемента должно быть заранее задано разработчиком в метаданных конфигурации. Наша задача в программном коде — это "привязать" существующий элемент данных в информационной базе к предопределенному элементу, заданному в конфигураторе, или, при необходимости, создать новый элемент данных и присвоить ему это предопределенное имя. Для этих целей используется стандартный реквизит объекта ИмяПредопределенныхДанных.

  1. Создаем или находим элемент: Если предопределенного элемента нет в базе данных, мы сначала создаем обычный элемент справочника. Если элемент с нужным наименованием уже существует, мы можем использовать его.
  2. Присваиваем имя предопределенных данных: Необходимо присвоить реквизиту ИмяПредопределенныхДанных точное имя предопределенного элемента, которое было задано в конфигураторе. Критически важно: присваиваемое имя должно уже существовать в списке предопределенных элементов, определенных в конфигураторе. Попытка присвоить несуществующее имя приведет к ошибке "Предопределенный элемент не существует".
  3. Записываем объект: После присвоения имени мы обязательно должны записать объект, чтобы изменения вступили в силу.

Рассмотрим пример программного создания и привязки предопределенного элемента для справочника "ВидыНоменклатуры", если в конфигураторе для него определено предопределенное имя "Материалы":


// В конфигураторе для справочника "ВидыНоменклатуры"
// задан предопределенный элемент с ИменемПредопределенныхДанных = "Материалы"

&НаСервере
Функция ПолучитьИлиСоздатьПредопределенныйВидНоменклатуры()

    Перем СсылкаНаВидНоменклатуры;
    ИмяПредопределенного = "Материалы";
    ВидНоменклатурыНайден = Ложь;

    // 1. Попытаемся получить ссылку на предопределенный элемент через его имя
    // Этот способ сработает, если элемент уже существует в ИБ и привязан к предопределенному имени
    Попытка
        СсылкаНаВидНоменклатуры = Справочники.ВидыНоменклатуры[ИмяПредопределенного];
        Если СсылкаНаВидНоменклатуры <> Неопределено Тогда
            ВидНоменклатурыНайден = Истина;
        КонецЕсли;
    Исключение
        // Если предопределенный элемент еще не создан в ИБ, будет исключение
        // (например, "Предопределенный элемент с именем 'Материалы' не найден.")
    КонецПопытки;

    Если Не ВидНоменклатурыНайден Тогда
        // 2. Попытаемся найти элемент в базе данных по ИмениПредопределенныхДанных
        // Метод НайтиПоИмениПредопределенныхДанных() возвращает ссылку или Неопределено
        СсылкаНаВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоИмениПредопределенныхДанных(ИмяПредопределенного);

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

КонецФункции

// Пример вызова
// СсылкаНаМатериалы = ПолучитьИлиСоздатьПредопределенныйВидНоменклатуры();
// Если СсылкаНаМатериалы <> Неопределено Тогда
//     Сообщить("Работаем с предопределенным видом номенклатуры: " + СсылкаНаМатериалы);
// Иначе
//     Сообщить("Не удалось получить или создать предопределенный вид номенклатуры.");
// КонецЕсли;

Программное редактирование предопределенных элементов

Содержимое предопределенных элементов (например, наименование, код, значения реквизитов) можно программно изменять точно так же, как и у любых обычных элементов справочника. Для этого мы сначала должны получить объект предопределенного элемента, внести необходимые изменения в его реквизиты и затем записать объект.

Рассмотрим пример, как мы можем изменить наименование предопределенного элемента "Материалы":


&НаСервере
Процедура ОтредактироватьПредопределенныйВидНоменклатуры()
    ИмяПредопределенного = "Материалы";

    // 1. Получаем объект предопределенного элемента
    // Мы можем использовать метод НайтиПоИмениПредопределенныхДанных
    // или прямое обращение по имени, если элемент гарантированно существует
    ОбъектВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоИмениПредопределенныхДанных(ИмяПредопределенного).ПолучитьОбъект();

    Если ОбъектВидНоменклатуры <> Неопределено Тогда
        Сообщить("Текущее наименование предопределенного элемента '" + ИмяПредопределенного + "': " + ОбъектВидНоменклатуры.Наименование);

        // 2. Вносим изменения в реквизиты
        ОбъектВидНоменклатуры.Наименование = "Сырье и материалы";
        // Здесь можно изменить и другие реквизиты, например:
        // ОбъектВидНоменклатуры.Код = "000000001";
        // ОбъектВидНоменклатуры.НекийРеквизит = "Новое значение";

        // 3. Записываем объект
        Попытка
            ОбъектВидНоменклатуры.Записать();
            Сообщить("Наименование предопределенного элемента '" + ИмяПредопределенного + "' успешно изменено на: " + ОбъектВидНоменклатуры.Наименование);
        Исключение
            Сообщить("Ошибка при редактировании предопределенного элемента: " + ОписаниеОшибки());
        КонецПопытки;
    Иначе
        Сообщить("Предопределенный элемент '" + ИмяПредопределенного + "' не найден для редактирования.");
    КонецЕсли;
КонецПроцедуры

// Пример вызова
// ОтредактироватьПредопределенныйВидНоменклатуры();

Проверка наличия предопределенного элемента

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

Метод 1: Использование глобальной функции ПредопределенноеЗначение()

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


// Пример использования ПредопределенноеЗначение()
// Допустим, мы проверяем наличие предопределенного элемента Справочника "Валюты" с именем "Рубль"

&НаСервере
Функция ПроверитьНаличиеПредопределеннойВалюты()

    Перем СсылкаНаВалюту;
    ИмяПредопределенного = "Справочник.Валюты.Рубль";

    Попытка
        СсылкаНаВалюту = ПредопределенноеЗначение(ИмяПредопределенного);
        Сообщить("Ссылка на предопределенный элемент '" + ИмяПредопределенного + "': " + СсылкаНаВалюту);
        Возврат Истина;
    Исключение
        Сообщить("Ошибка: Предопределенный элемент '" + ИмяПредопределенного + "' отсутствует в информационной базе или недоступен. " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

КонецФункции

// Пример вызова
// Если ПроверитьНаличиеПредопределеннойВалюты() Тогда
//     Сообщить("Предопределенная валюта 'Рубль' существует.");
// Иначе
//     Сообщить("Предопределенная валюта 'Рубль' отсутствует.");
// КонецЕсли;

Метод 2: Использование Библиотеки стандартных подсистем (БСП)

В конфигурациях, которые используют Библиотеку стандартных подсистем (БСП) версии 2.1.4 и выше, для проверки наличия предопределенного элемента рекомендуется использовать функцию ПредопределенныйЭлемент из общих модулей ОбщегоНазначения или ОбщегоНазначенияКлиент. Эта функция возвращает значение Неопределено, если предопределенный элемент отсутствует в информационной базе, что является более удобным способом проверки, так как не требует использования блока Попытка...Исключение. При этом серверный вызов происходит только при первом обращении, а результат автоматически кешируется для оптимизации производительности.


// Пример использования функции БСП ПредопределенныйЭлемент
// Предполагается, что БСП подключена и доступны общие модули, например "ОбщегоНазначения".

&НаСервере
Функция ПроверитьНаличиеПредопределеннойВалютыБСП()

    Перем СсылкаНаВалютуБСП;
    ИмяПредопределенного = "Справочник.Валюты.Рубль";

    // Функция возвращает ссылку на предопределенный элемент или Неопределено
    СсылкаНаВалютуБСП = ОбщегоНазначения.ПредопределенныйЭлемент(ИмяПредопределенного);

    Если СсылкаНаВалютуБСП <> Неопределено Тогда
        Сообщить("Ссылка на предопределенный элемент '" + ИмяПредопределенного + "' (БСП): " + СсылкаНаВалютуБСП);
        Возврат Истина;
    Иначе
        Сообщить("Предопределенный элемент '" + ИмяПредопределенного + "' отсутствует в информационной базе (БСП).");
        Возврат Ложь;
    КонецЕсли;

КонецФункции

// Пример вызова
// Если ПроверитьНаличиеПредопределеннойВалютыБСП() Тогда
//     Сообщить("Предопределенная валюта 'Рубль' существует (проверено БСП).");
// Иначе
//     Сообщить("Предопределенная валюта 'Рубль' отсутствует (проверено БСП).");
// КонецЕсли;

Метод 3: Получение списка имен предопределенных метаданных

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


// Пример получения списка предопределенных имен для справочника "Валюты"

&НаСервере
Процедура ПоказатьИменаПредопределенныхВалют()

    // Получим список всех предопределенных имен для справочника "Валюты"
    МассивИмен = Метаданные.Справочники.Валюты.ПолучитьИменаПредопределенных();

    Если МассивИмен.Количество() > 0 Тогда
        Сообщить("Список предопределенных имен для справочника 'Валюты', заданных в конфигурации:");
        Для Каждого ИмяПредопределенного Из МассивИмен Цикл
            Сообщить("- " + ИмяПредопределенного);
        КонецЦикла;
    Иначе
        Сообщить("Для справочника 'Валюты' предопределенные элементы в конфигурации не заданы.");
    КонецЕсли;

КонецПроцедуры

// Пример вызова
// ПоказатьИменаПредопределенныхВалют();

Механизм отвязки элемента от предопределенного

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


&НаСервере
Процедура ОтвязатьПредопределенныйВидНоменклатуры()
    ИмяПредопределенного = "Материалы"; // Имя, которое мы хотим отвязать

    ОбъектВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоИмениПредопределенныхДанных(ИмяПредопределенного).ПолучитьОбъект();

    Если ОбъектВидНоменклатуры <> Неопределено Тогда
        Сообщить("Текущее ИмяПредопределенныхДанных элемента: " + ОбъектВидНоменклатуры.ИмяПредопределенныхДанных);

        // Присваиваем пустую строку реквизиту ИмяПредопределенныхДанных
        ОбъектВидНоменклатуры.ИмяПредопределенныхДанных = "";

        Попытка
            ОбъектВидНоменклатуры.Записать();
            Сообщить("Элемент '" + ОбъектВидНоменклатуры.Наименование + "' успешно отвязан от предопределенного имени.");
        Исключение
            Сообщить("Ошибка при отвязке элемента: " + ОписаниеОшибки());
        КонецПопытки;
    Иначе
        Сообщить("Предопределенный элемент '" + ИмяПредопределенного + "' не найден для отвязки.");
    КонецЕсли;
КонецПроцедуры

// Пример вызова
// ОтвязатьПредопределенныйВидНоменклатуры();

Обновление предопределенных данных и роль БСП

Платформа 1С:Предприятие предоставляет механизмы для автоматического обновления предопределенных элементов, особенно при обновлении конфигураций. У объектов конфигурации, которые могут иметь предопределенные элементы, есть свойство ОбновлениеПредопределенныхДанных. Оно определяет, как платформа будет создавать и обновлять предопределенные элементы в информационной базе. Возможные значения:

  1. Авто (значение по умолчанию): Платформа автоматически создает недостающие предопределенные элементы при обновлении конфигурации.
  2. ОбновлятьАвтоматически: Аналогично Авто, но явно указывает на автоматическое обновление.
  3. НеОбновлятьАвтоматически: Платформа не будет автоматически создавать или обновлять предопределенные элементы. В этом случае ответственность за их наличие и актуальность ложится на разработчика/администратора.

В большинстве случаев рекомендуется оставлять значение Авто, так как это обеспечивает надежное автоматическое создание элементов.

Библиотека стандартных подсистем (БСП) предоставляет ряд полезных функций для более глубокой работы с предопределенными данными, особенно в контексте обслуживания информационной базы:

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

Особенности использования предопределенных элементов

При работе с предопределенными элементами важно учитывать несколько ключевых аспектов:

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

← На главную