gifts2017

1С 8. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей

Опубликовал Владимир Лучинский (Luchik) в раздел Программирование - Практика программирования

Возникла у меня необходимость в существующем отчете на СКД, имеющем набор данных - запрос, изменить тип набора данных с запроса на объект - таблицу значений. Но при смене типа набора данных слетели все поля, роли, ресурсы, оформление – в общем, все слетело.
Погуглил и нашел способ – редактирование xml- файла схемы компоновки данных в текстовом редакторе. А почему бы не написать обработку для 1С, которая все сделает сама?
Предлагаю вместе создать такую обработку.
На примере обработки рассмотрим, как в 1С реализовать:
Чтение и запись XML, использование СериализаторXDTO;
Программное изменение схемы компоновки данных;
Рекурсивное построение дерева значений;
Изменение вида элемента управления (флажок вместо поля ввода);
Работа с файлами диалог открытия, сохранения;
Управление видимостью строк/колонок и отдельных ячеек дерева значений.

Возникла у меня необходимость в существующем отчете на СКД, имеющем набор данных - запрос, изменить тип набора данных с запроса на объект - таблицу значений. Но при смене типа набора данных слетели все поля, роли, ресурсы, оформление – в общем, все слетело.

Нашел способ - http://infostart.ru/public/285576/ (хочу выразить свое уважение 1cKiller Alexey - респект) - редактирование xml- файла схемы компоновки данных в текстовом редакторе. А почему бы не написать обработку для 1С, которая все сделает сама?

Предлагаю вместе создать такую обработку.

Итак, у нас xml – файл СКД,  в котором присутствует набор данных – запрос (учтем, что в данном файле наборы данных могут быть не только на основании запросов, но и объектов, а также объединения). Файл получен, нажатием в конфигураторе кнопки «Сохранить схему в файл»:

Предлагаю на форме разместить два поля: первое для отображения наборов данных (тип ДеревоЗначений, т.к. объединение тоже может содержать различные наборы данных, то использование таблицы значений нам не подойдет), второе для отображения текста запроса набора данных-запрос(строка неограниченной длины, на форме многострочная):

 

Теперь организуем выбор и обработку файла исходной схемы компоновки данных. Для этого создадим кнопку «Заполнить из файла», назначим ей событие при нажатии:

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

        

        //Открытие диалога выбора файла

        Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);

        Диалог.ПолноеИмяФайла = "";

        Диалог.Фильтр = "файлы СКД *.xml|*.xml";

        Диалог.МножественныйВыбор = Ложь;

        Диалог.Заголовок = "Выберите файл СКД - ресурс";

        Если Диалог.Выбрать() Тогда

               МассивФайлов = Диалог.ВыбранныеФайлы;

            Для Каждого ИмяФайла Из МассивФайлов Цикл

                ИсходныйФайл = ИмяФайла;

            КонецЦикла;

        

               Файл = Новый Файл(ИсходныйФайл);

               Если Файл.Существует() Тогда

                       ЗаполнитьТЧ(ИсходныйФайл);//Чтение XML-файла и заполнение дерева наборов

               Иначе

                       Сообщить("Не найден файл " + ИсходныйФайл);

               КонецЕсли;

               

        КонецЕсли;

        

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

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

Процедура ЗаполнитьДерево(Позиция, НаборыДанных)

        Сч = 0;

        Для Каждого НаборДанных Из НаборыДанных Цикл

               Сч = Сч + 1;

               НовСтр = Позиция.Строки.Добавить();

               ЗаполнитьЗначенияСвойств(НовСтр, НаборДанных);

               НовСтр.Номер = Сч;

               Если ЗначениеЗаполнено(НовСтр.Запрос) Тогда

                       НовСтр.ТипНабора = "Запрос";

               ИначеЕсли ЗначениеЗаполнено(НовСтр.ИсточникДанных) Тогда

                       НовСтр.ТипНабора = "Объект";

               Иначе

                       НовСтр.ТипНабора = "Объединение";

                       //Т.к. объединение может содержать различные наборы,

                       //то разберем набор-объединение по наборам данных

                       ЗаполнитьДерево(НовСтр, НаборДанных.Элементы);

               КонецЕсли;

        КонецЦикла;

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

Для того, чтобы в нижней части обработки в поле РасшифровкаСтроки отображался текст запроса текущего набора данных (если, конечно, этот набор даных-запрос) используем событие ПриАктивацииСтроки нашего дерева:

Процедура ДеревоНаборовПриАктивизацииСтроки(Элемент)

        ТекДанные = Элемент.ТекущиеДанные;

        Если ТекДанные.ТипНабора = "Запрос" Тогда

               РасшифровкаСтроки = ТекДанные.Запрос;

        ИначеЕсли ТекДанные.ТипНабора = "Объект" Тогда

               РасшифровкаСтроки = ТекДанные.ИмяОбъекта;

        Иначе

               РасшифровкаСтроки = "";

        КонецЕсли;

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

 

Теперь можно в дереве указать, какие наборы заменять (установка флажка в колонке «Пометка» и имя объекта, содержащего данные в колонке «Имя объекта»), например, так:

 

Создадим кнопку «Сохранить СКД в файл как…», процедура, вызываемая по нажатию этой кнопки:

Процедура КоманднаяПанель1СохранитьВФайл(Кнопка)

        

        Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);

        Диалог.ПолноеИмяФайла = "";

        Диалог.Фильтр = "файлы СКД *.xml|*.xml";

        Диалог.МножественныйВыбор = Ложь;

        Диалог.Заголовок = "Файл СКД исправленный";

        Если Диалог.Выбрать() Тогда

               

               МассивФайлов = Диалог.ВыбранныеФайлы;

            Для Каждого ИмяФайла Из МассивФайлов Цикл

                КоррФайл = ИмяФайла;

            КонецЦикла;

               

               НовСКД = Новый СхемаКомпоновкиДанных;

               НовСКД = СКД;

               

               ВыполнитьЗамену(ДеревоНаборов.Строки, НовСКД.НаборыДанных);

               

               ЗаписьXML = Новый ЗаписьXML;

               ЗаписьXML.ОткрытьФайл(КоррФайл);

               СериализаторXDTO.ЗаписатьXML(ЗаписьXML,       НовСКД);

               

        КонецЕсли;

               

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

А вот и сама, так сказать, процедура-гвоздь программы ВыполнитьЗамену(), рекурсивно:

Процедура ВыполнитьЗамену(ДеревоНаборовСтроки, НовСКДНаборыДанных)

        

        Для Каждого Стр Из ДеревоНаборовСтроки Цикл

               Если Стр.Отметка Тогда

                       

                       НовыйНабор = НовСКДНаборыДанных.Вставить(Стр.Номер-1, Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));

                       

                       СтарыйНабор = НовСКДНаборыДанных[Стр.Номер];

                       

                       ЗаполнитьЗначенияСвойств(НовыйНабор, СтарыйНабор);

                       НовыйНабор.ИмяОбъекта = Стр.ИмяОбъекта;

                       Для Каждого СтарыйНаборПоле ИЗ СтарыйНабор.Поля Цикл

                               НовПоле = НовыйНабор.Поля.Добавить(ТипЗнч(СтарыйНаборПоле));

                               ЗаполнитьЗначенияСвойств(НовПоле ,СтарыйНаборПоле);

                       КонецЦикла;

                       НовСКДНаборыДанных.Удалить(СтарыйНабор);

                       

               Иначе

                       Если Стр.ТипНабора = "Объединение" Тогда

                               ВыполнитьЗамену(Стр.Строки, НовСКДНаборыДанных[Стр.Номер-1].Элементы);

                       КонецЕсли;

               КонецЕсли;

        КонецЦикла;

        

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

Все очень просто, обработка (неуправляемые формы) прилагается – используйте.

При необходимости, не против добавить и на управляемых формах. Удачи…

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

Наименование Файл Версия Размер
Обработка для смены типа набора данных СКД с сохранением полей 2
.epf 8,27Kb
06.10.15
2
.epf 8,27Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Никита Грызлов (nixel) 07.10.15 11:18
Я боюсь, что открою Америку, но смена типа набора данных проводится в блокноте за... пару секунд =/
Сохраняем схему в xml, открываем блокнотом, находим тег dataSet, меняем атрибут xsi:type="DataSetQuery" на xsi:type="DataSetObject", удаляем вложенный тег query целиком
....
PROFIT!

Update:
Пардон, читал статью по диагонали, вы указали способ через текстовый редактор. На мой взгляд в блокноте все же проще и быстрее, но спасибо вам за обработку :)
zqzq; Luchik; +2 Ответить 1
2. Владимир Лучинский (Luchik) 07.10.15 11:43
(1) nixel, (1) nixel, да, я же об этом написал
(хочу выразить свое уважение 1cKiller Alexey - респект) - редактирование xml- файла схемы компоновки данных в текстовом редакторе
. Эта публикация - возможность поделиться своими навыками, что и как можно реализовать в 1С.
Более того, оказывается, аналогичная обработка есть (infostart.ru)
3. Владимир Лучинский (Luchik) 08.10.15 10:05