Как настроить форматную строку даты и исправить ошибку «Недопустимое значение параметра» при программном добавлении колонок формы в 1С

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

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

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

Выясняем причину ошибки: Архитектурное разделение «Имени» и «Заголовка»

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


НазваниеКолонки = Дата(ДобавитьМесяц(МесяцНачалаПланирования, н)); 
НазваниеКолонки = Формат(НазваниеКолонки, "ДФ='ММММ гггг'");
НовыйЭлемент = Элементы.Добавить(НазваниеКолонки, Тип("ПолеФормы"), Элементы.ПланированиеТаб);

Платформа выдает ошибку в первой строке метода Элементы.Добавить(). Причина кроется в том, что переменная НазваниеКолонки после форматирования принимает значение вида «январь 2019». Разработчик попытался передать эту строку с пробелом в качестве первого параметра метода — имени нового элемента формы.

Давайте разберем по шагам требования платформы 1С к свойствам элементов:

  1. Имя элемента формы (первый параметр метода Элементы.Добавить()) — это уникальный системный идентификатор элемента в рамках формы. К нему применяются те же жесткие правила, что и к именованию переменных во встроенном языке 1С. Имя может состоять только из букв (русского или латинского алфавита), цифр и знаков подчеркивания. Оно обязательно должно начинаться с буквы или знака подчеркивания и не может содержать пробелы, спецсимволы, точки или дефисы. Именно поэтому строка «январь 2019» вызывает ошибку недопустимого значения параметра.
  2. Заголовок элемента (свойство Заголовок созданного объекта) — это текстовое описание, которое видит конечный пользователь на экране. Вот здесь как раз допускается использовать абсолютно любые символы: пробелы, знаки препинания, спецсимволы и цифры.

Для исправления ошибки нам необходимо четко разделить формирование технического имени и пользовательского заголовка.

Правильное решение задачи в коде

Рассмотрим правильный вариант реализации алгоритма в цикле. Для формирования уникального и валидного имени элемента мы будем использовать фиксированный префикс и индекс цикла н. Отформатированное представление даты мы запишем в свойство Заголовок созданного элемента:


Для н = 0 по ИнтервалПланирования - 1 Цикл
    
    // Шаг 1. Формируем уникальное имя элемента без пробелов
    ИмяКолонки = "КолонкаПланирования_" + н; 
    
    // Шаг 2. Вычисляем дату для текущей колонки
    ТекДата = ДобавитьМесяц(МесяцНачалаПланирования, н);
    
    // Шаг 3. Получаем красивое строковое представление даты
    ЗаголовокКолонки = Формат(ТекДата, "ДФ='ММММ гггг'");
    
    // Шаг 4. Программно создаем элемент формы (Поле ввода)
    НовыйЭлемент = Элементы.Добавить(ИмяКолонки, Тип("ПолеФормы"), Элементы.ПланированиеТаб);
    НовыйЭлемент.ПутьКДанным = "ПланированиеТаб.Месяц" + н;
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    
    // Шаг 5. Присваиваем заголовок, который увидит пользователь
    НовыйЭлемент.Заголовок = ЗаголовокКолонки; 
    
КонецЦикла;

Нюансы работы форматной строки даты в 1С

Теперь подробно разберем работу с форматной строкой Формат(ТекДата, "ДФ='ММММ гггг'") и особенности, о которых важно помнить разработчику:

Стандарты разработки 1С и локализация форматных строк

Согласно официальным стандартам разработки систем «1С:Предприятие», жесткое прописывание форматных строк непосредственно в коде (так называемый «хардкод») считается ошибкой проектирования, если ваше прикладное решение может использоваться в многоязычной среде или внедряться в разных странах.

В разных государствах приняты различные стандарты отображения дат и разделителей (например, в России принято представление ДД.ММ.ГГГГ, а в США — ММ/ДД/ГГГГ). Для обеспечения корректной локализации форматную строку всегда следует оборачивать в функцию НСтр(). Это позволит переводчикам адаптировать вывод даты под язык интерфейса конкретного пользователя:


// Пример написания кода в соответствии со стандартами 1С
ФорматнаяСтрока = НСтр("ru='ДФ=''ММММ гггг'''; en='DF=''MMMM yyyy'''");
ЗаголовокКолонки = Формат(ТекДата, ФорматнаяСтрока);

Важный контекст: программное добавление реквизитов формы

Обратим внимание на еще один критически важный аспект в коде автора темы. Строка кода:

НовыйЭлемент.ПутьКДанным = "ПланированиеТаб.Месяц" + н;

будет успешно выполнена только в том случае, если в структуре таблицы ПланированиеТаб (которая является реквизитом формы) уже физически существуют колонки с системными именами «Месяц0», «Месяц1» и так далее.

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

Разберем полный рабочий шаблон создания динамической таблицы:


&НаСервере
Процедура СоздатьДинамическиеКолонкиНаСервере()
    
    // Шаг 1. Подготавливаем массив для добавления новых реквизитов формы
    ДобавляемыеРеквизиты = Новый Массив;
    ПутьКТаблице = "ПланированиеТаб";
    
    Для н = 0 по ИнтервалПланирования - 1 Цикл
        ИмяРеквизита = "Месяц" + н;
        ТипРеквизита = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
        
        // Создаем новый реквизит внутри существующей таблицы формы
        НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизита, ТипРеквизита, ПутьКТаблице, "Месяц " + (н + 1));
        ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
    КонецЦикла;
    
    // Шаг 2. Применяем изменения структуры формы
    ИзменитьРеквизиты(ДобавляемыеРеквизиты);
    
    // Шаг 3. Теперь создаем элементы отображения на форме
    Для н = 0 по ИнтервалПланирования - 1 Цикл
        
        ИмяКолонки = "КолонкаПланирования_" + н;
        ТекДата = ДобавитьМесяц(МесяцНачалаПланирования, н);
        ЗаголовокКолонки = НРег(Формат(ТекДата, НСтр("ru='ДФ=''ММММ гггг'''")));
        
        // Добавляем поле ввода в таблицу на форме
        НовыйЭлемент = Элементы.Добавить(ИмяКолонки, Тип("ПолеФормы"), Элементы.ПланированиеТаб);
        НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
        
        // Связываем элемент с созданным ранее динамическим реквизитом
        НовыйЭлемент.ПутьКДанным = "ПланированиеТаб.Месяц" + н;
        
        // Назначаем понятный заголовок без ошибок в именовании
        НовыйЭлемент.Заголовок = ЗаголовокКолонки;
        
    КонецЦикла;
    
КонецПроцедуры

Используя данный подход, мы полностью исключаем возникновение ошибок именования элементов интерфейса, соблюдаем стандарты локализации и гарантируем стабильную работу динамических форм в любых конфигурациях на платформе «1С:Предприятие 8.3».

← На главную