Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
25 ноя 2024, 06:02

Вывод данных в отчете-обработке

Автор sandro1, 29 ноя 2011, 11:34

0 Пользователей и 1 гость просматривают эту тему.

sandro1

Насчет модуля я как то не понял

sergeevds

Можешь скинуть текст модуля, выполняемого по кнопке "Печать" твоей формы, и текст процедуры общего модуля, на который она ссылается (если ссылается)?

sandro1

// Процедура осуществляет печать по выбранному шаблону.
//
Процедура Печать()
   
   Если Товары.Количество() = 0 Тогда
      
      Предупреждение("Не заполнена табличная часть ""Товары к печати""!");
      Возврат;
      
   КонецЕсли;
   
   ЕстьСтрокиДляПечати = Ложь;
   Для Каждого СтрокаТовары Из Товары Цикл
      
      Если СтрокаТовары.Печатать Тогда
         
         ЕстьСтрокиДляПечати = Истина;
         Прервать;
         
      КонецЕсли;
      
   КонецЦикла;
   
   Если Не ЕстьСтрокиДляПечати Тогда
      
      Предупреждение("Не выбрано строк для печати!");
      Возврат;
      
   КонецЕсли;
   
   ФормаХодВыполнения = ПолучитьОбщуюФорму("ХодВыполненияОбработкиДанных");
   ФормаХодВыполнения.НаименованиеОбработкиДанных = "Печать этикеток и ценников";
   ФормаХодВыполнения.КомментарийОбработкиДанных  = "Идет формирование макета..";
   
   Таб = Новый ТабличныйДокумент;
   
   ТекстЗапроса = ПостроитьТекстЗапроса();
   
   // Подготовим макет и настройки СКД
   масОбязательныхПолей = Новый Массив;
   масОбязательныхПолей.Добавить("Номенклатура.Штрихкод");
   
   МакетТабДокумента = ?(ЗначениеЗаполнено(Шаблон), Шаблон.Шаблон.Получить(), Обработки.ПечатьЭтикетокИЦенников.ПолучитьМакет("ЭталонныйМакет"));
   НастройкиФормирования = УправлениеШаблонами.ПодготовитьсяКЗаполнениюТабличногоШаблона(Метаданные(), МакетТабДокумента, масОбязательныхПолей, ТекстЗапроса);
   
   Если НастройкиФормирования = Неопределено Тогда
      Возврат;
   КонецЕсли;
   
   ФормаХодВыполнения.Открыть();
   
   Таб.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ШАБЛОНА_" + ?(ЗначениеЗаполнено(Шаблон), Шаблон.Наименование, "ЭталонныйШаблон");
   
   ПараметрПериод = НастройкиФормирования.Компоновщик.Настройки.ПараметрыДанных.Элементы.Найти("ДатаЦен");
   ПараметрПериод.Значение      = КонецДня(Дата);
   ПараметрПериод.Использование = Истина;
   
   Если ВидЦен = 0 Тогда
      УправлениеШаблонами.ДобавитьОтборВСКДПоПолномуИмениПоля(НастройкиФормирования, "Номенклатура.ТипЦен", ВидСравненияКомпоновкиДанных.Равно, ТипЦен);
   Иначе
      УправлениеШаблонами.ДобавитьОтборВСКДПоПолномуИмениПоля(НастройкиФормирования, "Магазин.Ссылка", ВидСравненияКомпоновкиДанных.Равно, Магазин);
   КонецЕсли;
   
   // Выполним запрос
   УправлениеШаблонами.ПодготовитьПроцессорКомпоновкиДанных(НастройкиФормирования);
   
   Если ЗначениеЗаполнено(Шаблон) Тогда
      
      КоличествоПоВертикали   = Шаблон.КоличествоПоВертикали;
      КоличествоПоГоризонтали = Шаблон.КоличествоПоГоризонтали;
      
   Иначе
      
      КоличествоПоВертикали   = 3;
      КоличествоПоГоризонтали = 5;
      
   КонецЕсли;
   
   Строки  = 0;
   Колонки = 0;
   
   //подсчитаем общее количество этикеток к печати
   КоличествоЭтикеток = 0;
   Для Каждого СтрокаТовары Из Товары Цикл
      
      Если СтрокаТовары.Печатать Тогда
         КоличествоЭтикеток = КоличествоЭтикеток + СтрокаТовары.КоличествоЭкземпляров;
      КонецЕсли;
      
   КонецЦикла;
   
   ФормаХодВыполнения.МаксимальноеЗначение = КоличествоЭтикеток;
   ФормаХодВыполнения.Значение = 0;
   
   // Переберем полученные данные
   Для Каждого СтрокаТовары Из Товары Цикл
      
      Если Не СтрокаТовары.Печатать Тогда
         Продолжить;
      КонецЕсли;
      
      Для Инд = 1 По СтрокаТовары.КоличествоЭкземпляров Цикл
      
         ФормаХодВыполнения.Значение = ФормаХодВыполнения.Значение + 1;
         
         Строки = Строки + 1;
         Колонки = ?(Колонки = КоличествоПоГоризонтали, 1, Колонки + 1);
         
         ИмяОбласти = НастройкиФормирования.МакетТабДокумента.ОбластьПечати.Имя;
         Область = НастройкиФормирования.МакетТабДокумента.ПолучитьОбласть(ИмяОбласти);
         
         НайдЗн = СтрокаТовары.табВычПолей.Найти("Номенклатура.ЦенаЗаГрамм","Поле");
         Если НЕ НайдЗн = неопределено Тогда
            Если НЕ НайдЗн.Значение = СтрокаТовары.Номенклатура_ЦенаЗаГрамм Тогда
               НайдЗн.Значение = СтрокаТовары.Номенклатура_ЦенаЗаГрамм;
            КонецЕсли;
         КонецЕсли;
         Для СчК = 1 По Область.ШиринаТаблицы Цикл
            
            Для СчС = 1 По Область.ВысотаТаблицы Цикл
               
               Ячейка = Область.Область(СчС, СчК);
               
               УправлениеШаблонами.ВыполнитьЗаменыВТекстеПоВычисляемымПолям(СтрокаТовары.табВычПолей, Ячейка.Текст, Ячейка.Формат);
               
            КонецЦикла;
            
         КонецЦикла;
         
         КодШтрихкода = Неопределено;
         ПредставлениеШтрихкода = Неопределено;
         ТипКода      = -1;
         Для Каждого Стр Из СтрокаТовары.табВычПолей Цикл
            
            Если Стр.Поле = "Номенклатура.Штрихкод" Тогда
               
               КодШтрихкода = Стр.Значение;
               
            ИначеЕсли Стр.Поле = "Номенклатура.ПредставлениеШтрихкода" Тогда
               
               ПредставлениеШтрихкода = Стр.Значение;
               
            ИначеЕсли Стр.Поле = "Номенклатура.ТипШтрихкода" Тогда
               
               ТипКода = ПолучитьЗначениеТипаШтрихкодаДляЭУ(Стр.Значение);
               
            КонецЕсли;
            
         КонецЦикла;
         
         Если (ЗначениеЗаполнено(КодШтрихкода) Или Не ПустаяСтрока(ПредставлениеШтрихкода))
            И ТипКода > -1 Тогда
            Для Каждого Рисунок Из Область.Рисунки Цикл
               
               Если Рисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Объект
                  И ТипЗнч(Рисунок.Объект) = Тип("ActiveX") Тогда
                  
                  //предположим что этот рисунок - штрихкод
                  Попытка
                     Рисунок.Объект.ТипКода   = ТипКода;
                     Рисунок.Объект.Сообщение = ?(ПустаяСтрока(ПредставлениеШтрихкода),
                                                  КодШтрихкода,
                                                  ПредставлениеШтрихкода);
                  Исключение
                  КонецПопытки;
                  
               КонецЕсли;
               
            КонецЦикла;
            
         Иначе

            //получим первоначальный массив рисунков таб документа
            МассивРисунковТабДокумента = Новый Массив;
            Для Каждого Рисунок Из Область.Рисунки Цикл
               
               Если Рисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Объект
                  И ТипЗнч(Рисунок.Объект) = Тип("ActiveX") Тогда
               
                  МассивРисунковТабДокумента.Добавить(Рисунок);
               
               КонецЕсли;
               
            КонецЦикла;
            
            //удалим все штрихкода
            Для Каждого Рисунок Из МассивРисунковТабДокумента Цикл
               
               Попытка
               
                  Область.Рисунки.Удалить(Рисунок);
                  
               Исключение
               КонецПопытки;
                  
            КонецЦикла;
            
         КонецЕсли;
         
         Если Колонки = 1 Тогда
            Таб.Вывести(Область);
         Иначе
            Таб.Присоединить(Область);
         КонецЕсли;
         
         Если Строки = КоличествоПоВертикали * КоличествоПоГоризонтали Тогда
            
            Если КоличествоПоГоризонтали = 1 Тогда
               Таб.ВывестиВертикальныйРазделительСтраниц();
            КонецЕсли;
            
            Таб.ВывестиГоризонтальныйРазделительСтраниц();
            Строки = 0;
            
         КонецЕсли;
         
         ОбработкаПрерыванияПользователя();
         
      КонецЦикла; // по количеству экземпляров
      
   КонецЦикла;
   
   ФормаХодВыполнения.Закрыть();
   
   // Выведем таблицу на экран
   Таб.ОтображатьГруппировки = Ложь;
   Таб.ОтображатьЗаголовки   = Ложь;
   Таб.ОтображатьСетку       = Ложь;
   Таб.Показать("Печать ценников и этикеток");
   
КонецПроцедуры
// конец процедуры печать




sandro1

////////////////////////////////////////////////////////////////////////////////
// ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС

// Функция формирует контекстное меню у текстового поля по дереву значений
//
Функция СформироватьПодменюШаблоновТекста(Ссылка, СоответствиеТЧ, Действие) Экспорт
   
   МаксКнопокВМеню = 10;
   
   ТабКнопок = Новый ТаблицаЗначений;
   ТабКнопок.Колонки.Добавить("Кнопка");
   ТабКнопок.Колонки.Добавить("Поле");
   ТабКнопок.Колонки.Добавить("Шаблон");
   
   // Удалим старые кнопки меню
   Для Каждого Пара Из СоответствиеТЧ Цикл
      Подменю = Пара.Ключ;
      Подменю.Кнопки.Очистить();
   КонецЦикла;
   
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ " + (МаксКнопокВМеню + 1) + "
   |   Шаблоны.Ссылка,
   |   Шаблоны.ТипШаблона,
   |   Шаблоны.Наименование КАК Наименование
   |ИЗ
   |   Справочник.ХранилищеШаблонов КАК Шаблоны
   |ГДЕ
   |   Шаблоны.Объект = &Объект
   |   И (Шаблоны.ТипШаблона = Значение(Перечисление.ТипыШаблонов.Текстовый) ИЛИ Шаблоны.ТипШаблона = Значение(Перечисление.ТипыШаблонов.HTML))
   |
   |УПОРЯДОЧИТЬ ПО
   |   Наименование";
   
   Запрос.УстановитьПараметр("Объект", Ссылка.Метаданные().ПолноеИмя());
   Выборка = Запрос.Выполнить().Выбрать();
   
   // Для каждого найденного шаблона создадим кнопку во всех меню
   КолвоПунктов = 0;
   Пока Выборка.Следующий() Цикл
      
      // Проверим, нужно ли выводить меню выбора остальных шаблонов
      Если КолвоПунктов >= МаксКнопокВМеню Тогда
         Картинка = Неопределено;
         Для Каждого Пара Из СоответствиеТЧ Цикл
            Пара.Ключ.Кнопки.Добавить("", ТипКнопкиКоманднойПанели.Разделитель);
            ДобавитьВМенюШаблоновКнопку(Пара.Ключ, ТабКнопок, ТипКнопкиКоманднойПанели.Действие, "Все шаблоны", Действие, Картинка, Неопределено, "Остальные");
         КонецЦикла;
         Прервать;
      КонецЕсли;
      КолвоПунктов = КолвоПунктов + 1;
      
      // Для каждого меню добавим кнопку по текущему шаблону
      Картинка = КартинкаВМенюПоТипуШаблона(Выборка.ТипШаблона);
      Для Каждого Пара Из СоответствиеТЧ Цикл
         ДобавитьВМенюШаблоновКнопку(Пара.Ключ, ТабКнопок, ТипКнопкиКоманднойПанели.Действие, Выборка.Наименование, Действие, Картинка, Пара.Значение, Выборка.Ссылка);
      КонецЦикла;
      
   КонецЦикла;
   
   Для Каждого Пара Из СоответствиеТЧ Цикл
      // Добавим разделитель
      Пара.Ключ.Кнопки.Добавить("", ТипКнопкиКоманднойПанели.Разделитель);
      // Добавим кнопку редактирования шаблонов
      ДобавитьВМенюШаблоновКнопку(Пара.Ключ, ТабКнопок, ТипКнопкиКоманднойПанели.Действие, "Редактировать шаблоны", Действие, БиблиотекаКартинок.Настройка, Неопределено, "Редактирование");
   КонецЦикла;
   
   Возврат ТабКнопок;
   
КонецФункции

// Получить картинку в меню для типа шаблона
//
Функция КартинкаВМенюПоТипуШаблона(ТипШаблона)

   Если ТипШаблона = Перечисления.ТипыШаблонов.HTML Тогда
      Возврат БиблиотекаКартинок.ШаблонHTML;
      
   ИначеЕсли ТипШаблона = Перечисления.ТипыШаблонов.Табличный Тогда
      Возврат БиблиотекаКартинок.ШаблонТабличный;
      
   ИначеЕсли ТипШаблона = Перечисления.ТипыШаблонов.Текстовый Тогда
      Возврат БиблиотекаКартинок.ШаблонТекстовый;
      
   Иначе
      Возврат Неопределено;
      
   КонецЕсли;

КонецФункции // КартинкаВМенюПоТипуШаблона()

// В меню шаблонов добавить кнопку
//
Процедура ДобавитьВМенюШаблоновКнопку(Подменю, ТабКнопок, ТипКнопки, Наименование, Действие, Картинка, Поле, Шаблон)

   Кнопка = Подменю.Кнопки.Добавить("", ТипКнопки, Наименование, Действие);
   Если Картинка <> Неопределено Тогда
      Кнопка.Картинка = Картинка;
   КонецЕсли;
   
   новСтр = ТабКнопок.Добавить();
   новСтр.Кнопка = Кнопка;
   новСтр.Поле   = Поле;
   новСтр.Шаблон = Шаблон;

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

// Открыть форму списка шаблонов
//
Функция ОткрытьФормуСпискаШаблонов(ФормаВладелец, ТипШаблонов, ИмяМетаданныхОбъекта, ДляВыбора, КлючУникальности, ОткрыватьМодально, МакетДляНовыхШаблонов = Неопределено) Экспорт

   Форма = Справочники.ХранилищеШаблонов.ПолучитьФормуВыбора(, ФормаВладелец, КлючУникальности);
   Форма.МакетДляНовыхШаблонов = МакетДляНовыхШаблонов;
   Форма.РежимВыбора = ДляВыбора;
   
   // Установим отбор по объекту
   Форма.СправочникСписок.Отбор.Объект.Значение = ИмяМетаданныхОбъекта;
   Форма.СправочникСписок.Отбор.Объект.Использование = Истина;
   Форма.ЭлементыФормы.СправочникСписок.НастройкаОтбора.Объект.Доступность = Ложь;
   
   // Установим отбор по типам шаблонов
   Форма.СправочникСписок.Отбор.ТипШаблона.ВидСравнения = ?(ТипЗнч(ТипШаблонов) = Тип("СписокЗначений"), ВидСравнения.ВСписке, ВидСравнения.Равно);
   Форма.СправочникСписок.Отбор.ТипШаблона.Значение = ТипШаблонов;
   Форма.СправочникСписок.Отбор.ТипШаблона.Использование = Истина;
   Форма.ЭлементыФормы.СправочникСписок.НастройкаОтбора.ТипШаблона.Доступность = Ложь;
   
   Если ОткрыватьМодально Тогда
      Возврат Форма.ОткрытьМодально();
   Иначе
      Форма.Открыть();
      Возврат Неопределено;
   КонецЕсли;

КонецФункции

// В поле ввода вывести текст
//
Процедура ВывестиТекстВПолеВвода(ТипШаблона, ПолеВвода, Текст)

   Если ТипШаблона = Перечисления.ТипыШаблонов.Текстовый Тогда
      Если ТипЗнч(ПолеВвода) = Тип("ПолеТекстовогоДокумента") Тогда
         ПолеВвода.ВыделенныйТекст = Текст;
      Иначе
         selection = ПолеВвода.document.selection.CreateRange();
         selection.text = Текст;
      КонецЕсли;
   Иначе
      Если ТипЗнч(ПолеВвода) = Тип("ПолеТекстовогоДокумента") Тогда
         ПолеВвода.ВыделенныйТекст = ИзHTMLПолучитьТекст(Текст);
      Иначе
         selection = ПолеВвода.document.selection.CreateRange();
         selection.pasteHTML(Текст);
      КонецЕсли;
   КонецЕсли;

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

////////////////////////////////////////////////////////////////////////////////
// ЗАПОЛНЕНИЕ В ТЕКСТОВЫХ ШАБЛОНАХ

// Обработчик нажатия на кнопку в меню шаблонов формы
//
Процедура ОбработатьНажатиеНаДополнительнуюКнопкуШаблоновТекста(Форма, КнопкиШаблоновТекста, Кнопка, Объект, ПолеВывода = Неопределено) Экспорт

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

// Расчитать вычислемые поля в шаблоне и заполнить их значения в поле ввода
//
Процедура ВыполнитьЗаполнениеПоВыбранномуТекстовомуШаблону(ЭлементШаблона, Объект, ПолеВвода)

   ТипШаблона = ЭлементШаблона.ТипШаблона;
   Текст = ЭлементШаблона.Шаблон.Получить();
   
   // Получим список полей которые нужно будет вычислить
   табВычПолей = ПолучитьВычисляемыеПоляИзТекста(?(ТипШаблона = Перечисления.ТипыШаблонов.Текстовый, Текст, ИзHTMLПолучитьТекст(Текст)));
   
   // Получим СКД по характеристикам
   СхемаКомпоновки = ПолучитьСхемуСКДДляПодстановкиВШаблоне(Объект.Метаданные());
   Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
   Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
   ТекстЗапросаПроХарактеристики = ТекстЗапросаКХарактеристикам(СхемаКомпоновки.НаборыДанных[0].Запрос);
   
   // Вычислим значения всех полей
   Для Каждого Стр Из табВычПолей Цикл
      Если Стр.НужноВычислять Тогда
         ИмяПоля = ПолучитьИмяПоляДляВычисленияЗначения(Компоновщик.Настройки.Выбор.ДоступныеПоляВыбора.Элементы, Стр.Поле);
         Если ИмяПоля <> "" Тогда
            Стр.Значение = ВычислитьЗначениеПоляПоПолномуПути(Объект, ИмяПоля, ТекстЗапросаПроХарактеристики)
         КонецЕсли;
      КонецЕсли;
   КонецЦикла;
   
   // Сделаем замены в тексте
   ВыполнитьЗаменыВТекстеПоВычисляемымПолям(табВычПолей, Текст);
   
   // Выведем результат в поле ввода
   ВывестиТекстВПолеВвода(ТипШаблона, ПолеВвода, Текст);

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

// Из имени поля вырезать имена папок заданных в СКД
//
Функция ПолучитьИмяПоляДляВычисленияЗначения(ДоступныеЭлементы, ИмяПоля)

   ПолеСКД = НайтиПолеСКДПоПолномуИмени(ДоступныеЭлементы, ИмяПоля);
   Если ПолеСКД = Неопределено Тогда
      Возврат "";
   КонецЕсли;
   
   НовоеИмя = ИмяПоля;
   Пока ПолеСКД <> Неопределено Цикл
      Если ПолеСКД.Папка Тогда
         Поз = Найти(НовоеИмя, ".");
         НовоеИмя = ?(Поз = 0, "", Сред(НовоеИмя, Поз + 1));
      КонецЕсли;
      ПолеСКД = ПолеСКД.Родитель;
   КонецЦикла;
   
   Возврат НовоеИмя;

КонецФункции // ПолучитьИмяПоляДляВычисленияЗначения()

////////////////////////////////////////////////////////////////////////////////
// ВЫЧИСЛЯЕМЫЕ ПОЛЯ

// Получить пустую таблицу для хранения полей которые требуется вычислить
//
Функция ПолучитьПустуюТаблицуВычисляемыхПолей()

   табВычПолей = Новый ТаблицаЗначений;
   табВычПолей.Колонки.Добавить("Поле",           Новый ОписаниеТипов("Строка"));
   табВычПолей.Колонки.Добавить("Значение");
   табВычПолей.Колонки.Добавить("НужноВычислять", Новый ОписаниеТипов("Булево"));
   табВычПолей.Колонки.Добавить("НомерПоля",      Новый ОписаниеТипов("Число"));
   табВычПолей.Колонки.Добавить("ЗаголовокПоля",  Новый ОписаниеТипов("Строка"));
   
   Возврат табВычПолей;

КонецФункции // ПолучитьПустуюТаблицуВычисляемыхПолей()

// В таблице вычисляемых полей заполнить значения дополнительных полей
//
Процедура ВТаблицеВычисляемыхПолейЗаполнитьДополнительные(табВычПолей)

   текДата = ТекущаяДата();
   Для Каждого Стр Из табВычПолей Цикл
      Если ВРЕГ(Стр.Поле) = ВРЕГ("СистемныеПоля.ТекущаяДатаИВремя") Тогда
         Стр.Значение = Формат(текДата, "ДЛФ=DT");
         
      ИначеЕсли ВРЕГ(Стр.Поле) = ВРЕГ("СистемныеПоля.ТекущаяДата") Тогда
         Стр.Значение = Формат(текДата, "ДФ=dd.MM.yyyy");
         
      ИначеЕсли ВРЕГ(Стр.Поле) = ВРЕГ("СистемныеПоля.ТекущееВремя") Тогда
         Стр.Значение = Формат(текДата, "ДФ=ЧЧ:мм:сс");
         
      ИначеЕсли ВРЕГ(Стр.Поле) = ВРЕГ("СистемныеПоля.ИмяПользователя") Тогда
         Стр.Значение = ИмяПользователя();
         
      Иначе
         Стр.НужноВычислять = Истина;
         
      КонецЕсли;
   КонецЦикла;

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

// Добавить запись в таблицу вычисляемых полей
//
Процедура ДобавитьПолеВТаблицуВычисляемыхПолей(табВычПолей, Поле, НужноВычислять)

   Если табВычПолей.Найти(Поле, "Поле") = Неопределено Тогда
      новСтр = табВычПолей.Добавить();
      новСтр.Поле = Поле;
      новСтр.НужноВычислять = НужноВычислять;
      новСтр.НомерПоля = 0;
   КонецЕсли;

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

// Из строки шаблона добавить все вычисляемые поля в таблицу
//
Процедура ДобавитьПоляИзТекстаВТаблицуВычисляемыхПолей(табВычПолей, Текст)

   Для Сч = 1 По СтрЧислоСтрок(Текст) Цикл
      Стр = СтрПолучитьСтроку(Текст, Сч);
      
      Пока Истина Цикл
         Поз = Найти(Стр, "%%");
         Если Поз = 0 Тогда
            Прервать;
         КонецЕсли;
         Стр = Сред(Стр, Поз + 2);
         
         Поз = Найти(Стр, "%%");
         Если Поз = 0 Тогда
            Прервать;
         КонецЕсли;
         Поле = Лев(Стр, Поз-1);
         Стр = Сред(Стр, Поз+2);
         
         ДобавитьПолеВТаблицуВычисляемыхПолей(табВычПолей, Поле, Ложь);
      КонецЦикла;
      
   КонецЦикла;

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

// По тексту шаблона создать таблицу с вычисляемыми полями
//
Функция ПолучитьВычисляемыеПоляИзТекста(Текст)

   табВычПолей = ПолучитьПустуюТаблицуВычисляемыхПолей();
   ДобавитьПоляИзТекстаВТаблицуВычисляемыхПолей(табВычПолей, Текст);
   ВТаблицеВычисляемыхПолейЗаполнитьДополнительные(табВычПолей);
   
   Возврат табВычПолей;

КонецФункции // ПолучитьВычисляемыеПоляИзТекста()

// По табличному шаблону создать таблицу с вычисляемыми полями
//
Функция ПолучитьВычисляемыеПоляИзТаблицы(Таб)

   табВычПолей = ПолучитьПустуюТаблицуВычисляемыхПолей();
   
   Для СчСтр = 1 По Таб.ВысотаТаблицы Цикл
      Для СчКол = 1 По Таб.ШиринаТаблицы Цикл
         ДобавитьПоляИзТекстаВТаблицуВычисляемыхПолей(табВычПолей, Таб.Область(СчСтр, СчКол).Текст);
      КонецЦикла;
   КонецЦикла;
   
   ВТаблицеВычисляемыхПолейЗаполнитьДополнительные(табВычПолей);
   
   Возврат табВычПолей;

КонецФункции // ПолучитьВычисляемыеПоляИзТаблицы()

// В строке с вычисляемыми полями выполнить замены значений
//
Процедура ВыполнитьЗаменыВТекстеПоВычисляемымПолям(табВычПолей, Текст, СтрокаФормата = "") Экспорт

   Для Каждого Стр Из табВычПолей Цикл
      СтрЗн = ?(ПустаяСтрока(СтрокаФормата), Стр.Значение, Формат(Стр.Значение, СтрокаФормата));
      Текст = СтрЗаменить(Текст, "%%" + Стр.Поле + "%%", СтрЗн);
   КонецЦикла;
   
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// РАБОТА С СКД

// Для объекта получить макет СКД для подстановки в шаблоне
//
Функция ПолучитьСхемуСКДДляПодстановкиВШаблоне(МетаданныеОбъекта, ИмяМакета = "") Экспорт

   Имя = МетаданныеОбъекта.Имя;
   Если ПустаяСтрока(ИмяМакета) Тогда
      ИмяМакета = "ПоляШаблона";
   КонецЕсли;
   
   Если Метаданные.Справочники.Содержит(МетаданныеОбъекта) Тогда
      Возврат Справочники[Имя].ПолучитьМакет(ИмяМакета);
      
   ИначеЕсли Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
      Возврат Документы[Имя].ПолучитьМакет(ИмяМакета);
      
   ИначеЕсли Метаданные.Отчеты.Содержит(МетаданныеОбъекта) Тогда
      Возврат Отчеты[Имя].ПолучитьМакет(ИмяМакета);
      
   ИначеЕсли Метаданные.Обработки.Содержит(МетаданныеОбъекта) Тогда
      Возврат Обработки[Имя].ПолучитьМакет(ИмяМакета);
      
   Иначе
      Возврат Неопределено;
      
   КонецЕсли;

КонецФункции // ПолучитьСхемуСКДДляПодстановкиВШаблоне()

// Среди элементов полей СКД найти поле по имени
//
Функция НайтиПолеСКДПоИмени(Элементы, Имя, Кэш = Неопределено)

   Если Кэш <> Неопределено Тогда
      Элемент = Кэш.Получить(Имя);
      Если Элемент <> Неопределено Тогда
         Возврат Элемент;
      КонецЕсли;
   КонецЕсли;
   
   Для Каждого Элемент Из Элементы Цикл
      Если ВРЕГ(Строка(Элемент.Поле)) = ВРЕГ(Имя) Тогда
         
         Если Кэш <> Неопределено Тогда
            Кэш.Вставить(Имя, Элемент);
         КонецЕсли;
         
         Возврат Элемент;
      КонецЕсли;
   КонецЦикла;
   
   Возврат Неопределено;

КонецФункции // НайтиПолеСКДПоИмени()

// Найти поле СКД по полному имени
//
Функция НайтиПолеСКДПоПолномуИмени(Элементы, ПолноеИмя, Кэш = Неопределено) Экспорт

   Если Кэш <> Неопределено Тогда
      Поле = Кэш.Получить(ПолноеИмя);
      Если Поле <> Неопределено Тогда
         Возврат Поле;
      КонецЕсли;
   КонецЕсли;
   
   масЧастейИмен = ИзПолногоИмениПоляПолучитьЧасти(ПолноеИмя);
   колЧастей = масЧастейИмен.Количество();
   
   текИмя = масЧастейИмен[0];
   Поле = НайтиПолеСКДПоИмени(Элементы, текИмя, Кэш);
   Если Поле = Неопределено Тогда
      Возврат Неопределено;
   КонецЕсли;
   
   Для Сч = 2 По колЧастей Цикл
      текИмя = текИмя +"." + масЧастейИмен[Сч-1];
      Поле = НайтиПолеСКДПоИмени(Поле.Элементы, текИмя, Кэш);
      Если Поле = Неопределено Тогда
         Возврат Неопределено;
      КонецЕсли;
   КонецЦикла;
   
   Если Кэш <> Неопределено Тогда
      Кэш.Вставить(ПолноеИмя, Поле);
   КонецЕсли;
   
   Возврат Поле;

КонецФункции // НайтиПолеСКДПоПолномуИмени()

// Вычислить значение поля объекта по полному пути
//
Функция ВычислитьЗначениеПоляПоПолномуПути(Объект, Путь, ТекстЗапросаПроХарактеристики) Экспорт

   масЧастейИмен = ИзПолногоИмениПоляПолучитьЧасти(Путь);
   колЧастей = масЧастейИмен.Количество();
   
   ПервоеЗначение = ПолучитьЗначениеРеквизитаОбъекта(Объект, масЧастейИмен[0]);
   Если Не ЗначениеЗаполнено(ПервоеЗначение) ИЛИ колЧастей = 1 Тогда
      Возврат ПервоеЗначение;
   КонецЕсли;
   
   Если (НЕ Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(ПервоеЗначение)))
      И (НЕ Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(ПервоеЗначение)))
      И (НЕ ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипЗнч(ПервоеЗначение)))
      И (НЕ ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(ТипЗнч(ПервоеЗначение)))
      И (НЕ ПланыСчетов.ТипВсеСсылки().СодержитТип(ТипЗнч(ПервоеЗначение))) Тогда
      ИмяМетаданных = ПервоеЗначение.Метаданные().ПолноеИмя();
      
      Возврат "";
   КонецЕсли;
   
   ИмяМетаданных = ПервоеЗначение.Метаданные().ПолноеИмя();
   
   ТекстЗапроса = "ВЫБРАТЬ Таблица.Ссылка ИЗ " + ИмяМетаданных + " КАК Таблица
   |" + ТекстЗапросаПроХарактеристики;
   
   
   СКД = Новый СхемаКомпоновкиДанных;
   
   Источник = СКД.ИсточникиДанных.Добавить();
   Источник.Имя = "ИсточникДанных1";
   Источник.ТипИсточникаДанных = "Local";
   
   Набор = СКД.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
   Набор.Имя = "НаборДанных1";
   Набор.ИсточникДанных = "ИсточникДанных1";
   Набор.Запрос = ТекстЗапроса;
   
   Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
   Поле.ПутьКДанным = "Ссылка";
   Поле.Поле = "Ссылка";
   
   Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
   Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СКД));
   
   текИмя = "Ссылка";
   Поле = НайтиПолеСКДПоИмени(Компоновщик.Настройки.Выбор.ДоступныеПоляВыбора.Элементы, текИмя);
   Если Поле = Неопределено Тогда
      Возврат Неопределено;
   КонецЕсли;
   ПолеСсылка = Поле;
   
   Для Сч = 2 По колЧастей Цикл
      текИмя = текИмя +"." + масЧастейИмен[Сч-1];
      Поле = НайтиПолеСКДПоИмени(Поле.Элементы, текИмя);
      Если Поле = Неопределено Тогда
         Возврат Неопределено;
      КонецЕсли;
   КонецЦикла;
   
   ВыбранноеПоле = Компоновщик.Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
   ВыбранноеПоле.Поле = Поле.Поле;
   
   ДобавитьОтборВНастройкиСКД(Компоновщик.Настройки, ПолеСсылка.Поле, ПервоеЗначение, ВидСравненияКомпоновкиДанных.Равно);
   ДобавитьАвтоГруппировкуВНастройкиСКД(Компоновщик.Настройки);
   
   КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
   МакетКомпоновки = КомпоновщикМакета.Выполнить(СКД, Компоновщик.Настройки,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
   
   ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
   ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
   
   Пока Истина Цикл
      ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
      Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
         Прервать;
      КонецЕсли;
      
      Значения = ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров;
      Если Значения.Количество() > 0 Тогда
         
         Для Каждого Значение Из Значения Цикл
            Возврат Значение.Значение;
         КонецЦикла;
      КонецЕсли;
   КонецЦикла;
   
   Возврат Неопределено;

КонецФункции // ВычислитьЗначениеПоляПоПолномуПути()

// Из текста запроса получить текст про характеристики
//
Функция ТекстЗапросаКХарактеристикам(ТекстЗапроса)
   
   Поз = Найти(ВРег(ТекстЗапроса), "{ХАРАКТЕРИСТИКИ");
   Возврат ?(Поз = 0, "", Сред(ТекстЗапроса, Поз));
   
КонецФункции // ТекстЗапросаКХарактеристикам()

sandro1


// В настройки СКД добавить автогруппировку
//
Процедура ДобавитьАвтоГруппировкуВНастройкиСКД(Настройки)

   Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
   Группировка.Использование = Истина;
   Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));

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

// В настройки СКД добавить отбор
//
Функция ДобавитьОтборВНастройкиСКД(Настройки, Поле, Значение, ВидСравнения)

   ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
   ЭлементОтбора.Использование = Истина;
   ЭлементОтбора.ЛевоеЗначение = Поле;
   ЭлементОтбора.ПравоеЗначение = Значение;
   ЭлементОтбора.ВидСравнения = ВидСравнения;
   
   Возврат ЭлементОтбора;

КонецФункции

////////////////////////////////////////////////////////////////////////////////
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ

// Полное имя поля разделить по частям
//
Функция ИзПолногоИмениПоляПолучитьЧасти(ПолноеИмя)

   масЧастей = Новый Массив;
   СтрИмя = ПолноеИмя;
   
   Пока Не ПустаяСтрока(СтрИмя) Цикл
      Если Лев(СтрИмя, 1) = "[" Тогда
         
         Поз = Найти(СтрИмя, "]");
         Если Поз = 0 Тогда
            масЧастей.Добавить(Сред(СтрИмя, 2));
            СтрИмя = "";
         Иначе
            масЧастей.Добавить(Сред(СтрИмя, 1, Поз));
            СтрИмя = Сред(СтрИмя, Поз + 2);
         КонецЕсли;
         
      Иначе
         
         Поз = Найти(СтрИмя, ".");
         Если Поз = 0 Тогда
            масЧастей.Добавить(СтрИмя);
            СтрИмя = "";
         Иначе
            масЧастей.Добавить(Лев(СтрИмя, Поз - 1));
            СтрИмя = Сред(СтрИмя, Поз + 1);
         КонецЕсли;
      КонецЕсли;
   КонецЦикла;
   
   Возврат масЧастей;

КонецФункции // ИзПолногоИмениПоляПолучитьЧасти()

// Получить значение реквизита объекта
//
Функция ПолучитьЗначениеРеквизитаОбъекта(Объект, Реквизит)

   Если Реквизит = "Код" Тогда
      Возврат Объект.Код;
   ИначеЕсли Реквизит = "Ссылка" Тогда
      Возврат Объект.Ссылка;
   ИначеЕсли Реквизит = "Номер" Тогда
      Возврат Объект.Номер;
   ИначеЕсли Реквизит = "Наименование" Тогда
      Возврат Объект.Наименование;
   ИначеЕсли Реквизит = "Проведен" Тогда
      Возврат Объект.Проведен;
   ИначеЕсли Реквизит = "Родитель" Тогда
      Возврат Объект.Родитель;
   ИначеЕсли Реквизит = "Владелец" Тогда
      Возврат Объект.Владелец;
   Иначе
      Возврат Объект[Реквизит];
   КонецЕсли;

КонецФункции // ПолучитьЗначениеРеквизитаОбъекта()

// Из HTML текста получить текст без тэгов
//
Функция ИзHTMLПолучитьТекст(Текст)

   НовыйHTMLДокумент = Новый COMОбъект("HtmlFile");
   НовыйHTMLДокумент.open("text/html");
   НовыйHTMLДокумент.write(Текст);
   НовыйHTMLДокумент.close();
   
   Возврат НовыйHTMLДокумент.all.tags("html").item(0).innerText;

КонецФункции // ИзHTMLПолучитьТекст()

////////////////////////////////////////////////////////////////////////////////
// ЗАПОЛНЕНИЕ В ТАБЛИЧНЫХ ШАБЛОНАХ

// Выполнить подготовку перед заполнением табличного шаблона
//
Функция ПодготовитьсяКЗаполнениюТабличногоШаблона(МетаданныеОбъекта, МакетТабДокумента, ОбязательныеПоляДляВычисления = Неопределено, ЗаменяемыйТекстЗапросаСКД = "") Экспорт

   НастройкиФормирования = Новый Структура;
   
   // Получим макет СКД
   СхемаСКД = ПолучитьСхемуСКДДляПодстановкиВШаблоне(МетаданныеОбъекта);
   
   // Если нужно, заменим текст запроса СКД
   Если Не ПустаяСтрока(ЗаменяемыйТекстЗапросаСКД) Тогда
      СхемаСКД.НаборыДанных[0].Запрос = ЗаменяемыйТекстЗапросаСКД + Символы.ПС + ТекстЗапросаКХарактеристикам(СхемаСКД.НаборыДанных[0].Запрос);
   КонецЕсли;
   
   // Получим макет табличного документа
   // Получим список полей которые нужно будет вычислить
   табВычПолей = ПолучитьВычисляемыеПоляИзТаблицы(МакетТабДокумента);
   
   // Добавим обязательные для вычисления поля
   Если ОбязательныеПоляДляВычисления <> Неопределено Тогда
      Для Каждого Поле Из ОбязательныеПоляДляВычисления Цикл
         ДобавитьПолеВТаблицуВычисляемыхПолей(табВычПолей, Поле, Истина);
      КонецЦикла;
   КонецЕсли;
   
   // Подготовим компоновщик
   Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
   Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаСКД));
   
   // Каждое поле, которое нужно вычислить через СКД, добавим в список выбранных полей
   СчПолей = 0;
   Для Каждого Стр Из табВычПолей Цикл
      Если Стр.НужноВычислять Тогда
         ПолеСКД = НайтиПолеСКДПоПолномуИмени(Компоновщик.Настройки.Выбор.ДоступныеПоляВыбора.Элементы, Стр.Поле);
         Если ПолеСКД = Неопределено Тогда
            Сообщить("Указанное в шаблоне поле <"+Стр.Поле+"> не найдено", СтатусСообщения.Важное);
            Возврат Неопределено;
         КонецЕсли;
         
         СчПолей = СчПолей + 1;
         ВыбранноеПоле = Компоновщик.Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
         ВыбранноеПоле.Поле = ПолеСКД.Поле;
         ВыбранноеПоле.Заголовок = "Поле" + Формат(СчПолей, "ЧРГ=");
         
         Стр.НомерПоля = Компоновщик.Настройки.Выбор.Элементы.Количество();
         Стр.ЗаголовокПоля = ВыбранноеПоле.Заголовок;
      КонецЕсли;
   КонецЦикла;
   
   ДобавитьАвтоГруппировкуВНастройкиСКД(Компоновщик.Настройки);

   НастройкиФормирования.Вставить("СхемаСКД",    СхемаСКД);
   НастройкиФормирования.Вставить("табВычПолей", табВычПолей);
   НастройкиФормирования.Вставить("Компоновщик", Компоновщик);
   НастройкиФормирования.Вставить("МакетТабДокумента", МакетТабДокумента);
   
   Возврат НастройкиФормирования;

КонецФункции // ПодготовитьсяКЗаполнениюТабличногоШаблона()

// Подготовить процессор компоновки данных
//
Процедура ПодготовитьПроцессорКомпоновкиДанных(НастройкиФормирования) Экспорт

   КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
   МакетКомпоновки = КомпоновщикМакета.Выполнить(НастройкиФормирования.СхемаСКД, НастройкиФормирования.Компоновщик.Настройки,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
   
   ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
   ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
   
   НастройкиФормирования.Вставить("ПроцессорКомпоновкиДанных", ПроцессорКомпоновкиДанных);

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

// Из процессора компоновки получить значения вычисляемых полей
//
Функция ИзПроцессораКомпоновкиПолучитьВычисляемыеПоля(НастройкиФормирования) Экспорт

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

КонецФункции // ИзПроцессораКомпоновкиПолучитьВычисляемыеПоля()

// Добавить отбор в СКД по полному имени поля
//
Функция ДобавитьОтборВСКДПоПолномуИмениПоля(НастройкиФормирования, ИмяПоля, ВидСравнения, ЗначениеОтбора) Экспорт

   ПолеСсылка = НайтиПолеСКДПоПолномуИмени(НастройкиФормирования.Компоновщик.Настройки.ДоступныеПоляОтбора.Элементы, ИмяПоля);
   Возврат ДобавитьОтборВНастройкиСКД(НастройкиФормирования.Компоновщик.Настройки, ПолеСсылка.Поле, ЗначениеОтбора, ВидСравнения);

КонецФункции

// Получить и заполнить вычисленными значениями область для вывода табличного шаблона
//
Функция ПолучитьОбластьДляВыводаТабличногоШаблона(НастройкиФормирования) Экспорт

   ИмяОбласти = НастройкиФормирования.МакетТабДокумента.ОбластьПечати.Имя;
   Область = НастройкиФормирования.МакетТабДокумента.ПолучитьОбласть(ИмяОбласти);
   
   Для СчК = 1 По Область.ШиринаТаблицы Цикл
      Для СчС = 1 По Область.ВысотаТаблицы Цикл
         Ячейка = Область.Область(СчС, СчК);
         
         // Сделаем замены в тексте
         ВыполнитьЗаменыВТекстеПоВычисляемымПолям(НастройкиФормирования.табВычПолей, Ячейка.Текст, Ячейка.Формат)
      КонецЦикла;
   КонецЦикла;
   
   Возврат Область;

КонецФункции // ПолучитьОбластьДляВыводаТабличногоШаблона()

// Получить вычисленное поле шаблона по имени
//
Функция ПолучитьВычисленноеПолеШаблонаПоИмени(НастройкиФормирования, ИмяПоля) Экспорт

   Стр = НастройкиФормирования.табВычПолей.Найти(ИмяПоля, "Поле");
   Возврат ?(Стр = Неопределено, Неопределено, Стр.Значение);

КонецФункции // ПолучитьВычисленноеПолеШаблонаПоИмени()

// В таблице вычисляемых полей заполнить колонку Значение по результатам выборки
//
Процедура ЗаполнитьТаблицуВычисляемыхПолейПоРезультату(СтрРезультат, КолонкиТабРезультат, ТабВычПолей) Экспорт

   Для Каждого Стр Из ТабВычПолей Цикл
      
      Если Стр.НужноВычислять Тогда
         
         Номер = Стр.НомерПоля;
         Если (Номер > 0) И (Номер <= КолонкиТабРезультат.Количество()) Тогда
            Стр.Значение = СтрРезультат.Получить(Номер - 1);
         Иначе
            Стр.Значение = Неопределено;
         КонецЕсли;
         
      КонецЕсли;
      
   КонецЦикла;

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

// Процедура открывает форму списка шаблонов ценников и этикеток
//
//  Параметры:
//   Нет
Процедура ОткрытьСписокШаблонов() Экспорт
   
   Форма = Справочники.ХранилищеШаблонов.ПолучитьФормуСписка();
   Форма.СправочникСписок.Отбор.ТипШаблона.Установить(Перечисления.ТипыШаблонов.Табличный);
   Форма.ЭлементыФормы.СправочникСписок.НастройкаОтбора.ТипШаблона.Доступность = Ложь;
   
   Форма.СправочникСписок.Отбор.Объект.Установить("Обработка.ПечатьЭтикетокИЦенников");
   Форма.ЭлементыФормы.СправочникСписок.НастройкаОтбора.Объект.Доступность = Ложь;
   
   Форма.Открыть();
   
КонецПроцедуры

// Процедура - обработчик события "При открытии" Формы списка шаблонов
//
//  Параметры:
//   Нет
Процедура ВФормеСпискаШаблоновПриОткрытии(ЭлементыФормы, СправочникСписок) Экспорт
   
   Если СправочникСписок.Отбор.Объект.Использование Тогда
      ЭлементыФормы.СправочникСписок.Колонки.Объект.Видимость = Ложь;
   КонецЕсли;
   
   Если СправочникСписок.Отбор.ТипШаблона.Использование Тогда
      ЭлементыФормы.СправочникСписок.Колонки.ТипШаблона.Видимость = Ложь;
   КонецЕсли;
   
КонецПроцедуры

// Процедура - обработчик события "Перед началом добавления" Формы списка шаблонов
//
//  Параметры:
//   Нет
Процедура ВФормеСпискаШаблоновПередНачаломДобавления(СправочникСписок, МакетДляНовыхШаблонов, Отказ) Экспорт
   
   Если СправочникСписок.Отбор.Объект.Использование Тогда
      
      Отказ = Истина;
      
      Форма = Справочники.ХранилищеШаблонов.ПолучитьФормуНовогоЭлемента();
      Форма.Объект     = СправочникСписок.Отбор.Объект.Значение;
      Если СправочникСписок.Отбор.ТипШаблона.ВидСравнения = ВидСравнения.Равно Тогда
         Форма.ТипШаблона = СправочникСписок.Отбор.ТипШаблона.Значение;
      КонецЕсли;
      Форма.МакетДляНовыхШаблонов = МакетДляНовыхШаблонов;
      Форма.Открыть();
      
   ИначеЕсли СправочникСписок.Отбор.ТипШаблона.Использование
           И СправочникСписок.Отбор.ТипШаблона.ВидСравнения = ВидСравнения.Равно Тогда
      
      Отказ = Истина;
      
      Форма = Справочники.ХранилищеШаблонов.ПолучитьФормуНовогоЭлемента();
      Форма.ТипШаблона = СправочникСписок.Отбор.ТипШаблона.Значение;
      Форма.МакетДляНовыхШаблонов = МакетДляНовыхШаблонов;
      Форма.Открыть();
      
   КонецЕсли;   
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ЗАПОЛНЕНИЕ В ИЕРАРХИЧЕСКИХ ШАБЛОНАХ

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

   РезультатЗапроса = Новый ДеревоЗначений;
   
   Если СхемаКомпоновкиДанных = Неопределено ИЛИ Компоновщик = Неопределено Тогда
      СхемаКомпоновкиДанных = ПолучитьСхемуСКДДляПодстановкиВШаблоне(Ссылка.Метаданные(), ИмяМакета);
   КонецЕсли;
      
   Если  Компоновщик = Неопределено Тогда
      // Подготовка компоновщика макета компоновки данных
      Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
      Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
   КонецЕсли;
   
   Компоновщик.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
   
   // Переносим настройки выбранных полей из настроек шаблона
   Кэш = Новый Соответствие;
   ИдентификаторыПолейСКД = ПолучитьИдентификаторыПолейСКД(ШаблонЧека);
   Для каждого ЭлементСтруктуры Из ИдентификаторыПолейСКД Цикл
      ДобавитьВыбранноеПолеСКД(Компоновщик, ЭлементСтруктуры.Значение, ЭлементСтруктуры.Ключ, Кэш);
   КонецЦикла;
   
   // Отбор по ссылке
   ПолеОтбора = НайтиПолеСКДПоПолномуИмени(Компоновщик.Настройки.Отбор.ДоступныеПоляОтбора.Элементы, "Ссылка");
   Если ПолеОтбора <> Неопределено Тогда
      ДобавитьОтборВНастройкиСКД(Компоновщик.Настройки,ПолеОтбора.Поле, Ссылка, ВидСравненияКомпоновкиДанных.Равно);
   КонецЕсли;
   
   // Компоновка макета СКД
   КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
   МакетСКД = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Компоновщик.Настройки,,,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
   
   Процессор = Новый ПроцессорКомпоновкиДанных;
   Процессор.Инициализировать(МакетСКД);
   
   ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
   ПроцессорВывода.УстановитьОбъект(РезультатЗапроса);
   ПроцессорВывода.Вывести(Процессор);

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

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

sandro1



// Функция генерирует уникальный идентификатор строки дерева шаблона
//
// Параметры
//  Нет
//
// Возвращаемое значение:
//   <Строка>   - Уникальный идентификатор
//
Функция ПолучитьИдентификатор() Экспорт
   
   Возврат "ID"+СтрЗаменить(Новый УникальныйИдентификатор,"-","_");
   
КонецФункции // ПолучитьИдентификатор()

////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МАКЕТОМ ТЕКСТОВОГО ДОКУМЕНТА

// Процедура вставляет в текстовый макет параметры области
//
// Параметры
//  Идентификатор      - <Строка> - Идентификатор области
//  Выравнивание       - <Строка> - Выравнивание в области: Лево, Право, ПоЦентру
//  РазмещениеТекста   - <Число> - Размещение текста в области: Переносить, Обрещать или Забивать
//  Формат             - <Строка> - Форматная строка области
//  ТекстовыйДокумент  - <ТекстовыйДокумент> - Макет текстового документа
//
Процедура ВставитьПараметрыОбласти(Идентификатор, Выравнивание = "Лево", РазмещениеТекста = 0, Формат = "", ТекстовыйДокумент)
   
   // Значения параметра "РазмещениеТекста":
   //  2 - Забивать
   //  1 - Обрезать
   //  0 - Переносить
   
   Если ЗначениеЗаполнено(Выравнивание)
      ИЛИ РазмещениеТекста = 2
      ИЛИ ЗначениеЗаполнено(Формат) Тогда
      ТекстовыйДокумент.ДобавитьСтроку(Символы.Таб+"#Поле " +Идентификатор);
   КонецЕсли;
   
   Если ЗначениеЗаполнено(Выравнивание) Тогда
      ТекстовыйДокумент.ДобавитьСтроку(Символы.Таб+Символы.Таб+"#Выравнивание "+Выравнивание);
   КонецЕсли;
   
   Если РазмещениеТекста = 2 Тогда
      ТекстовыйДокумент.ДобавитьСтроку(Символы.Таб+Символы.Таб+"#Забивать Истина");
   КонецЕсли;
   
   Если ЗначениеЗаполнено(Формат) Тогда
      ТекстовыйДокумент.ДобавитьСтроку(Символы.Таб+Символы.Таб+"#Формат "+""""+Формат+"""");
   КонецЕсли;
   
КонецПроцедуры // ВставитьПараметрыОбласти()

// Процедура вставляет в текстовый макет блок начала области
//
// Параметры
//  Идентификатор      - <Строка> - Идентификатор области
//  ТекстовыйДокумент  - <ТекстовыйДокумент> - Макет текстового документа
//
Процедура ВставитьНачалоОбласти(Идентификатор, ТекстовыйДокумент)
   ТекстовыйДокумент.ДобавитьСтроку("#Область "+Идентификатор);
   ТекстовыйДокумент.ДобавитьСтроку("#ЗаменаСимвола "+"""@"" ""#""");
КонецПроцедуры

// Процедура вставляет в текстовый макет блок окончания области
//
// Параметры
//  Идентификатор      - <Строка> - Идентификатор области
//  ТекстовыйДокумент  - <ТекстовыйДокумент> - Макет текстового документа
//
Процедура ВставитьКонецОбласти(ТекстовыйДокумент)
   ТекстовыйДокумент.ДобавитьСтроку("#КонецОбласти");
КонецПроцедуры

// Процедура генерирует пустные строки необходимой ширины
//
// Параметры
//  Идентификатор      - <Строка> - Идентификатор области
//  ТекстовыйДокумент  - <ТекстовыйДокумент> - Макет текстового документа
//
Функция ВставитьШиринуКолонки(Строка, Структура)
   
   Перем Ширина;
   Пробелы = "";
   
   Пробелы50 = "                                                  ";
   
   Значение = "";
   Структура.Свойство(Строка.Идентификатор,Значение);
   
   // Минимальная ширина колонки = 2 символам
   
   // Ширина колонки не задана
   Если Строка.Ширина = 0 Тогда
      
      Ширина = СтрДлина(СокрЛП(Значение)) - 2;
      Если Ширина >= -1 Тогда
         
         n = Цел(Ширина/50);
         Для Счетчик = 0 По n Цикл
            Пробелы = Пробелы +Пробелы50;
         КонецЦикла;
         Пробелы = Лев(Пробелы, Ширина);
         
      КонецЕсли;
      
   // Колонка имеет фиксированную ширину
   Иначе
      
      Ширина = Строка.Ширина - 2;
      Если Строка.Ширина > 2 Тогда
         
         n = Цел(Ширина/50);
         Для Счетчик = 0 По n Цикл
            Пробелы = Пробелы +Пробелы50;
         КонецЦикла;
         Пробелы = Лев(Пробелы, Ширина);
         
      КонецЕсли;
      
      // обрежем строку если для строки стоит флаг Обрезать
      Если Строка.РазмещениеТекста = 1 Тогда
         Структура.Вставить(Строка.Идентификатор, Лев(Значение,Строка.Ширина));
      КонецЕсли;
   КонецЕсли;
   
   //Структура.Пробелы.Вставить(Ширина, Пробелы);
   
   Возврат Пробелы;
   
КонецФункции

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

// Процедура вставляет в текстовый макет блок области
//
// Параметры
//  Область      - <Строка> - Идентификатор области
//  ТекстовыйДокумент  - <ТекстовыйДокумент> - Макет текстового документа
//  Структура  - <Структура> - Структура параметров
//
Процедура ВставитьТелоОбласти(Область, ТекстовыйДокумент, Структура)
   
   Для каждого СтрокаОбласти Из Область.Строки Цикл
      
      ВставитьТелоСтрокиОбласти(СтрокаОбласти, ТекстовыйДокумент, Структура);

   КонецЦикла;
   
КонецПроцедуры

sandro1


// Процедура производит заполнение структуры параметров по строке табличной части
//
// Параметры
//  СтрокаТаблицыЗначений      - <СтрокаТаблицыЗначений> - Строка таблицы значений
//  ШаблонЧека  - <КоллекцияСтрокДереваЗначений> - Коллекция строк дерева значений
//  Структура  - <Структура> - Структура параметров
//
Процедура ЗаполнитьСтруктуруПараметровШаблонаПоСтрокеТЧ(СтрокаТаблицыЗначений, Структура, ШаблонЧека) Экспорт
   
   Индекс = 0;
   ТаблицаЗначений = СтрокаТаблицыЗначений.Владелец();
   Для каждого ЗначениеКолонки Из СтрокаТаблицыЗначений Цикл
      
      ИмяКолонки = ТаблицаЗначений.Колонки[Индекс];
      
      Отбор = Новый Структура;
      Отбор.Вставить("ИмяКолонки",ИмяКолонки.Имя);
      МассивСтрок = ШаблонЧека.Строки.НайтиСтроки(Отбор,Истина);
      Для каждого СтрокаМассива Из МассивСтрок Цикл
         
         // Префикс и постфикс
         Префикс  = СтрокаМассива.Префикс;
         ПостФикс = СтрокаМассива.Постфикс;
         
         // Обработаем Null
         Если ЗначениеКолонки = NULL Тогда
            Значение = ?(СтрокаМассива.СтрокаПустоеЗначение = "","",Префикс) + СтрокаМассива.СтрокаПустоеЗначение + ?(СтрокаМассива.СтрокаПустоеЗначение = "","",ПостФикс);
            Значение = СтрЗаменить(Значение,"¶",Символы.ПС);
            Структура.Вставить(СтрокаМассива.Идентификатор,Значение);
         Иначе
            
            ЗначениеКолонкиЗаполнено = Ложь;
            Если СтрокаМассива.ПустоеЗначение = Неопределено Тогда
               // Необходимо проводить стандартную проверку заполненности значения
               Если ЗначениеЗаполнено(ЗначениеКолонки) Тогда
                   ЗначениеКолонкиЗаполнено = Истина;
               КонецЕсли;
            Иначе
               // Заполненность определяется по неравенству значению ПустоеЗначение
               Если СтрокаМассива.ПустоеЗначение <> ЗначениеКолонки Тогда
                   ЗначениеКолонкиЗаполнено = Истина;
               КонецЕсли;
            КонецЕсли;
            
            Если ЗначениеКолонкиЗаполнено Тогда
               Значение = Формат(ЗначениеКолонки,СтрокаМассива.Формат);
               Значение = СтрЗаменить(Префикс+Значение+ПостФикс,"¶",Символы.ПС);
               Структура.Вставить(СтрокаМассива.Идентификатор,Значение);
            Иначе
               Значение = ?(СтрокаМассива.СтрокаПустоеЗначение = "","",Префикс) + СтрокаМассива.СтрокаПустоеЗначение + ?(СтрокаМассива.СтрокаПустоеЗначение = "","",ПостФикс);
               Значение = СтрЗаменить(Значение,"¶",Символы.ПС);
               Структура.Вставить(СтрокаМассива.Идентификатор,Значение);
            КонецЕсли;
            
         КонецЕсли;
      
      КонецЦикла;
      
      // Для обхода ошибки, возникающей если свойство имеет сложное имя
      Попытка
         Структура.Вставить(ИмяКолонки.Имя, ?(ЗначениеКолонки = NULL, "", ЗначениеКолонки));
      Исключение
      КонецПопытки;
      
      Индекс = Индекс + 1;
      
   КонецЦикла;
   
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ПАРАМЕТРАМИ ИЕРАРХИЧЕСКОГО ШАБЛОНА

// Функция заполняет структуру параметров значениями составных строк
// Рекурсивная функция.
//
// Параметры
//  Шаблон  - <ДеревоЗначений> - Шаблон. В строках шаблона могут находиться параметры
//  Структура  - <Структура> - Структрура, которую необходимо заполнить значениями составных строк
//
// Возвращаемое значение:
//   Структура   - структура параметров
//
Процедура ЗаполнитьСоставныеСтрокиПоСтруктуре(ШаблонЧека, Структура) Экспорт
   
   // Заполняем значения составных полей
   Отбор = Новый Структура;
   Отбор.Вставить("ТипЭлемента","СоставнаяСтрока");
   Массив = ШаблонЧека.Строки.НайтиСтроки(Отбор,Истина);
   
   ТЗ = Новый ТаблицаЗначений;
   ТЗ.Колонки.Добавить("СоставнаяСтрока");
   ТЗ.Колонки.Добавить("Уровень");
   
   // Выбираем составные строки...
   Для каждого СоставнаяСтрока Из Массив Цикл
      НоваяСтрока = ТЗ.Добавить();
      НоваяСтрока.СоставнаяСтрока = СоставнаяСтрока;
      НоваяСтрока.Уровень = СоставнаяСтрока.Уровень();
   КонецЦикла;
   
   ТЗ.Сортировать("Уровень Убыв");
   
   // Выбираем составные строки в порядке возрастания уровней
   Для каждого СтрокаТЗ Из ТЗ Цикл
      
      ЗначениеСоставнойСтроки = "";
      
      // Склеиваем значение составной строки из значений входящих в нее полей
      Для каждого Строка Из СтрокаТЗ.СоставнаяСтрока.Строки Цикл
         
         Если Строка.ТипЭлемента = "СтрокаТекста" И Строка.Вычислять Тогда
            Попытка
               Значение = Вычислить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Строка.Элемент,".",""),"%",""),"Структура","Структура."));
            Исключение
               Значение = "Ошибка вычисления!";
            КонецПопытки;
         Иначе
            Структура.Свойство(Строка.Идентификатор, Значение);
            Если Значение = Неопределено Тогда
               Продолжить;
            КонецЕсли;
         КонецЕсли;
         
         // Форматируем, если задан формат строки
         Если Строка.Формат <> "" И ТипЗнч(Значение) <> Тип("Строка") Тогда
            Значение = Формат(Значение,Строка.Формат);
         КонецЕсли;
         
         ЗначениеСоставнойСтроки = ЗначениеСоставнойСтроки + Значение;
         
      КонецЦикла;
      
      // Проверка на заполненность
      ЗначениеКолонкиЗаполнено = Ложь;
      Если СтрокаТЗ.СоставнаяСтрока.ПустоеЗначение = Неопределено Тогда
         // Необходимо проводить стандартную проверку заполненности значения
         Если ЗначениеЗаполнено(ЗначениеСоставнойСтроки) Тогда
            ЗначениеКолонкиЗаполнено = Истина;
         КонецЕсли;
      Иначе
         // Заполненность определяется по неравенству значению ПустоеЗначение
         Если СтрокаТЗ.СоставнаяСтрока.ПустоеЗначение <> ЗначениеСоставнойСтроки Тогда
            ЗначениеКолонкиЗаполнено = Истина;
         КонецЕсли;
      КонецЕсли;
      
      Если ЗначениеКолонкиЗаполнено Тогда
         ЗначениеСоставнойСтроки = СтрЗаменить(ЗначениеСоставнойСтроки,"¶",Символы.ПС);
         Структура.Вставить(СтрокаТЗ.СоставнаяСтрока.Идентификатор, ЗначениеСоставнойСтроки);
      Иначе
         ЗначениеСоставнойСтроки = СтрЗаменить(СтрокаТЗ.СоставнаяСтрока.СтрокаПустоеЗначение,"¶",Символы.ПС);
         Структура.Вставить(СтрокаТЗ.СоставнаяСтрока.Идентификатор, ЗначениеСоставнойСтроки);
      КонецЕсли;
      
   КонецЦикла;
   
КонецПроцедуры

// Функция заполняет структуру параметров, которые заданы пользователем
// или являются составными строками
// Рекурсивная функция.
//
// Параметры
//  Шаблон  - <ДеревоЗначений> - Шаблон. В строках шаблона могут находиться параметры
//  Структура  - <Структура> - Структрура, которую необходимо заполнить параметрами
//
// Возвращаемое значение:
//   Структура   - структура параметров, которые заданы пользователем
//
Функция ПолучитьИдентификаторыПользовательскихПолей(Шаблон, Структура = Неопределено) Экспорт

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

         Если ЗначениеКолонкиЗаполнено Тогда
            Значение = Префикс+Значение+ПостФикс;
            Значение = СтрЗаменить(Значение,"¶",Символы.ПС);
            Структура.Вставить(Строка.Идентификатор,Префикс+Значение+ПостФикс);
         Иначе
            Значение = ?(Строка.СтрокаПустоеЗначение = "","",Префикс) + Строка.СтрокаПустоеЗначение + ?(Строка.СтрокаПустоеЗначение = "","",ПостФикс);
            Значение = СтрЗаменить(Значение,"¶",Символы.ПС);
            Структура.Вставить(Строка.Идентификатор, Значение);
         КонецЕсли;
         
      КонецЕсли;
      
   КонецЦикла;

   Возврат Структура;
   
КонецФункции

// Функция заполняет структуру параметров, которые необходимо получить в СКД
// Рекурсивная функция.
//
// Параметры
//  Шаблон  - <ДеревоЗначений> - Шаблон. В строках шаблона могут находиться параметры
//  Структура  - <Структура> - Структрура, которую необходимо заполнить параметрами
//
// Возвращаемое значение:
//   Структура   - структура параметров, которые необходимо получить
//                   в системе компоновки данных
//
Функция ПолучитьИдентификаторыПолейСКД(Шаблон, Структура = Неопределено)
   
   Если Структура = Неопределено Тогда
      Структура = Новый Структура;
   КонецЕсли;
   
   Для каждого Строка Из Шаблон.Строки Цикл
      
      Если Строка.ТипЭлемента = "СтрокаТекста" И Строка.Вычислять Тогда
         ВычисляемыеПоля = ПолучитьВычисляемыеПоляИзТекста(Строка.Элемент);
         Если ВычисляемыеПоля.Количество() > 0 Тогда
            Для каждого СтрокаТЗ Из ВычисляемыеПоля Цикл
               Структура.Вставить(ПолучитьИдентификатор(),СтрокаТЗ.Поле);
            КонецЦикла;
         КонецЕсли;
      КонецЕсли;
      
      Если НЕ Строка.ТипЭлемента = "СтрокаДанных" Тогда
         ПолучитьИдентификаторыПолейСКД(Строка, Структура);
      Иначе
         Структура.Вставить(Строка.Идентификатор,СтрЗаменить(Строка.Элемент,"%%",""));
      КонецЕсли;
      
   КонецЦикла;

   Возврат Структура;
   
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ИЕРАРХИЧЕСКИМ ШАБЛОНОМ

// Функция получает макет текстового документа для строки дерева (шаблона)
//
// Параметры
//  <СтрокаДерева>  - <СтрокаДереваЗначений> - строка шаблона
//  <Структура>  - <Структура> - параметры, которые необходимо
//                 подставить в макет шаблона
//
// Возвращаемое значение:
//   <ТекстовыйДокумент>   - Макет текстового документа для строки дерева,
//
Функция ПолучитьМакетДляСтрокиДерева(СтрокаДерева, Структура)
   
   // Кэширование СтрокДерева
   
   ТекстовыйДокумент = Новый ТекстовыйДокумент;
   
   ВставитьНачалоОбласти(СтрокаДерева.Идентификатор, ТекстовыйДокумент);
   
   Если СтрокаДерева.Уровень() = 0 Тогда
      ВставитьТелоОбласти(СтрокаДерева, ТекстовыйДокумент, Структура);
   Иначе
      ВставитьТелоСтрокиОбласти(СтрокаДерева, ТекстовыйДокумент, Структура);
   КонецЕсли;
   
   ВставитьКонецОбласти(ТекстовыйДокумент);
   
   Возврат ТекстовыйДокумент;
   
КонецФункции // ПолучитьМакетДляВетвиДерева()

// Функция выполняет преобразование шаблона (строки дерева) в текстовый документ, заполненный по структуре параметров
//
// Параметры
//  <СтрокаДерева>  - <СтрокаДереваЗначений> - строка шаблона
//  <СтруктураПараметров>  - <Структура> - параметры, которые необходимо
//                 подставить в макет шаблона
//
// Возвращаемое значение:
//   <ТекстовыйДокумент>   - результирующий текстовый документ,
//   полученный по макету для строки дерева
//
Функция ПолучитьТекстовыйДокументДляСтрокиДереваШаблона(СтрокаДерева, СтруктураПараметров)

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

   Возврат ТекстовыйДокумент;
   
КонецФункции // ПолучитьТекстовыйДокументДляСтрокиДереваШаблона()

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

// Функция выполняет преобразование шаблона (строки дерева) в массив текстовых строк, заполненный по структуре параметров
//
// Параметры
//  <СтрокаДерева>  - <СтрокаДереваЗначений> - строка шаблона
//  <СтруктураПараметров>  - <Структура> - параметры, которые необходимо
//                 подставить в макет шаблона
//
// Возвращаемое значение:
//   <Массив>   - результирующий массив текстовых строк,
//   полученный по макету для строки дерева
//
Функция ПолучитьМассивСтрокДляСтрокиДереваШаблона(СтрокаДерева, СтруктураПараметров) Экспорт
   
   ТекстовыйДокумент = ПолучитьТекстовыйДокументДляСтрокиДереваШаблона(СтрокаДерева, СтруктураПараметров);
   Возврат ПреобразоватьТекстовыйДокументВМассивСтрок(ТекстовыйДокумент);
   
КонецФункции


sandro1

Каккие мысли будут. Может всё-таки как то есть способ передать из формы обработки "ПечатьЭтикетокИЦенников"
в печатную форму шаблона следующие значения:

ЭлементОтбора.Значение.Дата       
                                            и
ЭлементОтбора.Значение.Номер

sergeevds

А вот эта ФормаХодВыполнения это что за общая форма, у тебя из нее твоя обработка вызывается?

sandro1

на время выполнения формирования печатной формы с ценниками на экран выводится небольшая такая
форма(из общих) с заголовком окна (формы) - Печать этикеток и ценников с индикатором выполнения,\
потом закрывается и выводится на экран печатная форма.

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск