Программное создание графических схем

Публикация № 537353

Разработка - Практика программирования

Графическая схема GRS сериализация xml-структура внутренний формат графической схемы

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

Сначала я собирался накатать большую и умную статью по итогам исследования внутреннего формата различных общих объектов 1С - всяких там географических карт, дендрограмм и прочих мокселей. О том, как оно устроено, что означает тот или иной кусок и какая польза может от того получиться. Ряд манипуляций возможен только с сериализованным текстом, ряд действий просто быстрее и удобнее. Так вот, а потом мне здраво указали, что теория нафиг не нужна и вообще подавай конкретные примеры.

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

К недостаткам схемы стоит отнести сложность позиционирования (вам самостоятельно придётся прикидывать, куда "сунуть" каждый новый объект), и капризная чувствительность к правке. Перетаскивать добавленные объекты, связанные добавленными стрелочками, не советую - всё рискует разъехаться. Но для "только просмотр" это сгодится более чем. Также, напомню, графическая схема поддерживает событие расшифровки, что делает её не просто иллюстративным инструментом, но и навигационным.

Где это может пригодиться? Начиная от построения простейших отчётов-связок, вроде "Структуры подчинённости", и заканчивая отражением связей метаданных, как это делали в механизмах, изучающих внутреннюю структуру конфигураций. Для цели отрисовки графов может пригодиться; правда, опять же, позиционирование надо продумывать самим, в отличие от стороннего софта, обычно используемого в таких случаях.

Собственно, код и все пояснения по формату в описаниях функций. Особенно см. подробное описание функции ДобавитьФигуру.

#Область РаботаСГрафическимиСхемами

&НаСервереБезКонтекста
Функция СериализоватьГС(рГС)
    зап=Новый ЗаписьXML;
    зап.УстановитьСтроку("UTF-8");
    //СериализаторXDTO.ЗаписатьXML(зап,ГС,НазначениеТипаXML.Явное,ФормаXML.Атрибут);
    СериализаторXDTO.ЗаписатьXML(зап,рГС);
    Возврат зап.Закрыть();
КонецФункции

&НаСервереБезКонтекста
Функция ДесериализоватьГС(рСтрока)
    чтен=Новый ЧтениеXML;
    чтен.УстановитьСтроку(рСтрока);
    Возврат СериализаторXDTO.ПрочитатьXML(чтен,Тип("ГрафическаяСхема"));
КонецФункции

// Преобразует значение системного перечисления в его англоязычный вариант представления
&НаКлиенте
Функция АнглИмя(рЗначение)
    Возврат СокрЛП(СериализаторXDTO.XMLСтрока(рЗначение));
КонецФункции

&НаКлиенте
// Возвращает список значений, где значение - тип (тип элемента граф.схемы),
// а порядковый номер в списке значений соответствует коду сериализации.
//
Функция ПолучитьТипыЭлементов()
    сптэ=Новый СписокЗначений;
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыДекорация"),"Декорация");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыДекоративнаяЛиния"),"Линия");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыСтарт"),"Начало");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыЗавершение"),"Завершение");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыУсловие"),"Условие");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыДействие"),"Действие");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыВыборВарианта"),"Выбор варианта");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыРазделение"),"Разделение");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыСлияние"),"Слияние");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыОбработка"),"Обработка");
    сптэ.Добавить(Тип("ЭлементГрафическойСхемыВложенныйБизнесПроцесс"),"Вложенный БП");
    Возврат сптэ;
КонецФункции

&НаКлиенте
// Возвращает соответствие, где ключ - значение типа ТипСтороныЭлементаГрафическойСхемы, а значение - число.
// Значения чисел и их смысл: 
//    1 - влево, 2 - вверх, 
//    3, 5, 7, 9, 11 итд - вправо (3 в блоках и условиях, 5 в обычных блоках, 7 и более в выборе вариантов);
//    4 - вниз, 6 и 8 - ???
//
Функция ПолучитьТипыСторонЭлементов()
    соот=Новый Соответствие;
    соот.Вставить(ТипСтороныЭлементаГрафическойСхемы.Лево,1);
    соот.Вставить(ТипСтороныЭлементаГрафическойСхемы.Верх,2);
    соот.Вставить(ТипСтороныЭлементаГрафическойСхемы.Право,3);
    соот.Вставить(ТипСтороныЭлементаГрафическойСхемы.Низ,4);
    Возврат соот;
КонецФункции

&НаКлиенте
// Разбирает текст по элементам с именем itemId, рассматривает их как числа и возвращает значение наибольшего.
//
// Параметры:
//    рТекст - рассматриваемый текст сериализованной граф.схемы.
//
Функция ПолучитьСтаршийИдентификатор(рТекст) Экспорт
    чтен=Новый ЧтениеXML;
    чтен.УстановитьСтроку(рТекст);
    постр=Новый ПостроительDOM;
    докДом=постр.Прочитать(чтен);
    спис=докДом.ПолучитьЭлементыПоИмени("itemId");
    максИд=0;
    Для каждого знч Из спис Цикл
        Попытка чисИд=Число(СокрЛП(знч.ТекстовоеСодержимое)) Исключение чисИд=0 КонецПопытки;
        максИд=Макс(максИд,чисИд);
    КонецЦикла;
    Возврат максИд+1;
КонецФункции

&НаКлиенте
// Возвращает строку, содержащую теги, описывающие фигуру элемента графической схемы согласно её типу.
// Обычно вызывается из ДобавитьФигуру и самостоятельно не употребляется.
// При ошибке возвращает пустую строку.
//
// Параметры:
//    рТипЭлемента - числовой тип элемента граф.схемы; должен быть ранее преобразован из типа Тип, если надо;
//    рКоординатыКонтура - структура, обязательно уже содержащая ключи Верх, Низ, Лево, Право с числовыми значениями;
//        если этих значений нет, то выполняется попытка их автоопределить (для линии их можно пропускать, найдёт сама по
//        данным объекта-откуда и объекта-куда). Вместо "Низ" можно указывать "Высота"; вместо "Право" можно "Ширина";
//        для линий можно задать только ключи "СерединаГор" и "СерединаВерт", координаты средней точки линии, что бывает
//        нужно для диагонально-ориентированных линий.
//
Функция ДобавитьКоординатыФигуры(рТипЭлемента,рКоординатыКонтура)
Попытка
    рВерх=рКоординатыКонтура.Верх;
    рНиз=рКоординатыКонтура.Низ;
    рЛево=рКоординатыКонтура.Лево;
    рПраво=рКоординатыКонтура.Право;
    рСерединаГор=рЛево+(рПраво-рЛево)/2;
    рСерединаВер=рВерх+(рНиз-рВерх)/2;
    //
    сс="";
    Если рТипЭлемента=1 Тогда // декор.линия
        х=рЛево; у=рВерх;     сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        Если рКоординатыКонтура.Свойство("СерединаГор") Тогда
            х=рКоординатыКонтура.СерединаГор;
        Иначе
            х=рСерединаГор; 
        КонецЕсли;
        Если рКоординатыКонтура.Свойство("СерединаВерт") Тогда
            у=рКоординатыКонтура.СерединаВерт;
        Иначе
            у=рСерединаВер;
        КонецЕсли;
        сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    ИначеЕсли рТипЭлемента=2 Тогда // начало
        х=рЛево; у=рВерх;     сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";        
        х=рПраво-1; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рСерединаВер; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рСерединаГор; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рЛево; у=рСерединаВер; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    ИначеЕсли рТипЭлемента=3 Тогда // завершение
        х=рСерединаГор; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рСерединаВер; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рЛево; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рЛево; у=рСерединаВер; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    ИначеЕсли рТипЭлемента=4 Тогда // условие
        х=рЛево; у=рСерединаВер; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рЛево+11; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-12; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рСерединаВер; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-12; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рЛево+11; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    ИначеЕсли рТипЭлемента=7 Тогда // разделение
        х=рЛево; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рСерединаГор; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    ИначеЕсли рТипЭлемента=8 Тогда // слияние
        х=рЛево; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рСерединаГор; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    Иначе // действие, вариант, обработка, вложенный БП
        х=рЛево; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рВерх; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рПраво-1; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
        х=рЛево; у=рНиз-1; сс=сс+"<point><x>"+Строка(х)+"</x><y>"+Строка(у)+"</y></point>";
    КонецЕсли;
    //
    Возврат сс;
Исключение
    Сообщить("ДобавитьКоординатыФигуры, ошибка: "+ОписаниеОшибки());
    Возврат "";
КонецПопытки;
КонецФункции

&НаКлиенте
// Готовит фрагмент xml-текста согласно указанным параметрам; внутри себя дописывает этот фрагмент в общую строку всей схемы.
// Возвращает строку фрагмента, соответствующую добавленному элементу графической схемы (фигуре).
// При ошибке возвращает пустую строку.
//
// Параметры:
//    строГС - строка сериализованной схемы в целом; изменяется внутри функции;
//    пар (структура), описание см.ниже в области "ОписаниеПараметров":
//
#Область ОписаниеПараметров

#Область ОбщиеДляВсехЭлементов
    //   Имя (строка), 
    //   ТипЭлемента (тип, строка или число от 0 до 10 - имя типа элемента ГС в нотации 1С или числовой идентификатор)
    //   [Идентификатор] (число, полученное, например, с помощью ПолучитьСтаршийИдентификатор, itemId), 
    //   ТекстЗаголовка (строка), 
    //   [ТекстПодсказки] (строка), 
    //   [НомерВОбходе] (число; может совпадать с Идентификатор), 
    //   [Гиперссылка] (булево),
    //   [Прозрачность] (булево),
    //   [ГоризонтальноеПоложение] (ГоризонтальноеПоложение),
    //   [ВертикальноеПоложение] (ВертикальноеПоложение),
    //   [ПоложениеКартинки] (ПоложениеКартинкиЭлементаГрафическойСхемы),
    //   КоординатыКонтура (структура с числовыми значениями ключей: Лево,Верх,Право,Низ или Лево,Верх,Ширина,Высота, причём
    //       при задании Право, Низ правая граница считается относительно 0, а не левой, и нижняя граница - относительно 0, а не верхней.
    //       для линий это необязательный параметр; при его отсутствии линия пытается определиться по Откуда/Куда 
    //       и НаправлениеОткуда/НаправлениеКуда; при его наличии Лево,Верх это начальная точка линии, а Право,Низ - конечная; причём
    //       задание через Ширина и Высота также приведёт к нужному результату.
    //    Изменение координат контура выполняется с изменением коллекции параметров.
    //
#КонецОбласти

#Область ДляДекорации
    //   Фигура (ФигурыГрафическойСхемы)
#КонецОбласти

#Область ДляЛинии
    //   Откуда (число) - идентификатор (itemId) элемента, откуда идёт линия, если ниоткуда не идёт, то -1
    //   Куда (число) - дентификатор (itemId) элемента, куда идёт линия, если никуда не идёт, то -1
    //   ВариантОткуда (для линий, выходящих из выбора варианта, № варианта (нач.с 0),
    //   [ДекоративнаяЛиния] (булево),
    //   [ПоложениеТекста] (ПоложениеТекстаСоединительнойЛинии),
    //   [СтильСтрелкиНачало] (СтильСтрелки),
    //   [СтильСтрелкиКонец] (СтильСтрелки),
    //   НаправлениеОткуда (числовой номер визуального направления отправителя; край, откуда выходит линия),
    //   НаправлениеКуда (числовой номер визуального направления получателя; край, куда входит линия),
    //         т.е. это стороны объектов, связанных линией, куда прикрепляется линия тем или иным своим концом:
    //         1 - влево, 2 - вверх, 
    //         3, 5, 7, 9, 11 итд - вправо (3 в блоках и условиях, 5 в обычных блоках, 7 и более в выборе вариантов);
    //         4 - вниз, 6 и 8 - ???
    //         или значение типа ТипСтороныЭлементаГрафическойСхемы.
    //   Если указано направление типа ТипСтороныЭлементаГрафическойСхемы, то оно преобразуется в число также и в параметрах.
#КонецОбласти

#Область ДляУсловия
    // выход ветки (1 - влево, 3 - вправо)
    //   [НаправлениеВеткиДа] (число),
    //   [НаправлениеВеткиНет] (число).
#КонецОбласти

#Область ДляДействия
    //   ОписаниеДействия (строка), 
    //   АдресацияДействия (строка), 
    //   [ГрупповаяАдресация] (булево), 
    //   [ВысотаОбластиАдресации] (число)
#КонецОбласти

#Область ДляВыбораВарианта
    //  Варианты - массив структур: Идентификатор (строка), ТекстЗаголовка (строка), Куда (идентификатор получателя стрелки), НаправлениеКуда (его боковина)
#КонецОбласти

#Область ДляВложенногоБП
    //   ТекстЗаголовкаБП (строка)
#КонецОбласти

#КонецОбласти
//
//    также по ходу работы в структуру "пар" добавляются или могут для оптимизации быть указаны заранее:
//        СписокТиповЭлементов - список значений, согласно функции ПолучитьТипыЭлементов();
//        ТипыСторонЭлементов - соответствие, согласно функции ПолучитьТипыСторонЭлементов(); вносится только при добавлении линий.
//    соотДобавленных - соответствие, где ключи - числовые ID элементов, а значения - структуры параметров их построения.
//        
Функция ДобавитьФигуру(строГС,пар,соотДобавленных=Неопределено)
Попытка
    Если ТипЗнч(соотДобавленных)<>Тип("Соответствие") Тогда соотДобавленных=Новый Соответствие КонецЕсли;
    
    #Область ОбработкаТипаИИдентификатора
    
    рТипЭлемента=ТипЗнч(пар.ТипЭлемента);
    Если рТипЭлемента=Тип("Строка") Тогда
        Попытка чисТип=Число(СокрЛП(пар.ТипЭлемента)) Исключение чисТип=-1 КонецПопытки;
        Если чисТип=-1 Тогда
            // передано имя типа элемента в нотации 1С, преобразуем в идентификатор
            Если пар.Свойство("СписокТиповЭлементов") Тогда
                сптэ=пар.СписокТиповЭлементов;
            Иначе // получим "по месту" и занесём в параметры
                сптэ=ПолучитьТипыЭлементов();
                пар.Вставить("СписокТиповЭлементов",сптэ);
            КонецЕсли;
            пози=сптэ.НайтиПоЗначению(Тип(СокрЛП(пар.ТипЭлемента)));
            Если пози=Неопределено Тогда
                Сообщить("ДобавитьФигуру: не удалось найти идентификатор типа """+СокрЛП(пар.ТипЭлемента)+", фигура не добавляется!",СтатусСообщения.Важное);
                Возврат "";
            КонецЕсли;        
            рТипЭлемента=сптэ.Индекс(пози);
        Иначе
            // передан сразу идентификатор; проверять не будем, сразу вставляем
            рТипЭлемента=чисТип;
        КонецЕсли;        
    ИначеЕсли рТипЭлемента=Тип("Тип") Тогда
        // передан тип элемента (удобнее писать с использованием подсказок 1С), преобразуем в идентификатор
        Если пар.Свойство("СписокТиповЭлементов") Тогда
            сптэ=пар.СписокТиповЭлементов;
        Иначе // получим "по месту" и занесём в параметры
            сптэ=ПолучитьТипыЭлементов();
            пар.Вставить("СписокТиповЭлементов",сптэ);
        КонецЕсли;
        пози=сптэ.НайтиПоЗначению(пар.ТипЭлемента);
        Если пози=Неопределено Тогда
            Сообщить("ДобавитьФигуру: не удалось найти идентификатор типа """+СокрЛП(пар.ТипЭлемента)+", фигура не добавляется!",СтатусСообщения.Важное);
            Возврат "";
        КонецЕсли;        
        рТипЭлемента=сптэ.Индекс(пози);
    ИначеЕсли рТипЭлемента=Тип("Число") Тогда
        // передан сразу идентификатор; проверять не будем, сразу вставляем
        рТипЭлемента=пар.ТипЭлемента;
    КонецЕсли;
    Если рТипЭлемента<0 или рТипЭлемента>10 Тогда Возврат "" КонецЕсли;
    //
    Если не пар.Свойство("Идентификатор") Тогда // получаем "по месту" как старшего и занесём в параметры
        // при такой идеологии работы важно потом переустановить/сбросить значение этого параметра!
        рИдентификатор=ПолучитьСтаршийИдентификатор(строГС);
        пар.Вставить("Идентификатор",рИдентификатор);
    Иначе
        рИдентификатор=пар.Идентификатор;
    КонецЕсли;    
    
    #КонецОбласти
    
    фБул="БЛ=false; БИ=true";
    
    сс="
    |<item>";
    
    #Область ДобавлениеОбщихСвойств
        
    // общие свойства
    сс=сс+"
    |<itemType>"+СокрЛП(рТипЭлемента)+"</itemType>
    |<itemId>"+СокрЛП(рИдентификатор)+"</itemId>
    |<currentLanguage>#</currentLanguage>
    |<itemTitle><item xmlns=""http://v8.1c.ru/8.1/data/core""><lang>#</lang>
    |<content>"+пар.ТекстЗаголовка+"</content></item></itemTitle>
    |<tipText><item xmlns=""http://v8.1c.ru/8.1/data/core""><lang>#</lang>
    |<content>"+?(пар.Свойство("ТекстПодсказки"),пар.ТекстПодсказки,"")+"</content></item></tipText>
    |<itemCode>"+пар.Имя+"</itemCode>
    |<itemTabOrder>"+СокрЛП(?(пар.Свойство("НомерВОбходе"),пар.НомерВОбходе,рИдентификатор))+"</itemTabOrder>
    // // пар.Оформление.ЦветФона,  // пар.Оформление.ЦветТекста,  // пар.Оформление.ЦветЛинии,  // пар.Оформление.Шрифт
    |<backColor>auto</backColor>
    |<textColor xmlns:d3p1=""http://v8.1c.ru/8.1/data/ui/style"">d3p1:FormTextColor</textColor>
    |<lineColor xmlns:d3p1=""http://v8.1c.ru/8.1/data/ui/style"">d3p1:BorderColor</lineColor>
    |<groupNum>0</groupNum>
    |<zOrder>"+СокрЛП(?(пар.Свойство("НомерВОбходе"),пар.НомерВОбходе,рИдентификатор))+"</zOrder>
    |<hyperlink>"+?(пар.Свойство("Гиперссылка"),Формат(пар.Гиперссылка,фБул),"false")+"</hyperlink>
    |<transparent>"+?(пар.Свойство("Прозрачность"),Формат(пар.Прозрачность,фБул),"false")+"</transparent>
    |<textFont kind=""AutoFont""/>
    |<alignHor>"+?(пар.Свойство("ГоризонтальноеПоложение"),АнглИмя(пар.ГоризонтальноеПоложение),"Center")+"</alignHor>
    |<alignVer>"+?(пар.Свойство("ВертикальноеПоложение"),АнглИмя(пар.ВертикальноеПоложение),"Center")+"</alignVer>
    |<picturePlacement>"+?(пар.Свойство("ПоложениеКартинки"),АнглИмя(пар.ПоложениеКартинки),"Left")+"</picturePlacement>
    // работу с картинками пока не реализуем
    |<picture/>
    |<pictureStyle>4</pictureStyle>
    // pictureStyle - порядковый номер значения сис.перечисления РазмерКартинки, как он задан не в СП, а в списке выбора палитры свойств, 4 - АвтоРазмер
    //<pointUUID>GUIDОбъекта</pointUUID>
    |";
    
    #КонецОбласти
    
    #Область ДополнительнаяПодготовка
    
    Если рТипЭлемента=1 Тогда
        рНаправлениеОткуда=пар.НаправлениеОткуда;
        Если ТипЗнч(рНаправлениеОткуда)=Тип("ТипСтороныЭлементаГрафическойСхемы") Тогда
            Если пар.Свойство("ТипыСторонЭлементов") Тогда
                соотНапр=пар.ТипыСторонЭлементов;
            Иначе
                соотНапр=ПолучитьТипыСторонЭлементов();
                пар.Вставить("ТипыСторонЭлементов",соотНапр);
            КонецЕсли;
            рНаправлениеОткуда=соотНапр.Получить(рНаправлениеОткуда);
            Если рНаправлениеОткуда=Неопределено Тогда рНаправлениеОткуда=4 КонецЕсли; // из нижней
            пар.Вставить("НаправлениеОткуда",рНаправлениеОткуда);
        КонецЕсли;
        //
        рНаправлениеКуда=пар.НаправлениеКуда;
        Если ТипЗнч(рНаправлениеКуда)=Тип("ТипСтороныЭлементаГрафическойСхемы") Тогда
            Если пар.Свойство("ТипыСторонЭлементов") Тогда
                соотНапр=пар.ТипыСторонЭлементов;
            Иначе
                соотНапр=ПолучитьТипыСторонЭлементов();
                пар.Вставить("ТипыСторонЭлементов",соотНапр);
            КонецЕсли;
            рНаправлениеКуда=соотНапр.Получить(рНаправлениеКуда);
            Если рНаправлениеКуда=Неопределено Тогда рНаправлениеКуда=4 КонецЕсли; // из нижней
            пар.Вставить("НаправлениеКуда",рНаправлениеКуда);            
        КонецЕсли;
        //
    Иначе
        // эти параметры задём статично (более частные свойства)
        //сс=сс+"
        //|<passageState>0</passageState>
        //|<tableCode>34</tableCode>
        //|<bpPointValue xmlns:d3p1="http://v8.1c.ru/8.1/data/enterprise/current-config" xsi:type="d3p1:BusinessProcessRoutePointRef.БизнесПроцесс1">18c0a78b-c146-4790-86b7-9f833864fadf</bpPointValue>
        //|";
        //
    КонецЕсли;
    
    #КонецОбласти
    
    #Область ДобавлениеКонтураИКоординат
    
    // очерчиваем область, где будет расположен элемент (для линии могут быть не заданы)
    рКоординатыБылиЗаданы=Истина;
    рКоординатыОткудаЗаданы=Истина; 
    рКоординатыКудаЗаданы=Истина;
    //
    Если не пар.Свойство("КоординатыКонтура") Тогда
        рКоординатыБылиЗаданы=Ложь;
        рКоординатыОткудаЗаданы=Ложь; 
        рКоординатыКудаЗаданы=Ложь;
        пар.Вставить("КоординатыКонтура",Новый Структура);
    Иначе
        Если не пар.КоординатыКонтура.Свойство("Ширина") 
        и не пар.КоординатыКонтура.Свойство("Высота")
        и не пар.КоординатыКонтура.Свойство("Лево")
        и не пар.КоординатыКонтура.Свойство("Право")
        и не пар.КоординатыКонтура.Свойство("Верх")
        и не пар.КоординатыКонтура.Свойство("Низ")
        Тогда
            // переданы, возможно, только координаты середины линии, а остальное надо автоопределить
            рКоординатыБылиЗаданы=Ложь;
        КонецЕсли;
        Если не пар.КоординатыКонтура.Свойство("Лево") и не пар.КоординатыКонтура.Свойство("Верх") Тогда
            рКоординатыОткудаЗаданы=Ложь;
        КонецЕсли;        
        Если (не пар.КоординатыКонтура.Свойство("Ширина") и не пар.КоординатыКонтура.Свойство("Право"))
        или (не пар.КоординатыКонтура.Свойство("Высота") и не пар.КоординатыКонтура.Свойство("Низ"))
        Тогда 
            рКоординатыКудаЗаданы=Ложь;
        КонецЕсли;
    КонецЕсли;
    //
    Если пар.КоординатыКонтура.Свойство("Ширина") и не пар.КоординатыКонтура.Свойство("Право") Тогда 
        пар.КоординатыКонтура.Вставить("Право",пар.КоординатыКонтура.Лево+пар.КоординатыКонтура.Ширина);
    КонецЕсли;
    Если пар.КоординатыКонтура.Свойство("Высота") и не пар.КоординатыКонтура.Свойство("Низ") Тогда 
        пар.КоординатыКонтура.Вставить("Низ",пар.КоординатыКонтура.Верх+пар.КоординатыКонтура.Высота);
    КонецЕсли;
    //
    Если рТипЭлемента=1 Тогда // линия
        Если не рКоординатыБылиЗаданы или не рКоординатыОткудаЗаданы Тогда
            Попытка рОткуда=соотДобавленных.Получить(пар.Откуда) Исключение рОткуда=Неопределено КонецПопытки;
            Если рОткуда<>Неопределено Тогда
                рЛево=-1; рВерх=-1;
                Если пар.НаправлениеОткуда=1 Тогда // выходим влево, нужна середина левой границы
                    рЛево=рОткуда.КоординатыКонтура.Лево;
                    рВерх=рОткуда.КоординатыКонтура.Верх+(рОткуда.КоординатыКонтура.Низ-рОткуда.КоординатыКонтура.Верх)/2;
                ИначеЕсли пар.НаправлениеОткуда=2 Тогда // выходим вверх, нужна середина верхней границы
                    рЛево=рОткуда.КоординатыКонтура.Лево+(рОткуда.КоординатыКонтура.Право-рОткуда.КоординатыКонтура.Лево)/2;
                    рВерх=рОткуда.КоординатыКонтура.Верх;
                ИначеЕсли пар.НаправлениеОткуда=3 или пар.НаправлениеОткуда=5 Тогда // выходим вправо стандартно, середина правой границы
                    рЛево=рОткуда.КоординатыКонтура.Право;
                    рВерх=рОткуда.КоординатыКонтура.Верх+(рОткуда.КоординатыКонтура.Низ-рОткуда.КоординатыКонтура.Верх)/2;
                ИначеЕсли пар.НаправлениеОткуда=4 Тогда // выходим вниз, нужна середина нижней границы
                    рЛево=рОткуда.КоординатыКонтура.Лево+(рОткуда.КоординатыКонтура.Право-рОткуда.КоординатыКонтура.Лево)/2;
                    рВерх=рОткуда.КоординатыКонтура.Низ;
                КонецЕсли;
                Если рЛево<>-1 Тогда пар.КоординатыКонтура.Вставить("Лево",рЛево) КонецЕсли;
                Если рВерх<>-1 Тогда пар.КоординатыКонтура.Вставить("Верх",рВерх) КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        //
        Если не рКоординатыБылиЗаданы или не рКоординатыКудаЗаданы Тогда            
            Попытка рКуда=соотДобавленных.Получить(пар.Куда) Исключение рКуда=Неопределено КонецПопытки;
            Если рКуда<>Неопределено Тогда
                рПраво=-1; рНиз=-1;
                Если пар.НаправлениеКуда=1 Тогда // входим влево, нужна середина левой границы
                    рПраво=рКуда.КоординатыКонтура.Лево;
                    рНиз=рКуда.КоординатыКонтура.Верх+(рКуда.КоординатыКонтура.Низ-рКуда.КоординатыКонтура.Верх)/2;
                ИначеЕсли пар.НаправлениеКуда=2 Тогда // входим вверх, нужна середина верхней границы
                    рПраво=рКуда.КоординатыКонтура.Лево+(рКуда.КоординатыКонтура.Право-рКуда.КоординатыКонтура.Лево)/2;
                    рНиз=рКуда.КоординатыКонтура.Верх;
                ИначеЕсли пар.НаправлениеКуда=3 или пар.НаправлениеКуда=5 Тогда // входим вправо стандартно, середина правой границы
                    рПраво=рКуда.КоординатыКонтура.Право;
                    рНиз=рКуда.КоординатыКонтура.Верх+(рКуда.КоординатыКонтура.Низ-рКуда.КоординатыКонтура.Верх)/2;
                ИначеЕсли пар.НаправлениеКуда=4 Тогда // входим вниз, нужна середина нижней границы
                    рПраво=рКуда.КоординатыКонтура.Лево+(рКуда.КоординатыКонтура.Право-рКуда.КоординатыКонтура.Лево)/2;
                    рНиз=рКуда.КоординатыКонтура.Низ;
                КонецЕсли;
                Если рПраво<>-1 Тогда пар.КоординатыКонтура.Вставить("Право",рПраво) КонецЕсли;
                Если рНиз<>-1 Тогда пар.КоординатыКонтура.Вставить("Низ",рНиз) КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        //
    Иначе
        // не линия, т.е. имеет контур
        Попытка
            сс=сс+"
            |<rectLeft>"+СокрЛП(пар.КоординатыКонтура.Лево)+"</rectLeft>
            |<rectRight>"+СокрЛП(пар.КоординатыКонтура.Право)+"</rectRight> 
            |<rectTop>"+СокрЛП(пар.КоординатыКонтура.Верх)+"</rectTop>
            |<rectBottom>"+СокрЛП(пар.КоординатыКонтура.Низ)+"</rectBottom>";
        Исключение
            Сообщить("Ошибка получения координат контура: "+ОписаниеОшибки());
            Возврат "";
        КонецПопытки;        
    КонецЕсли;
    // рисуем реальные координаты фигур (актуально для всех, в т.ч. прямоугольных и линии)
    сс=сс+ДобавитьКоординатыФигуры(рТипЭлемента,пар.КоординатыКонтура);
    
    #КонецОбласти
    
    // возможно, доделать это место!
    сс=сс+"
    |<border width=""1"" gap=""false"">
    |  <style xmlns=""http://v8.1c.ru/8.1/data/ui"" xmlns:d4p1=""http://v8.1c.ru/8.2/data/graphscheme"" xsi:type=""d4p1:ConnectorLineType"">Solid</style>
    |</border>";    

    #Область ДобавлениеСпецифическихСвойств
    
    Если рТипЭлемента=0 Тогда // декорация
        сс=сс+"        
        |<shape>"+АнглИмя(пар.Фигура)+"</shape>
        |<flipMode>0</flipMode>
        |<angle xsi:type=""xs:decimal"">0</angle>"; // вероятно, поворот вокруг своей оси
        
    ИначеЕсли рТипЭлемента=1 Тогда // линия
        сс=сс+"
        |<connectFromItemId>"+СокрЛП(пар.Откуда)+"</connectFromItemId>
        |<connectFromPortIndex>"+СокрЛП(пар.ВариантОткуда)+"</connectFromPortIndex>
        |<connectToItemId>"+СокрЛП(пар.Куда)+"</connectToItemId>
        |<decorativeLine>"+?(пар.Свойство("ДекоративнаяЛиния"),Формат(пар.ДекоративнаяЛиния,фБул),"false")+"</decorativeLine>
        |<portIndexFrom>"+СокрЛП(пар.НаправлениеОткуда)+"</portIndexFrom>
        |<portIndexTo>"+СокрЛП(пар.НаправлениеКуда)+"</portIndexTo>
        |<textPos>"+?(пар.Свойство("ПоложениеТекста"),АнглИмя(пар.ПоложениеТекста),"FirstSegment")+"</textPos>
        |<beginArrowStyle>"+?(пар.Свойство("СтильСтрелкиНачало"),АнглИмя(пар.СтильСтрелкиНачало),"None")+"</beginArrowStyle>
        |<endArrowStyle>"+?(пар.Свойство("СтильСтрелкиКонец"),АнглИмя(пар.СтильСтрелкиКонец),"Filled")+"</endArrowStyle>";
        
    ИначеЕсли рТипЭлемента=2 Тогда // начало
        // специальных нет
        
    ИначеЕсли рТипЭлемента=3 Тогда // завершение
        // специальных нет
        
    ИначеЕсли рТипЭлемента=4 Тогда // условие
        сс=сс+"        
        //<eventHandler>
        //   <id>0</id>
        //   <name>БлокУсловияПроверкаУсловия</name>
        ///eventHandler>        
        // выход ветки Нет (1 - влево, 3 - вправо)
        |<truePortIndex>"+?(пар.Свойство("НаправлениеВеткиДа"),Строка(пар.НаправлениеВеткиДа),"3")+"</truePortIndex>
        |<falsePortIndex>"+?(пар.Свойство("НаправлениеВеткиНет"),Строка(пар.НаправлениеВеткиНет),"1")+"</falsePortIndex>";
        
    ИначеЕсли рТипЭлемента=5 Тогда // действие
        сс=сс+"
        |<taskDescription>"+пар.ОписаниеДействия+"</taskDescription>
        |<explanation>"+пар.АдресацияДействия+"</explanation>
        |<groupAddressing>"+?(пар.Свойство("ГрупповаяАдресация"),Формат(пар.ГрупповаяАдресация,фБул),"false")+"</groupAddressing>
        // значение разделения на область адресации и область описания, ставим всегда Истина
        |<isAddrZoneDivideValid>true</isAddrZoneDivideValid>
        // позиция разделителя по высоте между областью адресации и описанием действия
        |<addrZoneDivideYPos>"+Строка(?(пар.Свойство("ВысотаОбластиАдресации"),пар.ВысотаОбластиАдресации,16))+"</addrZoneDivideYPos>
        |";
        
    ИначеЕсли рТипЭлемента=6 Тогда // выбор варианта
        квоВариантов=пар.Варианты.Количество();
        Для й=0 По квоВариантов-1 Цикл
            рВариант=пар.Варианты.Получить(й);
            сс=сс+"
            |<transition>
            |<name>"+рВариант.Идентификатор+"</name>
            |<description><item xmlns=""http://v8.1c.ru/8.1/data/core""><lang>#</lang>
            |<content>"+рВариант.ТекстЗаголовка+"</content></item></description>
            |<backColor>auto</backColor>
            |</transition>";
            //
            // добавляем линию с координатой, начинающейся от середины варианта
            //парПолучателяЛинии=соотДобавленных.Получить(рВариант.Куда); - если надо получитьэти данные
            парЛВ=Новый Структура;
            парЛВ.Вставить("Имя","ЛинияВарианта"+рВариант.Идентификатор);
            парЛВ.Вставить("ТипЭлемента","ЭлементГрафическойСхемыДекоративнаяЛиния");
            парЛВ.Вставить("Идентификатор",ПолучитьСтаршийИдентификатор(строГС));
            парЛВ.Вставить("ТекстЗаголовка","");
            парЛВ.Вставить("Откуда",рИдентификатор);
            парЛВ.Вставить("Куда",рВариант.Куда); // идентификатор элемента, куда должна вести стрелка от варианта
            парЛВ.Вставить("ВариантОткуда",0);
            парЛВ.Вставить("ДекоративнаяЛиния",Истина);
            парЛВ.Вставить("ПоложениеТекста",ПоложениеТекстаСоединительнойЛинии.СерединаЛинии);
            парЛВ.Вставить("НаправлениеОткуда",ТипСтороныЭлементаГрафическойСхемы.Право); // всегда
            парЛВ.Вставить("НаправлениеКуда",?(ЗначениеЗаполнено(рВариант.НаправлениеКуда),рВариант.НаправлениеКуда,ТипСтороныЭлементаГрафическойСхемы.Верх));
            рКоординатыЛинии=Новый Структура;
            рКоординатыЛинии.Вставить("Лево",пар.КоординатыКонтура.Право);
            рКоординатыЛинии.Вставить("Верх",пар.КоординатыКонтура.Низ-9-18*(квоВариантов-1-й));
            парЛВ.Вставить("КоординатыКонтура",рКоординатыЛинии);
            ДобавитьФигуру(строГС,парЛВ,соотДобавленных);
        КонецЦикла;
        
        //<eventHandler>
        //    <id>0</id>
        //    <name>БлокВыборВариантаОбработкаВыбораВарианта</name>
        //</eventHandler>
        
    ИначеЕсли рТипЭлемента=7 Тогда // точка разделения
        // специальных нет
        
    ИначеЕсли рТипЭлемента=8 Тогда // точка слияния
        // специальных нет
        
    ИначеЕсли рТипЭлемента=9 Тогда // обработка
        // специальных нет
        
    ИначеЕсли рТипЭлемента=10 Тогда // вложенный процесс
        //<subprocessUUID>a5f642e1-d2ab-4106-b6dc-d6f85222c430</subprocessUUID>
        сс=сс+"
        |<taskDescription>"+пар.ТекстЗаголовкаБП+"</taskDescription>";
        
    КонецЕсли;
    
    #КонецОбласти

    сс=сс+"
    |</item>";
    
    строГС=СтрЗаменить(строГС,"<!--ReplacingPoint-->",сс+Символы.ПС+"<!--ReplacingPoint-->");
    
    соотДобавленных.Вставить(рИдентификатор,пар);

    Возврат сс;
    
Исключение
    Сообщить("ДобавитьФигуру, ошибка: "+ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
    Возврат "";
КонецПопытки;
КонецФункции

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

&НаКлиенте
// Готовит общее объявление пустой графической схемы с общими свойствами
//   [ИспользоватьСетку] (булево),
//   [РежимОтрисовкиСетки] (РежимОтрисовкиСеткиГрафическойСхемы), если не указан, и ИспользоватьСетку=Истина, то Lines.
//   [ГоризонтальныйШагСетки] (число),
//   [ВертикальныйШагСетки] (число),
//   [Вывод] (ИспользованиеВывода)
//
Функция ИнициализироватьГрафическуюСхему(пар=Неопределено)
    Если ТипЗнч(пар)<>Тип("Структура") Тогда пар=Новый Структура КонецЕсли;
    Если пар.Свойство("ИспользоватьСетку") и пар.ИспользоватьСетку и не пар.Свойство("РежимОтрисовкиСетки") Тогда
        рРежимОтрисовки="Lines";
    Иначе
        рРежимОтрисовки=?(пар.Свойство("РежимОтрисовкиСетки"),пар.РежимОтрисовкиСетки,"None");
    КонецЕсли;
    сс="<FlowchartContextType xmlns=""http://v8.1c.ru/8.2/data/graphscheme"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
    |<backColor xmlns:d2p1=""http://v8.1c.ru/8.1/data/ui/style"">d2p1:FieldBackColor</backColor>
    |<enableGrid>"+?(пар.Свойство("ИспользоватьСетку"),Формат(пар.ИспользоватьСетку,"БЛ=false; БИ=true"),"false")+"</enableGrid>
    |<drawGridMode>"+рРежимОтрисовки+"</drawGridMode>
    |<gridHorizontalStep>"+Строка(?(пар.Свойство("ГоризонтальныйШагСетки"),СокрЛП(пар.ГоризонтальныйШагСетки),20))+"</gridHorizontalStep>
    |<gridVerticalStep>"+Строка(?(пар.Свойство("ВертикальныйШагСетки"),СокрЛП(пар.ВертикальныйШагСетки),20))+"</gridVerticalStep>
    |<bpUUID>00000000-0000-0000-0000-000000000000</bpUUID>
    |<useOutput>"+?(пар.Свойство("Вывод"),АнглИмя(пар.Вывод),"Auto")+"</useOutput>
    |<printPropItem><key>6</key><val>10</val></printPropItem>
    |<printPropItem><key>7</key><val>10</val></printPropItem>
    |<printPropItem><key>8</key><val>10</val></printPropItem>
    |<printPropItem><key>9</key><val>10</val></printPropItem>
    |<printPropItem><key>13</key><val>0</val></printPropItem>
    |<printPropItem><key>16</key><val>0</val></printPropItem>
    |<!--ReplacingPoint-->
    |</FlowchartContextType>";
    Возврат сс;
КонецФункции

#КонецОбласти



// Пример использования (он и порождает схему, представленную на картинке к публикации):

&НаКлиенте
Процедура ВывестиСхему()

    соотДобавленных=Новый Соответствие;
    
    пар=Новый Структура;
    строГС=ИнициализироватьГрафическуюСхему(пар);
    //
    идСтарт=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестСтарта");
    пар.Вставить("ТипЭлемента","ЭлементГрафическойСхемыСтарт");
    пар.Вставить("Идентификатор",идСтарт);
    пар.Вставить("ТекстЗаголовка","Погнали!");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",100,30,100,40));
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идДействие1=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестДействия");
    пар.Вставить("ТипЭлемента",Тип("ЭлементГрафическойСхемыДействие"));
    пар.Вставить("Идентификатор",идДействие1);
    пар.Вставить("ТекстЗаголовка","Это действие");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",100,120,100,60));
    пар.Вставить("ОписаниеДействия","Некое действие в системе");
    пар.Вставить("АдресацияДействия","И.И.Иванов");
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идУсловие=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестУсловия");
    пар.Вставить("ТипЭлемента",Тип("ЭлементГрафическойСхемыУсловие"));
    пар.Вставить("Идентификатор",идУсловие);
    пар.Вставить("ТекстЗаголовка","А я знаю?");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",100,220,100,40));
    пар.Вставить("НаправлениеВеткиДа",3); // вправо
    пар.Вставить("НаправлениеВеткиНет",1); // влево
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идДействие2=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестДействия2");
    пар.Вставить("ТипЭлемента",Тип("ЭлементГрафическойСхемыДействие"));
    пар.Вставить("Идентификатор",идДействие2);
    пар.Вставить("ТекстЗаголовка","Тоже что-то");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",10,280,100,60));
    пар.Вставить("ОписаниеДействия","Некое действие в системе");
    пар.Вставить("АдресацияДействия","Петров");
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    пар=Новый Структура;
    пар.Вставить("Имя","ТестЛинии2");
    пар.Вставить("ТипЭлемента","ЭлементГрафическойСхемыДекоративнаяЛиния");
    пар.Вставить("Идентификатор",ПолучитьСтаршийИдентификатор(строГС));
    пар.Вставить("ТекстЗаголовка","Нет");
    пар.Вставить("Откуда",идУсловие);
    пар.Вставить("Куда",идДействие2);
    пар.Вставить("ВариантОткуда",0);
    пар.Вставить("ДекоративнаяЛиния",Истина);
    пар.Вставить("ПоложениеТекста",ПоложениеТекстаСоединительнойЛинии.ПервыйСегмент);
    пар.Вставить("СтильСтрелкиНачало",СтильСтрелки.Нет);
    пар.Вставить("СтильСтрелкиКонец",СтильСтрелки.Заполненная);
    пар.Вставить("НаправлениеОткуда",ТипСтороныЭлементаГрафическойСхемы.Лево);
    пар.Вставить("НаправлениеКуда",ТипСтороныЭлементаГрафическойСхемы.Верх);
    пар.Вставить("КоординатыКонтура",Новый Структура("СерединаГор,СерединаВерт",60,240));
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идОбр=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестОбработки");
    пар.Вставить("ТипЭлемента",Тип("ЭлементГрафическойСхемыОбработка"));
    пар.Вставить("Идентификатор",идОбр);
    пар.Вставить("ТекстЗаголовка","Зашли сюды");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",180,290,100,60));
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    пар=Новый Структура;
    пар.Вставить("Имя","ТестЛинии3");
    пар.Вставить("ТипЭлемента","ЭлементГрафическойСхемыДекоративнаяЛиния");
    пар.Вставить("Идентификатор",ПолучитьСтаршийИдентификатор(строГС));
    пар.Вставить("ТекстЗаголовка","Да");
    пар.Вставить("Откуда",идУсловие);
    пар.Вставить("Куда",идОбр);
    пар.Вставить("ВариантОткуда",0);
    пар.Вставить("ДекоративнаяЛиния",Истина);
    пар.Вставить("ПоложениеТекста",ПоложениеТекстаСоединительнойЛинии.ПервыйСегмент);
    пар.Вставить("СтильСтрелкиНачало",СтильСтрелки.Нет);
    пар.Вставить("СтильСтрелкиКонец",СтильСтрелки.Заполненная);
    пар.Вставить("НаправлениеОткуда",ТипСтороныЭлементаГрафическойСхемы.Право);
    пар.Вставить("НаправлениеКуда",ТипСтороныЭлементаГрафическойСхемы.Верх);
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идСтоп=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестСтопа");
    пар.Вставить("ТипЭлемента","ЭлементГрафическойСхемыЗавершение");
    пар.Вставить("Идентификатор",идСтоп);
    пар.Вставить("ТекстЗаголовка","Тпрууу!");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",740,210,100,40));
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идБП1=ПолучитьСтаршийИдентификатор(строГС);
    пар=Новый Структура;
    пар.Вставить("Имя","ТестБП");
    пар.Вставить("ТипЭлемента",Тип("ЭлементГрафическойСхемыВложенныйБизнесПроцесс"));
    пар.Вставить("Идентификатор",идБП1);
    пар.Вставить("ТекстЗаголовка","Вложенный БП");
    пар.Вставить("ТекстЗаголовкаБП","Нечто внутри!");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",560,290,100,60));
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    идВар=ПолучитьСтаршийИдентификатор(строГС);
    мвар=Новый Массив;
    мвар.Добавить(Новый Структура("Идентификатор,ТекстЗаголовка,Куда,НаправлениеКуда","Вариант1","Превосходно!",идСтоп));
    мвар.Добавить(Новый Структура("Идентификатор,ТекстЗаголовка,Куда,НаправлениеКуда","Вариант2","Замечательно!",идБП1));
    пар=Новый Структура;
    пар.Вставить("Имя","ТестВарианта");
    пар.Вставить("ТипЭлемента",Тип("ЭлементГрафическойСхемыВыборВарианта"));
    пар.Вставить("Идентификатор",идВар);
    пар.Вставить("ТекстЗаголовка","Так как, собственно?");
    пар.Вставить("КоординатыКонтура",Новый Структура("Лево,Верх,Ширина,Высота",440,100,140,100));
    пар.Вставить("Варианты",мвар);
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    пар=Новый Структура;
    пар.Вставить("Имя","ТестЛинии4");
    пар.Вставить("ТипЭлемента","ЭлементГрафическойСхемыДекоративнаяЛиния");
    пар.Вставить("Идентификатор",ПолучитьСтаршийИдентификатор(строГС));
    пар.Вставить("ТекстЗаголовка","");
    пар.Вставить("Откуда",идОбр);
    пар.Вставить("Куда",идВар);
    пар.Вставить("ВариантОткуда",0);
    пар.Вставить("ДекоративнаяЛиния",Истина);
    пар.Вставить("ПоложениеТекста",ПоложениеТекстаСоединительнойЛинии.ПервыйСегмент);
    пар.Вставить("СтильСтрелкиНачало",СтильСтрелки.Нет);
    пар.Вставить("СтильСтрелкиКонец",СтильСтрелки.Заполненная);
    пар.Вставить("НаправлениеОткуда",ТипСтороныЭлементаГрафическойСхемы.Право);
    пар.Вставить("НаправлениеКуда",ТипСтороныЭлементаГрафическойСхемы.Верх);
    пар.Вставить("КоординатыКонтура",Новый Структура("СерединаГор,СерединаВерт",400,80));
    ДобавитьФигуру(строГС,пар,соотДобавленных);
    
    СоединитьФигурыЛинией(строГС,соотДобавленных,идСтарт,идДействие1,"Вниз");
    СоединитьФигурыЛинией(строГС,соотДобавленных,идДействие1,идУсловие,"Вниз");
    //СоединитьФигурыЛинией(строГС,соотДобавленных,идУсловие,идДействие2,"Влево");
    //СоединитьФигурыЛинией(строГС,соотДобавленных,идУсловие,идСтоп,"Вниз");
    
    ГС=ДесериализоватьГС(строГС);
КонецПроцедуры

Если теги всё-таки побьются, пишите в личку - пришлю исходник как файл.

Кому пригодится - буду рад. Если возникнут пожелания по доработке, тоже отписывайтесь в теме или в личке. А то ведь метода УдалитьФигуру я делать пока не стал, лень-матушка.

 

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

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Alias 156 19.07.16 16:54 Сейчас в теме
Тэги не побились, всё работает.
Вернее, почти всё... в случае если региональные установки разделителя целой и дробной является запятая (Россия), в XML попадают числа типа 191,5 (с запятой), что делает результирующую XML-строку некорректной. Дроби получились от деления на 2 (когда ищем середину).
Заменил Строка() на XMLСтрока() в функции ДобавитьКоординатыФигуры(), после чего стало совсем замечательно.

P.S. Линии декоративные вместо нормально-привязанных (например, от выбора варианта), это недоработка или особенность?
2. Yashazz 3318 19.07.16 19:28 Сейчас в теме
(1) Alias, блин, насчёт декоративных линий - это я в итоге мучений с публикацией не ту версию скопипастил. Конечно, там должны быть привязываемые. Это рулится параметром "ДекоративнаяЛиния". Извиняюсь. А вот насчёт формата - тупо прохлопал. Постараюсь обновить публикацию, спасибо.
Atori-kun; +1 Ответить
3. vandalsvq 1154 19.07.16 22:55 Сейчас в теме
(2) прикрепи обработку, у кого мани есть могут скачать. Все лучше чем со статьи копипастить ))))
4. Сурикат 307 20.07.16 08:44 Сейчас в теме
Огромное спасибо за публикацию!
5. Yashazz 3318 20.07.16 09:28 Сейчас в теме
Коллеги-товарищи, я собираюсь эту штуку развивать дальше, поэтому очень приветствуется критика. Где-какие косяки и недоработки, пишите.
6. konstruktiv 20.07.16 13:59 Сейчас в теме
(5) тоже делал такое, также использовал XDTO-сериализацию. В своем время разобрался со многими вещами, даже которые нельзя было сделать интерактивно (перевернуть фигуру на 75 градусов, фон заштриховать). Бросил это дело из-за одной мелочи, поэтому хочу сразу предостеречь. Но возможно я просто не нашел решения.
1. Получается, что стрелки можно сделать только параллельно осям с изгибом только в 90 градусов. Тут вроде бы не страшно. Не так уж плохо и выглядит.
2. Когда связываешь стрелку с фигурой - то есть при интерактивном перетаскивании фигуры стрелка не отклеивается - так вот стрелка может примыкать только к одному из 4 секторов, только к одной точке. А это уже порождает ограничения.
Например разными стрелками будем обозначать товар, деньги и т.п. Соответственно из-за описанных выше ограничений стрелки разного вида сольются в одну. Можно сделать чтобы при первом формировании они не склеивались, но как только передвинешь что-то мышкой, они склеиваются. А интерактивность все-таки лучше оставить в таком продукте.
8. Yashazz 3318 20.07.16 14:35 Сейчас в теме
(6) Ага, копаю в эту сторону.
Кстати, в процессе изучения выяснилось, что рисовать можно ЛЮБЫЕ фигуры. Любой формы. Если задать координаты, так получаются жуткие звёзды, кривые косоугольники и прочая прелесть. Ну и декорации со всякими овалами тоже))) Тут да, простор для творчества. Правда, надпись при этом может отказаться не внутри многоугольника, а где-то вообще мимо.

(7) Справедливости ради, я где-то в планах 1С видел программное изменение коллекций фигур схемы, но под таким пятизначным приоритетом, что ещё год-полтора ждать точно...
9. konstruktiv 20.07.16 15:19 Сейчас в теме
(8) про любые фигуры тоже проходили)) вроде скрытых возможностей дофига, но как только пытаешься приложить к какой-нибудь реальной задаче, так руки опускаются
7. konstruktiv 20.07.16 14:03 Сейчас в теме
(5) с этими ключами тоже разобрался:
<printPropItem><key>6</key><val>10</val></printPropItem>
|<printPropItem><key>7</key><val>10</val></printPropItem>
|<printPropItem><key>8</key><val>10</val></printPropItem>
|<printPropItem><key>9</key><val>10</val></printPropItem>
|<printPropItem><key>13</key><val>0</val></printPropItem>
|<printPropItem><key>16</key><val>0</val></printPropItem>
Я не скачивал обработку, но я использовал только сериализованные объекты, которые дает платформа, сам текст XML не парсил и не собирал.
А вообще ощущение, что сами 1сники забросили этот объект, а жаль...
10. Nikola23 511 21.07.16 09:08 Сейчас в теме
(5) Зачем тратить силы на собирание строк XML вручную, если то же самое прекрасно работает с использованием XDTO? Объектная модель рулит.
Чем принципиально эта публикация отличается от еще нескольких подобных? Много кода, но зачем?
11. Yashazz 3318 21.07.16 15:45 Сейчас в теме
(10) Nikola23, покажите мне эти подобные, пожалуйста. Кроме работы Diversus'а, конечно. И объясните насчёт XDTO - вы предлагаете оперировать абстракциями на уровне элементов схемы? Ну, можно и так, конечно, только вот у меня несколько попыток подобного подхода обламывались - схема не собиралась обратно.

Чем ещё отличается - полной доступностью. Можно воспользоваться безо всяких стартманей.
12. Nikola23 511 27.07.16 00:53 Сейчас в теме
(11) Никаких хитрых абстракций.
Предлагаю возможность настраивать свойства (в т..ч. методом тыка) с использованием привычной объектной модели.
Если задача сводится к нарисовать - то Ваш метод может и подойдет, а если необходимо проанализировать структуру связей схемы и построить по нарисованной картинке автоматизацию?
Если не нашли решения на инфостарте, это значит, либо плохо искали, либо оно куда-то делось.
Я пользуюсь наработками скачанными отсюда.
13. Yashazz 3318 27.07.16 17:44 Сейчас в теме
(12) Nikola23, а, так это я тоже практикую. В публикации http://infostart.ru/public/531533/ я именно так и поступил - создал только самое необходимое, дальше донастроил штатными методами и свойствами языка.
А вот за отсутствие пруфлинка и при этом фразу "плохо искали" - мой вам респект, ибо отсутствие ссылки значит, что аналогов у моей публикации всё-таки нету)))
14. user595212_go.blin2014 25.08.16 22:39 Сейчас в теме
Ценная статья, благодарю.
16. Yashazz 3318 08.09.16 09:55 Сейчас в теме
(15) DrAku1a, да, я указал её как первоисточник. Я от этой идеи собственно и отталкивался. Ещё раз Diversus'у спасибо.
Правда, там в комментах один товарищ указывает, что это всё было изобретено ещё раньше. Что, в общем, не удивительно)
21. RainyAugust22 250 29.12.16 07:26 Сейчас в теме
Где можно скачать в виде обработки?
Скопипастил код в обработку, не получается запустить, помогите плз:
{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(16)}: Ошибка при вызове метода контекста (ПрочитатьXML)
Возврат СериализаторXDTO.ПрочитатьXML(чтен,Тип("ГрафическаяСхема"));
по причине:
Ошибка преобразования данных XDTO:
НачалоСвойства: {http://v8.1c.ru/8.2/data/graphscheme}FlowchartContextType Форма: Элемент Тип: {http://v8.1c.ru/8.2/data/graphscheme}FlowchartContextType
по причине:
Ошибка преобразования данных XDTO:
Значение: 191,5 Тип: {http://www.w3.org/2001/XMLSchema}decimal
по причине:
Ошибка отображения типов:
Отображение типа '{http://www.w3.org/2001/XMLSchema}decimal' в тип 'Число'
22. Yashazz 3318 29.12.16 12:15 Сейчас в теме
(21) Ух, красота... Какая у Вас платформа 1С?
23. RainyAugust22 250 29.12.16 15:41 Сейчас в теме
24. Yashazz 3318 29.12.16 20:46 Сейчас в теме
(23) Так это, думаю, просто релиз кривой. 1С, как всегда, косячат неимоверно. Попробуйте на чём-то надёжном вроде 8.3.6
17. serg_infostart 330 22.09.16 16:38 Сейчас в теме
Нужен жесткий контроль за itemid, нельзя допускать повторения - иначе будут глюки (срывается соединение между элементами при любой подвижке элемента).
В вышеуказанном блоке изменить:
				// добавляем линию с координатой, начинающейся от середины варианта
				//парПолучателяЛинии=соотДобавленных.Получить(рВариант.Куда); - если надо получитьэти данные
				парЛВ=Новый Структура;
				парЛВ.Вставить("Имя","ЛинияВарианта"+рВариант.Идентификатор);
				парЛВ.Вставить("ТипЭлемента","ЭлементГрафическойСхемыДекоративнаяЛиния");
				парЛВ.Вставить("Идентификатор",ПолучитьСтаршийИдентификатор(строГС));

на:
				// добавляем линию с координатой, начинающейся от середины варианта
				//парПолучателяЛинии=соотДобавленных.Получить(рВариант.Куда); - если надо получитьэти данные
				парЛВ=Новый Структура;
				парЛВ.Вставить("Имя","ЛинияВарианта"+рВариант.Идентификатор);
				парЛВ.Вставить("ТипЭлемента","ЭлементГрафическойСхемыДекоративнаяЛиния");
				парЛВ.Вставить("Идентификатор",пар.Идентификатор + й + 1); // Вот тут нужно изменить - иначе добавляет существующие itemid 

В остальном, все хорошо.
Напрашивается оптимизация кода, возможно через использование ФабрикиXDTO. И выпустить в виде отдельного серверного модуля.
Я же хочу на вход подавать простейшую структуру взаимосвязей, на выходе получать ГрафическуюСхему - как раз в процессе производства.
И конечно же благодаря статье сэкономлена куча времени. Автору и предшественникам благодарность.
18. serg_infostart 330 22.09.16 17:01 Сейчас в теме
Да, еще нюанс.
Системные перечисления сторон (portIndex):
1: Лево
2: Верх
3: Право
4: Низ
5: Центр
6: Вариант 1 Лево
7: Вариант 1 Право
8: Вариант 2 Лево
9: Вариант 2 Право
10: ..... и т.д.

Поэтому, придется исправить еще и порт источника для Декоративной линии варианта.
Кусок кода
				парЛВ.Вставить("НаправлениеОткуда",ТипСтороныЭлементаГрафическойСхемы.Право); // всегда

меняем на
				парЛВ.Вставить("НаправлениеОткуда",7+й*2); // всегда
19. serg_infostart 330 22.09.16 17:09 Сейчас в теме
Не обязательно, т.к. работает и без этого, но...
Для чистоты преобразований заменим
парЛВ.Вставить("ВариантОткуда",0);
заменить на
парЛВ.Вставить("ВариантОткуда",й);
20. serg_infostart 330 27.09.16 15:29 Сейчас в теме
Сделал объектную модель. Ссылка на эту статью имеется - без этой статьи не решился бы создать свой вариант реализации.
http://infostart.ru/public/551576/ (скоро будет доступна).
Оставьте свое сообщение

См. также

Использование программных перечислений, ч.1: строковые константы Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    36785    unichkin    46    

Программная работа с настройками СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

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

27.01.2020    21889    ids79    26    

[СКД] Программное создание схемы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

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

15.01.2020    20464    John_d    22    

Последовательности событий. Шпаргалка

Практика программирования v8 Россия Бесплатно (free)

Собрал информацию о событиях/подписках/расширениях в одном месте.

30.12.2019    15255    kuzyara    33    

Вспомогательные инструкции в коде 1С Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    29292    tormozit    100    

30 задач. Странных и не очень

Практика программирования v8 Бесплатно (free)

30 задач на знание языка программирования 1С и некоторого поведения платформы. Маленьких. Странных и не очень.

02.12.2019    16240    YPermitin    72    

Как передать IP адрес, который вызвал HTTP запрос в 1C (для веб-сервера Apache)

Практика программирования v8 Бесплатно (free)

Столкнулся с задачей получения IP адреса, который вызывает http сервис 1С. Итак, решение:

22.11.2019    7864    Sibars    19    

Таблица значений. Нюансы

Практика программирования v8 Бесплатно (free)

Обзор некоторых аспектов использования общеизвестного инструмента 1С.

01.10.2019    30122    Yashazz    46    

Оформление и рефакторинг сложных логических выражений Промо

Практика программирования v8 Россия Бесплатно (free)

В сложных логических выражениях нередко самому автору спустя какое-то время тяжело разобраться, не говоря уже о других программистах. Предлагаемая методика позволяет повысить наглядность таких выражений путем оформления в виде И-ИЛИ дерева и одновременно выполнять их рефакторинг.

20.09.2012    77191    tormozit    131    

[Шпаргалка] Программное создание элементов формы

Практика программирования Работа с интерфейсом v8 1cv8.cf Бесплатно (free)

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

06.09.2019    43515    rpgshnik    63    

Агрегатные функции СКД, о которых мало кто знает

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    45191    ids79    54    

Регистры бухгалтерии. Общая информация

Практика программирования Математика и алгоритмы v8 v8::БУ БУ Бесплатно (free)

Общая информация о внутреннем устройстве регистров бухгалтерии.

05.09.2019    26109    YPermitin    24    

Запись значения в поле ввода/формы со срабатыванием события ПриИзменении Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

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

11.07.2007    47477    tormozit    40    

Три костыля. Сказ про фокусы в коде

Практика программирования v8 Бесплатно (free)

Три интересных (или странных) костыля в коде, которые могут помочь в повседневных и не очень задачах.

03.09.2019    24814    YPermitin    80    

Отслеживание выполнения фонового задания

Практика программирования Универсальные функции Разработка v8 1cv8.cf Бесплатно (free)

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    30037    ids79    16    

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    71723    ids79    49    

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    43773    tormozit    74    

Фоновое выполнение кода в 1С - это просто

Практика программирования v8 1cv8.cf Бесплатно (free)

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

02.08.2019    31446    avalakh    22    

Разбираемся с параметрами редактирования СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Связь по типу, Параметры выбора, Связи параметров выбора

31.07.2019    21491    json    13    

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    53056    ids79    11    

Выгрузка документа по условию Промо

Практика программирования Разработка v8 Бесплатно (free)

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    15843    m-rv    2    

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ

Инструментарий разработчика Практика программирования v8 v8::СКД Бесплатно (free)

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    33719    ids79    27    

Регистры сведений. За кулисами

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Небольшие заметки по внутреннему устройству регистров сведений.

09.07.2019    25105    YPermitin    14    

"Меньше копипаста!", или как Вася универсальную процедуру писал

Практика программирования Разработка v8 v8::СКД 1cv8.cf Бесплатно (free)

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    19268    SeiOkami    50    

Как прикрутить ГУИД к регистру сведений Промо

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 Бесплатно (free)

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

16.04.2019    19832    m-rv    17    

Работа с настройками системы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

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

02.07.2019    41466    ids79    17    

Создание отчетов с помощью СКД - основные понятия и элементы

Практика программирования Математика и алгоритмы v8 v8::СКД Бесплатно (free)

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    48739    ids79    25    

Многопоточное ускорение однопользовательских нагрузок в 1С + Microsoft SQL Server 2017

Практика программирования Производительность и оптимизация (HighLoad) v8 v8::Запросы Бесплатно (free)

Взаимодействие с Microsoft SQL Server нередко вызывает трудности у 1С-ников, а потому интересны любые моменты, связанные с его использованием. О своем опыте работы с новым SQL Server 2017 участникам конференции Infostart-2018 рассказал директор ООО «Аналитика софт» Дмитрий Дудин.

11.06.2019    23913    dmurk    144    

Как сделать запрос на изменение данных Промо

Практика программирования v8 v8::Запросы 1cv8.cf Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    29927    m-rv    21    

Регистры накопления. Виртуальные таблицы. Часть №2: "Остатки" и "Остатки и обороты"

Практика программирования v8 1cv8.cf Бесплатно (free)

Описание работы платформы 1С:Предприятие 8.2 с виртуальными таблицами регистров накопления "Остатки" и "Остатки и обороты". Анализ SQL-запрос при работе с виртуальными таблицами

22.05.2019    21921    YPermitin    7    

Регистры накопления. Структура хранения в базе данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

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

16.05.2019    40350    YPermitin    30    

Выполнение внешней обработки в фоновом задании

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Подробное описание подхода к созданию длительной операции на основе внешней обработки. Реализация протестирована на 1С 8.3.12.1714 (x64).

11.05.2019    28369    Eret1k    23    

Метод формирования движений в типовых регистрах нетиповыми регистраторами Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    27988    itriot11    34    

О расширениях замолвите слово...

Практика программирования Разработка v8 Бесплатно (free)

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    34148    ellavs    126    

Git-репозитории для 1С-кода (опыт использования при небольших проектах)

Практика программирования v8 Бесплатно (free)

Инструкции по взаимодействию с Git-репозиторием, которые писались для тех наших программистов, которые вообще никогда не работали с Git (руководства в духе "Как получить код из git-репозитория?", "Как отправить код в git-репозиторий")...

28.03.2019    26502    ellavs    88    

Трюки с внешними источниками данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Некоторые трюки для преодоления ограничений внешних источников данных.

14.03.2019    30346    YPermitin    53    

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    75433    Serginio    108    

Ошибки при работе с хранилищем конфигурации и способы их решения

Практика программирования v8 Бесплатно (free)

В статье собраны наиболее распространенные ошибки при работе с хранилищем конфигурации и способы их обхода и решения.

01.03.2019    35903    Смешной 1С    27    

Разработка и сценарное тестирование с Vanessa-ADD. Отчетность Allure. Автоматизация запуска сценариев

Практика программирования Vanessa Automation v8 Россия Бесплатно (free)

Формируем отчетность о результатах выполнения сценариев. Автоматизируем запуск.

26.02.2019    20921    Vladimir Litvinenko    27    

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С Промо

Математика и алгоритмы Практика программирования v8 v8::blocking 1cv8.cf Бесплатно (free)

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    33662    ids79    40    

Возможности типовых шаблонов ограничения доступа на уровне записей (RLS)

Практика программирования БСП (Библиотека стандартных подсистем) Роли и права v8 v8::Права Бесплатно (free)

Краткий обзор применения типовых шаблонов ограничения доступа на уровне записей в конфигурациях, созданных на базе БСП: #ПоЗначениям, #ПоНаборамЗначений, #ПоЗначениямРасширенный, #ПоЗначениямИНаборамРасширенный

03.02.2019    36767    ids79    9    

Тестер: частые вопросы Промо

Практика программирования v8 Бесплатно (free)

Ошибкам бой - тесты норма жизни!

25.07.2018    28855    grumagargler    28    

EnterpriseData – часть 2. Процесс выгрузки данных

Практика программирования Обмен через XML v8 v8::УФ Россия Бесплатно (free)

Основные этапы выгрузки данных через ED, обработчики событий выгрузки, правила обработки данных, правила конвертации объектов, конвертация свойств первого и второго этапов, процедуры БСП, используемые при выгрузке данных, структура «КомпонентыОбмена».

26.12.2018    25731    ids79    31    

Новый подход к обмену данными EnterpriseData

Практика программирования Обмен через XML v8 v8::УФ Россия Бесплатно (free)

Хочу предложить Вашему вниманию цикл статей, посвященных обмену данными через универсальный формат (EnterpriseData или ED).

14.12.2018    39494    ids79    72    

EnterpriseData - пример доработки правил конвертации без использования КД 3.0 в расширении конфигурации

Практика программирования Обмен через XML v8 v8::УФ БП3.0 УТ11 Россия Бесплатно (free)

В статье подробно описан реальный пример доработки обмена данными через EnterpriseData (универсальный формат обмена) между конфигурациями УТ 11.4 и Бухгалтерия 3.0

16.11.2018    35833    ids79    40    

Ускоряем 1С: модули с повторным использованием возвращаемых значений Промо

Практика программирования v8 Бесплатно (free)

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

04.09.2017    51764    m-rv    61    

Программное заполнение пользовательских параметров и отборов СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

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

13.11.2018    43894    Unk92    21