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

13.07.15

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

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

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

 

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

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

 

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

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

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

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

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

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

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

Или

 

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


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

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

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


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

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

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

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

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



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


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

См. также

Планы обмена VS История данных

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

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

11.12.2023    6410    dsdred    36    

112

1С-ная магия

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

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

06.10.2023    18475    SeiOkami    46    

118

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    8824    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

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

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

2 стартмани

22.08.2023    2072    21    progmaster    7    

3

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

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

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    6952    SeiOkami    10    

140

Версионирование объектов VS История данных

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

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    18951    dsdred    54    

193

Практическая шпаргалка по новым возможностям языка запросов 1С

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

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

21.11.2022    23426    quazare    36    

122

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

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

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16146    133    sapervodichka    112    

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

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