Варианты применения СКД вне отчетов в отраслевых конфигурациях

18.11.21

Разработка - СКД

Директор и ведущий разработчик компании «Арт Порт» Максим Артеменко выступил на митапе, посвященном практике применения СКД. Максим рассказал о вариантах применения механизма настроек СКД для решения нестандартных задач – визуального оформления, сегментирования данных и автоматического заполнения примечаний к документам.

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

 

 

Нашей группе компаний более 25 лет, и 10 из них мы автоматизируем транспортный и зерновой бизнес.

Находимся на юге Украины, работаем с ближним зарубежьем.

В основном, решаем задачи оперативного и управленческого учета – например, учет экспедирования железнодорожного транспорта, складской учет на зерновых элеваторах, портах и т.д.

Для этих задач мы реализовали 10 отраслевых решений. И сегодня я хочу рассказать об интересных вариантах применения СКД в них.

 

Варианты применения СКД в отраслевых решениях

 

 

У нас в отраслевых решения мы применяем СКД для следующих случаев:

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

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

  • Для оформления табличного документа. У нас есть несколько разработок, где мы с помощью табличного документа выполняем визуализацию вагонов или грузов на складах. Там необходимо использовать условное оформление СКД, чтобы менять цвет, границы различных ячеек схемы и так далее.

 

Визуализация вагонов в табличном документе

 

 

Начнем с визуализации в табличном документе.

У нас есть отраслевая конфигурация по управлению железнодорожным терминалом – она разработана для компаний, выполняющих отгрузку на железнодорожный транспорт. Например, это могут быть глиняные или щебневые карьеры. Им подают пустые вагоны, выполняется погрузка, а затем вагоны отправляются на станцию выгрузки. Второй вариант – портовый терминал: у компании есть локомотивы, и она оказывает услуги по подаче/уборке вагонов и маневровым работам.

5 лет назад у нас заказали визуализацию вагонов, а не просто их учет. В качестве инструмента был выбран табличный документ, потому что тогда через графическую схему реализовать визуализацию в нужном виде не получилось.

Сначала вагоны расцвечивались по жесткому правилу – для клиентов, под которых вагоны подаются, выбирался определенный цвет в справочнике контрагентов.

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

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

Пришли к тому, что в обработке «Рабочее место диспетчера», в которой выполняется сбор вагонов с информацией, которая будет сюда выводиться, используется схема компоновки данных.

 

 

Эта же СКД используется для нового справочника «Варианты оформления вагонов» - в нем хранятся настройки СКД.

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

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    ТекущийОбъект.ПользовательскиеНастройки = Новый ХранилищеЗначения(КомпоновщикНастроек.ПолучитьНастройки());
КонецПроцедуры

Во всех подобных решениях мы используем одинаковый принцип сохранения настроек. Мы это делаем через хранилище значений.

  • У нас в макете обработки «АртсофтАРМДиспетчера» есть схема компоновки данных. В обработчике «ПриСозданииНаСервере» формы справочника «Варианты оформления вагонов», мы из этой обработки через команду ПолучитьМакет получаем схему компоновки данных и помещаем ее во временное хранилище.

  • Адрес этого временного хранилища передается для инициализации компоновщика настроек.

  • В реквизит формы КомпоновщикНастроек загружаются настройки по умолчанию, полученные из схемы.

  • Если это не новый элемент справочника, и пользовательские настройки в нем уже сохранены, мы в КомпоновщикНастроек загружаем их.

  • И потом, в обработчике «ПередЗаписьюНаСервере» происходит сохранение этих пользовательских настроек через хранилище значения.

Я думаю, что этот принцип многие используют.

 

 

В самом справочнике «Варианты оформления отчетов» у нас из всего компоновщика настроек выведено на форму только условное оформление.

Тут, как и в отчетах, пользователь может настроить, для какого отбора какое оформление нужно. Здесь мы настраиваем само условие – как раскрашивать вагоны.

Но пользователь же не будет добавлять для каждого собственника вагона свое условное оформление – если таких элементов будет более 20, это неудобно. Для этого мы реализовали кнопку «Добавить условия по значениям», которая открывает отдельную форму.

 

 

И тут мы второй раз используем СКД: на форму выведено поле «Выбор» из компоновщика настроек – в нем мы можем выбрать поле объекта и потом заполнить табличную часть всеми его возможными значениями.

Работает это так: в поле «Выбор» пользователь выбирает поле определенного перечисления или справочника, нажимает ОК, и в таблице заполняются все возможные значения этого объекта.

 

 

Дальше он добавляет в таблицу колонки с оформлением – цвет фона, цвет границы. Таким образом, итоговую таблицу вариантов оформления вагонов мы формируем намного проще.

Например, мы выбираем в поле «Выбор» значение «Разметка», и тут у нас подставляются все разметки – направления, куда вагон можно отправить (страны СНГ, Россия, Украина и так далее).

По кнопке «Добавить» мы выбираем варианты оформления – например, «Цвет фона», он автоматически заполняется по умолчанию, но оформление каждого значения можно отредактировать.

После этого настройки сохраняются, и я покажу, что происходит с ними дальше.

 

Принцип накладывания условного оформления вагонов

 

После того как мы в «Рабочем месте диспетчера» получаем результат СКД по вагонам, мы рисуем табличный документ и начинаем каждый вагон выводить в цикле:

  • выводим вагон на определенный путь;

  • выводим в ячейку, объединяем;

  • выводим текст;

  • и применяем к каждому вагону на пути полученное оформление.

Разберем код, который отвечает за условное оформление.

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

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

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

  • мы создаем чистый табличный документ;

  • из варианта оформления вагонов, выбранного на форме, получаем вариант настроек (клиент может выбрать раскраску по собственникам, по грузам и т.д.);

  • искусственно добавляем в схему группировку по детальным записям, куда в выбранные поля добавляем поле «Вагон»;

  • далее мы искусственно добавляем в существующее условное оформление отступ 1 – это нужно для того, чтобы мы потом смогли найти конкретные вагоны, которые по условию нужно раскрасить. Потому что даже если в этом табличном документе мы вагоны раскрасили, когда мы выводим их в самой обработке, нам нужно понять, выполняется ли для конкретного вагона условие или нет – чтобы это понять, мы добавляем отступ.

  • выполняем схему компоновки данных с условным оформлением и выводим ее в табличный документ;

  • и дальше этот табличный документ возвращается в кусок кода, где выполняется обработка и вывод этих вагонов

&НаСервере
Функция ПолучитьОформлениеВагона(ВагонПредставление, ТабличныйДокументОформления)
    Оформление = Новый Структура("ГраницаСверху, ГраницаСлева, ГраницаСнизу, ГраницаСправа, Узор, ЦветРамки, ЦветТекста, ЦветУзора, ЦветФона, Шрифт",
                                  АртсофтВизуализацияКлиентСервер.Линия3(), АртсофтВизуализацияКлиентСервер.Линия3(), АртсофтВизуализацияКлиентСервер.Линия3(), АртсофтВизуализацияКлиентСервер.Линия3(),
                                  ТипУзораТабличногоДокумента.БезУзора, WebЦвета.Черный, WebЦвета.Черный, WebЦвета.Белый, WebЦвета.Белый, Новый Шрифт(, 8));
    Область = ТабличныйДокументОформления.НайтиТекст(ВагонПредставление);
    Если Область <> Неопределено Тогда
        Если Область.Отступ = 1 Тогда // Программно установленный отступ 1 - признак выполнения отбора условия оформления
            ЗаполнитьЗначенияСвойств(Оформление, Область);
        КонецЕсли;
        Оформление.Шрифт = Новый Шрифт(Область.Шрифт,, 8);
    КонецЕсли;
    Возврат Оформление;
КонецФункции // ПолучитьОформлениеВагона()

Вот код, где мы получаем оформление для конкретной области табличного документа, куда мы вывели этот вагон.

  • Мы создаем структуру на все необходимые элементы оформления (цвет, граница и т.д.), чтобы потом через «ЗаполнитьЗначенияСвойств» передать все свойства в область.

  • Потом в табличном документе, куда у нас выведен отчетом с раскрашенными вагонами, мы ищем по тексту номер вагона.

  • Если мы его нашли в табличном документе, мы проверяем – действительно ли это вагон, который нам нужен, с отступом 1.

  • Если отступ равен 1, то мы из этой области копируем значения в структуру и эту структуру возвращаем – из нее область, куда мы выводим вагон, получает все параметры оформления.

 

 

В итоге мы получаем вот такой результат – вы видите, что по-разному раскрашены рамки, различается цвет вагонов и так далее.

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

 

Группировка вагонов через выбор полей

 

Второй кейс используется в том же самом «Рабочем месте диспетчера».

 

 

Здесь возникла другая задача: когда диспетчеры работают с вагонами, их интересуют не номера, а группы вагонов. Например, 10 вагонов с пшеницей, 2 пустых вагона и еще 20 вагонов с углем. Поэтому возникла необходимость в группировке вагонов.

Сначала нужно было группировать по клиенту, а потом возникла задача группировать по собственникам и так далее. Этот механизм мы тоже решили реализовать с помощью СКД, но эту задачу мы делали уже чуть-чуть по-другому.

 

 

Суть задачи в том, что в табличном документе нужно свернуть вагоны – показать их в одном квадратике. Допустим, мы хотим показать, что у нас справа стоит пять вагонов с пшеницей, а слева – пять с углем.

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

 

 

Мы решили эту задачу следующим образом – создали отдельный справочник для хранения настроек, назвали его «Варианты группировки вагонов» – в нем, в отличие от предыдущего примера, хранятся списки выбранных полей, по которым мы потом будем группировать.

Когда пользователь выбирает этот вариант группировки, вагоны сворачиваются, и внутри пишется количество вагонов и значения, по которым мы свернули.

 

 

Как это делается? На слайде я привел алгоритм кода.

  • У нас на входе есть настройки: по каким выбранным полям СКД нужно выполнить свертку. Мы берем СКД и программно добавляем в нее один элемент – группировку, которую набираем из выбранных полей в настройках, но уже формируем полноценную программную группировку.

  • Затем внутри группировки мы добавляем еще один параметр: независимо от типа группировки (по собственникам, клиентам и т.д.), нам нужно разбивать вагоны на пустые или груженые. Поэтому дополнительно добавляется еще один признак: пустой или груженый вагон.

  • В детальные записи добавляется сам вагон и результат мы выводим в коллекцию дерево значений.

  • А затем мы начинаем обходить группировки – формируем имя группы, и записываем это все в соответствие. Ключом будет вагон, а значением – идентификатор (наименование) группировки, куда входит вагон.

  • Во время программного вывода вагонов, в случае, если включен режим группировки, мы группируем подряд по совпадению имени группы – если предыдущая группировка вагона такая же, мы его добавляем в группу. Вот так мы накапливаем такие группы и дальше.

 

 

Здесь у нас внизу есть цикл, в котором мы будем обходить эти вагоны.

Но сначала мы создаем соответствие «ГруппыСворачиванияВагонов» и переходим в функцию, которая получает соответствие.

Функция ПолучитьСоответствиеГруппСворачиванияВагонов()

    СхемаКомпоновкиДанных = ПолучитьИзВременногоХранилища(АдресСКДОтбораВагонов);
    Настройки = Построитель.ПолучитьНастройки();

    // Перенос выбранных полей в группировку СКД
    Настройки.Структура.Очистить();

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

    Для каждого Элемент Из НастройкиСворачивания.Выбор.Элементы Цикл

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

    КонецЦикла;

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

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

    ДетальныеЗаписи = ГруппировкаСКД.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
    ДетальныеЗаписи.Имя = "Детальные";
    ДетальныеЗаписи.Использование = Истина;

    ВыбранноеПоле = ДетальныеЗаписи.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
    ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("Вагон");

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

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

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

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

    СоответствиеГруппСворачиванияВагонов = Новый Соответствие;

    Для каждого ТекСтрокаГруппа Из ДеревоГруппВагонов.Строки Цикл

        СтруктураПолей = Новый Структура;
        НаименованиеГруппы = "";
        Для каждого Колонка Из ДеревоГруппВагонов.Колонки Цикл

            Если Колонка.Имя <> "Порожний" Тогда
                Если ТекСтрокаГруппа[Колонка.Имя] = Неопределено Тогда
                    Продолжить;
                Иначе

                    ЗначениеПоля = ТекСтрокаГруппа[Колонка.Имя];
                    ЧастьСтроки = ?(Колонка.ТипЗначения.СодержитТип(Тип("Булево")), Колонка.Имя, ЗначениеПоля);
                    НаименованиеГруппы = НаименованиеГруппы + ?(ПустаяСтрока(НаименованиеГруппы), "", "; ") + ЧастьСтроки;

                КонецЕсли;
            КонецЕсли;
            СтруктураПолей.Вставить(Колонка.Имя, ТекСтрокаГруппа[Колонка.Имя]);

        КонецЦикла;
        СтруктураПолей.Вставить("НаименованиеГруппы", НаименованиеГруппы);

        Для каждого ТекСтрока Из ТекСтрокаГруппа.Строки Цикл
            СоответствиеГруппСворачиванияВагонов.Вставить(ТекСтрока.Вагон, СтруктураПолей);
        КонецЦикла;

    КонецЦикла;

    Возврат СоответствиеГруппСворачиванияВагонов;

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

Здесь происходит работа с СКД:

  • мы получаем схему из временного хранилища и создаем в ней сборную группировку СКД;

  • получаем настройки сворачивания из справочника «ВариантыГруппировкиВагонов» и начинаем обходить их выбранные поля. Можно было использовать свойство «ПоляГруппировки» настроек, но мы решили, что через поля «Выбор» будет проще. Мы обходим поля выбора и добавляем их программно в сборную группировку;

  • после этого искусственно добавляем еще один элемент группировки – «Порожний» (пустой вагон);

  • и добавляем детальные записи, где будет наш вагон.

 

 

  • отбираем только те вагоны, которые выведены на текущей зоне отображения.

  • формируем дерево групп вагонов – выводим результат компоновки данных в дерево,

  • и, как я и говорил, обходим дерево с формированием соответствия вагонов группам:

    • из названий колонок дерева мы формируем наименования для каждой группы;

    • вставляем в структуру полей наименование группы;

    • и формируем для вагона соответствие – в какую группу он входит.

 

 

И дальше, когда мы выводим вагоны, в случае, если они выводятся в свернутом виде, то у вагона отображается текущая группа. Мы по группам собираем квадратики из наших вагонов.

 

Сегментирование данных

 

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

 

 

С такими задачами мы сталкивались чаще всего. Один из примеров – черные списки.

Суть задачи «черного списка» в том, чтобы при въезде на территорию предприятия (например, в портовый терминал или на зерновой элеватор) определенного автотранспорта нужно, чтобы охранник получал оповещение, если автомобиль нельзя впускать или выпускать. Или у него запрет на въезд на территорию на определенный срок.

Условия отбора могут быть разными: мы можем заблокировать поставщика или может быть заблокирован конкретный водитель или перевозчик.

Здесь мы также решили использовать отборы СКД.

У нас есть «Рабочее место контрольно-пропускного пункта». Если вбивается автомобиль, который нельзя пропускать, пользователю выводится пометка, что водитель в черном списке – его по такой-то причине нельзя пропускать.

 

 

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

Мы выводим на форму возможность редактировать отбор – период черного списка и его описание. А внутри отбора выбираются параметры, по которым машину нельзя пускать.

 

 

Работа с СКД здесь заключается в том, что мы создаем в СКД набор данных «Объект» – таблицу значений, в которую в качестве полей входят типы объектов, по которым мы потом будем отбирать. В данном случае эта таблица будет формироваться по данным документа «Товарно-транспортная накладная» (ТТН), поэтому мы забиваем сюда все поля, по которым пользователю нужно давать отбор.

В самих настройках выводятся только детальные записи, в которых выбираются все необходимые поля, которые, возможно, потом нужно будет вывести.

 

 

Как и в следующих кейсах, везде применяется схожая технология.

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

Правда, если вариантов настроек будет много, то это неоптимально, ведь мы получаем запрос в цикле. Мы хотели это оптимизировать – каким-то образом собирать текст запроса СКД из всех возможных вариантов настроек, одним запросом это генерировать и получать тот вариант настроек, в который у нас вошел проверяемый объект – но пока мы это не реализовали. Поэтому пока происходит обход всех вариантов черного списка по периоду.

  • мы для каждого варианта черного списка получаем схему компоновки;

  • в таблицу объекта-запроса схемы мы помещаем данные ТТН и передаем СКД на выполнение;

  • если в результате выполнения у нас есть хотя бы одна запись, мы считаем условие черного списка выполненным – т.е. машину пускать нельзя.

 

 

Схожий принцип применяется и в другой задаче, которую мы реализовали для нашего железнодорожного оператора.

Бывало такое, что определенный грузополучатель писал письмо ЖД-оператору, что не справляется с получением груза, и просит вагоны от определенного поставщика с определенным грузом переадресовывать на другой причал (на другого контрагента).

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

Здесь можно было бы реализовать поля замены с помощью полей выбора схемы компоновки данных, но на данный момент все поля, которые можно заменить, здесь указаны жестко – это контрагент и ряд определенных признаков.

В момент, когда данные по вагону вводятся в систему, мы по такому же алгоритму получаем СКД и проверяем вагон на выполняемые условия. Если он входит хотя бы в одно из условий, мы выполняем замену полей и переадресацию на другого контрагента.

 

Примечания к документам

 

И последний кейс на сегодня – это примечания к документам

 

 

Это другая конфигурация – «Управление стивидорной компанией», конфигурация для портового оператора. По сути, это складская логистика, но с портовой спецификой.

Там есть особенность, что когда приходит приемный акт на груз, по определенным грузам необходимо при печати карточки приема груза печатать примечание.

Например, по грузу «Заготовка» нужно печатать примечание «Вес заявлен отправителем», по другому грузу – нужно печатать размеры. Еще иногда по грузам нужно вбивать какие-то примечания вручную, но их нужно ограничивать по определенным условиям, чтобы можно было ввести только определенный текст.

Это опять же реализуется с помощью СКД.

Создается элемент справочника «Примечание к документу»:

  • выбирается вид документа – может использоваться определенный набор документов: ТТН на отгрузку, приемный акт на автомобиль или вагон и прочие документы;

  • указывается наименование;

  • указывается отбор для документа – например, конкретная номенклатура;

  • перечисляется, какие примечания могут автозаполняться;

  • и какие примечания нужно отобрать пользователю при условии выполнения отбора.

Используется СКД по тому же принципу, который я показывал – набивается внешний источник данных-объект, где перечисляются все поля, по которым пользователь сможет настроить этот отбор для вывода примечаний.

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

 

Вопросы

 

Можно ли эти механизмы применить к какой-нибудь другой конфигурации, насколько это сложно?

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

Предположим, вы в конфигурации «Управление торговлей» хотите сделать черный список поставщиков или автозаполнение примечаний – чтобы для работника склада на приходный складской ордер автоматически добавлялись какие-то комментарии. Пожалуйста, мы просто набиваем в объект-запрос СКД таблицу полей, по которым мы даем возможность отобрать – добавляем в выбранные поля детальных записей абсолютно любое поле и потом выполняем этот СКД. Если в результате выполнения у нас есть хотя бы одно значение, то мы считаем условие выполненным и дальше идем по некоему алгоритму.

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

Зачем использовать при инициализации схемы именно адрес временного хранилища, а не сразу вызывать схему?

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

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

Что у вас за конфигурации, что они реализуют?

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

То же самое – конфигурация «Арт:Маслоналивной терминал», она реализует учет масла.

Помимо этого, у нас большой процент разработок – это ЖД-решения. Те примеры, которые я сегодня показывал, были из систем «Арт:ЖД Терминал» и «Арт.ЖД Отгрузка». Это, как правило, большие проекты, когда на предприятии есть какой-то карьер, добывается очень много сырья и оно отгружается в порожние вагоны. В таких случаях необходима система по управлению вот этими вагонами.

Для этих конфигураций у нас много «фишек» реализовано на табличном документе – вагоны можно перетаскивать на другие пути, пункты, учитываются перегоны, работа локомотивов, увязка с датчиками GPS и с топливом. И потом выставляются услуги.

Что касается ЖД-перевозок, то наше флагманское решение – это «Арт:ЖД логистика», конфигурация, которая реализует обмен электронными накладными через систему «АС клиент УЗ», украинский аналог системы «Этран», которую использует РЖД для электронных ЖД-накладных. Мы можем из нашей системы создавать ЖД-накладные, учитывать заказы на перевозку. Она основана на УНФ – просчитывается рентабельность вагонного парка, заказов на перевозку и т.д.

Есть свое решение по автотранспорту со спецификой под тех клиентов, с которыми мы работаем.

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

 

*************

Данная статья написана по итогам доклада (видео), прочитанного на онлайн-митапе "Практика применения СКД".

 

30 мая - 1 июня 2024 года состоится конференция Анализ & Управление в ИТ-проектах, на которой прозвучит 130+ докладов.

Темы конференции:

  • Программная инженерия.
  • Инструментарий аналитика.
  • Решения 1С: архитектура, учет и кейсы автоматизации на 1С.
  • Управление проектом.
  • Управление продуктом.
  • Soft skills, управление командой проекта.

Конференция для аналитиков и руководителей проектов, а также других специалистов из мира 1С, которые занимаются системным и бизнес-анализом, работают с требованиями, управляют проектами и продуктами!

Подробнее о конференции.

 


См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    121599    670    389    

711

Генератор схемы компоновки данных (СКД), написание кода схемы программно

Инструментарий разработчика СКД Платформа 1С v8.3 Конфигурации 1cv8 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

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

3 стартмани

05.02.2024    4032    25    obmailok    17    

63

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2000    2    Yashazz    0    

29

СКД на JavaScript в 1С

СКД WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

11.12.2023    8153    20    John_d    25    

123

Использование менеджера временных таблиц в СКД

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

Рассмотрим еще не получивший широкого распространения способ работы с внешними данным в СКД. В процессе обсуждения работы с СКД выяснилось, что многие не знакомы со способом помещения туда временной таблицы, полученной предварительно. Статья будет полезна разработчикам, знакомым с программным созданием СКД.

05.12.2023    4649    PROSTO-1C    13    

61

Модель СКД

Инструментарий разработчика СКД Платформа 1С v8.3 Система компоновки данных Абонемент ($m)

DSL для работы с СКД.

1 стартмани

15.11.2023    5804    15    kalyaka    5    

86

Пользовательские настройки отчетов 1С. Часть 1. Простые и расширенные настройки

СКД Инструкции пользователю Платформа 1С v8.3 Конфигурации 1cv8 1С:Бухгалтерия 3.0 Россия Бесплатно (free)

Простые приемы работы с отчетами на СКД. Что нужно знать пользователю про настройку отчетов, чтобы использовать их на полную катушку.

18.09.2023    6689    accounting_cons    5    

29

Разрыв страницы в СКД. Легко!

СКД Платформа 1С v8.3 Система компоновки данных Бесплатно (free)

Когда отчет надо разделить по страницам, это всегда проблема для разработчика. Поскольку в СКД нет стандартных вариантов, как это сделать. Нашел (на свой взгляд) самое простое и оптимальное решение.

01.09.2023    4517    KVIKS    15    

80
Оставьте свое сообщение