Форматирование области табличного документа

Программное изменение внешнего вида табличного документа позволяет изменить границу ячейки или области (на примере — пунктирная граница):

ГраницаПунктир = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.РедкийПунктир,1);

ОбластьМакета = Макет.ПолучитьОбласть(«СтрокаТаблицы»);

ОбластьМакета.Область(«R1C4:R1C7»).ГраницаСнизу = ГраницаПунктир;
ОбластьМакета.Область(«R2C4:R2C7»).ГраницаСверху = ГраницаПунктир;
ОбластьМакета.Область(«R1C4:R1C7»).ГраницаСлева = ГраницаПунктир;
ОбластьМакета.Область(«R1C4:R1C7»).ГраницаСправа = ГраницаПунктир;

Так же можно программно объединять ячейки в табличном документе:

ТабДок.Область(«R1C1:R1C4»).Объединить();

Печать на принтере документов Word и Excel из 1Сv8.3

Если требуется немедленная программная печать на принтере по выбору, к примеру,  при распечатке прикрепленных документов. Ниже приведен код, позволяющий распечатать документы Word и Excel:

&НаКлиенте
Процедура ПечатьDOCФайлов(ПутьКФайлу, ИмяПринтера = «»
WordAppl = Новый COMОбъект(«Word.Application»);
WordAppl.Documents.Open(ПутьКФайлу);
WordAppl.Documents(ПутьКФайлу).Activate();
WordAppl.ActivePrinter = ИмяПринтера;
WordAppl.ActiveDocument.PrintOut();
WordAppl.ActiveDocument.close();
КонецПроцедуры

&НаКлиенте
Процедура ПечатьExcelФайлов(ПутьКФайлу, ИмяПринтера = «»)
ExcelAppl = Новый COMОбъект(«Excel.Application»);
ExcelAppl.Workbooks.Open(ПутьКФайлу);
ExcelAppl.ActiveSheet.PrintOut(,,,,ИмяПринтера);
ExcelAppl.WorkBooks.Close();
ExcelAppl.Quit();
КонецПроцедуры

Полезные функции

Выделяет из строки числовые символы и возвращает число
Функция ОставитьЧисловыеСимволыВСтроке(СтрокаСЧислом, ВернутьЧисло=истина)

ДлинаСтроки = СтрДлина(СтрокаСЧислом);
СтрокаФинал = «»;
для й=1 по ДлинаСтроки цикл
ТекСимвол = Сред(СтрокаСЧислом,й,1);
Если ТекСимвол >= «0» и ТекСимвол <= «9» тогда
СтрокаФинал = СтрокаФинал + ТекСимвол;
КонецЕсли;
КонецЦикла;
Возврат ?(ВернутьЧисло, Число(СтрокаФинал), СтрокаФинал);
КонецФункции

Получение описания типа (для динамического добавления колонки в таблицу значений)
Функция ПолучитьОписаниеЦелочисленногоТипа() Экспорт

КЧ = Новый КвалификаторыЧисла(10);
Массив = Новый Массив;
Массив.Добавить(Тип(«Число»));
Возврат Новый ОписаниеТипов(Массив, , ,КЧ);
КонецФункции

Преобразование строки таблицы значений в структуру
Функция СтрокуТЗВСтруктуру(ТЗ, НомерСтроки=0) Экспорт
Стрктура = новый Структура;
для каждого Колонка из ТЗ.Колонки цикл
Стрктура.Вставить(Колонка.Имя, ТЗ[НомерСтроки][Колонка.Имя]);
КонецЦикла;
возврат Стрктура;
КонецФункции

Функция для получения описания типов строки, заданной длины
Функция ПолучитьОписаниеТиповСтроки(ДлинаСтроки
Массив = Новый Массив;
Массив.Добавить(Тип(«Строка»));
КвалификаторСтроки = Новый КвалификаторыСтроки(ДлинаСтроки, ДопустимаяДлина.Переменная);
Возврат Новый ОписаниеТипов(Массив, , КвалификаторСтроки);
КонецФункции

Функция для получения описания типов числа, заданной разрядности
Функция ПолучитьОписаниеТиповЧисла(Разрядность,РазрядностьДробнойЧасти=0
Массив = Новый Массив;
Массив.Добавить(Тип(«Число»));
КвалификаторЧисла = Новый КвалификаторыЧисла(Разрядность,РазрядностьДробнойЧасти);
Возврат Новый ОписаниеТипов(Массив, КвалификаторЧисла);
КонецФункции

Функция для получения описания типов даты
Функция ПолучитьОписаниеТиповДаты(ЧастиДаты
Массив = Новый Массив;
Массив.Добавить(Тип(«Дата»));
КвалификаторДаты = Новый КвалификаторыДаты(ЧастиДаты);
Возврат Новый ОписаниеТипов(Массив, , , КвалификаторДаты);
КонецФункции

Создание дерева в СКД и выгрузка его в дерево значений

Допустим, имеется таблица с товарами и суммами, колонки приведены ниже:
— Идентификатор строки (id)
— Идентификатор строки родителя (idParent)
— Наименование (строка)
— Сумма

id idParent Наименование Сумма (руб.)
1 Монитор 5000
2 Мышь, клавиатура 2000
3 Системный блок
4 3 Материнская плата 10000
5 3 Жесткий диск 3000

Колонка «Наименование» не является справочником и не позволяет автоматически создать иерархию, конечно ее можно создать программно, но это трудоемко, особенно собирать суммы итогов по иерархии. Итак, нам нужно получить дерево значений без особо трудного кодирования. Для начала, создадим СКД и создадим 2 частично одинаковых выборки с данными, как показано на рисунках ниже:

Первая выборка, задающая иерархию

SetIerarh

Вторая выборка, такая же как первая, но содержит больше колонок

SetData

Связи между выборками, образующих дерево

svyaz

Структура итоговых данных — само дерево

report

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

result

Ниже приведен код, позволяющий получить дерево из СКД в переменную «ДеревоЗначений»:

СхемаКомпоновкиДанных = РеквизитФормыВЗначение(«Отчет»).ПолучитьМакет(«МакетДанные»);
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);

НастройкиКомпоновщика = КомпоновщикНастроек.Настройки;
ПараметрыНастройки = НастройкиКомпоновщика.ПараметрыДанных;

// если нужны параметры — устанавливаем так
Параметр = ПараметрыНастройки.Элементы.Найти(«Дата»);
Параметр.Использование = Истина;
Параметр.Значение = Отчет.Дата;

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновщика, , , Тип(«ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений»));
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ДеревоЗначений = Новый ДеревоЗначений;
ПроцессорВывода.УстановитьОбъект(ДеревоЗначений);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

Как изменить представление документа в 1С v 8.3

Допустим для документа Реализация товаров услуг нужно настроить представление в виде «Реализация т/у № 150 от 20.05.2016 (Контрагент: ООО Альфа)». Для этого в модуле менеджера объекта документа создаем обработчики событий получения представления и полей представления:

Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
Представление = «Реализация т/у № « + Данные.Номер + » от « + Формат(Данные.Дата,«ДФ=dd.MM.yyyy») + » (Контрагент: «+Строка(Данные.Контрагент)+«)»;
СтандартнаяОбработка=Ложь;
КонецПроцедуры

Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
Поля.Добавить(«Номер»);
Поля.Добавить(«Дата»);
Поля.Добавить(«Контрагент»);
СтандартнаяОбработка=Ложь;
КонецПроцедуры

Проверка принадлежности элемента иерархии

Проверять принадлежность элемента справочника вышестоящему элементу или группе можно двумя способами:
1. Запросом
2. Программно

Допустим надо проверить принадлежность некоторого элемента ПодчиненныйКонтрагент справочника Контрагенты элементу ГлавныйКонтрагент этого же справочника.

Запросом

Наличие хотя бы одной записи в запросе говорит о том, что элемент ПодчиненныйКонтрагент подчинен элементу или группе ГлавныйКонтрагент:

Запрос = новый Запрос(«Выбрать
|Контрагенты.Ссылка
|    из
|Справочник.Контрагенты как Контрагенты
|    где
|Контрагенты.Ссылка в Иерархи(&ГлавныйКонтрагент) и Контрагенты.Ссылка |= &ПодчиненныйКонтрагент»);

Запрос.УстановитьПараметр(«ГлавныйКонтрагент», ГлавныйКонтрагент);
Запрос.УстановитьПараметр(«ПодчиненныйКонтрагент»ПодчиненныйКонтрагент);
Если Запрос.Выполнить().Выбрать().Следующий() тогда
    Сообщить(«Элемент подчинен»);
Иначе
    Сообщить(«Элемент НЕ подчинен»);
КонецЕсли;

Программно

Легче данную операцию сделать программно, для этого используется процедура ПринадлежитЭлементу элемента справочника:

Если ПодчиненныйКонтрагент.ПринадлежитЭлементу(ГлавныйКонтрагент) тогда
    Сообщить(«Элемент подчинен»);
Иначе
    Сообщить(«Элемент НЕ подчинен»);
КонецЕсли;

Примечание:
Выражение ГлавныйКонтрагент.ПринадлежитЭлементу(ГлавныйКонтрагент) вернет ЛОЖЬ.

Получение всех типов

Динамическое создание элементов или таблиц значений иногда требует задания всех типов, для этого ниже приведен код возвращающий описание таковых:

// Заполняем массив доступных типов. Из этого массива будет выбираться тип редактируемого значения.
МассивДоступныхТипов = Новый Массив;
МассивДоступныхТипов.Добавить(Тип(Новый ОписаниеТипов(«Число»,Новый КвалификаторыЧисла(22, 5, ДопустимыйЗнак.Любой))));
МассивДоступныхТипов.Добавить(Тип(Новый ОписаниеТипов(«Строка»,,Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная))));
МассивДоступныхТипов.Добавить(Тип(Новый ОписаниеТипов(«Дата»,,,Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя))));
МассивДоступныхТипов.Добавить(Тип(Новый ОписаниеТипов(«Булево»)));

// Добавляем ссылки на справочники
Для Каждого ЭлементТипа Из Справочники.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на документы
Для Каждого ЭлементТипа Из Документы.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на перечисления
Для Каждого ЭлементТипа Из Перечисления.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на ПланыВидовХарактеристик
Для Каждого ЭлементТипа Из ПланыВидовХарактеристик.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на ПланыСчетов
Для Каждого ЭлементТипа Из ПланыСчетов.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на БизнесПроцессы
Для Каждого ЭлементТипа Из БизнесПроцессы.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на точки маршрута
Для Каждого ЭлементТипа Из БизнесПроцессы.ТипВсеСсылкиТочекМаршрутаБизнесПроцессов().типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на Задачи
Для Каждого ЭлементТипа Из Задачи.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на ПланВидовРасчета
Для Каждого ЭлементТипа Из ПланыВидовРасчета.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

// Добавляем ссылки на ПланОбменаСсылка
Для Каждого ЭлементТипа Из ПланыОбмена.ТипВсеСсылки().Типы() Цикл
   МассивДоступныхТипов.Добавить(ЭлементТипа);
КонецЦикла;

Возврат новый ОписаниеТипов(МассивДоступныхТипов);

Динамическое добавление колонки в дерево на управляемой форме 1Сv8.3

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

  1. Получить значение реквизита — ДеревоЗначений
  2. Добавить колонку в дерево значений
  3. Добавить реквизит (колонку) дерева на форму (невидимая часть, справа в редакторе форм)
  4. Выгрузить дерево значений в реквизит формы
  5. Добавить на форму элемент колонку дерева (видимая часть, слева в редакторе форм)

Пример кода:

// 1. получаем дерево как програмный объект
ДеревоОбъект = РеквизитФормыВЗначение(«Дерево»);
// 2. добавляем колонку
ДеревоОбъект.Колонки.Добавить(«Узел», Новый ОписаниеТипов(«Строка»));
// 3. создаем РЕКВИЗИТ КОЛОНКИ (невидимая часть, справа в редакторе форм)
МассивДобавляемыхРеквизитов = Новый Массив;
// реквизит принадлежит дереву
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(«Узел», Новый ОписаниеТипов(«Строка»), «Дерево»));
// добавляем реквизит в форму (невидимая часть, справа в редакторе форм)
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);

// 4. заполняем дерево (реквизит формы) занчением
ЗначениеВРеквизитФормы(ДеревоОбъект, «Дерево»);
// 5. добавляем НА ФОРМУ (видимая часть, слева в редакторе форм)
// назовем ДеревоУзел, принадлежит элементу дерева, связан с добавленной колонкой «Узел»
НовыйЭлемент = Элементы.Добавить(«ДеревоУзел», Тип(«ПолеФормы»), Элементы.Дерево);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = «Дерево.Узел»;

Как проверить тип колонки таблицы значений

Колонка таблицы значений может иметь один или несколько типов, для проверки необходимо использовать функцию СодержитТип() колонки таблицы значений:

Для Каждого КолонкаТЧ из ТЗ.Колонки цикл
   Если КолонкаТЧ .ТипЗначения.СодержитТип(Тип(«ХранилищеЗначения»))
      Тогда
      ПропуститьКолонку = истина;
   КонецЕсли;
КонецЦикла;

 

Получение таблицы динамического списка

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

&НаСервере
Функция Получить_ТЗ_Из_ДинамическогоСписка()
// получаем схему
Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
// получаем настройки
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
// можем добавлять произвольные отборы дополнительно
// НовыйЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
// НовыйЭлементОтбора .ЛевоеЗначение = …
// УстанавливаемыйЭлементОтбора.ВидСравнения = …
//УстанавливаемыйЭлементОтбора.ПравоеЗначение =
// УстанавливаемыйЭлементОтбора.Использование = Истина;

// создаем компоновщик макета и формируем выборку в ТЗ
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных();
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип(«ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений»));

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

ТЗ = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат ТЗ;

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