В процессе разработки на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью использования реквизитов «неопределенного типа». Это мощный инструмент, позволяющий хранить в одном поле данные разных видов: от простых строк и чисел до ссылок на элементы справочников или документов. Однако работа с такими реквизитами имеет свои особенности, особенно когда речь заходит о программном создании объектов (например, в обработках загрузки данных), где контекст формы недоступен.
В этой статье мы подробно разберем, как правильно использовать метод НазначитьТип() вне контекста формы, проанализируем синтаксис и рассмотрим практические примеры кода для различных ситуаций.
Для начала выясним причину возникновения затруднений. При работе в модуле формы мы привыкли обращаться к элементам управления. Если на форме расположен реквизит «Значение» с неопределенным типом, мы пишем:
Форма.Значение.НазначитьТип("Справочник.Цвета", , );
В данном случае Форма.Значение — это обращение к визуальному элементу. Метод отрабатывает корректно, ограничивая выбор пользователя нужным типом. Однако при работе в модуле обработки или глобальном модуле, где мы создаем объект через СоздатьОбъект(), атрибут Форма недоступен. Попытка вызвать метод напрямую у созданного объекта без указания имени реквизита также приведет к ошибке.
Рассмотрим подробнее синтаксис метода, когда он применяется непосредственно к программному объекту (справочнику, документу, операции и т.д.). Основное отличие заключается в том, что первым параметром всегда должно выступать строковое имя реквизита, как оно задано в конфигураторе.
Синтаксис: Объект.НазначитьТип(ИмяРеквизита, ИмяТипа, Длина, Точность)
Разберем параметры:
"Строка", "Число", "Справочник.Товары").Представим ситуацию, когда нам необходимо создать новый элемент справочника «Характеристики», где реквизит «Значение» может принимать разные типы в зависимости от вида характеристики. Проанализируем, как это реализовать в коде обработки:
// Создаем объект справочника
СпрХар = СоздатьОбъект("Справочник.Характеристики");
СпрХар.Новый();
// Устанавливаем наименование или владельца
СпрХар.Наименование = "Цвет кузова";
// Программное назначение типа реквизиту "Значение"
// Предположим, нам нужен тип Справочник.Цвета
СпрХар.НазначитьТип("Значение", "Справочник.Цвета");
// Теперь можно присваивать значение
// (предполагается, что СсылкаНаЦвет — это объект или ссылка на элемент Справочник.Цвета)
СпрХар.Значение = СсылкаНаЦвет;
СпрХар.Записать();
Выясним, как сделать код более универсальным. Если мы копируем данные из одного объекта в другой, нам не обязательно жестко прописывать строку типа. Мы можем использовать встроенную функцию ТипЗначенияСтр(), которая возвращает строковое представление типа переданного ей объекта.
Посмотрим на пример, где тип реквизита определяется динамически на основании другого значения:
Процедура ЗаполнитьРеквизит(ОбъектПриемник, ИсходноеЗначение)
// Динамически получаем тип исходного значения
СтрТип = ТипЗначенияСтр(ИсходноеЗначение);
// Если это справочник или документ, уточняем вид
Если (СтрТип = "Справочник") Или (СтрТип = "Документ") Тогда
СтрТип = СтрТип + "." + ИсходноеЗначение.Вид();
КонецЕсли;
// Назначаем тип и записываем значение
ОбъектПриемник.НазначитьТип("Значение", СтрТип);
ОбъектПриемник.Значение = ИсходноеЗначение;
КонецПроцедуры
При работе с числами и строками важно не забывать про параметры длины и точности. Если их пропустить, система применит значения по умолчанию, что может привести к обрезанию данных при записи в базу данных. Разберем пример для числового значения:
// Назначаем числовой тип: длина 15 знаков, 3 знака после запятой
Спр.НазначитьТип("Значение", "Число", 15, 3);
Спр.Значение = 123.456;
Для строковых данных ситуация аналогичная:
// Назначаем строковый тип неограниченной (или заданной) длины
Спр.НазначитьТип("Значение", "Строка", 100);
Спр.Значение = "Пример текста характеристики";
Проанализируем несколько критических моментов, которые помогут избежать ошибок при разработке:
НазначитьТип() должен вызываться после метода Новый() или НайтиЭлемент() (для существующих элементов), но обязательно до вызова метода Записать().Справочник, Документ, Операция, Константа, Регистр.НазначитьТип() помогает системе корректно подготовить структуру данных для конкретной записи.НазначитьТип(). Однако явное назначение считается хорошим тоном, так как оно гарантирует корректное поведение системы при последующем чтении или обращении к методам этого значения (например, Выбрать()).Таким образом, мы выяснили, что программное управление типами в 1С 7.7 полностью реализуемо без открытия форм. Главное — помнить о разнице в параметрах метода при обращении к экранному объекту и программному контексту базы данных.