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