1С 8. Часть 2 - Управляемые формы. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей

Публикация № 406318 08.10.15

Приемы и методы разработки - СКД

СКД система компоновки данных служебные разработчику такси

Продолжение публикации "1С 8. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей" http://infostart.ru/public/405762/ . Теперь напишем обработку под управляемые формы. Мы узнаем как в управляемой форме (под тонкий-клиент и web-клиент) реализовать: Открытие диалога выбора файла с выделением в асинхронную процедуру; Открытие диалога сохранения файла с выделением в асинхронную процедуру; Передача файла с клиента на сервер; Заполнение дерева значений (оперирование с ДанныеФормыДерево, ДанныеФормыКоллекцияЭлементовДерева, ДанныеФормыЭлементДерева); Передача файла с сервера на клиент.

Создадим управляемую форму обработки, со следующими реквизитами:

  • Адрес – строка неограниченная
  • ДеревоНаборов – ДеревоЗначений (и колонки к нему)
  • РасшифровкаСтроки – Строка, на форме многострочная

 

 

Добавим команды формы и соответствующие клиентские процедуры к ним

 

 

 Процедура для кнопки «Заполнить из файла»:

//--Открытие диалога выбора файла с выделением в асинхронную процедуру

&НаКлиенте
Процедура ЗаполнитьИзФайла(Команда)

    //Открытие диалога выбора файла 
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);  
    Диалог.ПолноеИмяФайла = "";  
    Диалог.Фильтр = "файлы СКД *.xml|*.xml";  
    Диалог.МножественныйВыбор = Ложь;  
    Диалог.Заголовок = "Выберите файл СКД - ресурс";   
    Диалог.Показать(Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение1", ЭтаФорма, Новый Структура("Диалог", Диалог)));   
    
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение1(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Диалог = ДополнительныеПараметры.Диалог;
    
    Если (ВыбранныеФайлы <> Неопределено) Тогда   
        МассивФайлов = Диалог.ВыбранныеФайлы;
        Для Каждого ИмяФайла Из МассивФайлов Цикл  
            ИсходныйФайл = ИмяФайла; 
        КонецЦикла;
        
        Файл = Новый Файл(ИсходныйФайл);
        Файл.НачатьПроверкуСуществования(Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение", ЭтаФорма, Новый Структура("ИсходныйФайл", ИсходныйФайл)));
        
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение(Существует, ДополнительныеПараметры) Экспорт
    
    ИсходныйФайл = ДополнительныеПараметры.ИсходныйФайл;
    
    Если Существует Тогда
        ЗаполнитьТЧ(ИсходныйФайл); //Чтение XML-файла и заполнение дерева наборов
    Иначе
        Сообщить("Не найден файл " + ИсходныйФайл);
    КонецЕсли;
    
КонецПроцедуры
//--

{Замечание! Хочу обратить внимание, что данный код можно создать при помощи такой удобной возможности, как рефакторинг кода:

Выделяем процедуру диалога выбора файла

Процедура КоманднаяПанель1ЗаполнитьИзФайла(Кнопка)
    
    //Открытие диалога выбора файла
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.ПолноеИмяФайла = "";
    Диалог.Фильтр = "файлы СКД *.xml|*.xml";
    Диалог.МножественныйВыбор = Ложь;
    Диалог.Заголовок = "Выберите файл СКД - ресурс";
    Если Диалог.Выбрать() Тогда
        МассивФайлов = Диалог.ВыбранныеФайлы;
        Для Каждого ИмяФайла Из МассивФайлов Цикл
            ИсходныйФайл = ИмяФайла;
        КонецЦикла;
        
        Файл = Новый Файл(ИсходныйФайл);
        Если Файл.Существует() Тогда
            ЗаполнитьТЧ(ИсходныйФайл); //Чтение XML-файла и заполнение дерева наборов
        Иначе
            Сообщить("Не найден файл " + ИсходныйФайл);
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

И воспользовавшись пунктом меню «Текст -> Рефакторинг -> Нерекомендуемые синхронное вызовы -> Выделить в асинхронную процедуру» получаем асинхронный код

 

 

Конец замечания}

В неуправляемых формах, чтобы очистить строки дерева, мы использовали

ДеревоНаборов.Строки.Очистить();

В управляемых формах это будет выглядеть следующим образом:

ЭлементыДанныеФормыДерево = ДеревоНаборов.ПолучитьЭлементы();
ЭлементыДанныеФормыДерево.Очистить();

Процедура ЗаполнитьТЧ() рекурсивно формирует дерево наборов данных и создает колонки соответствующего элемента формы:

&НаКлиенте
Процедура ЗаполнитьТЧ(ИсходныйФайл)
    
    //Очистим строки и колонки дерева наборов
    ЭлементыДанныеФормыДерево = ДеревоНаборов.ПолучитьЭлементы();
    ЭлементыДанныеФормыДерево.Очистить();
    
    ДвоичДанные = Новый ДвоичныеДанные(ИсходныйФайл);
    Адрес = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
    ЗаполнитьДеревоИзФайлаНаСервере(Адрес);
    
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДеревоИзФайлаНаСервере(Адрес)
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
    ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
    ДвоичныеДанные.Записать(ИмяВременногоФайлаXML);
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.ОткрытьФайл(ИмяВременногоФайлаXML);
    ЧтениеXML.Прочитать();
    СКД = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); //Производит чтение значения в формате XML
    ЗаполнитьДерево(ДеревоНаборов.ПолучитьЭлементы(), СКД.НаборыДанных); //Рекурсивное построение дерева значений
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДерево(Позиция, НаборыДанных)
    
    Сч = 0;
    
    Для Каждого НаборДанных Из НаборыДанных Цикл
        Сч = Сч + 1;
        НовСтр = Позиция.Добавить();
        ЗаполнитьЗначенияСвойств(НовСтр, НаборДанных);
        НовСтр.Номер = Сч;
        Если ЗначениеЗаполнено(НовСтр.Запрос) Тогда
            НовСтр.ТипНабора = "Запрос";
        ИначеЕсли ЗначениеЗаполнено(НовСтр.ИсточникДанных) Тогда
            НовСтр.ТипНабора = "Объект";
        Иначе
            НовСтр.ТипНабора = "Объединение";
            //Т.к. объединение может содержать различные наборы,
            //то разберем набор-объединение по наборам данных
            ЗаполнитьДерево(НовСтр.ПолучитьЭлементы(), НаборДанных.Элементы);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Для передачи файла с клиента на сервер используем временное хранилище. На клиенте:

ДвоичДанные = Новый ДвоичныеДанные(ИсходныйФайл);
Адрес = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
ЗаполнитьДеревоИзФайлаНаСервере(Адрес);

На сервере:

ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
ДвоичныеДанные.Записать(ИмяВременногоФайлаXML);

Для вывода текста запроса в поле Расшифровка строки в управляемой форме изменим путь к данным элемента «РасшифровкаСтроки»:

 

 

Процедура для ранее созданной кнопке «Сохранить файл…»

&НаКлиенте
Процедура СохранитьВФайл(Команда)
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    Диалог.ПолноеИмяФайла = "";
    Диалог.Фильтр = "файлы СКД *.xml|*.xml";
    Диалог.МножественныйВыбор = Ложь;
    Диалог.Заголовок = "Файл СКД исправленный";
    Диалог.Показать(Новый ОписаниеОповещения("СохранитьВФайлЗавершение", ЭтаФорма, Новый Структура("Диалог", Диалог)));
КонецПроцедуры

&НаКлиенте
Процедура СохранитьВФайлЗавершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Диалог = ДополнительныеПараметры.Диалог;
    
    Если (ВыбранныеФайлы <> Неопределено) Тогда    
        
        МассивФайлов = Диалог.ВыбранныеФайлы;
        Для Каждого ИмяФайла Из МассивФайлов Цикл
            КоррФайл = ИмяФайла;
        КонецЦикла;
        
        НовыйАдрес = ВыполнитьЗаменуНаСервере();
        
        ДвоичныеДанные = ПолучитьИзВременногоХранилища(НовыйАдрес);
        ДвоичныеДанные.Записать(КоррФайл);
        
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Функция ВыполнитьЗаменуНаСервере()
    
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
    ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
    ДвоичныеДанные.Записать(ИмяВременногоФайлаXML);
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.ОткрытьФайл(ИмяВременногоФайлаXML);
    ЧтениеXML.Прочитать();
    СКД = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); //Производит чтение значения в формате XML
    
    НовСКД = Новый СхемаКомпоновкиДанных;
    НовСКД = СКД;
    
    ВыполнитьЗамену(ДеревоНаборов.ПолучитьЭлементы(), НовСКД.НаборыДанных);
    
    НовыйФайл = ПолучитьИмяВременногоФайла("xml");
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.ОткрытьФайл(НовыйФайл);
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, НовСКД);
    ЗаписьXML.Закрыть();
    
    ДвоичДанные = Новый ДвоичныеДанные(НовыйФайл);
    АдресВозвр = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
    
    Возврат АдресВозвр;
    
КонецФункции

&НаСервере
Процедура ВыполнитьЗамену(ДеревоНаборовСтроки, НовСКДНаборыДанных)
    
    Для Каждого Стр Из ДеревоНаборовСтроки Цикл    
        Если Стр.Отметка Тогда
            
            НовыйНабор = НовСКДНаборыДанных.Вставить(Стр.Номер - 1, Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
            
            СтарыйНабор = НовСКДНаборыДанных[Стр.Номер];
            
            ЗаполнитьЗначенияСвойств(НовыйНабор, СтарыйНабор);
            НовыйНабор.ИмяОбъекта = Стр.ИмяОбъекта;
            Для Каждого СтарыйНаборПоле ИЗ СтарыйНабор.Поля Цикл
                НовПоле = НовыйНабор.Поля.Добавить(ТипЗнч(СтарыйНаборПоле));
                ЗаполнитьЗначенияСвойств(НовПоле, СтарыйНаборПоле);
            КонецЦикла;
            НовСКДНаборыДанных.Удалить(СтарыйНабор);
            
        Иначе
            
            Если Стр.ТипНабора = "Объединение" Тогда
                ВыполнитьЗамену(Стр.ПолучитьЭлементы(), НовСКДНаборыДанных[Стр.Номер - 1].Элементы);
            КонецЕсли;
        КонецЕсли;    
    КонецЦикла;
    
КонецПроцедуры

Обработка прилагается. Надеюсь, что материал кому-то будет полезен. Всего хорошего…

Скачать файлы

Наименование Файл Версия Размер
Обработка: Управляемые формы. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей

.epf 9,10Kb
4
.epf 9,10Kb 4 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. echo77 1570 16.06.22 14:13 Сейчас в теме
А есть такая же, но чтобы еще порядок полей в наборе данных можно было менять?
2. echo77 1570 16.06.22 15:23 Сейчас в теме
(0) К сожалению, при использовании этой обработки все свойства полей конвертируемого набора данных очищаются
Прикрепленные файлы:
3. echo77 1570 30.06.22 19:55 Сейчас в теме
Сделал обработку (УФ) которая может изменить тип набора данных, изменять порядок полей https://infostart.ru/public/1679241/
Оставьте свое сообщение

См. также

Редактирование СКД, смена типа набора данных

Инструментарий разработчика v8 Абонемент ($m)

Еще один мини-редактор СКД

1 стартмани

21.06.2022    1181    22    echo77    2    

Таблица умножения, деления на СКД, управляемые формы (пример тестового задания)

Подготовка к аттестации СКД v8 Абонемент ($m)

Пример тестового задания и его реализации. Протестировано на версии платформы 8.3.18.1289.

1 стартмани

30.05.2022    1460    5    Johnson1987    13    

Программное формирование отчетов в БП 3.0 на примере оборотно-сальдовой ведомости по счету

Адаптация типовых решений СКД v8 v8::БУ v8::СКД БП3.0 Россия БУ Абонемент ($m)

Порой возникает задача получить программно результат отчета на основе СКД в виде табличного документа. В данной статье будет описан один из вариантов реализации данной задачи.

1 стартмани

14.07.2021    5004    19    arman1997    1