Кодогенерация и метагенерация в 1С

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

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

24
В своем докладе на конференции INFOSTART EVENT 2018 EDUCATION Дмитрий Белозеров рассказал о разработке инструмента, позволяющего программно работать с метаданными 1С и писать скрипты для выполнения тех же действий, которые выполняет разработчик в конфигураторе –  с какими сложностями и нюансами пришлось столкнуться, и что получилось в итоге.

 

 

Здравствуйте, коллеги. Меня зовут Дмитрий Белозеров. Я работаю системным архитектором в компании LM Soft. Мы занимаемся внедрением систем проектного управления, управления жизненным циклом изделий и другими сложными и интересными решениями.

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

 

Что такое кодогенерация?

 

 

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

 

 

Но в самой идее, которая заложена в основе, нет ничего особо нового. 

 

 

Если вы в поисковике напишите слово «кодогенерация», то можете найти на эту тему много хороших статей и видео, в том числе и на русском языке – в последнее время я видел на YouTube несколько классных докладов по кодогенерации от разработчиков из мира Java, .NET, Swift и т.д.

Но надо понимать, что наша 1С – это достаточно специфическая среда разработки, и все эти практики требуют некоторой адаптации под особенности платформы.

 

 

Давайте сначала дадим определение, что такое кодогенерация. Это – очень широкое понятие:

  • Когда вы просто пишите код в конфигураторе, вы тоже в каком-то смысле занимаетесь кодогенерацией. 

  • Или, когда, например, вы в «Конвертации данных 3.0» пишите правило, а потом на его основе формируете код на языке 1С, это тоже кодогенерация. 

  • Или, например, когда вы заходите на сайт Facebook или ВКонтакте, то в этот момент тоже выполняется кодогенерация – весь Web2.0 технически основан на кодогенерации.

  • Но в нашем случае кодогенерация – это когда одна программа на языке высокого уровня пишет другую программу на языке высокого уровня. Я буду говорить сегодня именно об этом. 

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

После такого определения, я думаю, у вас должен возникнуть вопрос – зачем такие сложности? Зачем генератор? Зачем код на исходном языке?

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

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

  • Расширяете состав определяемого типа;

  • Включаете объект в состав подписки на событие;

  • Добавляете какую-то строчку в модуль формы, еще что-то. 

Это – простые действия, не требующие раздумий, но при этом их выполнение отнимает время. Тем более что в современных больших конфигурациях достаточно много подобных примеров. Например, в ERP есть огромное количество объектов, которые имеют функциональность присоединенных файлов, и для каждого такого объекта создается свой собственный справочник присоединенных файлов. В результате получается огромное количество дублирующихся объектов метаданных и кода – несмотря на то, что с дублированием мы пытаемся бороться. Как раз такие задачи очень хорошо было бы переложить на плечи машины.

 

 

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

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

 

 

Если выражаться на языке бизнеса, то получается, что кодогенерация – это способ:

  • Во-первых, уменьшить себестоимость разработки;

  • А во-вторых, увеличить качество продукта.

 

 

Примеры применения кодогенерации для 1С

 

 

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

Первый, наиболее понятный пример – это наш программный продукт, MDM-система (от английского Master Data Management), с помощью которой мы управляем нормативно-справочной информацией. Фактически это конфигурация на платформе 1С, которая содержит большое количество справочников. Причем, все эти справочники обладают общей функциональностью – возможность поиска дублей, нормализации и т.д. По сути, они разные, но однотипные. 

 

 

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

 

 

В какой-то момент мы решили, что так больше жить нельзя, и реализовали собственный инструмент, который позволил выполнять эту работу автоматически. 

Как теперь выполняется разработка нашей MDM-системы?

  • У нас есть «ядро MDM» – некий набор общих механизмов, некая базовая конфигурация, в которой нет справочников НСИ, но есть некий эталонный справочник. 

  • Дальше есть Jinnee (джинн) – мы так назвали наш кодогенератор, который:

    • Берет эталонный справочник, копирует его;

    • Изменяет его необходимые свойства – добавляет нужные реквизиты, выводит их на форму;

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

Соответственно, если мы вносим изменения в ядро – мы можем перегенерировать конфигурацию еще раз, и все эти изменения туда попадут.

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

 

 

Но наша MDM-система – это не единственный пример того, как мы используем этот инструмент. В процессе разработки мы пользуемся библиотеками (как стандартными библиотеками 1С, так и собственными) – у нас есть некоторые подсистемы, которые «кочуют» из проекта в проект, используются более чем в одной конфигурации. Соответственно, возникает вопрос поддержки такого кода, потому что не очень интересно внести какое-то изменение в библиотеку, а потом копировать его в десять конфигураций.

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

Получается «умный Continuous Integration» – именно интеграция на уровне кода, когда машина сама знает, что, куда и как нужно внести.

 

 

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

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

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

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

 

 

Следующий возможный кейс – это то, к чему мы все придем в ближайшее время – разработка через моделирование. 

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

Как я это вижу? 

  • У нас есть некая модель. Мы реализуем ее в любом редакторе, в любой нотации, в которой хотим.

  • Следующим шагом мы выгружаем эту модель в формат XML. 

  • Полученный результат конвертируем в Jinnee-сценарий. 

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

Дальше я покажу, как это у нас реализовано. Я надеюсь, что так будет понятнее. 

 

 

Основные принципы проектирования инструмента

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

 

 

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

Почему это важно? Потому что писать код, который напишет за вас код, экономически выгодно только в том случае, если его написание не занимает у нас много времени. 

Например, если вы написали скрипт на 100 строк, который вам сгенерировал 1000 строк, вы сэкономили время и исключили риски человеческого фактора – это хорошо.

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

 

 

Второй принцип – это правильный выбор уровня абстракции. Что это означает? Дело в том, что наш инструмент работает на уровне XML. Это означает, что:

  • У нас есть исходный набор XML-файлов (мы выгрузили конфигурацию из конфигуратора в XML);

  • Что-то там с этими XML-ками программно сделали;

  • А потом их загрузили в конфигуратор и получили готовую конфигурацию.

Так вот, вся эта программная модификация XML не должна сильно напрягать разработчика. Разработчик не должен думать, как это реализовано на уровне XML. Например, чтобы изменить имя объекта метаданных, нужно внести изменения в нескольких местах XML-файла. Зачем разработчику это знать? Он просто напишет «ИзменитьСвойствоОбъектаМетаданных(<Имя>, <Значение>)».

Получается, что в нашем случае разработчик может мыслить именно в терминах объектов метаданных. Он вообще не знает, как это устроено с точки зрения XML, он делает то, что делал бы сам в конфигураторе руками. 

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

 

 

Третий архитектурный паттерн, который мы применили, я назвал «Сыктывкар». Объясню почему. 

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

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

Примеров такого подхода тоже много – это Конвертация данных, АПК, Инструменты разработчика. Разработчики, используя платформу 1С, уже существенно облегчили себе жизнь.

 

 

Работа с инструментом на практике

 

 

Перейдем к самому инструменту – рассмотрим, как он выглядит. 

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

 

 

Перейдем к правилу, посмотрим, как оно устроено. 

Принцип реализации правила независимо от используемой платформы всегда примерно один и тот же:

  • берется некий шаблон;

  • неким образом модифицируется;

  • и получается итоговый результат. 

Вопрос только в том, что в случае 1С считать шаблоном? Мы посчитали, что шаблоном могут быть какие-то объекты метаданных исходной конфигурации. Соответственно, у нас здесь есть визуальный интерфейс, где мы в дереве метаданных можем выбрать, какие объекты исходной конфигурации нам нужно переместить в нашу результирующую конфигурацию. Этот состав объектов мы можем буквально «накликать» мышкой.

 

 

В результате, при переходе на соседнюю вкладку у нас получится вот такой сценарий. Причем, обратите внимание – в сценарии есть один и тот же объект (имя объекта метаданных одинаковое), но команды разные. Это означает, что мы можем переносить как объекты метаданных в отдельности, так и подсистему целиком.

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

 

 

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

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

На текущий момент у нас написано 84 правила (84 скрипта). Это уже достаточно большая кодовая база.

 

 

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

  • ИзменитьСвойствоОбъектаМетаданных; 

  • ПолучитьСвойствоОбъектаМетаданных;

  • ДобавитьЭлементФормы;

  • УдалитьЭлементФормы. 

Принцип, я думаю, понятен.

 

 

Разберем одну из этих функций. 

Как на практике происходит программная модификация объекта метаданных? 

  • Мы пишем «ИзменитьСвойствоОбъектаМетаданных()»;

  • В качестве первого параметра передаем полное имя изменяемого объекта – это у нас определяемый тип ВладелецФайлов;

  • Далее указываем, какое свойство этого объекта мы хотим изменить, и какое значение ему присвоить. 

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

 

 

Расскажу про возможность параметризации правила. Что это значит? 

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

  • Одно и то же правило;

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

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

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

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

 

 

Версионирование правил при помощи Git

 

 

Расскажу про версионирование. Почему у нас вообще возникла необходимость версионирования?

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

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

  • У нас есть некая серверная часть – база, где хранятся общие данные, 

  • И есть клиентская часть – именно клиент является средой разработки правила. 

  • Но само правило в базе вообще не хранится, оно хранится в XML-файле под версионированием Git. Самая ближайшая аналогия – это EDT. 

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

 

 

Проблемы и их решения

 

 

Чтобы начать этим пользоваться, нужно было все это пережить и разрулить проблемы. У нас это получилось не сразу. Расскажу про самые интересные проблемы, с которыми мы столкнулись. 

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

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

 

 

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

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

 

 

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

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

 

 

Роль кодогенератора в решении архитектурных проблем

 

 

Тут стоит задуматься вот о чем. Если вы решили пойти по пути модульной разработки, когда у вас есть подсистемы, которые собираются и изменяются с помощью какого-то инструмента, вы должны решить ряд архитектурных проблем, ответить себе на вопрос: «Как мне проектировать мои механизмы, чтобы они были отчуждаемые, встраиваемые и т.д.?»

И сейчас на следующем слайде мы увидим ответ, как наш кодогенератор решает эти архитектурные проблемы.

 

 

Никак он их не решает. Что вы хотели? Но это, наверное, и хорошо. Иначе, зачем мы были бы нужны?

Этим я просто хочу подчеркнуть, что необходимость грамотного проектирования никуда не делась. Скорее, наоборот, она встает еще более остро.

 

 

Заключение

 

 

И еще один архитектурный антипаттерн, который тоже нужно учитывать – называется «Золотой молоток». Это – когда разработчик освоил какую-то крутую технологию, и она ему настолько сильно понравилась, что он начинает ее использовать везде. Даже там, где это нецелесообразно. Поэтому помните, что любая технология имеет границы применимости и подходить к её использованию нужно с позиции здравого смысла и экономической целесообразности.

Два слова о том, как мы видим дальнейшее развитие инструмента. Во-первых, это реализовать поддержку формата EDT. Интересно было бы научит Jinnee парсить код на языке 1С и формировать AST-tree (хотя у нас большой потребности в этом не было, но это могло бы открыть новые интересные возможности). Есть много идей по развитию внутреннего инструментария, а также хочется попробовать реализовать конвертацию моделей в jinnee-сценарии, т.е. приблизится к разработке через моделирование.

 

 

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

 

 

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

Данная статья написана по итогам доклада (видео), прочитанного на конференции INFOSTART EVENT 2018 EDUCATION. Больше статей можно прочитать здесь.
Приглашаем вас на новую конференцию INFOSTART EVENT 2019!

24

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

Комментарии
Избранное Подписка Сортировка: Древо
1. user-z99999 21 26.08.19 17:22 Сейчас в теме
Jinnee - в тексте повторяется 6 раз.
Как скачать?
Примеры как использовать?

Платно/бесплатно ?
2. VmvLer 26.08.19 17:57 Сейчас в теме
(1) Львиная доля статей-докладов не более чем маркетинг а ля
"конкретно мы вам ничего не скажем, просто покажем вам картинки чтобы вы поняли какие мы крутые и купили у нас услуги, товары и т.п."
wowik; sm.artem; Anchoret; for_sale; +4 Ответить
6. kirovsbis 24 27.08.19 10:05 Сейчас в теме
(2)

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


Хотелось бы больше конкретики в претензиях на отсутствие конкретики :) Статья всё-таки написана по итогам 30-минутного доклада, в котором полноценно раскрыть тему невозможно при всём желании. Целью было донести до слушателей саму идею, плюсы-минусы, реальные кейсы применения технологии, рассказать кратко про сам инструмент и возможные проблемы использования. Если тематика интересна - могу более подробно рассказать в следующих статьях о том как оно работает, как организован сам процесс разработки, каких архитектурных принципов стараемся придерживаться при разработке, как реализуем модульность на практике.
drmaxart; +1 Ответить
8. VmvLer 27.08.19 10:16 Сейчас в теме
(6) Моя реплика - это общий взгляд на современные презентации.
3. for_sale 783 26.08.19 18:02 Сейчас в теме
(1)
Очередная статья из серии "Смотрите, как мы умеем!"
5. kirovsbis 24 27.08.19 09:48 Сейчас в теме
(1)
Jinnee - в тексте повторяется 6 раз.


Не считал, но верю Вам на слово :)


Как скачать?
Примеры как использовать?

Платно/бесплатно ?


Инструмент нигде не публиковали пока. Изначально его разрабатывали для решения вполне конкретных собственных задач (в первоначальной постановке он назывался "механизм клонирования справочников"). Когда получили что-то более-менее работоспособное возникла мысль рассказать об этом сообществу с целью понять будет ли тема интересна коллегам (на мой взгляд технология имеет достаточно широкий потенциал для применения). Я планирую подготовить первый полноценный релиз с документацией и примерами до конца этого года. Буду признателен за конструктивные комментарии, предложения и идеи. Готов ответить на возникающие вопросы.
drmaxart; +1 Ответить
7. user-z99999 21 27.08.19 10:11 Сейчас в теме
(5)
Выложите инструмент, дайте попробовать.
Научите в нём работать. Простые примеры, создание справочников.

Если вы продаете, так и пишите - распространение на платной основе.
4. nytlenc 27.08.19 06:44 Сейчас в теме
Все мне пора в отпуск. Прочитал как "Кодогенерация и матогенерация в 1С"...
9. kirovsbis 24 27.08.19 10:23 Сейчас в теме
Выложите инструмент, дайте попробовать.
Научите в нём работать. Простые примеры, создание справочников.


Выложу, как только подготовлю версию, которую не стыдно выложить :) Про планируемые сроки уже написал.

Если вы продаете, так и пишите - распространение на платной основе.


С моделью распространения ещё не определились, поэтому пока не знаю что ответить на этот вопрос.
10. Darklight 19 27.08.19 11:29 Сейчас в теме
Великолепное решение! Великолепная статья! Браво! За кодогенерацией будущее! Ближайшее будущее! Очень ждём таких решений для платформы 1С Предприятие. "Подписываюсь" практически под каждым тезисом из статьи, ну разве что смутила фраза


Как на практике происходит программная модификация объекта метаданных?

Мы пишем «ИзменитьСвойствоОбъектаМетаданных()»;

В качестве первого параметра передаем полное имя изменяемого объекта – это у нас определяемый тип ВладелецФайлов;

Далее указываем, какое свойство этого объекта мы хотим изменить, и какое значение ему присвоить.

Очень принципиально смутило название функции "ИзменитьСвойствоОбъектаМетаданных"
Хотя по тексту и не совсем понятно, как она работает: предположил - что глагол "Изменить" означает что функция заменяет одно значение на другое - это конечно может быть иногда полезно, но чаще - это не лучшее решение (тем более в качестве демонстрационного примера). В кодогенерации нужно стараться чаще оперировать не термином "изменить", а термином "Расширить" (ну и ещё - "Исключить" в широком смысле понимания; а так же - "Сдвинуть"). То есть алгоритм кодогенерации должен стараться оперировать не абсолютными величинами, а относительными - воспринимая исходный объект как "черный ящик" (но ожидаемо удовлетворяющий некоторым правилам - и включать инструменты проверки на соответствие этим правилам - формату/интерфейсу), а команды скрипта должны это "черный ящик" видоизменять на заданную величину требуемого изменения, не меняя ничего, что не входит в это изменение.

Другими словами, для данного примера правильно было бы выполнить команду "ДобавитьВЗначениеСвойстваОбъектаМетаданного" - которая в данном случае в существующие ОписаниеТипов внесла бы новый тип (в случае его отсутствия), не меняя существующие.
Хотя, может так функция "ИзменитьСвойствоОбъектаМетаданных" и работает - но название тогда не очень корректное.


Интересно было бы научит Jinnee парсить код на языке 1С и формировать AST-tree


Это очень правильное развитие. Оно добавило бы макропрограммирование. Ведь конфигурации состоят не только из метаданных, но и из программного кода их обслуживающего. И тут важно не только включать его целыми неделимыми блоками (максимум выводимыми с заменого текста по шаблону), но и модифицировать существующие. Вообще - тут целая отдельная тема - это расширение возможностей языка 1С за счёт макросов, которые выполняют кодогенерацию в designtime - что позволило бы существенно упростить интеграцию в алгоритмы, уменьшило бы объёмы кода и главное - выкинуло бы из runtime алгоритмы, как не используемые там (в силу текущих настроек), так и создающие лишнюю нагрузку проверок и вызовов функций - которые ничего полезного не делают и раз за разом выполняют одно и то же действие не несущее практической нагрузки (обычно в силу заданных настроек).

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

Так что желаю авторам всяческих успехов в развитии данного проекта. Давно сам грёзю о таком - но мне одному его не поднять проект. А вот данное решение с удовольствием бы начал применять в повседневной практике!

P.S.
Да и ещё - вот тут недавно всплыл новый 1С-подобный язык программирования - Перфолента- построенный на расширенном синтаксисе 1С (для платформы MS .NET Framework).
Отличным решением было бы скооперироваться с автором Перфоленты - и внедрить поддержку данного языка (а парсер и разбор в AST-tree уже есть у автора) в качестве основы как для написания встроенных скриптов, так и для исходного языка источника для кодогенерации (изменения) алгоритмов - это вообще была бы бомба в программировании на 1С. Позволившая как писать очень продвинутые скрипты, так и писать продвинутые алгоритмы для конфигурации 1С (например, с поддержкой ООП), которые после кодогенерации - превращались бы в понятные платформе 1С Предприятие инструкции (не факт что 100% на языке 1С, скорее всего тут некоторые вещи имеет смысл сразу компилировать в байткод (OpCode) стековой машины 1С, ну или сначала на промежуточный язык 1с-ассемблера (тоже недавно тут представленный).
Вот это вообще была бы сногсшибательная революция в программировании для 1С Предприятие 8
Perfolenta; dabu-dabu; kirovsbis; +3 Ответить
12. kirovsbis 24 27.08.19 12:33 Сейчас в теме
(10)

Спасибо за содержательный комментарий!

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

Пример:
Есть объект метаданных, например определяемый тип. Если мы зайдем в конфигуратор и в дереве метаданных выберем наш определяемый тип, а затем откроем окно свойств (Alt + Enter), то увидим существующие свойства объекта. Некоторые будут "простыми" - например "Имя" или "Синоним", другие "сложными" (или составными) - например "Тип", но всё равно это СВОЙСТВА объекта метаданных. Поэтому независимо от того меняем ли мы синоним или добавляем новый тип в состав определяемого типа (или наоборот удаляем тип из состава) мы фактически изменяем одно из свойств объекта метаданных.
Полное описание функции "ИзменитьСвойствоОбъектаМетаданных" выглядит так:
ИзменитьСвойствоОбъектаМетаданных(<Полное имя объекта метаданных>, <Имя свойства>, <Добавляемое значение>, <Удаляемое значение>)
Разработчик подает на вход функции имя объекта метаданных и имя свойства, а инструмент соответственно на основе этих данных понимает как правильно интерпретировать третий или четвертый параметр.

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

Сделаем справочник иерархическим:

ИзменитьСвойствоОбъектаМетаданных("Catalog.ПримерСправочника","Hierarchical","true");


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

ИзменитьСвойствоОбъектаМетаданных("DefinedType.ВладелецФайлов", "Type", "CatalogRef.ПримерСправочника");


А можем и сразу несколько типов добавить:

МассивТипов = Новый Массив;
МассивТипов.Добавить("CatalogRef.ПримерСправочника1");
МассивТипов.Добавить("CatalogRef.ПримерСправочника2");
ИзменитьСвойствоОбъектаМетаданных("DefinedType.ВладелецФайлов", "Type", МассивТипов);
14. Darklight 19 27.08.19 13:30 Сейчас в теме
(12)Спасибо за пояснения. Теперь механика стала понятнее . Хотя, если ориентироваться на новичков - мне кажется несколько отдельных функций с именами "ДобавитьВЗначениеСвойстваОбъектаМетаданного", "ИсключитьИзЗначенияСвойстваОбъектаМетаданного" было бы более понятным, но это не принципиально Хотя я бы вообще делал API боле универсально - как-то так:

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


Может код получился более ёмкий зато, боле универсальный, к примеру

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

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

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

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


Где "НекаяКонфигурация" - инициализированный объект проекта изменения метаданных конфигурации - где загружены все настройки!

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

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


P.S.
К своему предыдущему комментарию ещё хотел бы добавить пожелание - хорошо бы в движке кодогенерации метаданных реализовать поддержку:

1. Что-то типа наследования метаданных - когда, скажем, один справочник, в описании правил наследуется от другого - и в результате получается просто объединённый справочник. Это, конечно не наследование, а скорее - совмещение (объединение) - особенно когда есть несколько исходных справочников и новый создаётся путём как-бы множественного наследования/объединения - а все пересечения решаются за счёт заданных правил проведения такой операции (ну например, пересекающиеся реквизиты объединяются по типам, а пересекающиеся ТЧ объединяются по реквизитам - но это поведение должно быть настраиваемым)

2. Аналогично - но для управляемых форм - когда результирующая форма создаётся из отдельных фреймов (тоже форм) путём совмещения интерфейсных элементов (по заданным правилам) и переноса кода в модуль формы. Естественно сами формы тоже должны быть спроектированы по некоторым правилам, допускающим такое совмещение

3. Кроме форм неплохо бы совмещать макеты - но это уже высший пилотаж!
dabu-dabu; +1 Ответить
16. Darklight 19 28.08.19 00:41 Сейчас в теме
(14)А вот так я бы организовал обработку текстов алгоритмов (есть небольшие отличия от предыдущего примера т.к. я ещё немного подумал над архитектурой)
Фильтр1 = СоздатьФильтрМетаданых(); //Для фильрации текстов  подойдёт тот же объет что и длля фильтрации метаданных – я так считаю
Условие1 = Фильтр1.Условия.Добавить(); //Тут по группам не делим
Условие1.Отбор.Добавить(ПолучитьТип("УниверсальныйМаркер"), ИмяОтбора1, КомандыОтбора.СодержитВнутри, СоздатьМаркерМетаданных("ПрименениеОрганизации")); //Вид отбора – «СодержитВнутри» просит заглянуть внутрь анализируемых элементов (что типа «В ИЕРАРХИИ»)
Условие1.Отбор.Добавить(ПолучитьТип("ВидМетаданных"), ИмяОтбора2, КомандыОтбора.Наследование, НекаяКонфигурация.ПолучитьВидМетаданных("МодульМетод")); //По данному виду  «МодульМетод» отбираем все производные виды – Процедуры и Функции всех элементов, которые могут содержаться в любьых программных модулях (считаю что модуль не должен быть конечным объектом металднных модели, несморря на то, что в конфигурации он конечный и не имеет вложенных элементов метаданных) – это даёт бОльшую гибкость при анализе кода

//Будет использован ниже – хотя, в принципе, думаю, эти условия можно было вставить вместо Условия1 – и всё тоже работало (
Фильтр2 = СоздатьФильтрМетаданых(); 
Условие2 = Фильтр2.Условия.Добавить();
Условие2.Отбор.Добавить(ПолучитьТип("УниверсальныйМаркер"), ИмяОтбора1, КомандыОтбора.Содержит, СоздатьМаркерМетаданных("ПрименениеОрганизации")); //Здесь уже отбор «Содержит», т.к. маркеры, согласно соглашения и кодировании, должны быть заданны на блоки кода (о них ниже)
//Условие2.Отбор.Добавить(ПолучитьТип("ВидМетаданных"), ИмяОтбора2, КомандыОтбора.Равно, НекаяКонфигурация.ПолучитьВидМетаданных("БлокАлгоритма")); //Эта строка закоментирована – она будет нужна если ей заменить второй отбор сверху

Фильтр3 = СоздатьФильтрМетаданых(); 
Условие3 = Фильтр2.Условия.Добавить(СоздатьГруппуУсловий("ПрименениеОрганизации"));
Условие3.Отбор.Добавить(ПолучитьТип("УниверсальныйМаркер"), ИмяОтбора1, КомандыОтбора.Содержит, СоздатьМаркерМетаданных("ПрименениеОрганизации")); 
Условие4 = Фильтр2.Условия.Добавить(СоздатьГруппуУсловий("Иначе"));
Условие4.ИспользоватьИначе = Истина; //Эта группа условий будет применена как выборка «Иначе» для элементов, не удовлетворяющих другим условиям

ПараметрыВыборкиБлоковКода = СоздатьПараметрыВыборки();
ПараметрыВыборкиБлоковКода.Иерархия = ВидИерахии.Линейная; //Несмотря на то, что блоки могут быть вложенными, они выбираются линейным списком – т.к. в данном скрипте их вложенность никак не обрабатывается – и проще из перебирать линейным перебором
ПараметрыВыборкиБлоковКода.ОбработкаВложений = МетодОбработкиВложений.Исключить; //Если один блок вложен в другой и оба подходят по условию выборки – то риз родительского блока будет исключено содержимое вложенного блока – чтобы не обрабатывать их повторно (сначала в родителе, затем во вложении)

ВыборкаФункции = НекаяКонфигурация.Алгоритмы.ВыбратьМетаданные(Фильтр); //отделил выборку метаданных от выборки текстов – но это не обязательно, хотя физически в xml файлах они разнесены в разные структуры и процессоры их обработки тоже будут различны
Пока ВыборкаФункции.Следующий() Цикл
     МетаОписаниеПроцедуры = ВыборкаФункции.ЗначениеКак("МодульМетод");
     Если МетаОписаниеПроцедуры = неопределено Тогда продолжить; КонецЕсли;
     ВыборкаБлокиКода = МетаОписаниеПроцедуры.Тело.БолокиАлгоритмов.Выбрать(Фильтр2, ПараметрыВыборкиБлоковКода); //Как написал выше – можно было бы сразу отбирать блоки кода, а не процедуры/функции  тогда эта выборка тут была бы не нужна – привёл её просто, чтобы показать что та тоже было бы можно; БолокиАлгоритмов – это встроенное представление (зарегистрированное для объектов – «ТекстАлгоритма»), которое разбивает исходное содержимое (тело алгоритма функции) на составные блоки кода по заданным в него семан6тическим правилам (ну например – отделяя  регионы и тексты запросов, хотя можно выделять и циклы и условия ветвления как отдельные блоки, или ещё как-то отельно их обозночать – для метаанализа алгоритмов наличие правильно выделенных блоков очень важно – к блокам могут быть привязаны параметры и маркеры, используемые для метаобработки – как в данном случае – маркер «ПрименениеОрганизации» - тут отбираются только те блоки кода, где к ним такой маркер привязан в качестве аннотации)

     Пока ВыборкаФункции.Следующий() Цикл //Лийнейный перебор найденных блоков, согласно параметрам выборки, без повторов вложений
         БлокКода = ВыборкаФункции.Значение; //Тут всегда блоки алгоритмов – согласно выборки из предствления «БолокиАлгоритмов»
         //Дальше возможно несколько разных путей обработки блоков программного кода
         //1. Применить подстановку значений в макрошаблон 
         Шаблон = БлокКода.ПолучитьШаблон(); //Применяется шаблонизатор по-умолчанию, номожно было бы использовать внешний объект-шаблонизатор, связав его с данным блоком кода
         Шаблон.Параметры.Вставить(“НекийПараметрШаблона”, НекоеЗначение);
         Шаблон.Параметры.Вставить(“УчитыватьОрганизацию”, НекаяКонфигурация.ФункциональныеОпции.ВедениеПоНесколькимОрганизациям.ПолучитьЗначение());
         Шаблон.Применить(); //Шаблон будет готов использованию в блоке алгоритма (все параметры будут проинициализированы), но ещё но текст алгоритма ещё не будет заменён
         БлокКода.Обновить(КомандыИзмененияМетаданных.ПрименитьШаблон, Шаблон); //Шаблонные параметры будут проинцииализированы заданными значениями в тексте алгоритма блока кода

         //2. Применить обработку текста каким-либо Препроцессором (по заданным в тексте препроцессорным инструкциям)
         Препроцессор = НекаяКонфигурация.Препроцесоры.Найти(“ОсновнойПрепроцессор”); //Поиск нужного препроцессора в проекте, по имени – можно и так: НекаяКонфигурация.Препроцесоры.ОсновнойПрепроцессор; 
         НовыйБлокКода = Препроцессор.Выполнить(БлокКода); //Полученный из проекта «НекаяКонфигурация» препроцессор будет уже инициализирован необходимыми настройками и будет иметь доступ к функциональным опциям – поэтому его достаточно просто применить к блоку адгоритмов – он проверит свои инструкции препроцессора и вычистить тест от лишнего кода (и возможно сгенерирует новый)
         БлокКода.Обновить(КомандыИзмененияМетаданных.Заменить, НовыйБлокКода); //Замена содержимого блока кода на новое значение

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

         //Тут есть две отдельные схемы (и блоки кода желательно сразу отфильтровывать отдельно для каждой схемы – конечно выбрать нужные части блока кода можно и после открытия выборки – тем более что до этого этапа не производился синтаксический разбор – а тут уже потребуется лексер)
         Лексер = НекаяКонфигурация.Лексеры.ПолучитьОсновной(); //Получаем лексер проекта, назначенный в нём основным – он уже будет инициализирован параметрами проекта
         ASTДерево = Лексер.Выполнить(БлокКода); //Синтаксический разбор, будет исполиьзован синтаксический контекст, связанный с БлокКода (так что могут быть задействованы другие алгоритмы, вне данного блока – конечно такой разбор лучше делать для всех ммодулей алгоритма сразу – а уже потом их анализировать)
         ПотокИнструкций = ASTДерево.АлгоритмИнструкции.Выбрать(Фильтр3); //Выбираем только ветви ASTДерева вида «АлгоритмИнструкции», в которых есть нужный маркер
         НовыйПотокИнструкций = ASTДерево.АлгоритмИнструкции.СоздатьПоток(); //Новый пустой поток для преобразованных инструкций (в рамках текущего контекста лексического разбора)
         Пока ПотокИнструкций.Следующий() Цикл
             //самостоятельно перебираем и обрабатываем иерархию ASTДерева
             Если ПотокИнструкций.ЭтоГруппаУсоловий("ПрименениеОрганизации") Тогда
                  //Что делаем с данной инструкцией
                  //надо только учесть что внутри инструкций могут быть выражения – их можно пропускать – если они обрабатываются отдельно

             Иначе // ЭтоГруппаУсоловий("Иначе")
                  //Эта инструкция не содержит искомого маркера
             КонецЕсли;
             НовыйПотокИнструкций.Добавить(вносим обработанную или пропущенную инструкцию в новый поток)
         КонецЦикла;
         Генератор = СоздатьГенераторКода(“ГенераторИнструкций1С”); //Создаём базовый генератор кода языка 1С (можно было бы выбрать и из проекта: НекаяКонфигурация.ГенераторыКода.ПолучитьОсновной(“ГенераторИнструкций”) – тогда не пришлось бы его инициализировать
         Генератор.УстановитьКонтекстНастроек(НекаяКонфигурация);
         Генератор.Инициализировать();
         Генератор.УстановитьКонтекстВыполнения(БлокКода); //Контекст сразу инициализируется (прекомпилируется)
         Генератор.УстановитьИсходныйПоток(НовыйПотокИнструкций);
         НовыйБлокКода = Генератор.Выполнить(ПолучитьТип(“БлокКода”));
         БлокКода.Обновить(КомандыИзмененияМетаданных.Заменить, НовыйБлокКода);

         //Для выражений всё аналогично, но можно не не генерировать весь поток инструкций заново а заменять выражения на обработанные 

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

     КонецЦикла;

     //На самом деле тут выше допущен ряд логических ошибок – так отдельно генерировать инструкции и выражения нельзя – они пере затрут друг друга – но оставил пример так для наглядности

         //4. Можно выполнить просто текстовый перебор по ключевым словам
     Отбор = СоздатьТекстовыйФильтр();
     Отбор.Слово.Установить(“ПрименениеОрганизации”);
     ПозицияСлова = БлокКода.ТекстовыйПроцессор.НачатьПоиск(Отбор);
     НовыйПотокСлов = СоздатьПотокСлов();
     Пока ПозицияСлова.Следующий() Цикл //Нашли вхождение в текст «ПрименениеОрганизации»
         Предыдиущие5Слов = ПозицияСлова.ВзятьСлова(НаправлениеПоиска.Назад, 5);
         СледующиеСловаДоКонцаИнструкции = ПозицияСлова.ВзятьСлова(НаправлениеПоиска.Вперед,, Истина);

         //Ну и как-то их обрабатывать

         НовыйПотокСлов.Вставить(…);
     КонецЦикла;

     НовыйБлокКода = СоздатьБлокКода(НовыйПотокСлов);
     БлокКода.Обновить(КомандыИзмененияМетаданных.Заменить, НовыйБлокКода);

         //5. Ну или просто получить блок кода как текст и обрабатывать его как обычную строку - по старинке
     СтрокаАлгоритма = БлокКода.ПолучитьТекст();
     НоваяСтрокаАлгоритма = СтрЗаменить(СтрокаАлгоритма,…,…);
     НовыйБлокКода = СоздатьБлокКода(НоваяСтрокаАлгоритма);
     БлокКода.Обновить(КомандыИзмененияМетаданных.Заменить, НовыйБлокКода);

     БлокКода.Применить(); //Фиксируем изменения
     ///БлокКода.Применить(ВидФиксации.Отложенно); //Или откладываем на потом
КонецЦикла;

НекаяКонфигурация.Алгоритмы.Изменения.Применить(ГлобальныеКоманда.ВыполнитьОтложенныеИзменения); //Применяем все актуальные отложенные изменения алгоритмов

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

Может получилось несколько сложновато, зато какой глубокий потенциал заложен в таком подходе. Тут главное – это правильная декомпозиция, правильные фильтры и универсальный алгоритм обработки либо текстов либо инструкций/выражений
21. kirovsbis 24 28.08.19 10:31 Сейчас в теме
(16)

Спасибо как минимум за то что не поленились продумать и написать такой кусок кода :) Вечером я помедитирую над ним )
25. Darklight 19 28.08.19 12:18 Сейчас в теме
(21)Просто я тоже давно грёзю кодогенерацией в 1С и программными скриптами изменения метаданных - и много думал на эту тему. Так что подобные выкладки кода - это просто продолжение моих размышлений - и как стать, может когда-нибудь это всё станет не только моей фантазией....
27. Darklight 19 28.08.19 13:51 Сейчас в теме
(16)В листинге у меня небольшая опечатка: "КонецЦикла" перед. п.4. рано закрыл :-( - это же был цикл перебора блоков кода - его нужно закрыть в самом конце - перед закрытием последнего цикла перебора процедур/функций, чтобы контексты п.4 и п.5. были внутри этого цикла.

Ещё добавка - алгоритмы п.3 (анализирующие инструкции и выражения; да, впрочем, это важно для всех вариантов пунктов) в приведённом листинге не имеют проверки на вид блока кода - а это может быть очень важно для его разбора - например блок кода с текстом запроса скорее всего нужно обрабатывать иначе, чем просто инструкции языка 1С, уж как минимум Лексер в ASTДерево и Генератор кода для него должны быть свои (поэтому для п.3. это очень важно, для других случаев - это не обязательно, но всё-равно лучше всегда знать с каким видом блока кода имеешь дело).
18. kirovsbis 24 28.08.19 09:29 Сейчас в теме
(10)
Ну и как развитие данной тем - нужно присваивать исходным метаданным маркеры, на которые можно было бы опереться при кодогенерации - и дальше, например, решать включать или не включать это метаданное (или его часть) в итоговое решение, ну или как-то иначе модифицировать - т.е. оперировать уже не конкретными элементами метаданных - а некими общими признаками. Например, присвоив маркер "ЕстьОрганизация" как справочнику "Организация" (условно), так и измерениям регистров, и реквизитам документов "Организация", а также блокам программного кода, обращающимся к этим метаданным - то в зависимости от настройки - ведения учета по разным организациям - можно выкинуть все эти элементы из итоговой конфигурации, тем самым снизив её сложность - а значит повысив эффективность её исполнения платформой и СУБД.


Покажу на примере как мы решаем этот вопрос.
Допустим у нас есть некая "Подсистема1", которая содержит "Документ1" (причем реквизита "Организация" у этого документа изначально нет).
Мы написали "Правило1", которое переносит "Подсистему1" из исходной конфигурации в результирующую.

А ещё есть "Подсистема2", которая содержит справочник "Организации".
Мы написали "Правило2", которое переносит "Подсистему2" и добавляет в "Документ1" реквизит "Организация".

Если мы создадим сценарий генерации состоящий из двух шагов, например:

Шаг 1 по "Правилу1"
Шаг 2 по "Правилу2"

то в результате получим конфигурацию содержащую "Документ1" с реквизитом "Организация".
Но если "Шаг 2" отключить то в результате получим "Документ1" без реквизита "Организация" т.е. этот реквизит как бы "Удалится" (но правильнее сказать "не добавится"). Поэтому проблема быстрого исключения из конфигурации ненужной функциональности легко решается если изначально нужным образом спроектировать сценарий генерации.
24. Darklight 19 28.08.19 12:17 Сейчас в теме
(18)Немного разные сценарии - которые оба имеют веское право на применение в реальных проектах.
В моём случае, как я считаю, что это эффективнее для большинства случаев, но не для абсолютного большинства - проще создавать одну общую конфигурацию, в которой присутствует весь необходимый функционал (я тут лукавлю - ниже поясню почему). И результирующую конфигурацию получать путём отключения и исключения лишнего функционала. Почему именно так? Да потому что обычно (но далеко не всегда) проще разрабатывать и отлаживать одну единую инфраструктуру, где все её элементы размещены на своих местах как их задумал архитектор. А когда что-то не нужно - то удалять всегда проще, чем добавлять (при условии, что архитектура изначально спроектирована в расчёте на возможность исключения из неё некоторых составных частей).
Этот подход хорош и для случая - когда решение поставляется комплексно (как сейчас в типовых конфигурациюях 1С, например), а ненужный функционал уже отключается на месте в процессе первоначального развёртывания (или позже).

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

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

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

Я не зря привёл пример с организацией - это достаточно общий реквизит, который присущ большому числу метаданных. Аналогично я бы мог привести пример, например со складами. И эксплуатации ИБ не всегда есть потребность в ведение учета по разным организациям или складам. Нет смысла выносить эти части в отдельный модуль, и совмещать его резултьтирующей конфигурацией - проще сначала собрать её из более общих модулей (которые были оплачены) - и в таком виде её поставить заказчику, а уже при развёртывании у заказчика отключить ненужный функционал.

Я не зря в алгоритме сценария сослался на понятие "функциональная опция" - т.к. на мой взгляд в 1С её наличие - архиважное дело - но вот реализация - архи-неправильная и архи-ограниченная! Я же получаю значение функциональной опции не для ветвления алгоритмов в runtime, а ещё на стадии сборки конфигурации - по сути - это этап препроцессинга продуктивной конфигурации из подгтовленного релиза в репозитории ((собранного из девелоперских частей - отдельных бранчей).

Так что оба подхода важны и имеет право на практическое применение! Простоя привёл пример с другой стороны - для расширения кругозора так сказать ;-)

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

ПараметрыВыбораМетаданных = СоздатьПараметрыВыборки();
ПараметрыВыбораМетаданных.Иерархия = ВидИерахии.ВерхийУровеньЭлементов; //Метаданные выбираются только линейно и только верхний уровень элементов, без захода во вложения;

Фильтр = ПолчитьФильтр(); //Здесь можно получить фильтр для фильтрации подметаданных при совмещении метаданных верхнего уровня - если нужно

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


Всё очень компактно - т.к. основная логика скрыта в процессоре обработки команды "КомандыИзмененияМетаданных.Расширить" и настроенных правилах интеграции. Ну и модули уже импортированы в проект и к ним привязаны нужные настройки.
Здесь, в большинстве случаев, всё можно выполнять достаточно универсально - без необходимости глубоко вмешиваться процесс интеграции - декларативных правил и, на худой конец, обработчиков вполне хватит.

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

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


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

Но нужно будет ещё и встроить Организацию во многие уже присутствующие, в исходной конфигурации, метаданные: и в справочники, и в документы и в регистры. Задача очень не тривиальная (поэтому этот сценарий не лучший выбор - но порой иначе никак). Тогда нужно делать общий обход метаданных и решать - куда нужно встроить Реквизит/Измерение/Ресурс/Тип данных/Код обработки/Элемент на форму - Организация, а куда нет.
Решения тут могут быть разные - я не буду сейчас на этом останавливаться.
Я просто указал на наличие и такого сценария - когда при интеграции объединением обрабатываются метаданные исходной конфигурации и расширяются только программно и динамически, без присутствия в объединяемом модуле.
28. Darklight 19 28.08.19 13:57 Сейчас в теме
Аналогично объединению метаданных можно реализовать и алгоритм ввода нового метаданного на основании другого метаданного

Фильтр = ПолучитьФильтр(); //Какой-то фильтр, определяющий что нужно переносить из Родителя в Потомок (можно без него - команда сама знает как провести наследование)
ПравилаНаследование = ПолучитьПравилаНаследования(); //Если наследование должно идти по не стандартным правилам их можно тут задать - особенно будет полезно для множественного наследования
Родитель1 = НекаяКонфигурация.Метаданные.Найти(ПолныйПутьРодителя); //Ищем метаданное источник
Родитель2 = НекаяКонфигурация.Метаданные.Найти(ПолныйПутьРодителя); //Ищем метаданное источник
Потомок = НекаяКонфигурация.Метаданные.Найти(ПолныйПутьПотомк); //Ищем метаданное потомок, но без части, наследуемой у родителя

//Обновляем потомка - хотя можем сделать и совсем новое метаданное - особенно когда Потомок просто импортируется из какого-то вспомогательного модуля
Потомок.Обновить(КомандыИзмененияМетаданных.Наследовать, Родитель1, Фильтр, ПравилаНаследования);
Потомок.Обновить(КомандыИзмененияМетаданных.Наследовать, Родитель2, Фильтр, ПравилаНаследования); //Тут вполне допустимо множественное наследование - коллизии могут быть разрулены в ПравилаНаследования
Потомок.Применить();
Показать



Тут вся фишка во встроенной Команде "КомандыИзмененияМетаданных.Наследовать" в которой (в Процессоре обработки команды, который тоже можно задать свой) прописан универсальный алгоритм того, как совмещаются два объекта метаданных при операции наследования (ну и, он использует переданные "ПравилаНаследования" - если они не стандартные, которые тоже могут быть изменены, и берутся отсюда: НекаяКонфигурация.ПравилаНаследования.Основное()).
По умолчанию - она (команда) переносит из Родителя в Потомок всё то, чего там нет (согласно фильтру - если будет задан) - а где есть пересечения - объединяет их свойства с приоритетом потомка. Ну перенос текстовых алгоритмов тут более сложный - но в целом он должен работать как классическом ООП (специальные аннотации в методах модулей будут в помощь). Ну и совмещение форм и макетов - это тоже не простые задачи - но это всё внутренние универсальные задачи движка
11. sikuda 581 27.08.19 12:31 Сейчас в теме
А я то и не знал что пишу кодогенератор php1c.ru ;)
13. kirovsbis 24 27.08.19 12:34 Сейчас в теме
(11)

Наверное правильнее это транслятором назвать
15. PerlAmutor 45 27.08.19 19:09 Сейчас в теме
Вероятно в будущем конфигурации 1С начнут продавать исходя из пожеланий заказчика, который "накидал в корзину" прямо с сайта магазина перечень необходимых блоков и получил в итоге не ERP, а лишь то, что ему из неё реально необходимо: "бюджетирование, производство, кадры, складской учет, регламентированный учет"... "документооборот"...
17. Darklight 19 28.08.19 00:47 Сейчас в теме
(15)Абсолютно верно - я уже тоже давно пришёл к тому, что в будущем такой подход продажи будет очень оправдан - платишь ровно за то, что тебе нужно - и не получаешь ничего лишнего в нагрузку - соответственно конфигурация легче - понятнее и быстрее!
Ну а нужно потом что-то ещё - так докупаешь и быстренько интегрируешь в свою систему!
Но это всё-таки более далёкая перспектива, нежели покупка комплексных многофункциональных решений (как сейчас), и их самостоятельная настройка уже "на месте" с генерированием итоговых метаданных, в которых содержится скомпонованный только нужный пакет метаданных. Тут и в расширениях в итоге потребность должна отпасть - обновляться будут исходные конфигурации - а потом результирующая просто будет пересобираться из исходных (включая части с доработками).
19. muskul 28.08.19 09:33 Сейчас в теме
Я считаю что будущее это когда в конфигураторе можно будет звездочками отметить избранные (те объекты которые тебе нужны в данный момент) а не вот это вся матогенерация. Клонирование справочников(чем копировать вставить не то)? С данынми? Можно более конкретно в каким местах это может помочь на каких реальных задачах.
20. kirovsbis 24 28.08.19 10:20 Сейчас в теме
(19)
Клонирование справочников(чем копировать вставить не то)? С данынми? Можно более конкретно в каким местах это может помочь на каких реальных задачах.


Попробую более детально объяснить.
В нашей конфигурации MDM есть некий эталонный справочник, он уже содержит некую общую для всех справочников такого назначения функциональность. У него содержится код в модуле объекта, модуле менеджера, есть форма элемента и форма списка. Уже неплохо :)
У нас возникает потребность в создании вполне конкретного справочника НСИ, например справочника "Активы". Мы заходим в конфигуратор, копируем эталонный справочник. Соответственно в полученной копии будет такой же модуль объекта, модуль менеджера, формы и т.д. Ура!
Решён ли вопрос создания справочника "Активы"? Неа.
Нам как минимум ещё нужно:

1. Изменить значения некоторых свойств этого справочника (Например Имя, Синоним)
2. Включить созданный справочник в состав нужным нам определяемых типов, планов обмена и т.д.
3. Назначить права на этот справочник для одной или нескольких существующих ролей.
4. Добавить для этого справочника нужные реквизиты.
5. Вывести эти добавленные реквизиты на уже существующую форму элемента.
6. Модифицировать запрос динамического списка в форме списка справочника.
7. Возможно ещё ряд некоторых действий.

В статье об этом написано в целом, для создания справочника "руками" была даже написана специальная инструкция, просто скопировать объект метаданных недостаточно.
Но автоматизация создания справочников это в общем то не самое главное преимущество технологии. Как ни крути, справочник то мы создаем 1 раз, и в принципе можно и потерпеть и таки произвести все манипуляции "вручную" без "всей этой матогенерации".
На практике гораздо важнее стоит вопрос сопровождения этого кода. Допустим мы нашли ошибку в одном из модулей нашего справочника НСИ. Поскольку у нас все справочники НСИ создаются копированием эталонного, то значит ошибку надо исправлять в модуле КАЖДОГО справочника НСИ, а у нас их например штук 40. Заходить в каждый и вносить изменения удовольствие ниже среднего. В нашем случае ошибку достаточно исправить в модуле эталонного справочника, выполнить пересборку и нужные изменения будут внесены ВЕЗДЕ. Т.е. кодогенерация это по-сути способ масштабировать собственную работу.
22. ambrozii 28.08.19 10:43 Сейчас в теме
(20) >> Заходить в каждый и вносить изменения удовольствие ниже среднего

Будь мужиком! Исправь все руками!
23. kirovsbis 24 28.08.19 11:39 Сейчас в теме
(22)

)))

Ну да, настоящие мужики терпят!!!
26. Darklight 19 28.08.19 12:25 Сейчас в теме
(19)Смотрите мои посты (14)(16)(24) - я там как раз говорю об этом
Оставьте свое сообщение

См. также

Подбор оборудования для информационных систем на платформе 1С 25

Статья Системный администратор Программист Руководитель проекта Нет файла Бесплатно (free) Интеграция

При подборе оборудования по рекомендациям с сайта ИТС возникает противоречие: проводить ли нагрузочные тесты, чтобы определить возможную нагрузку, или достаточно просто взять данные из таблиц статистики? О том, какую тактику применить в том или ином случае, на конференции INFOSTART EVENT 2018 Education рассказал начальник отдела разработки компании IBS Филиппов Евгений.

09.09.2019    4740    jf2000    6       

Интеграция 1С с промышленным оборудованием 31

Статья Системный администратор Программист Руководитель проекта Нет файла Бесплатно (free) Интеграция

Эффективность управленческой информации в производственном процессе зависит от данных, собираемых на нижних уровнях. Про автоматизацию получения этих данных с использованием технологии OPC (OLE for process control) на конференции Infostart Event 2018 Education рассказал Юрий Коноваленко.

06.09.2019    4207    user642664_yurkeshk    12       

Как должна выглядеть правильная интеграция. Использование Mule ESB и RabbitMQ с 1С 46

Статья Программист Нет файла Бесплатно (free) Интеграция

Чем масштабнее проект, тем сложнее настроить все связи. Каждый решает эти проблемы по-своему: кто-то пользуется конвертацией, кто-то пользуется xml и json. Руководитель управления ИТ компании WiseAdvice Олег Филиппов рассказал, как можно применить такие инструменты, как Mule ESB и RabbitMQ.

02.09.2019    4521    comol    3       

Отказ от использования хранилищ 1С, переход на Git. 70

Статья Программист Нет файла Бесплатно (free) Инструментарий разработчика Разработка

Валерий Максимов в своем докладе на конференции INFOSTART EVENT 2018 EDUCATION делится опытом перехода нескольких команд (более 100 разработчиков) от использования хранилищ 1С на системы контроля версий Git.

25.07.2019    5951    theshadowco    31       

Раскручиваем Гайку: разработка ПО для роботов на платформе 1С 46

Статья no Нет файла Бесплатно (free) Разработка

Роботы на 1С стали реальностью. Их разработкой пока на общественных началах занимаются в компании «Цифровой кот». Насколько перспективно это направление, какие возникали сложности, и какая помощь коллег требуется, участникам конференции Infostart Event 2018 рассказал руководитель и ведущий разработчик компании - Юрий Лазаренко.

23.07.2019    3926    TitanLuchs    36       

Интеграция сценарного тестирования в процесс разработки 81

Статья Программист Нет файла Бесплатно (free) Практика программирования Разработка

Разработчик системы «Тестер» Дмитрий Решитко в своем докладе на конференции INFOSTART EVENT 2018 EDUCATION показывает, что процесс тестирования можно очень плотно интегрировать в процесс разработки, что внедрение тестирования – это возможность развития программиста как такового, позволяющая ему упорядочивать ход мыслей и оставаться «в фокусе». Навыки построения процесса кодирования на стыке с тестированием сокращают время на концентрацию, освобождают от страха перед изменениями и улучшают память разработчика.

08.07.2019    4402    grumagargler    7       

Управляй качеством кода 1С с помощью SonarQube 220

Статья Программист Нет файла Россия Бесплатно (free) Практика программирования Разработка

Управляй техническом долгом проектов 1С с помощью SonarQube. В статье рассматривается пример применения SonarQube при разработке.

07.07.2019    16040    olegtymko    191       

Тестирование интеграций между системами 70

Статья Программист Нет файла Бесплатно (free) Интеграция

Как начать разрабатывать интеграцию без реальной «второй стороны»? Как быть уверенным, что обмен не «сломается» при следующем обновлении? О том, какие подходы можно применять при тестировании интеграций и как такое тестирование может выглядеть в целом – в докладе Никиты Грызлова на конференции INFOSTART EVENT 2018 EDUCATION.

01.07.2019    5236    nixel    3       

И тогда наверняка нас захватят облака 18

Статья Программист Нет файла Бесплатно (free) Интеграция

Внимание! Данный текст содержит достаточно мало технических подробностей и готовых рецептов. Главным образом некоторые размышления на предмет будущего технологий и профессий. Некое лёгкое чтение на досуге.

28.06.2019    3987    comol    35       

По следам публикаций 1С + микроконтроллер, или 1С в железе 33

Статья no Нет файла Бесплатно (free) Интеграция

Несколько примеров удачного применения связки микроконтроллер и 1С, в производстве. Результат - исключение человеческого фактора, экономия средств на АСУ, повышение культуры производства ))), и др...

12.06.2019    4344    vostok1.dz    13       

Выдержки из книги Чистый код 24

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

Недавно я прочитал книгу "Чистый код" Роберта Мартина (Robert Cecil Martin). В ней описываются принципы организации и форматирование исходного кода программы так, чтобы в дальнейшем было легко поддерживать такой код. Эта книга является библией для многих программистов, но вот в среде программистов 1С, к сожалению, не очень распространено чтение подобной фундаментальной литературы. Книга более 400 страниц и так много порой лениво читать, да и времени всегда не хватает. По этому я решил выделить в виде цитирования по разделам самые важные моменты. А также снабдил текст своими примерами кода.

16.05.2019    5576    FreeArcher    82       

Быстрый ввод неудобных символов 66

Статья no Нет файла Бесплатно (free) Пользователю системы Инструментарий разработчика

Использование Alt-кодов для ввода “[”, “]”, “”, “&”, “#”, “|”

15.04.2019    5137    pparshin    24       

О времени и 1С 206

Статья Программист Нет файла Бесплатно (free) Практика программирования Разработка

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

01.04.2019    15191    YPermitin    58       

Быстрее чем INSERT! BULK-операции и примеры использования 112

Статья Системный администратор Программист Нет файла Бесплатно (free) Производительность и оптимизация (HighLoad) Практика программирования Разработка Внешние источники данных Перенос данных из 1C8 в 1C8

Microsoft SQL Server поддерживает так называемые BULK-операции, используемые для быстрого изменения больших объемов данных в базе. В статье пойдет речь о практических примерах их использования. Все примеры сделаны в контексте платформы 1С (а как иначе).

09.03.2019    9719    YPermitin    38       

Как писать понятные коммиты 67

Статья Программист Нет файла Россия Бесплатно (free) Практика программирования Разработка

Как писать сообщения коммитов так, чтобы потом не было мучительно больно.

06.03.2019    7813    Scorpion4eg    34       

Как писать код? Технологии древних цивилизаций, или все новое - это хорошо забытое старое 70

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

Все современные технологии - это развитие и доведение до ума (или маразма) древних идей. За последнее время не придумали ничего нового - все, что мы видим, было придумано тысячи лет назад. Не является исключением и программирование, которое в сути своей является переводом с языка условностей технического задания или заявки пользователя в формализованный и абсолютно точный язык математической логики. А логику придумали (по крайней мере первыми опубликовались в ведущих научных журналах) еще древние греки.

23.01.2019    8594    starik-2005    43       

Ректальное программирование: основы для практикующих 1С-программистов 294

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

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

19.12.2018    30557    for_sale    340       

Подмена заголовка 1С 26

Статья Системный администратор Программист Нет файла Россия Windows Бесплатно (free) Работа с интерфейсом Универсальные функции

Подстановка имени базы данных в начало заголовка окон с программой 1С (конфигуратор и предприятие). Удобно при одновременной работе с большим количеством баз данных. Скрипт интересен будет как для программистов, так и для администраторов баз данных. Заголовок можно менять для любой программы, не только для 1С, для этого требуется немного исправить скрипт. Программисту 1С не составит труда переделать скрипт.

08.12.2018    7538    moolex    26       

1С + asterisk (автоматический обзвон) часть 1 38

Статья Системный администратор Программист Нет файла Россия Бесплатно (free) Практика программирования WEB Телефония, SIP

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

29.11.2018    7211    dmarenin    9       

Почему внедрение ERP-системы не приносит пользы бизнесу? 87

Статья Бизнес-аналитик Пользователь Руководитель проекта Нет файла Бесплатно (free) Интеграция Управление проектом

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

15.11.2018    15654    rossoxa    62       

Развитие 1С программиста 51

Статья Программист Нет файла Бесплатно (free) Практика программирования Личная эффективность

Делюсь своим опытом и видением развития 1С программиста.

17.10.2018    13518    pashamak    62       

Записки про metadata.js 53

Статья Программист Нет файла Бесплатно (free) Практика программирования

Отличительные особенности разработки на metadata.js

31.07.2018    9102    1c-intelligence    59       

Учебный курс. Повышение качества разработки. Ошибки программы 97

Статья Программист Нет файла Бесплатно (free) Практика программирования Математика и алгоритмы Рефакторинг и качество кода

Учебный курс по теории и практике программирования. Бесплатно. В виде структурированного текста. Лекции № 3,4,5. Эти лекции посвящены ошибкам программ, их классификации и способам исправления

10.07.2018    15764    Артано    92       

Хостим OneScript.Web приложение 28

Статья Программист Нет файла Бесплатно (free) OneScript

Удобная возможность для размещения своего OneScript.Web приложение, это завернуть его в docker. Остается вопрос: где разместить контейнер, сделать это можно на vscale или DO, но хочется упростить и не делать установку самого docker на хосте. Один из вариантов - это сервис now https://zeit.co/.

04.07.2018    5715    pallid    3       

Автоматизируй это! 148

Статья Системный администратор Программист Нет файла Бесплатно (free) Практика программирования

Здравствуйте. Меня зовут Виталий Онянов. Я работаю в компании ФТО. Мы занимаемся внедрением и поддержкой ERP-систем, в том числе и на 1С. Сегодня я хотел бы поделиться нашим опытом автоматизации своих задач и рассказать о том, какие регламентные задания мы настраиваем на серверах наших клиентов. Возможно, кому-то покажется, что это совсем простые и очевидные вещи, но я в своей работе периодически вижу разработчиков, которые делают какие-то задачи руками изо дня в день, и мне бы хотелось донести до них мысль о том, что многие из этих задач можно и нужно автоматизировать.

02.07.2018    16102    Tavalik    12       

Учебный курс. Повышение качества разработки. Вводная лекция, часть 2 49

Статья Программист Нет файла Бесплатно (free) Практика программирования Математика и алгоритмы

Учебный курс по теории и практике программирования. Бесплатно. В виде структурированного текста. Лекция №2. Эта лекция посвящена абстракциям, их свойствами и практическому применению в рамках классических парадигм программирования.

24.05.2018    10679    Артано    36       

Учебный курс. Повышение качества разработки. Вводная лекция 116

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

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

10.05.2018    15549    Артано    51       

OneScript в облаке или Развертываем http-сервис OneScript на хостинге 23

Статья Программист Нет файла Бесплатно (free) OneScript

В статье описан процесс развертывания web-приложения, созданного на базе http-сервисов OneScript на бесплатном хостинге.

05.05.2018    7207    blackhole321    0       

Развертывание http-сервиса OneScript на Raspberry Pi 26

Статья Системный администратор Нет файла Бесплатно (free) OneScript

В статье описан процесс настройки, а также процесс развертывания http-сервиса (web-приложения) OneScript на Raspbian (Raspberry Pi 2).

23.04.2018    8399    blackhole321    10       

Веб-разработка на 1Script. Глава 2 64

Статья Программист Нет файла Бесплатно (free) Практика программирования WEB

Продолжение учебника по веб-разработке с помощью фреймворка Oscript.Web. Структура приложения, основные объекты, URL-маршрутизация, универсальная консоль серверов 1С.

22.04.2018    12058    Evil Beaver    27       

Развертывание http-сервиса (web-приложения) OneScript на Ubuntu Server 16.04 43

Статья Системный администратор Программист Нет файла Ubuntu Бесплатно (free) OneScript

В статье описан процесс настройки сервера, а также процесс развертывания http-сервиса (web-приложения) OneScript на Ubuntu Server 16.04

04.03.2018    12589    blackhole321    14       

Правила программирования и автоматизации 73

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

Изложил свой опыт программирования, больше десяти лет.

21.02.2018    16226    Dzenn    127       

Веб-разработка на 1Script. Глава 1 250

Статья Программист Нет файла Бесплатно (free) Практика программирования

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

12.02.2018    25552    Evil Beaver    97       

23 способа изменить язык интерфейса в 1С 164

Статья no Нет файла Бесплатно (free) Работа с интерфейсом

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

04.02.2018    48561    ekaruk    31       

Творим Историю вместе 55

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

Расширяем границы, выходим за рамки, ставим новые цели - все, как вы любите.

17.01.2018    14869    1c-intelligence    108       

Использование git при разработке на 1С 122

Статья Программист Нет файла Россия Бесплатно (free) Математика и алгоритмы

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

27.12.2017    25888    real_MaxA    57       

Версионирование правил обмена в Git 64

Статья Программист Нет файла Windows Бесплатно (free) Практика программирования

Статья рассказывает о принципах работы скриптов, позволяющих применять систему контроля версий git и подход gitflow для версионирования правил обмена.

15.12.2017    12944    bforce    22       

Двоичное дерево, двоичное дерево поиска, двоичная куча, B-дерево 34

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

В большинстве реляционных СУБД в качестве структуры данных для индексов (та или иная их реализация) используются именно деревья. И не просто деревья, а сбалансированные деревья поиска. В этой статье как раз о них.

24.11.2017    12380    Irwin    4       

Начало работы с OneScript 136

Статья Системный администратор Программист Нет файла Бесплатно (free) OneScript

Краткая инструкция по установке и начале работы с OneScript. Пишу потому что сам много шишек набил, пока нашел все инструменты. В статье рассмотрены: 1) Установка OneScript. 2) Установка редактора кода. 3) Настройка редактора кода под OneScript. 4) Запуск скриптов из редактора кода 5) Полезные ссылки

18.10.2017    30401    DmitrySinichnikov    50       

С чего начать разработку скриптов на OneScript? Первые шаги 155

Статья Программист Нет файла Бесплатно (free) OneScript

После моего доклада на INFOSTART 2017 EVENT COMMUNITY ко мне многие обращались с таким вопросом: с чего начать разработку скриптов на OneScript? В этой статье привожу набор ссылок и некий порядок действий (как его вижу я) для людей, не знакомым с этим инструментом.

11.10.2017    21677    Tavalik    12       

Некоторые особенности разработки ММО-игр на платформе 1С:Предприятие 25

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

Добрый день, уважаемые коллеги! На первый взгляд может показаться, что статья посвящена довольно необычным вещам, но поверьте мне, эти вещи всем нам вполне привычны, просто мы их обычно видим под другим углом зрения. Поговорим о том, что такое MMO. Многие из вас уже знают, что это такое, потому что существует такая игра, как World of Tanks, а те, кто в нее напрямую не играл, безусловно, о ней слышали. Игра World of Tanks является классическим MMO. MMO расшифровывается как Массивная Многопользовательская Online-игра. С технологической точки зрения это – нагрузки, нагрузки и еще раз нагрузки.

08.09.2017    9392    Inkasor    21       

Зачем 1С-нику NoSQL и CRDT 92

Статья Программист Нет файла Бесплатно (free) Производительность и оптимизация (HighLoad) Распределенная БД (УРИБ, УРБД) WEB

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

12.08.2017    19491    unpete    27       

Применение нейронных сетей и генетических алгоритмов в прикладных решениях на платформе 1С 170

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

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

03.07.2017    31881    comol    63       

Управление техническим долгом - Концепция Continuous Inspection 92

Статья no Нет файла Бесплатно (free) Управление проектом Практика программирования

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

30.06.2017    15112    nixel    16       

1Script – язык для автоматизации рутины в жизни специалиста по 1С 302

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

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

14.09.2016    44065    Evil Beaver    76       

BDD в 1С 123

Статья Программист Нет файла Бесплатно (free) Математика и алгоритмы

Я расскажу вам про магию BDD. Сначала будет немного теории, а потом я покажу, как это применимо к 1С на практике. BDD расшифровывается как Behavior Driven Development, разработка через поведение системы. Это означает, что мы выстраиваем весь наш процесс разработки, исходя из ожидаемого поведения.

30.08.2016    25956    Pr-Mex    19