Программное создание реквизита управляемой формы заданной точности

13.07.15

Разработка - Универсальные функции

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

Добрый день, коллеги и сочувствующие! 
На днях появилась задача - в форме обработки программно заполнять табличную часть данными документа. 
На примере коротенькой процедуры я отмечу, с какими подводными камнями столкнулся. 
Для простоты задачи я изначально подготовил в форме нужный реквизит с типом ТаблицаЗначений, разместил его на форме, но без колонок. 
А далее по кнопке выполняется заполнение таблицы по переданной ссылке. 
Но при пересчете числовых значений быстро обнаружилось, что суммы считаются не до 2 знаков после запятой, а гораздо больше. 
Провозившись в отладке пару часов, разобрался - все дело в создании числовых реквизитов, у которых описание типов создано на основании массива типов, а не единичного типа "Число". 

 

//<<Дополнение от 03,06,15

А ларчик просто открывался! Описание типов имеет два конструктора - на основании другого описания типов, и на основании типов и квалификаторов.

 

Так вот, для описанного ниже примера достаточно просто написать

		Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
			НоваяКолонка = Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ИмяТаблицы);
			МассивРеквизитов.Добавить(НоваяКолонка);
		КонецЦикла; 

Колонка.ТипЗначения - это описание типов. В случае, если нам нужно другое описание типов (вместо того, что мы получаем из типа значений колонки), можно пойти двумя путями - создать новое описание типов на основе исходного, либо новое описание на основе типов и квалификаторов.

В первом случае можно написать, например так (убираем из исходного описания тип Null):

Новый ОписаниеТипов(Колонка.ТипЗначения,,"Null")

А во втором случае есть два варианта; можно написать, например 

Новый ОписаниеТипов("Строка, Число", Новый КвалификаторыЧисла(12,2));

Или

 

Массив = Новый Массив(2);
Массив.Добавить(Тип("Строка"));
Массив.Добавить(Тип("Число"));
Новый ОписаниеТипов(МассивТипов, Новый КвалификаторыЧисла(12,2));


Тем самым мы явно задаем квалификаторы числа

//>>Конец дополнения

&НаСервере
Процедура ЗаполнитьТЗ(ДокЗаказ, ИмяТаблицы)
    
//Очищаем таблицу при передаче пустой ссылки (срабатывает при очистке реквизита ЗаказКлиента в форме)
    Если Не ЗначениеЗаполнено(ДокЗаказ) Тогда
        ТЗ_рез = РеквизитФормыВЗначение(ИмяТаблицы);
        ТЗ_рез.Очистить();
        ЗначениеВРеквизитФормы(ТЗ_рез, ИмяТаблицы);
        Возврат;
    КонецЕсли;


    ТЗ_рез = РеквизитФормыВЗначение(ИмяТаблицы);
    
    МассивРеквизитов = Новый Массив;
    
    //Выполним запрос
    ТекстЗапроса = "ВЫБРАТЬ
    |    ЗаказКлиентаТовары.Номенклатура,
    |    ЗаказКлиентаТовары.Характеристика,
    |    ЗаказКлиентаТовары.ВариантОбеспечения,
    |    ЗаказКлиентаТовары.КоличествоУпаковок,
    |    ЗаказКлиентаТовары.Упаковка,
    |    ЗаказКлиентаТовары.Цена,
    |    ЗаказКлиентаТовары.ПроцентРучнойСкидки,
    |    ЗаказКлиентаТовары.СуммаРучнойСкидки,
    |    ВЫРАЗИТЬ(ЗаказКлиентаТовары.Сумма КАК ЧИСЛО(15, 2)) КАК Сумма,
    |    ЗаказКлиентаТовары.СтавкаНДС,
    |    ЗаказКлиентаТовары.СуммаНДС,
    |    ЗаказКлиентаТовары.СуммаСНДС,
    |    ЗаказКлиентаТовары.Ссылка,
    |    ЗаказКлиентаТовары.НомерСтроки,
    |    ЗаказКлиентаТовары.ДатаОтгрузки,
    |    ЗаказКлиентаТовары.Назначение,
    |    ЗаказКлиентаТовары.ВидЦены,
    |    ЗаказКлиентаТовары.Количество,
    |    ЗаказКлиентаТовары.ПроцентАвтоматическойСкидки,
    |    ЗаказКлиентаТовары.СуммаАвтоматическойСкидки,
    |    ЗаказКлиентаТовары.ПричинаОтмены,
    |    ЗаказКлиентаТовары.КодСтроки,
    |    ЗаказКлиентаТовары.Отменено,
    |    ЗаказКлиентаТовары.КлючСвязи,
    |    ЗаказКлиентаТовары.Склад,
    |    ЗаказКлиентаТовары.СрокПоставки,
    |    ЗаказКлиентаТовары.Содержание,
    |    ЗаказКлиентаТовары.СтатусУказанияСерий,
    |    ЗаказКлиентаТовары.УказыватьСерии,
    |    ЗаказКлиентаТовары.дПретензияОтПокупателя,
    |    ЗаказКлиентаТовары.РС_НомерПалеты,
    |    ЗаказКлиентаТовары.Серия,
    |    ЗаказКлиентаТовары.НоменклатураНабора,
    |    ИСТИНА КАК БезВозвратнойТары,
    |    ЗаказКлиентаТовары.Сумма КАК СуммаБезВозвратнойТары,
    |    ЗаказКлиентаТовары.СуммаНДС КАК СуммаНДСБезВозвратнойТары,
    |    ЗаказКлиентаТовары.СуммаСНДС КАК СуммаСНДСБезВозвратнойТары,
    |    ЗаказКлиентаТовары.СуммаАвтоматическойСкидки КАК СуммаАвтоматическойСкидкиБезВозвратнойТары,
    |    ЗаказКлиентаТовары.СуммаРучнойСкидки КАК СуммаРучнойСкидкиБезВозвратнойТары,
    |    ЗаказКлиентаТовары.ХарактеристикаНабора
    |ИЗ
    |    Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
    |ГДЕ
    |    ЗаказКлиентаТовары.Ссылка = &Ссылка";
    Запрос = Новый Запрос;
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("Ссылка", ДокЗаказ);
//Такой запрос со всеми колонками ТЧ заказа нужен для того, чтобы затем корректно загрузить табличную часть в документ.
//В принципе этот пример можно рассматривать с одним единственным реквизитом:) 
ТЗ_рез = Запрос.Выполнить().Выгрузить();
    
    //Создадим реквизиты ТЗ
    _РеквизитТЗ = РеквизитФормыВЗначение(ИмяТаблицы);
    Если _РеквизитТЗ.Колонки.Количество()= 0 Тогда
        МассивРеквизитов.Очистить();

//Закомментированный кусок - не отработает, и тут есть такой нюанс.
//Если создавать реквизиты с описанием типов на основании массива, то даже если у вас с массиве один элемент, квалификаторычисла будут нулевыми
//Для того чтобы созданный реквизит (в моем случае числовой) имел заданную точность, его нужно создавать немного-по другому
        //Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
        // МассивТипов = Новый Массив;
        // МассивТипов.Добавить(Колонка.ТипЗначения);
        // НоваяКолонка = Новый РеквизитФормы(Колонка.Имя, Новый ОписаниеТипов(МассивТипов), ИмяТаблицы);
        // МассивРеквизитов.Добавить(НоваяКолонка);
        //КонецЦикла; 

        
        Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
 //Вторая хитрость. Таблица значений, которую возвращает запрос, по умолчанию имеет плюс ко всем типам тип NULL. В результате опять же массив типов (см.выше).
 //Мы убираем Null, и на выходе имеем описание типов с нужными квалификаторами (разумеется, если они получены из исходного запроса.
 //Если создаем реквизит не на основании готовой выборки или таблицы, делаем например так:
 //ОТ = Новый ОписаниеТипов(Колонка.ТипЗначения,,"Null",,,Новый КвалификаторыДанных(15,2));

            ОТ = Новый ОписаниеТипов(Колонка.ТипЗначения,,"Null");
            НоваяКолонка = Новый РеквизитФормы(Колонка.Имя, ОТ, ИмяТаблицы);
            МассивРеквизитов.Добавить(НоваяКолонка);
        КонецЦикла;      
        ИзменитьРеквизиты(МассивРеквизитов);  
        ЗначениеВРеквизитФормы(ТЗ_рез, ИмяТаблицы);
        
        //Создаем элементы на форме для отображения колонок
        ЭлементТЗ = Элементы[ИмяТаблицы];
        Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
            НовыйЭлементФормы = Элементы.Добавить(ИмяТаблицы+Колонка.Имя, Тип("ПолеФормы"), ЭлементТЗ);
            НовыйЭлементФормы.Вид = ВидПоляФормы.ПолеВвода;
            НовыйЭлементФормы.ПутьКДанным = ИмяТаблицы + "." + Колонка.Имя;
        КонецЦикла;
    Иначе
        ЗначениеВРеквизитФормы(ТЗ_рез, ИмяТаблицы);
    КонецЕсли;

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



Вот, собственно, и все. Я убил около 2 часов на то, чтобы понять, как создать реквизит с нужной мне точностью. Надеюсь, кому-нибудь пригодится.


Управляемые формы программное создание реквизит

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7459    bayselonarrend    20    

154

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    20134    dimanich70    81    

144

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11227    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23763    SeiOkami    48    

135

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    14735    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3581    56    progmaster    8    

4

Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    25538    SeiOkami    31    

113
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. DrAku1a 1745 04.06.15 03:43 Сейчас в теме
Примеры работы с описанием типов есть в справке 1С.
Полезного в статье - только первый приведённый блок кода.
Но всё-же спасибо, что делитесь опытом обхождения граблей - иной раз, две строчки кода бывают важнее, чем сотни.
2. pvlunegov 158 09.06.15 10:37 Сейчас в теме
(1) DrAku1a,
Я бы не стал так категорично к автору относится.
Я скажу - МОЛОДЕЦ!
Я занимаюсь таким же как ты делом.
Если успешно решил определенную проблему, делаю статью и выкладываю на Инфостарте.
Сначала навалятся всякие гении 1с и будут кидать тухлыми помидорами, улюлюкать и кричать отстой.
Подожди немного, позже подключатся нормальные люди, которым твоя статья поможет, они скажут спасибо или плюс поставят.

Короче, уважение за хорошую статью тебе, Алексей!
Оставьте свое сообщение