
Есть просьбы, которые повторяют так долго, что они превращаются в фольклор. Одна из них - "сделайте тёмную тему в Конфигураторе".
Я тоже просил. Потом надоело, и решил покрасить сам. Краски хватило ненадолго, дальше пришлось копать. Об этом и статья.
Пролог. Пятнадцать лет в светлом
Март 2012-го. На Инфостарте выходит "Приятная глазу цветовая схема 1С 8.х". Судя по названию, глазам уже тогда было неприятно. У статьи 429 плюсов, сто восемнадцать тысяч просмотров и сто тридцать два комментария. Автор при этом сам отговаривает от тёмной схемы: формы и остальные окна всё равно остаются светлые, глаза устают от перепада. Комментарии туда пишут до сих пор. В 2016-м кто-то предлагает написать петицию, а в январе 2026-го человек выкладывает свою подкрученную палитру "спустя годы работы на этой схеме".
Потом лет десять все делятся раскрасками: Solarized, «как в Sublime Text 3», Dracula на GitHub, таблицы hex-кодов, которые надо вбивать руками, обработки, чтобы перенести раскраску на другой компьютер. Везде одна и та же оговорка: темнеет только редактор модулей. Под обработкой 2021 года в первом же комментарии спрашивают, меняется ли теперь дерево и остальные окна. Нет? Тогда не интересно.
Сентябрь 2024-го: "Тёмная тема для конфигуратора", файл профиля на 13 килобайт. Вопрос в комментариях, темнеет ли дерево объектов. Автор отвечает, что нет, только модули. Следующий читатель просит показывать окно целиком, а то как-то нечестно. Получается чёрный квадрат в бежевой раме.

Дальше просят уже хоть что-нибудь. В 2019-м на форуме задают вопрос, можно ли поменять цвета самой среды, «не редактора кода». Самый запоминающийся ответ: купить VR-очки, и пусть по конфигуратору летают нимфы. Автор вопроса отказывается - нимфы будут отвлекать.

В 2023-м просят тёмные панели и палитру свойств. Цвет исходного кода человек уже поменял, теперь хочет тёмный весь Конфигуратор. Ему отвечают, что такой опции нет, есть в EDT, а на каком-то семинаре разработчики говорили, что не планируют. Он пишет, что перерыл полинтернета.
Июль 2024-го, статья "Черная метка": автор считает тёмную тему вопросом здоровья. Предлагает утилиту, которая инвертирует цвета окна фильтром Windows. Заодно меняют цвет и точки останова, и автор сам признаёт, что решение топорное. В комментариях вспоминают системную "Лупу" с инверсией, спорят, вредна ли тёмная тема для глаз, и кто-то рассказывает, как после ночного вызова на завод светлый экран отбивает сон ещё на час. В декабре там же один читатель выкладывает палитру из тринадцати цветов. Панель конфигурации он держит скрытой, от нижней панели жмурится и радуется новости, что скоро перекрасят "Такси".
Официальный ответ всё это время был простой: в EDT тёмная тема включается одной галочкой. Надо всего лишь перейти на другую среду разработки.
И наконец 8.5. В платформе появляется тёмная тема, переключатель "Авто. Светлая. Тёмная".
В пользовательском интерфейсе. То есть у бухгалтеров.


Акт первый. Дальше без имён
Дальше не называю продукты по именам - так спокойнее. Речь пойдёт о файлах и о том, как их читать. Договоримся о словах:
платформа - то, что исполняет;
штатная среда - то, в чём разрабатывают и что до сих пор светлое;
файл конфигурации - один файл примерно на гигабайт, в нём всё: объекты, модули, формы, макеты, права;
выгрузка - каталог XML, в который платформа умеет этот файл разложить и из которого умеет собрать обратно.
Задача была скромная: покрасить окно.
21 октября 2026 года на Инфостарте вышла "Темная тема для Конфигуратора". Автор перехватывает функции рисования и пересчитывает каждый цвет в палитру темы. Тёмным становится почти весь Конфигуратор, вместе с деревом, палитрой и конструктором запроса. Сделано аккуратно и с исходниками, мне очень понравилось.
Эта статья меня и завела. Я начал прикидывать свой вариант: инвертировать цвета через API системной лупы, вообще без перехватов. И довольно быстро понял, что перекрасить окно ещё не значит его переделать. В комментариях к той статье просят сделать шире поле поиска, и автор отвечает, что это уже правка кода платформы, а лицензия её запрещает. Так что поле шире не станет, и дерево быстрее не откроется. Всё, что глубже цвета - чужой код.
Значит, нужно своё окно.
В своём окне должно быть то же самое: дерево, свойства, модули. Для этого нужно читать файл конфигурации, причём без платформы.
А ещё нужна проверка, что читаешь правильно. Строгая, без всяких "примерно". Строже всего проверит сама платформа.
Примерный план буквально на салфетке. Только у каждого пункта оказался подвал, под подвалом погреб, а под погребом что-то на C++.

Сразу покажу, что получилось в итоге. Одно и то же окно, одна галочка:


Акт второй. Что внутри файла конфигурации
Снаружи это один файл, а внутри - матрёшка.
Сначала страничный контейнер: оглавление и записи, у каждой записи заголовок и сжатые данные. У крупной конфигурации записей десятки тысяч. Некоторые записи сами оказываются контейнерами. Открываешь коробку, в ней коробки, а в них скобки.
Скобочный формат тут почти везде:
{1,"строка с ""кавычками""",{вложенный,список},3f1e…-guid}
Имён полей нет, схемы нет, есть только позиции. Седьмое место у справочника и седьмое место у регистра означают разные вещи, и нигде об этом не написано.

Разобрать контейнер и скобки можно за вечер. А вот понять, что значит каждая позиция у каждого вида объекта - требует "немного" большего.
Акт третий. Дерево, модули и, наконец, цвет
Из записей собирается дерево: где справочник, где его форма, где модуль этой формы. Крупная конфигурация открывается примерно за секунду. Это не опечатка, цифры будут в конце.
Модули можно править. Редактор рисует только видимые строки, поэтому даже модуль на десятки тысяч строк открывается сразу. Подсветка своя, и раз уж всё затевалось ради цвета, я добавил темы Notepad++: если он установлен, окно берёт его темы как есть. Хотели тёмную — выбирайте любую.


На этом можно было бы и закончить: окно тёмное, все довольны...
Акт четвёртый. Проверка
Как убедиться, что понял формат, у которого нет описания? Можно смотреть глазами. Можно писать тесты по своему же пониманию, но тогда они проверяют только, что я согласен сам с собой.
Я выбрал простое и жёсткое правило:
Без потерь или ошибка.
Своё чтение файла я превращаю в выгрузку XML, такую же, какую делает платформа, и сравниваю с выгрузкой платформы. Сравниваю не на похожесть, а байт в байт.
У крупной прикладной конфигурации в выгрузке 90 385 файлов. Совпадают все 90 385, вплоть до переводов строк и табуляции.
В обратную сторону правило ещё строже. Загрузка XML должна понять каждый элемент и каждый атрибут. Если хоть что-то не поняла, файл не загружается совсем и попадает в список отказов вместе с причиной. Никаких "пропустим, потом разберёмся": молча потерянный флажок в одной форме - это потом чья-то сломанная конфигурация в продакшене и испорченная пятница.
Последнее слово опять за платформой: она загружает нашу выгрузку, а мы сверяем её записи со своими.

Загрузка пока не доделана. Полностью она проходит только на небольшой конфигурации для электронного документооборота. На крупной часть видов файлов ещё отвергается, каждый раз с указанием причины.
Акт пятый. Хэш-таблицы на дне
"Байт в байт" значит, что и порядок должен совпадать.
Почти все записи ведут себя прилично: идут в порядке XML или по идентификатору. Но несколько видов записей шли в каком-то непонятном порядке. Не по алфавиту, не по GUID, не в порядке объявления. Фазу Луны тоже проверили.
Ответ оказался до обидного простым. Платформа складывает эти элементы в хэш-таблицу и потом просто её обходит. Порядок записей в файле - это порядок обхода std::unordered_map из стандартной библиотеки MSVC. Он зависит от числа бакетов, правила роста, хэша строки и от того, что новый элемент встаёт в начало цепочки.
Всех нас учили, что порядок обхода unordered_map не определён и полагаться на него нельзя. А здесь он стал частью формата файла. Пришлось воспроизвести обход чужой хэш-таблицы.

Проверил на составе одного плана обмена: 1 693 элемента, порядок совпал полностью. А в другом месте платформы используется boost::unordered_map, со своим перемешиванием хэша и своими правилами роста. Его тоже пришлось повторить.
Напомню, с чего всё началось.
Я хотел покрасить окно.
Акт шестой. Язык запросов
В формах бывают динамические списки, и у некоторых из них свой запрос. Чтобы записать такую форму, нужно знать, какие поля возвращает этот запрос и как они называются. Платформа узнаёт это, когда компилирует запрос. Нам компилировать нечем.
Например, поле без псевдонима, через две точки:
ВЫБРАТЬ Т.Контрагент.ИНН ИЗ ...
Как будет называться это поле в результате? КонтрагентИНН. Части пути после источника склеиваются, и для каждого из двух языков запроса по-своему. Таких правил много, и каждое приходится выяснять отдельно.
В итоге пришлось написать свой разборщик языка запросов: лексер, грамматику, проверку по метаданным, вывод имён полей.
Всё ради того, чтобы покрасить окно.
Эпилог. Сколько это по времени
Раз уж движок свой, можно и время замерить. Крупная прикладная конфигурация: файл около 1 ГБ, около 15 тысяч объектов верхнего уровня, 90 тысяч файлов в выгрузке. Ryzen 5 7500F, SATA SSD, Windows 11.

Честно скажу сразу, чтобы не писали в комментариях: сравнение не совсем корректное. Платформе, чтобы работать с файлом конфигурации, нужна база - она загружает файл в базу и потом сохраняет обратно. Свой движок работает с файлом напрямую. Но когда сидишь и ждёшь, минута против секунды это лишняя чашка кофе.
Что получилось, а что нет
Получилось:
своё окно со знакомой раскладкой, светлой и тёмной темой и темами Notepad++;
чтение файла конфигурации, дерево, свойства, правка модулей и свойств, запись файла;
выгрузка в XML байт в байт, как у платформы, на крупной конфигурации целиком;
командная строка для всего этого.
Не получилось - пока или вообще:
загрузка из XML полностью работает пока только на небольшой конфигурации, на крупной частично;
редактора форм, отладки и работы с базой нет и не планируется;
проверка синтаксиса и всё, что требует выполнять код, это работа платформы, пусть она её и делает.
И серьёзно, без шуток. Цель проекта - совместимость с форматом файлов: читать и писать то, что читает и пишет платформа. Код платформы и прикладных решений в проекте не используется и не распространяется; значки и строки интерфейса окно берёт из платформы, установленной у пользователя.
Вопрос к читателям
Код пока не публикую: сначала хочу понять, нужно ли это кому-то, кроме меня и моих глаз.
Пользовались бы вы таким окном как просмотрщиком и быстрым редактором рядом со штатной средой, а не вместо неё?
Что нужнее: окно, командная строка (выгрузка, сравнение, правка из CI) или библиотека?
Про какую часть формата рассказать подробнее в следующий раз?
А тёмная тема работает.
Пятнадцать лет просьб, один контейнер, сотни тысяч скобок, чужая хэш-таблица и свой язык запросов.
Зато теперь темно.
kuza2000
"Вот ты светлый, Антон. А пиво пьешь - темное!" (С)