Декомпиляция и анализ форм с генерацией кода формы (обычное приложение)


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

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

Деструктивный анализ формы: //infostart.ru/projects/2412/

Декомпилятор форм: //infostart.ru/projects/1343/

Теоретическая база проекта: http://www.kb.mista.ru/article.php?id=650&

кроме объединения этих двух разработок в одну я добавил поддержку всех типов метаданных и улучшил «под себя» эргономичность использования.

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

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

Во 2-м окне видим описание всех элементов выбранной формы.

При двойном щелчке мыши на интересующем нас элементе в 3-м окне получим свойства элемента.

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

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

 

Решения, созданные при помощи данной обработки:

//infostart.ru/public/99363/

//infostart.ru/public/65449/

99 Comments

  1. raiml

    Супер! Спасибо за труд.

    Reply
  2. sound

    Нормально! Тока на некоторых формах ашипка вылазит

    СтраницаПанели = ЭлементНастройкиМакета.Страницы[ПеремЦикла-1];

    Reply
  3. MRAK

    (2) это я в курсе, в P.S. написал… начал копать в эту сторону, но времени слишком мало

    Reply
  4. Душелов

    Если рабочая, то плюс авансом. Посмотрю на досуге.

    Reply
  5. MRAK

    (4) не полностью рабочая, при разборе панелей пока могут вываливаться ошибки

    Reply
  6. Арчибальд

    Редко плюсую восьмерочное. Но здесь не удержусь…

    Reply
  7. sound

    (3) ага это я не дочитал, хотелось сразу пробовать 🙂

    Reply
  8. MRAK

    (1), (2), (4), (6) обновил файл! теперь ошибок будет меньше!

    Reply
  9. sound

    Думается надо

    1) чтоб сразу форма максимизировалась

    2) тока чтение

    Reply
  10. Ish_2

    Не скачивая , сразу +.

    Reply
  11. Шёпот теней

    предлагаю вернуть Гений 1С в лоно ИС ….

    … комментарий не к теме: «но страна должна знать своих героев» …

    … спасибо за ссылки в описании обработки …

    … удАчи …

    Reply
  12. MRAK

    (9) точно, так лучше. подправил

    Reply
  13. MRAK

    (11) не ради славы, а ради того, штоб поделиться… ну и на развитие проекта надеюсь, не обязательно мною.

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

    Reply
  14. Душелов

    (13) А от меня отдельный респект ;), воспользуюсь в своих низменных целях, для компилятор 1С-кода, у меня как раз застопорилось на разборе и генерации win-форм на основе 1С-ных.

    Reply
  15. asady

    Молодец

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

    Reply
  16. KapasMordorov

    2(0)

    По поводу ошибки

    СтраницаПанели = ЭлементНастройкиМакета.Страницы[ПеремЦикла-1];

    Ошибка в модуле формы.

    «»ФормаКопия = Форма;»» — нельзя так. Получается две ссылки на один и тот же объект.

    Reply
  17. MRAK

    (15) ну эт не я молодец… насчет остального — типовые конфы под 8.1 еще. данную обработку как раз для них использую. Насчет обработчиков, да их практически невозможно вытащить, но это и не особо нужно, в режиме попроцедурном объединении модуля формы это все легко разруливается.

    Reply
  18. KapasMordorov

    2(15)

    С обработчиками событий как раз всё нормально.

    В 8.2 у элемента формы есть «Родитель» — могильщик текущего проекта.

    Reply
  19. MRAK

    (16) спасибо, как раз дошел сейчас до этого места

    (18) так он про 8.1 говорит насчет обработчиков

    Reply
  20. KapasMordorov

    2(19)

    ПолучитьДействие()

    УстановитьДействие()

    Reply
  21. artbear

    Я для себя дорабатывал

    Деструктивный анализ формы — http://infostart.ru/projects/2412/

    1. В текстовый макет «СвойстваЭлементовФормы» добавил свойства типа

    ДействиеПриИзменении (Action_ПриИзменении)

    ДействиеНажатие (Action_Нажатие)

    ДействиеОбработкаВыбора (Action_ОбработкаВыбора)

    2. Далее в цикле обработки строк макета выполняю проверку реквизита на то, что в начале его имени стоит Действие, и через ПолучитьДействие получаю имя обработчика.

    // — Артур — 05.02.2009 — получим обработчики действий

    лИмяДействия = «»;

    лДлинаСловаДействия = СтрДлина(«Действие»);

    Если Лев(тИмя, лДлинаСловаДействия) = «Действие» Тогда

    лИмяДействия = Сред(тИмя, лДлинаСловаДействия+1);

    КонецЕсли;

    Если лИмяДействия <> «» Тогда

    Попытка

    лДействие = Вычислить(«тЭлемент.ПолучитьДействие(«»»+лИмяДействия+»»»)»);

    тЗнач = Строка(лДействие);

    Исключение

    Продолжить;

    КонецПопытки;

    Сообщить(«лДействие = <«+?(лДействие = Неопределено, «Неопределено», лДействие)+»>»);

    //Выполнить(«тФорма.»+лДействие+»(Неопределено)»);

    Иначе

    // —завершение

    Попытка

    тЗнач=тЭлемент[тИмя];

    Исключение

    Продолжить;

    КонецПопытки;

    // — Артур — 05.02.2009 — получим обработчики действий

    КонецЕсли;

    Reply
  22. MRAK

    (20) Точно, есть такое, я просто в эту сторону не копал.

    Мне этот функционал без надобности, хотя мож кому пригодится…

    (21) Ок, спасибо за готовый код, можно опционально включить в обработку.

    Reply
  23. Istur

    У меня все равно выдает эту ошибку((

    «Индекс находится за границами массива

    СтраницаПанели = ЭлементНастройкиМакета.Страницы[ПеремЦикла-1];»

    Reply
  24. MRAK

    (23) а последнюю обработку скачал? она называется «ДекомпиляцияИАнализФорм_2.epf »

    Если ошибка на типовой конфе, то напиши, на какой форме вызывается, я проверю

    Reply
  25. Istur

    (24) именно что скачал вторую. а выдает на моей обработке, http://infostart.ru/projects/5591/ , «Форма».

    Reply
  26. MRAK

    (25) Странно, у меня выдает другую ошибку… Попробуй закоментить весь свой модуль формы при переносе в данную обработку.

    Reply
  27. Istur

    (26) Нет, не помогло(( Ну ладно, фиг с ним. Главное что со стандартными работает)))

    Reply
  28. stilet

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

    Reply
  29. MRAK

    (28) последнего нет… на 10.3.5.1 отработал без ошибки. Пока на последнем нет возможности проверить(((

    Reply
  30. glek

    На УПП для Украины выдает ту же ошибку. На любой форме

    Reply
  31. glek

    Судя по анализу, имеем следующее:

    В первом анализе (строка 719 код КоличествоСтраниц = ЭлементНастройкиМакета.Страницы.Количество();) получаем общее количество страниц. Потом идет цикл для 1 по количество страниц. НО! в строке 725 в коде пФормаКопия.ЭлементыФормы[ЭлементНастройкиМакета.Имя].Страницы.Удалить(0); идет удаление сразу 1 страницы с панели

    Reply
  32. MRAK

    (28), (30) специально последний релиз УТ поставил, ошибка не воспроизводится.

    Навсякий случай сейчас файл на сайте обновлю, мож я че с этим накосячил…

    Reply
  33. rasswet

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

    Reply
  34. MRAK

    (33) думаю, проще добавить исследуемую форму в обработку. В дереве метаданных она будет доступна в ветке «ЭтотОбъект» в самом верху

    Reply
  35. rasswet

    жаль нельзя указать обе формы и прочитать различия

    Reply
  36. MRAK

    (35) хочу сделать, но пока нет времени.

    пока можно юзать «Файл» — «Сравнить файлы», если формы не слишком сильно различаются

    Reply
  37. Borisych

    Занимательный подход и много труда! Плюс.

    Правда иногда можно увидеть:

    Код
    {ВнешняяОбработка.ДекомпиляцияИАнализФорм(764)}: Поле объекта не обнаружено (ОсновнаяПанель)
             ЭлементНастройкиМакета = пФорма.ЭлементыФормы[ЭлементТаблицы.Имя];

    Показать полностью

    Reply
  38. MRAK

    (37) это в типовой? в какой форме, проверю

    Reply
  39. Borisych

    (38) нет не в типовой

    Reply
  40. Totoro

    (0) Замеченные недочеты по панелям (по собственному опыту генерации формы) 🙂

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

    +

    1) при присвоении текущей страницы отсутствует «.Страница»

    2) При прочтении свойств странице в дереве выдается ошибка

    3) После создания панели 1 страница уже существует, т.ч. добавлять нужно только со второй страницы, первую заполнять.

    4) Видимость страницы тоже не генерируется (видимость страницы тоже нужно устанавливать последней).

    Все тестировалось в ПередОткрытии формы

    Reply
  41. MRAK

    (40) спасибо за комментарий, в ближайшее время постараюсь посмотреть.

    Reply
  42. Totoro

    (41) Как вариант:

    1) для страниц добавить макет со свойствами страниц и проверка при при заполнении дерева на страницу.

    2) При формировании кода самый простой способ добавить строчку удаления 0-вой страницы после всех строчек добавления страниц + добавить заполнение свойств каждой страницы.

    ЗЫ Эта я вечером вчера смотрел. Вроде работало. Только с видимостью и прокручиваемыми страницами не разбирался.

    Reply
  43. lion11

    Большое спасибо за хорошую работу!

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

    (Надпись на транспаранте: Обновление нетиповой конфигурации за ОДИН день! :))

    Reply
  44. vadim1980

    Обработка очень нужная. Правда нашел пару недочетов, которые мешают при объединении с помощью merge

    1) необходимо при сортировке ТаблицаЭлементовФормы.Сортировать(«Панель,Страница,Тип»);

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

    ТаблицаЭлементовФормы.Сортировать(«Панель,Страница,Тип,Индекс»);

    2) вместо вставки колонки в табличное поле необходимо делать обычное добавление, тогда merge не сбивается при вставке колонки

    Непонятно только, почему отличается ширина в решиме Конфигуратор и в режиме Предприятие, поэтому я в комментарии ширины вывожу еще ширину * 6,875 чтобы забивать это значение в конфигуратор 🙂

    Reply
  45. vadim1980

    Обнаружились еще 2 проблемы:

    1) Не отображаются общие формы

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

    Reply
  46. e.kogan

    Дописала для анализа внешних отчётов и обработок. Выслать?

    Reply
  47. MRAK

    (46) Давайте, объединим услилия. А то, если честно, сейчас времени на доработку нет.

    Reply
  48. e.kogan

    (47) Посмотрите приложенный файл.

    Reply
  49. MRAK

    (48) благодарю, в ближайшее время посмотрю и обновлю

    Reply
  50. vorlogo

    Вставляется лишняя скобка в строках.

    ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница = ЭлементыФормы.ОсновнаяПанель.Дополнительно);
    
    Reply
  51. vorlogo

    буквально один вопрос — как вы затем используете полученный текст? Если в тексте модуля самой формы, то не будет ли метод ЭлементыФормы.Добавить() конфликтовать с тем, что элементы уже существуют? Или вы удаляете все элементы с формы? но это же неудобно

    Reply
  52. MRAK

    (51) лично я визуально добавляю нужные мне элементы и меняю существующие. Затем копирую для использования код только измененных и новых элементов.

    Конечно, е обработке не хватает сравнения форм, но можно заюзать типовое.

    Reply
  53. Dirk Diggler

    Кроме (50), еще обработка разбивает числа на триады, например

    КоманднаяПанель.Ширина = 1 276;

    вместо

    КоманднаяПанель.Ширина = 1276;

    Ругается проверка синтаксиса

    Reply
  54. Dirk Diggler

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

    Кнопка0 = ЭлементыФормы.ДействияФормы.Кнопки.Подменю.Кнопки.Вставить(5,»Действие4″,ТипКнопкиКоманднойПанели.Действие,»Установить интервал дат…»,Новый Действие(«Установитьинтервалдат…»));
    

    Как вы понимаете, процедуры «Установитьинтервалдат…» не существует

    Reply
  55. MRAK

    (35) теперь можно

    Reply
  56. Dirk Diggler

    Блестяще!

    Скажите, а нельзя формы извлекать из хранилища?

    Скажем, сравнивать форму текущей конфы и такую же, но из «конфигурации поставщика»?

    Reply
  57. MRAK

    (56) насколько я знаю, стандартных функций доступа к конфе поставщика не существует.

    пока предлагаю копировать нужную форму просто через буфер обмена и вставлять ее в данную обработку. Тогда можно будет сравнить новую форму из обработки со старой — из конфиги.

    Да, еще, ошибки вышеуказанные не оследил, так как сам не сильно модифицирую формы, на моих задачах они не возникали.

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

    Reply
  58. Dirk Diggler

    Да, логические значения сейчас тоже отображаются неверно:

    ПолеВвода = ЭлементыФормы.Добавить(Тип(«ПолеВвода»),»КодПоОКПО»,Истина,ЭлементыФормы.ПанельЮрФизЛицо);

    ПолеВвода.Видимость = Нет;

    Т.е. «нет» и «да» вместо истина и ложь

    Reply
  59. MRAK

    (58) странно, у меня такой проблемы не возникает…

    локализация российская? конфа типовая? если да, то в какой форме? (я проверял на форме элемента «Контрагенты» в УТ 10.3)

    Reply
  60. artbear

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

    Сейчас неудобно:

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

    Переходи на версионирование, лады?

    Reply
  61. MRAK

    (60) Добро, принято ))))

    Reply
  62. MRAK

    А проще — старые версии удалю. Последняя содержит функционал всех предыдущих.

    Reply
  63. vorlogo

    (59) у меня «да» и «нет» в режиме сравнения, в упп тоже на форме элемента «контрагенты».

    Правда, я сконвертировал под 8.2.

    Reply
  64. MRAK

    (63) под 8.2 не тестил, думаю в этом косяк.

    На 8.2 пока нет проектов, поэтому не тестил.

    Если переведу свою конфу «Личный органайзер» под 8.2, мож еще здесь выложу, то будет смысл тестить…

    Reply
  65. MRAK

    (63) + но думаю, под 8.2 данная обработка не так актуальна, как под 8.1.

    Там же управляемые формы…

    Reply
  66. Душелов

    (65) На управляемых формах проще. Получаешь дерево элементов — и вперед…

    Reply
  67. MRAK

    (66) ну так добивай свой компилятор для 8.2 с форточками)))

    Reply
  68. Душелов

    (67) Не успею 🙂 Думаю, скорее 8.3 выйдет 😀

    Reply
  69. Dirk Diggler

    (65) Там МОГУТ использоваться УФ. но бОльшая-то часть конф все еще на обычных.

    Reply
  70. Dirk Diggler

    Было бы здорово иметь режим генерации кода не создания формы, а её модификации.

    Т.е. генерации строк не вида

    ПолеВвода = ЭлементыФормы.Добавить(Тип(«ПолеВвода»),»КодПоОКПО»,Истина,ЭлементыФормы.ПанельЮрФизЛицо);

    а вот таких:

    ПолеВвода = ЭлементыФормы.КодПоОКПО; 

    Reply
  71. MRAK

    (70) над этим надо подумать, использую иногда. Можно сделать опционально

    Reply
  72. Dirk Diggler

    По поводу «Да»/»Нет»

    Из хелпа по 8.2:

    Использовать региональные установки текущего сеанса

    ……

    Значение типа Булево отображается в соответствии с используемым языком платформы, если в данных установках не заданы конкретные значения. Значение типа Булево отображаются словами «Да, Нет», «Yes, No» и т.д., если не используется режим совместимости.

    Reply
  73. Dirk Diggler

    Короче, нельзя там функцию Строка() использовать.

    Reply
  74. MRAK

    (72) понятно.

    но пока под 8.2 переделывать не планирую.

    Reply
  75. Dirk Diggler

    строка 515 модуля объекта:

    Текст.ДобавитьСтроку(Таб + ТекстЭлемент+».»+Свойство+ » = «+?(ТипЗначенияСвойства = Тип(«Булево»),?(Элемент[Свойство],»Истина»,»Ложь»),Элемент[Свойство]) +»;»);

    Reply
  76. Dirk Diggler

    доработал пару строк. под себя, так что не обессудьте что под 8.2

    Reply
  77. Dirk Diggler

    (74) А не факт что это под 8.1 работает. Не исключено, что Строка() и в 8.1 зависит от региональных установок базы.

    Reply
  78. Dirk Diggler

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

    КоманднаяПанель = ЭлементыФормы.Добавить(Тип(«КоманднаяПанель»),»ДействияФормы»,Истина);
    КоманднаяПанель.Имя = «ДействияФормы»;
    КоманднаяПанель.Верх = 0;
    КоманднаяПанель.Высота = 25;
    КоманднаяПанель.Ширина = 1 276;
    

    Там же, чуть ниже(это к слову об автозаполняемых ком. панелях):

    Кнопка1 = ЭлементыФормы.ДействияФормы.Кнопки.Подменю.Кнопки.Подменю.Кнопки.Вставить(2,»Действие1″,ТипКнопкиКоманднойПанели.Действие,»»,Новый Действие(«(Историяотборов)»));
    Reply
  79. MRAK

    (76) благодарю, добавлю в свою обработку

    Reply
  80. MRAK

    (78)

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

    Код

    КоманднаяПанель = ЭлементыФормы.Добавить(Тип(«КоманднаяПанель»),»ДействияФормы»,Истина);

    КоманднаяПанель.Имя = «ДействияФормы»;

    КоманднаяПанель.Верх = 0;

    КоманднаяПанель.Высота = 25;

    КоманднаяПанель.Ширина = 1 276;

    нет у меня таких широких в УПП…

    Reply
  81. Dirk Diggler

    и последнее

    СтрЗаменить(…..,» «,»»),

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

    Reply
  82. Dirk Diggler

    (80) А вы попробуйте это сделать сперва открыв эту форму и развернув на весь экран. Сразу появятся ))))

    Reply
  83. MRAK

    (82) Если только в режиме конфигуратора…

    Reply
  84. alexer

    Отличная штука, плюс +++.

    Reply
  85. alexer

    если получится выложу свой вариант

    Скриншот

    Reply
  86. MRAK

    (85) на скрине все выглядит красиво, буду ждать 🙂

    Reply
  87. Ish_2

    (85) Ага. Красиво.

    Reply
  88. alexer
  89. sergejr

    Цвет не переносит, а в остальном плюс

    и пожелание: в описании написано

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

    Reply
  90. sergejr

    Нашел ошибку.

    При декомпиляции формы на которой есть панель со страницами выдает такую строку: ЭлементыФормы.Панель.ТекущаяСтраница = ЭлементыФормы.Панель.ВыпускКакРасход);

    здесь лишний знак ) и должно быть так

    ЭлементыФормы.Панель.ТекущаяСтраница = ЭлементыФормы.Панель.Страницы.ВыпускКакРасход;

    Reply
  91. MRAK

    (90) Если это в типовой, то напишите, пожалуйста, в какой форме возникает ошибка.

    Reply
  92. sergejr

    Это документ Отчет мастера смены в УПП, я там добавил ещё одну страницу на панели, но ошибка выходит для всех панелей: лишний знак ) и не хватает слова СТРАНИЦЫ ЭлементыФормы.Панель.Страницы.ВыпускКакРасход;

    Reply
  93. Kiber_

    Во-первых, огромное спасибо. 🙂

    Во-вторых, лови багрепорт:

    При декомпиляции формы в УПП (то-ли спецификации номенклатуры, толи статей затрат)

    {ВнешняяОбработка.ДекомпиляцияИАнализФорм(747)}: Поле объекта не обнаружено (ПанельВыходноеИзделие)

    пФормаКопия.ЭлементыФормы[ЭлементНастройкиМакета.Имя].УстановитьДействие(«ПриСменеСтраницы», Неопределено);

    Reply
  94. sgromov@bk.ru

    От меня жирный плюс!

    багрепорт:

    запускал на БП 1.6.24, после названий страницы в результате декомпиляции рисует лишнюю закрывающую скобку, например:

    ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница = ЭлементыФормы.ОсновнаяПанель.СчетФактура);

    Reply
  95. sgromov@bk.ru

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

    лементыФормы.ОсновнаяПанель.ТекущаяСтраница = ЭлементыФормы.ОсновнаяПанель.СТРАНИЦЫ.СчетФактура;

    Reply
  96. _wlad_

    Уже давно крутилась такая идея, т.к. обновление перепаханных типовых форм порой заставляет материться! К сожалению дальше первых подступов не дело не дошло. Попробуем вашу

    Reply
  97. MRAK

    (96) Пожалуйста. Недоработок много, сам знаю — все никак не хватает времени добить.

    Но кое в чем обаботка полезна.

    Reply
  98. Asdam

    Del.

    Reply
  99. ave57

    {ВнешняяОбработка.ДекомпиляцияИАнализФорм(747)}: Поле объекта не обнаружено (ПанельОборотБольничного)пФормаКопия.ЭлементыФормы[ЭлементНастройкиМакета.Имя].УстановитьДействие(«ПриСменеСтраницы», Неопределено);

    Зарплата и Управление Персоналом, редакция 2.5 (2.5.25.3)

    Ошибка при декомпиляции формы «ФормаДокумента» документ «НачислениеПоБольничномуЛисту»

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *