Конечно же, я видел навороченные консоли кода и консоли запросов с подсветкой и подсказками, но в практической деятельности они у меня не прижились по следующим причинам:
1. для консоли кода:
- вывод результата только через Сообщить
2. для консоли запросов:
- неудобный ввод запроса, но это субъективно, просто я не люблю пользоваться конструктором запросов;
- слабые генераторы кода обработки, но, возможно, я не все видел.
Поэтому на протяжении нескольких лет потихоньку дорабатывал стандартные консоли, добавляя свои фишки, пока не получился концептуальный блэк-джек достойный внимания.
Представляю вам свою версию консоли кода.
Основные фишки:
- поддержка объявления процедур и функций, в том числе поддерживается рекурсия и ранние выходы из функций, объявление клиентских и серверных функций;
- минимальная поддержка макросов (замена кода, подключение внешнего файла);
- задание параметров для выполняемого кода;
- задание выражений для отслеживания результатов;
- функции для вывода таблицы значений, дерева значений, результата запроса, менеджера временных таблиц и др.
Описывать буду в хронологическом порядке появления возможностей, мне так удобнее.
Запускать код можно как на клиенте, так и на сервере -> кнопка-переключатель на панели.
Параметры кода
Задание параметров кода идет подстановкой их значений в исполняемый код, работает и на клиенте и на сервере, но не сразу одновременно.
Если рядом с параметром поставить галочку Откл, то вместо указанного значения будет передаваться Неопределено.
Отслеживание переменных
Отслеживание переменных работает подобно пункту "Вычислить выражение" в конфигураторе, пишем любое выражение или имя переменной и после выполнения основного кода скрипта, вычисляется выражение отслеживания, даже если основной код вылетел с ошибкой.
Отслеживание можно использовать даже без основного кода, например, записать в выражение текст "Новый УникальныйИдентификатор".
Перетаскивание для параметров кода и выражений отслеживания работает в обе стороны, можно просто выделить нужный текст и перетащить его.
Вывод результатов
Для вывода результатов на форме созданы 2 постоянных реквизита:
- Результат_Текст -- текстовое поле, выводим в него так: Результат_Текст = "Любой текст"
- Результат_ТабДокумент -- табличный документ, в него выводим, как в обычный табличный документ, либо функцией РезультатВТабДокумент.
Но эти реквизиты используются редко, основной вывод идет в динамически создаваемые табличные части, для этого предназначены 2 функции:
- Вывести(ЗначениеДляВывода, ИмяТЗ = 1, ВывестиНомерСтроки = Ложь)
ЗначениеДляВывода - произвольное значение. Допустимые типы: универсальные коллекции (таблица значений, дерево, массив, структура и др.), результат запроса, выборка, менеджер временных таблиц, строка ТЧ.
ИмяТЗ - число или строка (строка должна подходить для создания имени реквизита, т.е. нет пробелов, точек и т.п.)
ВывестиНомерСтроки - вывести номер строки в отдельном столбце
Выводит значение в отдельную страницу в группе Результат.
- ВывестиТипыКолонок(ТЗ, ИмяТЗ = 1, ВывестиНомерСтроки = Ложь)
ТЗ - объект для вывода
ИмяТЗ - число или строка (строка должна подходить для создания имени реквизита, т.е. нет пробелов, точек и т.п.)
ВывестиНомерСтроки - вывести номер строки в отдельном столбце
Выводит типы колонок для таблицы значений, дерева, результата запроса и возможно для других объектов содержащих св-во Колонки.
Вспомогательные функции
Иногда возникает желание посмотреть таблицу значений или табличную часть с группировкой по реквизитам, но создавать отдельный запрос для этого долго и зачастую лень, чтобы решить эту задачу создана функция, которая создает запрос по переданным параметрам.
- ТЗвДерево(ТЗ, КолонкиИерархии, КолонкиДляВывода = Неопределено)
ТЗ - таблица значений
КолонкиИерархии - строка, список имен колонок через запятую для группировки строк и построения иерархии.
КолонкиДляВывода - строка, список имен колонок для вывода. Неопределено - все колонки, кроме иерархии, "" - только иерархия,
"*" - все колонки, включая иерархию. Можно использовать формат "ИмяКолонки КАК НовоеИмяКолонки" для переименования колонок дерева.
Преобразует таблицу значений в дерево значений, возвращает дерево значений.
В параметры КолонкиИерархии, КолонкиДляВывода можно передавать не только названия колонок ТЗ, но и переходить от значений к их реквизитам, например, "Номенклатура.ЕдиницаИзмерения". Также можно передать условие, и данные будут сгруппированы по этому условию ("Цена > 100").
Обратная функция создает из дерева таблицу значений, была создана для эксперимента, но возможно кто-то найдет ей достойное применение.
ДеревоВТЗ(Дерево, КолонкаИерархии = Неопределено, ПоляИерархии = Неопределено)
Дерево - дерево для преобразования
КолонкаИерархии - имя колонки иерархии, по-умолчанию используется первая колонка
ПоляИерархии - строка, список имен колонок через запятую для распределения значений иерархии. Каждый уровень иерархии помещается в соответствующую колонку, если поле не задано, то создается новая колонка с имененем "Уровень_" + СтрокаДерева.Уровень().
Преобразует дерево значений в таблицу значений, возвращает таблицу значений.
Для сохранения таблиц, созданных функцией Вывести, можно использовать пункт меню Результаты >> Сохранить, либо функции ТЗвТабДокумент и РезультатВТабДокумент.
ТЗвТабДокумент(ТЗ, Заголовок = Неопределено)
ТЗ - таблица значений
Заголовок - заголовок для таблицы, если не задан, то заголовок не выводится
Создает новый табличный документ и выводит в него таблицу значений. Возвращает табличный документ.
Пример: Результат_ТабДокумент = ТЗвТабДокумент(Запрос.Выполнить().Выгрузить(), "Результат запроса");
РезультатВТабДокумент(ИмяТЗ = Неопределено)
ИмяТЗ - имя ТЗ, которое использовалось для вывода результата. Если не задано, будут выведены все результаты.
Создает новый табличный документ и выводит в него результат со страницы группы Результат. Работает только с таблицами, деревья не поддерживаются.
Пример:
Вывести(ТЗ, "ИмяТЗ", Истина);
Результат_ТабДокумент = РезультатВТабДокумент("ИмяТЗ");
Объявление процедур и функций
Разбор кода построен на парсере bsparser (https://github.com/lead-tools/bsparser), огромная благодарность автору.
Как это работает лучше смотреть в исходном коде.
Если кратко, то объявленные процедуры и функции вырезаются из кода в отдельные куски и сохраняются в таблицу, а их вызовы заменяются на вызов вспомогательной функции (одна для серверных и одна для клиентских).
Параметры метода переименуются по шаблону НовоеИмяПараметра = "п" + НомерПараметра, в коде они также заменяются на новое имя.
Возвраты значений заменяются на установку вспомогательной переменной и переход в конец метода. Для процедур возврат заменяется на переход в конец кода. Для основного кода теперь тоже можно использовать возврат для раннего его завершения.
Текст всех методов обрабатывается после обработки объявлений методов, это позволяет использовать рекурсию.
Существующие ограничения:
- вспомогательные функции принимают только 10 параметров, если нужно больше можно добавить в коде формы;
- директива &НаКлиенте ожидается сразу перед объявлением метода, если до этого будут комментарии, то метод будет определен как серверный;
- код метода компилируется при каждом вызове, поэтому в циклах возможны проблемы с производительностью (как вариант, можно подставлять код метода на место его вызова с переименованием параметров и локальных переменных, но это невозможно использовать при вызовах сервера с клиента; пока встраивание кода метода не реализовано).
Пример чтения XML и вывод его в дерево значений
Пример использования парсера
Макросы
Все макросы начинаются с "//#Макро" и должны располагаться в начале строки.
Макросы выполняются до разбора текста на методы.
Применение макросов производится к преобразованному тексту последовательно.
Макрос действует только на текст, расположенный ниже его объявления.
//#МакроЗамена ИсходныйТекст -> ЗамещающийТекст
Заменяет в коде исходный текст на замещающий текст.
пример: //#МакроЗамена Запрос.Выполнить(); -> ВыполнитьСТрассировкой(Запрос, Замеры);
Можно использовать для подмены функций модуля, например для внедрения замеров или склейки текста запросов.
//#МакроПодключить ИмяФайлаНаКлиенте
Вставляет содержимое указанного файла в код для исполнения.
Макросы в подключаемом файле обрабатываются отдельно и действуют только на его текст.
Если подключаемый файл подключает себя снова, то будет бесконечный цикл.
пример: //#МакроПодключить C:\Temp\Имя файла на клиенте.txt
Обновление от 17.09.2024:
1. Добавлена возможность передавать параметры по значению и указывать значения по-умолчанию в определении функции.
Например, Процедура ИмяПроцедуры(ПараметрПоСсылке, Знач ПараметрПоЗначению, ДругойПараметр = 123).
2. В таблицу параметров добавлена галочка Выр (Использовать выражение), теперь можно в качестве значения параметра использовать выражение.
Например: ТекущаяДата(). Или можно в выражении обратиться к предыдущим параметрам, например:
Ссылка -> документ
Дата -> Ссылка.Дата
Момент -> Новый МоментВремени(Дата, Ссылка)
3. Функция ВывестиТипыКолонок теперь может выводить типы колонок временных таблиц из объекта МенеджерВременныхТаблиц.
4. Функция Вывести:
- немного улучшен вывод структур и соответствий, теперь они выводятся в дерево;
- добавлен вывод объекта Запрос (текст, параметры, виртуальные таблицы из менеджера временных таблиц и их колонки, для поля значение колонок выбрано первое значение из виртуальной таблицы)
5. Добавлена функция СоздатьТЗ, в ней можно указать список необходимых колонок с их типами.
Пример:
ТЗ = СоздатьТЗ("КолонкаБезТипа, Валюта (СправочникСсылка.Валюты), Признак (Булево|Строка 50|Число 10.2), Описание (Строка 100), Сумма (Число 11.3), ЦенаНеотрицательная (Число +5.0)");
6. Немного улучшены сообщения об ошибках, теперь при ошибке в объявленном методе будет выведено его имя и строка с ошибкой.
Консоль запросов
Ну и попутно консоль запросов, её фишки:
- дерево объектов с возможностью бесконечно проваливаться в типы реквизитов, плюс виртуальные реквизиты Движения и СсылкиНаОбъект (места использования типа);
- генератор кода для обработки результата запроса, и естественно кнопка для переноса этого кода в консоль кода.
Дерево объектов получилось настолько удобным, что я зачастую смотрю структуру объектов не в конфигураторе, а именно в консоли. Для дерева объектов поддерживается перетаскивание объектов в код запроса, значения перечислений вставляются со словом ЗНАЧЕНИЕ, для ссылочных типов анализируется контекст и либо вставляется путь "Справочник.Организации", либо если есть сравнение перед местом вставки вставляется ссылка "= ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка)".
В контекстном меню расположены команды:
- по созданию минимального запроса для объекта конфигурации, также работает для табличных частей;
- открытия форм списка, выбора и остальных по имени;
- вставки предопределенного значения справочника.
Проваливаться в типы реквизитов, удобно двойным щелчком, но можно и через контекстное меню.
Если в коде запроса поставить курсор в текст с именем объекта дерева (либо выделить нужный текст), например ТоварыНаСкладах, то через контекстное меню можно найти этот объект в дереве.
Повторный поиск будет пытаться искать одноименные объекты ниже.
Генератор кода создает код для обработки в цикле либо таблице, возможно создание кода для обхода иерархии.
Автоматически создает код для заполнения параметров и в комментарии пишет код доступных реквизитов.
Если выделить пару строк запроса и нажать кнопку "Добавить условие", то будет создано обрамление этих строк условием, например:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Т.Ссылка КАК Ссылка,
|" + ?(условие, "
| Т.ПометкаУдаления КАК ПометкаУдаления,
| Т.Код КАК Код,
|", "") + "
| Т.Наименование КАК Наименование,
| Т.Префикс КАК Префикс,
| Т.ИНН КАК ИНН,
| Т.КПП КАК КПП
|ИЗ
| Справочник.Организации КАК Т";
Обновление от 17.09.2024:
1. Улучшена генерация кода для обработки запроса.
2. Убрана возможность работать с несколькими запросами в одном экземпляре обработки.
P.S.: представленные здесь обработки не являются каким-то продуктом и имеют кучу недоработок и нереализованных идей (в силу моей загруженности, они реализуются очень медленно и только те, что нужны мне в текущей работе), поэтому прошу рассматривать их лишь как концепцию, буду рад, если мои идеи будут реализованы и в более продвинутых инструментах.
Проверено на следующих конфигурациях и релизах:
- Зарплата и управление персоналом, редакция 3.1, релизы 3.1.30.57