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

13.07.15

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

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

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

 

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

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

 

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

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

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

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

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

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

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

Или

 

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


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

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

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


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

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

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

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

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



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


Вступайте в нашу телеграмм-группу Инфостарт

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

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

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

Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?

16.07.2025    32241    TitanLuchs    108    

149

Механизмы платформы 1С WEB-интеграция Программист 1С:Предприятие 8 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    33005    dsdred    106    

148

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

23.06.2024    28867    bayselonarrend    22    

177

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    57916    dimanich70    85    

175

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

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

06.10.2023    31458    SeiOkami    48    

140

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

28.08.2023    25497    YA_418728146    8    

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

Короче, уважение за хорошую статью тебе, Алексей!
Для отправки сообщения требуется регистрация/авторизация