Python tools for converting 1C ordinary form Form.bin into a Git-friendly
source package and building it back.
1C ordinary forms are stored inside Form.bin. That binary contains the form
module, pictures, and the ordinary-form layout/control data in the platform's
internal list-stream format. This is hard to review, diff, edit, and merge.
The goal of this project is to expose ordinary forms as source files that are
close to managed-form source exports: readable XML for the form object model,
Module.bsl as a separate file, and pictures as sidecar files.
The public source layout mirrors managed forms:
Forms/Form/Ext/Form.xml
Forms/Form/Ext/Form/Module.bsl
Forms/Form/Ext/Form/Items/<ElementName>/Picture.gif
Form.xml is the public editable object model. It should describe the form with
named controls and properties, not with raw platform records:
<Form>
<Title>
<Item lang="ru">Form title</Item>
</Title>
<Attributes>
<Attribute name="InputValue">
<Type>...</Type>
</Attribute>
</Attributes>
<Pages>
<Page name="Main">
<Panel name="MainPanel">
<Position left="8" top="8" right="640" bottom="480"/>
<LabelDecoration name="Caption">
<Title>
<Item lang="ru">Caption text</Item>
</Title>
</LabelDecoration>
<Button name="RunButton">
<Title>
<Item lang="ru">Run</Item>
</Title>
<Events>
<Event name="Нажатие">Run</Event>
</Events>
</Button>
<PictureDecoration name="Logo">
<Picture file="Items/Logo/Picture.gif"/>
</PictureDecoration>
</Panel>
</Page>
</Pages>
</Form>Control properties and events are type-specific and come from the platform help palette for ordinary controls. The XML should contain only values explicitly set on the form; platform defaults should stay implicit.
Public XML uses one English vocabulary for element and attribute names. Russian
platform names for ordinary-form controls, properties, events, and value types
belong in OrdinaryForm.xsd as xs:annotation/xs:appinfo metadata, not in a
separate mapping file and not as public XML tag names.
The exact schema is still being expanded, but the target direction is fixed: public XML must be managed-form-like, named, and understandable to a 1C developer.
The ordinary form source package is meant to be read from the top down:
Form.xmlis the form object model.Form/Module.bslis the ordinary form module.Form/Items/...contains extracted sidecar files such as pictures.
Inside Form.xml, the main sections are:
Title- localized form title.Events- form-level event handlers, for exampleПриОткрытии.Attributes- form attributes and their 1C type descriptions.Pages- top-level form pages and their nested controls.- control nodes such as
Panel,InputField,Button,Table,CommandBar,LabelDecoration, andPictureDecoration. Position- control geometry and bindings.ActionorEventsunder a control - handlers connected to that control.Picture file="..."- a reference to a sidecar image next to the XML.
For example, a button is edited as a named object:
<Button name="RunButton" id="12">
<Title>
<Item lang="ru">Run</Item>
</Title>
<Position left="16" top="40" right="120" bottom="64"/>
<Action name="RunButtonНажатие" title="Run button click"/>
</Button>During build-bin, the writer serializes these named XML objects into the
platform list-stream representation and then packs form and module into
Form.bin. That container layer is internal; users edit Form.xml,
Module.bsl, and sidecar files.
The target internal pipeline is symmetric:
Form.bin -> form raw stream -> ListInStream -> platform object model -> XSD-backed Form.xml
Form.xml -> platform object model -> ListOutStream -> form raw stream -> Form.bin
The schema layer is intentionally small and focused on ordinary forms:
OrdinaryForm.xsddescribes the publicForm.xmlroot, ordinary-form controls, reusable value/layout types, property/event vocabulary, and platform palette annotations;PlatformConfigStructure.xsdrecords platform-derived configuration, metadata tree, type-domain,CompositeID,ValueToStringInternal/ValueFromStringInternal, and serializer evidence used by the codec layer.
These codec concepts are not a public raw-stream dump. Full platform XSD
extractions are kept as reproducible research artifacts under ignored
scan-output/, not vendored into the package.
Regenerate platform schema evidence from a local platform mirror with:
python3 tools/extract_platform_xml_resources.py \
--root <platform-bin-dir> \
--out-dir scan-output/platform85/xml-clean \
--schemas-only
python3 tools/vendor_platform_schemas.py \
--resources-json scan-output/platform85/xml-clean/resources.json \
--source-dir scan-output/platform85/xml-clean \
--out-dir scan-output/platform85/vendor-check \
--platform-version 8.5Public Form.xml must not contain raw or renamed platform dumps. The following
are not acceptable public structures:
ObjectModelListStreamBracketStreamFormBinLogicalStreamRawBracketPlatformRecords- indexed trees such as
Field kind="list"orField kind="atom" - embedded base64 source streams
- binary placeholders or other lossless/fallback stream copies
The parser/writer may use the platform list-stream format internally. Platform
symbols such as cf_form_controls8, cf_form_controls_position8, and
cf_form_controls_info8 identify ordinary-control payload formats in the
platform mechanism. They are implementation details, not public XML nodes. If
a value is needed for rebuild, it must be promoted to a named XML concept: a
control, property, event, command, binding, picture reference, or type
descriptor.
Passing 1C Designer validation is required, but not sufficient by itself: the public XML must also remain a clean object model, not a renamed raw stream.
Current strict 1C validation uses build-bin without a public
template/fallback Form.bin: the ordinary Form.bin is built from object
Form.xml, Module.bsl, and sidecar files. Before platform import, validation
uses a copy of the source tree where the public ordinary Ext/Form.xml and
Ext/Form/ sidecar directory are removed; for an ordinary form, the platform
source layout keeps only Ext/Form.bin.
Обычные формы 1С лежат внутри Form.bin. В этом бинарном файле находятся
модуль формы, картинки и данные обычной формы во внутреннем list-stream /
скобкоформате платформы. Такой файл сложно смотреть в Git, сравнивать,
редактировать и мержить.
Цель проекта - разложить обычную форму в исходники примерно так же, как
платформа раскладывает управляемую форму: человекочитаемый XML объектной
модели, отдельный Module.bsl и картинки рядом.
Целевая структура файлов:
Forms/Form/Ext/Form.xml
Forms/Form/Ext/Form/Module.bsl
Forms/Form/Ext/Form/Items/<ИмяЭлемента>/Picture.gif
Form.xml - это публичная редактируемая объектная модель. Он должен описывать
форму именованными элементами и свойствами, а не сырыми платформенными
записями:
<Form>
<Title>
<Item lang="ru">Заголовок формы</Item>
</Title>
<Attributes>
<Attribute name="ВходноеЗначение">
<Type>...</Type>
</Attribute>
</Attributes>
<Pages>
<Page name="Основная">
<Panel name="ОсновнаяПанель">
<Position left="8" top="8" right="640" bottom="480"/>
<LabelDecoration name="Надпись">
<Title>
<Item lang="ru">Текст надписи</Item>
</Title>
</LabelDecoration>
<Button name="КнопкаВыполнить">
<Title>
<Item lang="ru">Выполнить</Item>
</Title>
<Events>
<Event name="Нажатие">Выполнить</Event>
</Events>
</Button>
<PictureDecoration name="Логотип">
<Picture file="Items/Логотип/Picture.gif"/>
</PictureDecoration>
</Panel>
</Page>
</Pages>
</Form>Публичный XML использует единый английский словарь элементов и свойств.
Платформенные русские имена свойств, событий и типов обычной формы хранятся в
OrdinaryForm.xsd как xs:annotation/xs:appinfo, а не отдельным mapping файлом и
не публичными XML-тегами. В XML должны попадать только явно заданные значения;
дефолты платформы остаются неявными.
Схема еще расширяется, но направление фиксированное: публичный XML должен быть похож на XML управляемой формы, быть именованным и понятным разработчику 1С.
Пакет исходников обычной формы читается сверху вниз:
Form.xml- объектная модель формы.Form/Module.bsl- модуль обычной формы.Form/Items/...- вынесенные рядом файлы, например картинки.
Внутри Form.xml основные разделы такие:
Title- локализованный заголовок формы.Events- события самой формы, напримерПриОткрытии.Attributes- реквизиты формы и описания их типов 1С.Pages- страницы формы и вложенные в них элементы.- узлы контролов:
Panel,InputField,Button,Table,CommandBar,LabelDecoration,PictureDecorationи другие элементы палитры. Position- геометрия элемента и привязки.ActionилиEventsвнутри элемента - обработчики, подключенные к нему.Picture file="..."- ссылка на картинку рядом с XML.
Например, кнопка редактируется как именованный объект:
<Button name="КнопкаВыполнить" id="12">
<Title>
<Item lang="ru">Выполнить</Item>
</Title>
<Position left="16" top="40" right="120" bottom="64"/>
<Action name="КнопкаВыполнитьНажатие" title="Нажатие кнопки выполнить"/>
</Button>При build-bin writer сериализует эти именованные XML-объекты во внутренний
list-stream/скобкоформат платформы и затем упаковывает документы form и
module в Form.bin. Этот контейнерный слой внутренний; пользователь
редактирует Form.xml, Module.bsl и файлы рядом.
Целевой внутренний конвейер симметричный:
Form.bin -> raw-поток form -> ListInStream -> объектная модель платформы -> Form.xml по XSD
Form.xml -> объектная модель платформы -> ListOutStream -> raw-поток form -> Form.bin
Слой схем специально небольшой и сфокусирован на обычных формах:
OrdinaryForm.xsdописывает публичный кореньForm.xml, элементы обычной формы, переиспользуемые типы значений/раскладки, единый английский словарь свойств/событий и аннотации платформенной палитры;PlatformConfigStructure.xsdфиксирует платформенные сведения о структуре конфигурации, дереве метаданных, type-domain,CompositeID,ValueToStringInternal/ValueFromStringInternalи сведения о сериализаторах, используемые слоем кодека.
Эти понятия кодека не являются публичным дампом сырого потока. Полные извлечения
платформенных XSD хранятся как воспроизводимые исследовательские артефакты в
игнорируемом scan-output/, а не поставляются внутри пакета.
Обновить платформенные сведения для схем из локального зеркала платформы можно так:
python3 tools/extract_platform_xml_resources.py \
--root <platform-bin-dir> \
--out-dir scan-output/platform85/xml-clean \
--schemas-only
python3 tools/vendor_platform_schemas.py \
--resources-json scan-output/platform85/xml-clean/resources.json \
--source-dir scan-output/platform85/xml-clean \
--out-dir scan-output/platform85/vendor-check \
--platform-version 8.5Публичный Form.xml не должен содержать сырые или переименованные дампы
платформенного формата. Нельзя выводить наружу:
ObjectModelListStreamBracketStreamFormBinLogicalStreamRawBracketPlatformRecords- индексные деревья вроде
Field kind="list"илиField kind="atom" - встроенные base64-потоки исходного файла
- бинарные заглушки и другие побайтно-сохраняющие или резервные копии потоковых структур
Парсер и writer могут использовать list-stream/скобкоформат платформы внутри.
Платформенные символы cf_form_controls8, cf_form_controls_position8,
cf_form_controls_info8 являются идентификаторами форматов данных обычных
контролов в типовом механизме платформы. Это внутренняя реализация, а не
публичные XML-узлы. Если значение нужно для обратной сборки, его нужно поднять
в именованное понятие XML: контрол, свойство, событие, команда, привязка,
ссылка на картинку или описание типа.
Проверка через 1C Designer обязательна, но сама по себе недостаточна: публичный XML все равно должен оставаться чистой объектной моделью, а не переименованным сырым потоком.
Текущая строгая проверка 1C выполняется без публичного шаблонного или
резервного Form.bin: build-bin собирает обычный Form.bin из объектного
Form.xml, Module.bsl и файлов рядом. Перед импортом платформой используется
копия исходной раскладки, где публичный Ext/Form.xml обычной формы и каталог
Ext/Form/ удалены; для обычной формы в платформенной раскладке остается
только Ext/Form.bin.
Current release: 0.4.5.
Current implementation status:
- read ordinary
Form.bincontainers; - dump readable object-model
Form.xml; - extract
Module.bsland picture sidecars; - validate
Form.xmlagainst bundled schemas; - build ordinary
Form.binfrom the named XML package without a sourceForm.binfallback in the public package; - preserve module payloads and typed Color/Font properties through repeated build/dump cycles without public raw sidecars;
- scan local EPF/ERF corpora without committing private artifacts.
Текущий статус реализации:
- чтение контейнеров обычных
Form.bin; - выгрузка читаемого объектного
Form.xml; - извлечение
Module.bslи файлов картинок рядом; - проверка
Form.xmlпо встроенным схемам обычных форм; - сборка обычного
Form.binиз именованного XML-пакета без исходногоForm.binкак публичного резервного источника; - сохранение данных модуля и типизированных свойств Color/Font при повторных циклах сборки/разборки без публичных raw-sidecar файлов;
- сканирование локальных EPF/ERF-корпусов без коммита приватных артефактов.
Validation status:
v0.4.5stabilizes typed ordinary-formColorandFontround-trips: rebuilt extended base-info records are dumped again without losingTextColor,BackColor,BorderColor, orFont, and the first 100 UT forms with Color/Font are stable across repeated build/dump cycles.v0.4.4writes regularPanelpage metadata with the platform 25-page capacity profile, fixing strict Designer load for XML-writer rebuilt forms that contain nested panel pages and typedActiveXControlpayloads.v0.4.3adds typed ordinary-formActiveXControlXML/XSD support, including CLSID and state blobs, and preserves the PDF ActiveX control found in a directForm.bindump/build check.v0.4.2extends thev0.4.1edit stabilization with strict platform-validated addButtonand delete leafLabelDecorationscenarios.v0.4.1preserves thev0.4.0no-op rebuild baseline and adds a strict platform-validated XML add-control path for a pagedLabelDecorationwithid=max(existing)+1.v0.4.0has one UT ordinary list-form no-op dump/build byte-identical for the fullForm.bincontainer, form payload, and module payload.- The first-50 UT corpus smoke currently has no exceptions and keeps module payloads stable, but only 1/50 forms are full byte-identical.
- The next known mismatch class is a root format/profile length variant.
Статус проверок:
v0.4.5стабилизирует обратную сборку типизированныхColorиFontдля обычных форм: расширенные base-info записи после rebuild снова выгружаются без потериTextColor,BackColor,BorderColorиFont, а первые 100 UT форм с Color/Font стабильны на повторных циклах build/dump.v0.4.4пишет metadata страниц обычногоPanelчерез платформенный capacity-профиль на 25 страниц, что чинит строгую загрузку Designer для форм, пересобранных XML-writer-ом, с вложенными страницами панели и типизированнымActiveXControl.v0.4.3добавляет типизированную XML/XSD-поддержку обычногоActiveXControl, включая CLSID и state blobs, и сохраняет PDF ActiveX control в прямой проверкеForm.bindump/build.v0.4.2расширяет стабилизацию редактированияv0.4.1строгими платформенными проверками добавленияButtonи удаления leafLabelDecoration.v0.4.1сохраняет baseline обратной сборкиv0.4.0и добавляет строгую платформенную проверку добавления pagedLabelDecorationиз XML сid=max(existing)+1.- в
v0.4.0один UT-сценарий обратной сборки обычной list-form без изменений совпадает побайтно по всему контейнеруForm.bin, данным формы и данным модуля; - first-50 UT smoke сейчас проходит без исключений и сохраняет данные модулей, но полное побайтное совпадение есть только у 1/50 форм;
- следующий известный класс расхождений - вариант длины корневого format/profile.
Automation:
- CI runs on GitHub Actions for pushes, pull requests, and manual dispatch on Python 3.10, 3.11, and 3.12.
- CI executes tests, CLI smoke, package build, and package metadata checks.
- Release workflow runs for
v*tags or manual dispatch with a tag input, rebuilds the package, rechecks it, and publishes GitHub Release assets.
Автоматизация:
- CI запускается в GitHub Actions для push, pull request и manual dispatch на Python 3.10, 3.11 и 3.12;
- CI выполняет тесты, CLI smoke, сборку пакета и проверку package metadata;
- релизный workflow запускается для тегов
v*или вручную с указанием тега, пересобирает пакет, проверяет его и публикует артефакты в GitHub Release.
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[dev]'
make testFor the same checks used in CI:
PYTHONPATH=src pytest -q
make smoke
python -m build
python -m twine check dist/*Dump an ordinary form binary:
onec-ordinary-forms dump-bin \
--bin scan-output/exported/Object/Forms/Form/Ext/Form.bin \
--out scan-output/exported/Object/Forms/Form/Ext/Form.xmlThis writes:
scan-output/exported/Object/Forms/Form/Ext/Form.xml
scan-output/exported/Object/Forms/Form/Ext/Form/Module.bsl
scan-output/exported/Object/Forms/Form/Ext/Form/Items/<ElementName>/Picture.gif
Validate and format the XML:
onec-ordinary-forms validate --xml scan-output/exported/Object/Forms/Form/Ext/Form.xml
onec-ordinary-forms format-xml --xml scan-output/exported/Object/Forms/Form/Ext/Form.xmlShow bundled schemas:
onec-ordinary-forms schemasBuild Form.bin back from the object XML package:
onec-ordinary-forms build-bin \
--xml scan-output/exported/Object/Forms/Form/Ext/Form.xml \
--out-bin scan-output/rebuilt/Form.binBefore platform import, use a copy of the source tree where the public ordinary
Ext/Form.xml and Ext/Form/ sidecar directory are removed. The platform
source layout for ordinary forms should contain Ext/Form.bin; managed forms
keep their native Ext/Form.xml.
Use --asset-root only when sidecars are not next to the XML as
<Form.xml without suffix>/....
Writer behavior is intentionally conservative while the named ordinary-form
object model is being completed. The only public source contract is Form.xml
with named form objects plus sidecars; old base-stream rebuild paths and raw
diagnostic formats are not supported public workflows.
Diagnostic commands:
onec-ordinary-forms unpack-bin --bin Form.bin --out-dir scan-output/form-parts
onec-ordinary-forms pack-bin --parts-dir scan-output/form-parts --out-bin Form.bin
onec-ordinary-forms scan-corpus --root "<private-processors-dir>" --out-json scan-output/corpus.jsonunpack-bin and pack-bin are diagnostics for Form.bin container research.
They are not the target public source layout and should not be used as the
editable representation of a form.
from onec_ordinary_forms import build_form_bin, dump_form_bin, validate_form_xml
dump_form_bin(
"scan-output/exported/Object/Forms/Form/Ext/Form.bin",
"scan-output/exported/Object/Forms/Form/Ext/Form.xml",
)
validate_form_xml("scan-output/exported/Object/Forms/Form/Ext/Form.xml")
build_form_bin(
"scan-output/exported/Object/Forms/Form/Ext/Form.xml",
"scan-output/rebuilt/Form.bin",
)The default asset root is the XML path without the .xml suffix. For
Forms/Form/Ext/Form.xml, sidecars are read from Forms/Form/Ext/Form/.
For writer changes, validate rebuilt processors through the 1C platform, not
only through metadata-level checks. The helper in
tools/platform_validate_epf.sh runs Designer batch export and catches
malformed ordinary form streams.
Private processors, platform exports, license configuration, and generated
reports must stay in ignored local directories such as scan-output/, work/,
or /tmp.
Do not commit private EPF/ERF files, CF/DT dumps, platform archives, license
files, OACS databases, generated platform exports, or customer metadata. The
examples/fixtures/ directory is ignored except for .gitkeep.