mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-18 16:49:41 +03:00
chore(repo): нормализация EOL к LF + .gitattributes
Приводим авторский контент (.ps1/.psm1/.py/.mjs/.md/.json, пин .bsl) к единому LF и закрепляем политикой в .gitattributes. Инструмент правки всегда пишет LF, поэтому единый LF убирает EOL-шум в диффах, ложные срабатывания blame и налог на ручную синхронизацию CRLF-файлов. BOM на .ps1 сохранён (git с eol=lf меняет только CR<->LF, BOM не трогает). Данные 1С (*.xml) и бинарники под нормализацию не берём. Гейт: PS-порт 459/459, Python-порт 459/459, web-test E2E 22/22 (с пересборкой стенда). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1832
-1832
File diff suppressed because it is too large
Load Diff
+1024
-1024
File diff suppressed because it is too large
Load Diff
+1043
-1043
File diff suppressed because it is too large
Load Diff
+628
-628
File diff suppressed because it is too large
Load Diff
+1240
-1240
File diff suppressed because it is too large
Load Diff
+1220
-1220
File diff suppressed because it is too large
Load Diff
+845
-845
File diff suppressed because it is too large
Load Diff
+173
-173
@@ -1,173 +1,173 @@
|
||||
# Сводный индекс спецификаций формата XML конфигурации 1С
|
||||
|
||||
Единая точка входа ко всем спецификациям XML-формата выгрузки 1С:Предприятие 8.3.
|
||||
|
||||
---
|
||||
|
||||
## 1. Корневые файлы конфигурации
|
||||
|
||||
| Файл | Описание | Спецификация |
|
||||
|------|----------|--------------|
|
||||
| `Configuration.xml` | Свойства и состав конфигурации | [1c-configuration-spec.md § 2](1c-configuration-spec.md#2-configurationxml--корневой-файл-конфигурации) |
|
||||
| `ConfigDumpInfo.xml` | Версии объектов (служебный) | [1c-configuration-spec.md § 3](1c-configuration-spec.md#3-configdumpinfoxml--служебный-файл-выгрузки) |
|
||||
| `Ext/` | Модули, интерфейс, начальная страница | [1c-configuration-spec.md § 4](1c-configuration-spec.md#4-ext--корневой-каталог-конфигурации) |
|
||||
| `Ext/ParentConfigurations.bin` | Состояние поддержки (конфигурации поставщика, пообъектные правила) | [1c-support-state-spec.md](1c-support-state-spec.md) |
|
||||
| `Languages/` | Языки конфигурации | [1c-configuration-spec.md § 5](1c-configuration-spec.md#5-языки-languages) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Объекты метаданных
|
||||
|
||||
Все типы объектов, встречающиеся в `ChildObjects` корневого `Configuration.xml`. Порядок соответствует порядку в XML.
|
||||
|
||||
### Служебные и интерфейсные
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `Language` | `Languages/` | Языки | [1c-configuration-spec.md § 5](1c-configuration-spec.md#5-языки-languages) |
|
||||
| `Subsystem` | `Subsystems/` | Подсистемы | [1c-subsystem-spec.md § 3](1c-subsystem-spec.md#3-формат-подсистемы) |
|
||||
| `StyleItem` | `StyleItems/` | Элементы стиля | [1c-configuration-spec.md § 6.16](1c-configuration-spec.md#616-styleitem--элемент-стиля) |
|
||||
| `Style` | `Styles/` | Стили (устаревший) | [1c-configuration-spec.md § 6.17](1c-configuration-spec.md#617-style--стиль-устаревший) |
|
||||
| `CommandGroup` | `CommandGroups/` | Группы команд | [1c-subsystem-spec.md § 5](1c-subsystem-spec.md#5-формат-группы-команд-commandgroup) |
|
||||
|
||||
### Общие объекты
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `CommonPicture` | `CommonPictures/` | Общие картинки | [1c-configuration-spec.md § 6.1](1c-configuration-spec.md#61-commonpicture--общая-картинка) |
|
||||
| `SessionParameter` | `SessionParameters/` | Параметры сеанса | [1c-configuration-spec.md § 6.6](1c-configuration-spec.md#66-sessionparameter--параметр-сеанса) |
|
||||
| `Role` | `Roles/` | Роли | [1c-role-spec.md § Файл метаданных](1c-role-spec.md#файл-метаданных-rolesимяролиxml) |
|
||||
| `CommonTemplate` | `CommonTemplates/` | Общие макеты | [1c-configuration-spec.md § 6.2](1c-configuration-spec.md#62-commontemplate--общий-макет) |
|
||||
| `FilterCriterion` | `FilterCriteria/` | Критерии отбора | [1c-configuration-spec.md § 6.11](1c-configuration-spec.md#611-filtercriterion--критерий-отбора) |
|
||||
| `CommonModule` | `CommonModules/` | Общие модули | [1c-config-objects-spec.md § 21](1c-config-objects-spec.md#21-общие-модули-commonmodules) |
|
||||
| `CommonAttribute` | `CommonAttributes/` | Общие реквизиты | [1c-configuration-spec.md § 6.3](1c-configuration-spec.md#63-commonattribute--общий-реквизит) |
|
||||
| `CommonCommand` | `CommonCommands/` | Общие команды | [1c-subsystem-spec.md § 6](1c-subsystem-spec.md#6-формат-общей-команды-commoncommand) |
|
||||
| `CommonForm` | `CommonForms/` | Общие формы | [1c-configuration-spec.md § 6.4](1c-configuration-spec.md#64-commonform--общая-форма) |
|
||||
|
||||
### Интеграция и сервисы
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `ExchangePlan` | `ExchangePlans/` | Планы обмена | [1c-config-objects-spec.md § 15](1c-config-objects-spec.md#15-планы-обмена-exchangeplans) |
|
||||
| `XDTOPackage` | `XDTOPackages/` | XDTO-пакеты | [1c-configuration-spec.md § 6.14](1c-configuration-spec.md#614-xdtopackage--xdto-пакет) |
|
||||
| `WebService` | `WebServices/` | Веб-сервисы | [1c-config-objects-spec.md § 25](1c-config-objects-spec.md#25-веб-сервисы-webservices) |
|
||||
| `HTTPService` | `HTTPServices/` | HTTP-сервисы | [1c-config-objects-spec.md § 24](1c-config-objects-spec.md#24-http-сервисы-httpservices) |
|
||||
| `WSReference` | `WSReferences/` | WS-ссылки | [1c-configuration-spec.md § 6.15](1c-configuration-spec.md#615-wsreference--ws-ссылка) |
|
||||
| `IntegrationService` | `IntegrationServices/` | Сервисы интеграции | [1c-configuration-spec.md § 6.13](1c-configuration-spec.md#613-integrationservice--сервис-интеграции) |
|
||||
|
||||
### Поведение и параметризация
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `EventSubscription` | `EventSubscriptions/` | Подписки на события | [1c-config-objects-spec.md § 23](1c-config-objects-spec.md#23-подписки-на-события-eventsubscriptions) |
|
||||
| `ScheduledJob` | `ScheduledJobs/` | Регламентные задания | [1c-config-objects-spec.md § 22](1c-config-objects-spec.md#22-регламентные-задания-scheduledjobs) |
|
||||
| `SettingsStorage` | `SettingsStorages/` | Хранилища настроек | [1c-configuration-spec.md § 6.10](1c-configuration-spec.md#610-settingsstorage--хранилище-настроек) |
|
||||
| `FunctionalOption` | `FunctionalOptions/` | Функциональные опции | [1c-configuration-spec.md § 6.7](1c-configuration-spec.md#67-functionaloption--функциональная-опция) |
|
||||
| `FunctionalOptionsParameter` | `FunctionalOptionsParameters/` | Параметры ФО | [1c-configuration-spec.md § 6.8](1c-configuration-spec.md#68-functionaloptionsparameter--параметр-функциональных-опций) |
|
||||
| `DefinedType` | `DefinedTypes/` | Определяемые типы | [1c-config-objects-spec.md § 20](1c-config-objects-spec.md#20-определяемые-типы-definedtypes) |
|
||||
| `Constant` | `Constants/` | Константы | [1c-config-objects-spec.md § 17](1c-config-objects-spec.md#17-константы-constants) |
|
||||
|
||||
### Прикладные объекты
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `Catalog` | `Catalogs/` | Справочники | [1c-config-objects-spec.md § 7](1c-config-objects-spec.md#7-справочники-catalogs) |
|
||||
| `Document` | `Documents/` | Документы | [1c-config-objects-spec.md § 8](1c-config-objects-spec.md#8-документы-documents) |
|
||||
| `DocumentNumerator` | `DocumentNumerators/` | Нумераторы документов | [1c-configuration-spec.md § 6.12](1c-configuration-spec.md#612-documentnumerator--нумератор-документов) |
|
||||
| `Sequence` | `Sequences/` | Последовательности | [1c-configuration-spec.md § 6.9](1c-configuration-spec.md#69-sequence--последовательность-документов) |
|
||||
| `DocumentJournal` | `DocumentJournals/` | Журналы документов | [1c-config-objects-spec.md § 19](1c-config-objects-spec.md#19-журналы-документов-documentjournals) |
|
||||
| `Enum` | `Enums/` | Перечисления | [1c-config-objects-spec.md § 16](1c-config-objects-spec.md#16-перечисления-enums) |
|
||||
| `Report` | `Reports/` | Отчёты | [1c-config-objects-spec.md § 18](1c-config-objects-spec.md#18-отчёты-и-обработки) |
|
||||
| `DataProcessor` | `DataProcessors/` | Обработки | [1c-config-objects-spec.md § 18](1c-config-objects-spec.md#18-отчёты-и-обработки) |
|
||||
|
||||
### Регистры
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `InformationRegister` | `InformationRegisters/` | Регистры сведений | [1c-config-objects-spec.md § 9.1](1c-config-objects-spec.md#91-регистры-сведений-informationregisters) |
|
||||
| `AccumulationRegister` | `AccumulationRegisters/` | Регистры накопления | [1c-config-objects-spec.md § 9.4](1c-config-objects-spec.md#94-регистры-накопления-accumulationregisters) |
|
||||
| `AccountingRegister` | `AccountingRegisters/` | Регистры бухгалтерии | [1c-config-objects-spec.md § 9.5](1c-config-objects-spec.md#95-регистры-бухгалтерии-accountingregisters) |
|
||||
| `CalculationRegister` | `CalculationRegisters/` | Регистры расчёта | [1c-config-objects-spec.md § 9.6](1c-config-objects-spec.md#96-регистры-расчёта-calculationregisters) |
|
||||
|
||||
### Планы
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `ChartOfCharacteristicTypes` | `ChartsOfCharacteristicTypes/` | Планы видов характеристик | [1c-config-objects-spec.md § 11](1c-config-objects-spec.md#11-планы-видов-характеристик-chartsofcharacteristictypes) |
|
||||
| `ChartOfAccounts` | `ChartsOfAccounts/` | Планы счетов | [1c-config-objects-spec.md § 10](1c-config-objects-spec.md#10-планы-счетов-chartsofaccounts) |
|
||||
| `ChartOfCalculationTypes` | `ChartsOfCalculationTypes/` | Планы видов расчёта | [1c-config-objects-spec.md § 12](1c-config-objects-spec.md#12-планы-видов-расчёта-chartsofcalculationtypes) |
|
||||
|
||||
### Бизнес-процессы
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `BusinessProcess` | `BusinessProcesses/` | Бизнес-процессы | [1c-config-objects-spec.md § 13](1c-config-objects-spec.md#13-бизнес-процессы-businessprocesses) |
|
||||
| `Task` | `Tasks/` | Задачи | [1c-config-objects-spec.md § 14](1c-config-objects-spec.md#14-задачи-tasks) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Вложенные форматы
|
||||
|
||||
Форматы файлов, вложенных в каталоги объектов метаданных.
|
||||
|
||||
| Формат | Файл | Описание | Спецификация |
|
||||
|--------|------|----------|--------------|
|
||||
| Управляемая форма | `Ext/Form.xml` | Элементы, реквизиты, команды | [1c-form-spec.md § 1](1c-form-spec.md#1-корневой-элемент) |
|
||||
| СКД (DataCompositionSchema) | `Ext/Template.xml` | Схема компоновки данных | [1c-dcs-spec.md § 2](1c-dcs-spec.md#2-общая-структура-datacompositionschema) |
|
||||
| Табличный документ (MXL) | `Ext/Template.xml` | Печатная форма | [1c-spreadsheet-spec.md](1c-spreadsheet-spec.md#структура-документа) |
|
||||
| Роль (Rights) | `Ext/Rights.xml` | Права доступа и RLS | [1c-role-spec.md](1c-role-spec.md#файл-прав-rolesимяролиextrightsxml) |
|
||||
| Справка (Help) | `Ext/Help/` | Встроенная справка | [1c-help-spec.md § 1](1c-help-spec.md#1-структура-файлов) |
|
||||
| Предопределённые элементы | `Predefined.xml` | Предопределённые справочники/ПВХ | [1c-config-objects-spec.md § 7.2](1c-config-objects-spec.md#72-предопределённые-элементы-predefinedxml) |
|
||||
| Состав плана обмена | `Content.xml` | Объекты синхронизации | [1c-config-objects-spec.md § 15.4](1c-config-objects-spec.md#154-состав-плана-обмена-contentxml) |
|
||||
| Карта маршрута | `Flowchart.xml` | Маршрут бизнес-процесса | [1c-config-objects-spec.md § 13.3](1c-config-objects-spec.md#133-карта-маршрута-flowchartxml) |
|
||||
|
||||
---
|
||||
|
||||
## 4. Расширения конфигурации (CFE)
|
||||
|
||||
| Тема | Описание | Спецификация |
|
||||
|------|----------|--------------|
|
||||
| Общая структура выгрузки | Каталоги, отличия от конфигурации | [1c-extension-spec.md § 1](1c-extension-spec.md#1-общая-структура-выгрузки-расширения) |
|
||||
| Configuration.xml расширения | Свойства, назначение, ChildObjects | [1c-extension-spec.md § 2](1c-extension-spec.md#2-configurationxml--корневой-файл-расширения) |
|
||||
| Заимствованные / собственные объекты | ObjectBelonging, ExtendedConfigurationObject | [1c-extension-spec.md § 4](1c-extension-spec.md#4-заимствованные-и-собственные-объекты) |
|
||||
| Расширение свойств (xr:PropertyState) | MultiState, ExtendedProperty | [1c-extension-spec.md § 6](1c-extension-spec.md#6-расширение-свойств-xrpropertystate-и-xrextendedproperty) |
|
||||
| Модули и декораторы перехвата | &Перед, &После, &Вместо, diff-маркеры | [1c-extension-spec.md § 7](1c-extension-spec.md#7-модули-в-расширениях) |
|
||||
| Предопределённые элементы | ExtensionState: Native | [1c-extension-spec.md § 8](1c-extension-spec.md#8-предопределённые-элементы-в-расширениях) |
|
||||
|
||||
---
|
||||
|
||||
## 5. Внешние обработки и отчёты
|
||||
|
||||
| Формат | Описание | Спецификация |
|
||||
|--------|----------|--------------|
|
||||
| EPF (внешняя обработка) | ExternalDataProcessor | [1c-epf-spec.md § 1](1c-epf-spec.md#1-структура-каталогов) |
|
||||
| ERF (внешний отчёт) | ExternalReport | [1c-erf-spec.md § 1](1c-erf-spec.md#1-структура-каталогов) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Общие элементы формата
|
||||
|
||||
Общие для всех типов объектов структуры XML описаны в спецификации объектов:
|
||||
|
||||
| Тема | Спецификация |
|
||||
|------|--------------|
|
||||
| Корневой элемент MetaDataObject | [1c-config-objects-spec.md § 2](1c-config-objects-spec.md#2-общий-формат-xml) |
|
||||
| Пространства имён XML | [1c-config-objects-spec.md § 2.2](1c-config-objects-spec.md#22-пространства-имён) |
|
||||
| InternalInfo / GeneratedType | [1c-config-objects-spec.md § 3](1c-config-objects-spec.md#3-internalinfo--внутренняя-информация) |
|
||||
| Общие свойства Properties | [1c-config-objects-spec.md § 4](1c-config-objects-spec.md#4-общие-элементы-properties) |
|
||||
| Стандартные реквизиты | [1c-config-objects-spec.md § 5](1c-config-objects-spec.md#5-стандартные-реквизиты-standardattributes) |
|
||||
| Дочерние объекты (Attribute, TabularSection, Form, Template, Command) | [1c-config-objects-spec.md § 6](1c-config-objects-spec.md#6-дочерние-объекты-childobjects) |
|
||||
| Формат ссылок на объекты | [1c-config-objects-spec.md § 28](1c-config-objects-spec.md#28-формат-ссылок-на-объекты-метаданных) |
|
||||
| Различия версий 2.17 → 2.20 | [1c-config-objects-spec.md § 26](1c-config-objects-spec.md#26-различия-версий-платформы) |
|
||||
|
||||
---
|
||||
|
||||
## 7. DSL-спецификации (компактный формат ввода)
|
||||
|
||||
| DSL | Описание | Спецификация |
|
||||
|-----|----------|--------------|
|
||||
| Meta DSL | JSON-формат для создания/редактирования объектов | [meta-dsl-spec.md](meta-dsl-spec.md) |
|
||||
| Form DSL | JSON-формат для компиляции форм | [form-dsl-spec.md](form-dsl-spec.md) |
|
||||
| SKD DSL | JSON-формат для компиляции СКД | [skd-dsl-spec.md](skd-dsl-spec.md) |
|
||||
| MXL DSL | JSON-формат для компиляции табличных документов | [mxl-dsl-spec.md](mxl-dsl-spec.md) |
|
||||
| Role DSL | JSON-формат для компиляции ролей | [role-dsl-spec.md](role-dsl-spec.md) |
|
||||
# Сводный индекс спецификаций формата XML конфигурации 1С
|
||||
|
||||
Единая точка входа ко всем спецификациям XML-формата выгрузки 1С:Предприятие 8.3.
|
||||
|
||||
---
|
||||
|
||||
## 1. Корневые файлы конфигурации
|
||||
|
||||
| Файл | Описание | Спецификация |
|
||||
|------|----------|--------------|
|
||||
| `Configuration.xml` | Свойства и состав конфигурации | [1c-configuration-spec.md § 2](1c-configuration-spec.md#2-configurationxml--корневой-файл-конфигурации) |
|
||||
| `ConfigDumpInfo.xml` | Версии объектов (служебный) | [1c-configuration-spec.md § 3](1c-configuration-spec.md#3-configdumpinfoxml--служебный-файл-выгрузки) |
|
||||
| `Ext/` | Модули, интерфейс, начальная страница | [1c-configuration-spec.md § 4](1c-configuration-spec.md#4-ext--корневой-каталог-конфигурации) |
|
||||
| `Ext/ParentConfigurations.bin` | Состояние поддержки (конфигурации поставщика, пообъектные правила) | [1c-support-state-spec.md](1c-support-state-spec.md) |
|
||||
| `Languages/` | Языки конфигурации | [1c-configuration-spec.md § 5](1c-configuration-spec.md#5-языки-languages) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Объекты метаданных
|
||||
|
||||
Все типы объектов, встречающиеся в `ChildObjects` корневого `Configuration.xml`. Порядок соответствует порядку в XML.
|
||||
|
||||
### Служебные и интерфейсные
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `Language` | `Languages/` | Языки | [1c-configuration-spec.md § 5](1c-configuration-spec.md#5-языки-languages) |
|
||||
| `Subsystem` | `Subsystems/` | Подсистемы | [1c-subsystem-spec.md § 3](1c-subsystem-spec.md#3-формат-подсистемы) |
|
||||
| `StyleItem` | `StyleItems/` | Элементы стиля | [1c-configuration-spec.md § 6.16](1c-configuration-spec.md#616-styleitem--элемент-стиля) |
|
||||
| `Style` | `Styles/` | Стили (устаревший) | [1c-configuration-spec.md § 6.17](1c-configuration-spec.md#617-style--стиль-устаревший) |
|
||||
| `CommandGroup` | `CommandGroups/` | Группы команд | [1c-subsystem-spec.md § 5](1c-subsystem-spec.md#5-формат-группы-команд-commandgroup) |
|
||||
|
||||
### Общие объекты
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `CommonPicture` | `CommonPictures/` | Общие картинки | [1c-configuration-spec.md § 6.1](1c-configuration-spec.md#61-commonpicture--общая-картинка) |
|
||||
| `SessionParameter` | `SessionParameters/` | Параметры сеанса | [1c-configuration-spec.md § 6.6](1c-configuration-spec.md#66-sessionparameter--параметр-сеанса) |
|
||||
| `Role` | `Roles/` | Роли | [1c-role-spec.md § Файл метаданных](1c-role-spec.md#файл-метаданных-rolesимяролиxml) |
|
||||
| `CommonTemplate` | `CommonTemplates/` | Общие макеты | [1c-configuration-spec.md § 6.2](1c-configuration-spec.md#62-commontemplate--общий-макет) |
|
||||
| `FilterCriterion` | `FilterCriteria/` | Критерии отбора | [1c-configuration-spec.md § 6.11](1c-configuration-spec.md#611-filtercriterion--критерий-отбора) |
|
||||
| `CommonModule` | `CommonModules/` | Общие модули | [1c-config-objects-spec.md § 21](1c-config-objects-spec.md#21-общие-модули-commonmodules) |
|
||||
| `CommonAttribute` | `CommonAttributes/` | Общие реквизиты | [1c-configuration-spec.md § 6.3](1c-configuration-spec.md#63-commonattribute--общий-реквизит) |
|
||||
| `CommonCommand` | `CommonCommands/` | Общие команды | [1c-subsystem-spec.md § 6](1c-subsystem-spec.md#6-формат-общей-команды-commoncommand) |
|
||||
| `CommonForm` | `CommonForms/` | Общие формы | [1c-configuration-spec.md § 6.4](1c-configuration-spec.md#64-commonform--общая-форма) |
|
||||
|
||||
### Интеграция и сервисы
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `ExchangePlan` | `ExchangePlans/` | Планы обмена | [1c-config-objects-spec.md § 15](1c-config-objects-spec.md#15-планы-обмена-exchangeplans) |
|
||||
| `XDTOPackage` | `XDTOPackages/` | XDTO-пакеты | [1c-configuration-spec.md § 6.14](1c-configuration-spec.md#614-xdtopackage--xdto-пакет) |
|
||||
| `WebService` | `WebServices/` | Веб-сервисы | [1c-config-objects-spec.md § 25](1c-config-objects-spec.md#25-веб-сервисы-webservices) |
|
||||
| `HTTPService` | `HTTPServices/` | HTTP-сервисы | [1c-config-objects-spec.md § 24](1c-config-objects-spec.md#24-http-сервисы-httpservices) |
|
||||
| `WSReference` | `WSReferences/` | WS-ссылки | [1c-configuration-spec.md § 6.15](1c-configuration-spec.md#615-wsreference--ws-ссылка) |
|
||||
| `IntegrationService` | `IntegrationServices/` | Сервисы интеграции | [1c-configuration-spec.md § 6.13](1c-configuration-spec.md#613-integrationservice--сервис-интеграции) |
|
||||
|
||||
### Поведение и параметризация
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `EventSubscription` | `EventSubscriptions/` | Подписки на события | [1c-config-objects-spec.md § 23](1c-config-objects-spec.md#23-подписки-на-события-eventsubscriptions) |
|
||||
| `ScheduledJob` | `ScheduledJobs/` | Регламентные задания | [1c-config-objects-spec.md § 22](1c-config-objects-spec.md#22-регламентные-задания-scheduledjobs) |
|
||||
| `SettingsStorage` | `SettingsStorages/` | Хранилища настроек | [1c-configuration-spec.md § 6.10](1c-configuration-spec.md#610-settingsstorage--хранилище-настроек) |
|
||||
| `FunctionalOption` | `FunctionalOptions/` | Функциональные опции | [1c-configuration-spec.md § 6.7](1c-configuration-spec.md#67-functionaloption--функциональная-опция) |
|
||||
| `FunctionalOptionsParameter` | `FunctionalOptionsParameters/` | Параметры ФО | [1c-configuration-spec.md § 6.8](1c-configuration-spec.md#68-functionaloptionsparameter--параметр-функциональных-опций) |
|
||||
| `DefinedType` | `DefinedTypes/` | Определяемые типы | [1c-config-objects-spec.md § 20](1c-config-objects-spec.md#20-определяемые-типы-definedtypes) |
|
||||
| `Constant` | `Constants/` | Константы | [1c-config-objects-spec.md § 17](1c-config-objects-spec.md#17-константы-constants) |
|
||||
|
||||
### Прикладные объекты
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `Catalog` | `Catalogs/` | Справочники | [1c-config-objects-spec.md § 7](1c-config-objects-spec.md#7-справочники-catalogs) |
|
||||
| `Document` | `Documents/` | Документы | [1c-config-objects-spec.md § 8](1c-config-objects-spec.md#8-документы-documents) |
|
||||
| `DocumentNumerator` | `DocumentNumerators/` | Нумераторы документов | [1c-configuration-spec.md § 6.12](1c-configuration-spec.md#612-documentnumerator--нумератор-документов) |
|
||||
| `Sequence` | `Sequences/` | Последовательности | [1c-configuration-spec.md § 6.9](1c-configuration-spec.md#69-sequence--последовательность-документов) |
|
||||
| `DocumentJournal` | `DocumentJournals/` | Журналы документов | [1c-config-objects-spec.md § 19](1c-config-objects-spec.md#19-журналы-документов-documentjournals) |
|
||||
| `Enum` | `Enums/` | Перечисления | [1c-config-objects-spec.md § 16](1c-config-objects-spec.md#16-перечисления-enums) |
|
||||
| `Report` | `Reports/` | Отчёты | [1c-config-objects-spec.md § 18](1c-config-objects-spec.md#18-отчёты-и-обработки) |
|
||||
| `DataProcessor` | `DataProcessors/` | Обработки | [1c-config-objects-spec.md § 18](1c-config-objects-spec.md#18-отчёты-и-обработки) |
|
||||
|
||||
### Регистры
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `InformationRegister` | `InformationRegisters/` | Регистры сведений | [1c-config-objects-spec.md § 9.1](1c-config-objects-spec.md#91-регистры-сведений-informationregisters) |
|
||||
| `AccumulationRegister` | `AccumulationRegisters/` | Регистры накопления | [1c-config-objects-spec.md § 9.4](1c-config-objects-spec.md#94-регистры-накопления-accumulationregisters) |
|
||||
| `AccountingRegister` | `AccountingRegisters/` | Регистры бухгалтерии | [1c-config-objects-spec.md § 9.5](1c-config-objects-spec.md#95-регистры-бухгалтерии-accountingregisters) |
|
||||
| `CalculationRegister` | `CalculationRegisters/` | Регистры расчёта | [1c-config-objects-spec.md § 9.6](1c-config-objects-spec.md#96-регистры-расчёта-calculationregisters) |
|
||||
|
||||
### Планы
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `ChartOfCharacteristicTypes` | `ChartsOfCharacteristicTypes/` | Планы видов характеристик | [1c-config-objects-spec.md § 11](1c-config-objects-spec.md#11-планы-видов-характеристик-chartsofcharacteristictypes) |
|
||||
| `ChartOfAccounts` | `ChartsOfAccounts/` | Планы счетов | [1c-config-objects-spec.md § 10](1c-config-objects-spec.md#10-планы-счетов-chartsofaccounts) |
|
||||
| `ChartOfCalculationTypes` | `ChartsOfCalculationTypes/` | Планы видов расчёта | [1c-config-objects-spec.md § 12](1c-config-objects-spec.md#12-планы-видов-расчёта-chartsofcalculationtypes) |
|
||||
|
||||
### Бизнес-процессы
|
||||
|
||||
| XML-элемент | Каталог | Русское название | Спецификация |
|
||||
|-------------|---------|-----------------|--------------|
|
||||
| `BusinessProcess` | `BusinessProcesses/` | Бизнес-процессы | [1c-config-objects-spec.md § 13](1c-config-objects-spec.md#13-бизнес-процессы-businessprocesses) |
|
||||
| `Task` | `Tasks/` | Задачи | [1c-config-objects-spec.md § 14](1c-config-objects-spec.md#14-задачи-tasks) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Вложенные форматы
|
||||
|
||||
Форматы файлов, вложенных в каталоги объектов метаданных.
|
||||
|
||||
| Формат | Файл | Описание | Спецификация |
|
||||
|--------|------|----------|--------------|
|
||||
| Управляемая форма | `Ext/Form.xml` | Элементы, реквизиты, команды | [1c-form-spec.md § 1](1c-form-spec.md#1-корневой-элемент) |
|
||||
| СКД (DataCompositionSchema) | `Ext/Template.xml` | Схема компоновки данных | [1c-dcs-spec.md § 2](1c-dcs-spec.md#2-общая-структура-datacompositionschema) |
|
||||
| Табличный документ (MXL) | `Ext/Template.xml` | Печатная форма | [1c-spreadsheet-spec.md](1c-spreadsheet-spec.md#структура-документа) |
|
||||
| Роль (Rights) | `Ext/Rights.xml` | Права доступа и RLS | [1c-role-spec.md](1c-role-spec.md#файл-прав-rolesимяролиextrightsxml) |
|
||||
| Справка (Help) | `Ext/Help/` | Встроенная справка | [1c-help-spec.md § 1](1c-help-spec.md#1-структура-файлов) |
|
||||
| Предопределённые элементы | `Predefined.xml` | Предопределённые справочники/ПВХ | [1c-config-objects-spec.md § 7.2](1c-config-objects-spec.md#72-предопределённые-элементы-predefinedxml) |
|
||||
| Состав плана обмена | `Content.xml` | Объекты синхронизации | [1c-config-objects-spec.md § 15.4](1c-config-objects-spec.md#154-состав-плана-обмена-contentxml) |
|
||||
| Карта маршрута | `Flowchart.xml` | Маршрут бизнес-процесса | [1c-config-objects-spec.md § 13.3](1c-config-objects-spec.md#133-карта-маршрута-flowchartxml) |
|
||||
|
||||
---
|
||||
|
||||
## 4. Расширения конфигурации (CFE)
|
||||
|
||||
| Тема | Описание | Спецификация |
|
||||
|------|----------|--------------|
|
||||
| Общая структура выгрузки | Каталоги, отличия от конфигурации | [1c-extension-spec.md § 1](1c-extension-spec.md#1-общая-структура-выгрузки-расширения) |
|
||||
| Configuration.xml расширения | Свойства, назначение, ChildObjects | [1c-extension-spec.md § 2](1c-extension-spec.md#2-configurationxml--корневой-файл-расширения) |
|
||||
| Заимствованные / собственные объекты | ObjectBelonging, ExtendedConfigurationObject | [1c-extension-spec.md § 4](1c-extension-spec.md#4-заимствованные-и-собственные-объекты) |
|
||||
| Расширение свойств (xr:PropertyState) | MultiState, ExtendedProperty | [1c-extension-spec.md § 6](1c-extension-spec.md#6-расширение-свойств-xrpropertystate-и-xrextendedproperty) |
|
||||
| Модули и декораторы перехвата | &Перед, &После, &Вместо, diff-маркеры | [1c-extension-spec.md § 7](1c-extension-spec.md#7-модули-в-расширениях) |
|
||||
| Предопределённые элементы | ExtensionState: Native | [1c-extension-spec.md § 8](1c-extension-spec.md#8-предопределённые-элементы-в-расширениях) |
|
||||
|
||||
---
|
||||
|
||||
## 5. Внешние обработки и отчёты
|
||||
|
||||
| Формат | Описание | Спецификация |
|
||||
|--------|----------|--------------|
|
||||
| EPF (внешняя обработка) | ExternalDataProcessor | [1c-epf-spec.md § 1](1c-epf-spec.md#1-структура-каталогов) |
|
||||
| ERF (внешний отчёт) | ExternalReport | [1c-erf-spec.md § 1](1c-erf-spec.md#1-структура-каталогов) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Общие элементы формата
|
||||
|
||||
Общие для всех типов объектов структуры XML описаны в спецификации объектов:
|
||||
|
||||
| Тема | Спецификация |
|
||||
|------|--------------|
|
||||
| Корневой элемент MetaDataObject | [1c-config-objects-spec.md § 2](1c-config-objects-spec.md#2-общий-формат-xml) |
|
||||
| Пространства имён XML | [1c-config-objects-spec.md § 2.2](1c-config-objects-spec.md#22-пространства-имён) |
|
||||
| InternalInfo / GeneratedType | [1c-config-objects-spec.md § 3](1c-config-objects-spec.md#3-internalinfo--внутренняя-информация) |
|
||||
| Общие свойства Properties | [1c-config-objects-spec.md § 4](1c-config-objects-spec.md#4-общие-элементы-properties) |
|
||||
| Стандартные реквизиты | [1c-config-objects-spec.md § 5](1c-config-objects-spec.md#5-стандартные-реквизиты-standardattributes) |
|
||||
| Дочерние объекты (Attribute, TabularSection, Form, Template, Command) | [1c-config-objects-spec.md § 6](1c-config-objects-spec.md#6-дочерние-объекты-childobjects) |
|
||||
| Формат ссылок на объекты | [1c-config-objects-spec.md § 28](1c-config-objects-spec.md#28-формат-ссылок-на-объекты-метаданных) |
|
||||
| Различия версий 2.17 → 2.20 | [1c-config-objects-spec.md § 26](1c-config-objects-spec.md#26-различия-версий-платформы) |
|
||||
|
||||
---
|
||||
|
||||
## 7. DSL-спецификации (компактный формат ввода)
|
||||
|
||||
| DSL | Описание | Спецификация |
|
||||
|-----|----------|--------------|
|
||||
| Meta DSL | JSON-формат для создания/редактирования объектов | [meta-dsl-spec.md](meta-dsl-spec.md) |
|
||||
| Form DSL | JSON-формат для компиляции форм | [form-dsl-spec.md](form-dsl-spec.md) |
|
||||
| SKD DSL | JSON-формат для компиляции СКД | [skd-dsl-spec.md](skd-dsl-spec.md) |
|
||||
| MXL DSL | JSON-формат для компиляции табличных документов | [mxl-dsl-spec.md](mxl-dsl-spec.md) |
|
||||
| Role DSL | JSON-формат для компиляции ролей | [role-dsl-spec.md](role-dsl-spec.md) |
|
||||
|
||||
+449
-449
@@ -1,449 +1,449 @@
|
||||
# Спецификация XML-формата табличного документа (SpreadsheetDocument)
|
||||
|
||||
Формат файла `Template.xml` для макетов типа `SpreadsheetDocument` (табличный документ / MXL).
|
||||
|
||||
## Namespace
|
||||
|
||||
```xml
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet"
|
||||
xmlns:style="http://v8.1c.ru/8.1/data/ui/style"
|
||||
xmlns:v8="http://v8.1c.ru/8.1/data/core"
|
||||
xmlns:v8ui="http://v8.1c.ru/8.1/data/ui"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
```
|
||||
|
||||
## Структура документа
|
||||
|
||||
Элементы внутри `<document>` идут в фиксированном порядке:
|
||||
|
||||
```
|
||||
<document>
|
||||
<languageSettings> — языковые настройки
|
||||
<columns> ... — наборы колонок (один или несколько)
|
||||
<rowsItem> ... — строки с данными (повторяются)
|
||||
<drawing> ... — рисунки (опционально, повторяются)
|
||||
<templateMode>true — признак макета
|
||||
<defaultFormatIndex> — индекс формата по умолчанию
|
||||
<height> — общее количество строк
|
||||
<vgRows> — видимых строк (обычно = height)
|
||||
<merge> ... — объединения ячеек (повторяются)
|
||||
<verticalUnmerge> ... — отмена объединений (опционально)
|
||||
<namedItem> ... — именованные области (повторяются)
|
||||
<line> ... — стили линий (повторяются)
|
||||
<font> ... — шрифты (опционально, повторяются)
|
||||
<format> ... — форматы (повторяются)
|
||||
<picture> ... — ресурсы картинок (опционально)
|
||||
</document>
|
||||
```
|
||||
|
||||
## Индексация
|
||||
|
||||
Все палитры (линии, шрифты, форматы) — **плоские массивы**, на элементы которых ссылаются по индексу.
|
||||
|
||||
| Палитра | Индексация | Индекс 0 означает |
|
||||
|-----------|------------|--------------------------------------|
|
||||
| `<line>` | 0-based | Первый элемент `<line>` |
|
||||
| `<font>` | 0-based | Первый элемент `<font>` |
|
||||
| `<format>`| **1-based**| 0 = «формат по умолчанию» (не задан) |
|
||||
|
||||
Формат с индексом N — это N-й элемент `<format>` в документе (считая от 1).
|
||||
|
||||
## Языковые настройки
|
||||
|
||||
```xml
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
```
|
||||
|
||||
## Колонки
|
||||
|
||||
### Основной набор
|
||||
|
||||
```xml
|
||||
<columns>
|
||||
<size>33</size> <!-- общее количество колонок -->
|
||||
<columnsItem>
|
||||
<index>1</index> <!-- индекс колонки (0-based) -->
|
||||
<column>
|
||||
<formatIndex>1</formatIndex> <!-- ссылка на format[] -->
|
||||
</column>
|
||||
</columnsItem>
|
||||
...
|
||||
</columns>
|
||||
```
|
||||
|
||||
Перечисляются только колонки с нестандартной шириной. Формат колонки определяет ширину через свойство `<width>` в палитре форматов.
|
||||
|
||||
### Дополнительные наборы колонок
|
||||
|
||||
Некоторые строки документа могут использовать **собственную сетку колонок**, отличную от основной. Каждый дополнительный набор имеет UUID:
|
||||
|
||||
```xml
|
||||
<columns>
|
||||
<id>f01e015f-de4c-4f97-9fbe-a244c4c30c6c</id>
|
||||
<size>17</size>
|
||||
<columnsItem>
|
||||
<index>0</index>
|
||||
<column>
|
||||
<formatIndex>12</formatIndex>
|
||||
</column>
|
||||
</columnsItem>
|
||||
...
|
||||
</columns>
|
||||
```
|
||||
|
||||
- Первый `<columns>` — основной набор (без `<id>`)
|
||||
- Дополнительные наборы — с `<id>` (UUID), могут иметь другое количество и ширину колонок
|
||||
- Строки, merge и namedItem ссылаются на набор через `<columnsID>`
|
||||
|
||||
Типичное применение: сложные печатные формы (УПД, УКД), где шапка/подвал/табличная часть имеют разную разбивку на колонки.
|
||||
|
||||
## Строки и ячейки
|
||||
|
||||
### Строка
|
||||
|
||||
```xml
|
||||
<rowsItem>
|
||||
<index>3</index> <!-- индекс строки (0-based) -->
|
||||
<indexTo>5</indexTo> <!-- опц.: диапазон [index..indexTo] с одинаковым содержимым -->
|
||||
<row>
|
||||
<columnsID>f01e015f-...</columnsID> <!-- опц.: набор колонок (UUID) -->
|
||||
<formatIndex>5</formatIndex> <!-- опц.: формат строки (определяет высоту) -->
|
||||
<empty>true</empty> <!-- опц.: пустая строка -->
|
||||
<c>...</c> <!-- ячейки (повторяются) -->
|
||||
</row>
|
||||
</rowsItem>
|
||||
```
|
||||
|
||||
- Строки с одинаковым содержимым объединяются через `<indexTo>`
|
||||
- `<columnsID>` привязывает строку к дополнительному набору колонок. Без него — используется основной набор
|
||||
|
||||
### Ячейка
|
||||
|
||||
Ячейки внутри `<row>` — элементы `<c>` (cell group), каждый содержит `<c>` (cell content):
|
||||
|
||||
```xml
|
||||
<c> <!-- cell group -->
|
||||
<i>6</i> <!-- индекс колонки (0-based), опционален -->
|
||||
<c> <!-- cell content -->
|
||||
<f>9</f> <!-- индекс формата -->
|
||||
<parameter>Имя</parameter> <!-- параметр для заполнения -->
|
||||
<detailParameter>Расш</detailParameter> <!-- параметр расшифровки -->
|
||||
<tl> <!-- текст (локализованная строка) -->
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Итого:</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</c>
|
||||
</c>
|
||||
```
|
||||
|
||||
**Правила позиционирования `<i>`:**
|
||||
- Если `<i>` указан — ячейка в этой колонке
|
||||
- Если `<i>` не указан — колонка = предыдущая + 1
|
||||
- Первая ячейка без `<i>` идёт в колонку 0
|
||||
|
||||
### Типы заполнения ячеек
|
||||
|
||||
Тип заполнения определяется свойством `fillType` в формате ячейки:
|
||||
|
||||
| fillType | Данные ячейки | Описание |
|
||||
|-------------|-------------------------------|----------------------------------------|
|
||||
| `Parameter` | `<parameter>Имя</parameter>` | Значение подставляется программно |
|
||||
| `Template` | `<tl>Текст [Параметр]</tl>` | Шаблон — `[Имя]` заменяется на значение |
|
||||
| `Text` | `<tl>Текст</tl>` | Статический текст |
|
||||
| *(нет)* | — | Пустая ячейка или ячейка с форматированием |
|
||||
|
||||
`<detailParameter>` — имя параметра расшифровки (для навигации при клике на ячейку).
|
||||
|
||||
## Рисунки
|
||||
|
||||
```xml
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>1</id>
|
||||
<formatIndex>11</formatIndex>
|
||||
<beginRow>3</beginRow>
|
||||
<beginRowOffset>6</beginRowOffset>
|
||||
<endRow>4</endRow>
|
||||
<endRowOffset>33</endRowOffset>
|
||||
<beginColumn>2</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>4</endColumn>
|
||||
<endColumnOffset>183</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Proportionally</pictureSize>
|
||||
<zOrder>1</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
```
|
||||
|
||||
Позиция задаётся через начальную/конечную строку и колонку + смещения в пикселях. `pictureIndex` ссылается на ресурс из палитры `<picture>`.
|
||||
|
||||
## Объединения ячеек
|
||||
|
||||
```xml
|
||||
<merge>
|
||||
<r>3</r> <!-- строка (0-based), -1 = все строки -->
|
||||
<c>1</c> <!-- колонка (0-based) -->
|
||||
<h>1</h> <!-- доп. строк (опц., по умолчанию 0 = одна строка) -->
|
||||
<w>30</w> <!-- доп. колонок -->
|
||||
<columnsID>f01e015f-...</columnsID> <!-- опц.: набор колонок -->
|
||||
</merge>
|
||||
```
|
||||
|
||||
Размер объединения: `(h + 1)` строк × `(w + 1)` колонок. Если `<h>` не указан — объединение в пределах одной строки.
|
||||
|
||||
`<r>-1</r>` — объединение действует для всех строк, использующих данный набор колонок (аналог объединения колонок на уровне всего документа).
|
||||
|
||||
### Отмена объединений
|
||||
|
||||
`<verticalUnmerge>` отменяет вертикальное объединение для конкретной строки:
|
||||
|
||||
```xml
|
||||
<verticalUnmerge>
|
||||
<r>10</r> <!-- строка (0-based) -->
|
||||
<c>7</c> <!-- колонка (0-based) -->
|
||||
<w>12</w> <!-- доп. колонок -->
|
||||
</verticalUnmerge>
|
||||
```
|
||||
|
||||
Используется в сложных макетах, когда глобальное объединение колонок (`<r>-1</r>`) нужно разорвать в отдельных строках.
|
||||
|
||||
## Именованные области
|
||||
|
||||
Именованные области — аналог «имён» в табличном документе 1С. Используются для программного вывода секций.
|
||||
|
||||
Получение области:
|
||||
```bsl
|
||||
// Горизонтальная область (диапазон строк)
|
||||
Область = Макет.ПолучитьОбласть("Заголовок");
|
||||
|
||||
// Пересечение горизонтальной и вертикальной областей
|
||||
Область = Макет.ПолучитьОбласть("ВысотаЭтикетки|ШиринаЭтикетки");
|
||||
```
|
||||
|
||||
Пересечение через `|` типично для этикеток и ценников, где нужна область фиксированного размера (высота × ширина).
|
||||
|
||||
### Тип Rows — горизонтальная область
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>Заголовок</name>
|
||||
<area>
|
||||
<type>Rows</type>
|
||||
<beginRow>1</beginRow> <!-- 0-based -->
|
||||
<endRow>4</endRow>
|
||||
<beginColumn>-1</beginColumn> <!-- -1 = все колонки -->
|
||||
<endColumn>-1</endColumn>
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Тип Columns — вертикальная область
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>ШиринаЭтикетки</name>
|
||||
<area>
|
||||
<type>Columns</type>
|
||||
<beginRow>-1</beginRow> <!-- -1 = все строки -->
|
||||
<endRow>-1</endRow>
|
||||
<beginColumn>1</beginColumn> <!-- 0-based -->
|
||||
<endColumn>5</endColumn>
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Тип Rectangle — прямоугольная область
|
||||
|
||||
Область, ограниченная и по строкам, и по колонкам. Используется с дополнительными наборами колонок:
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>ОбластьЗаписьДо</name>
|
||||
<area>
|
||||
<type>Rectangle</type>
|
||||
<beginRow>22</beginRow> <!-- 0-based -->
|
||||
<endRow>22</endRow>
|
||||
<beginColumn>5</beginColumn> <!-- 0-based -->
|
||||
<endColumn>17</endColumn>
|
||||
<columnsID>c6cb0794-...</columnsID> <!-- набор колонок -->
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Привязка к набору колонок
|
||||
|
||||
Именованные области могут ссылаться на дополнительный набор колонок через `<columnsID>`:
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>НумерацияЛистов</name>
|
||||
<area>
|
||||
<type>Rows</type>
|
||||
<beginRow>59</beginRow>
|
||||
<endRow>59</endRow>
|
||||
<beginColumn>-1</beginColumn>
|
||||
<endColumn>-1</endColumn>
|
||||
<columnsID>0adf41ed-...</columnsID>
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Тип Drawing — именованный рисунок
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemDrawing">
|
||||
<name>Штрихкод</name>
|
||||
<drawingID>1</drawingID> <!-- ссылка на drawing/id -->
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
## Стили линий
|
||||
|
||||
Палитра линий для границ ячеек и рисунков. Индексация 0-based.
|
||||
|
||||
```xml
|
||||
<!-- Для границ ячеек -->
|
||||
<line width="2" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</line>
|
||||
|
||||
<!-- Для границ рисунков -->
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">None</v8ui:style>
|
||||
</line>
|
||||
```
|
||||
|
||||
| xsi:type | Значения |
|
||||
|-----------------------------------------|-------------|
|
||||
| `v8ui:SpreadsheetDocumentCellLineType` | Solid, None |
|
||||
| `v8ui:SpreadsheetDocumentDrawingLineType` | Solid, None |
|
||||
|
||||
Атрибут `width` — толщина линии (1 = тонкая, 2 = толстая).
|
||||
|
||||
## Шрифты
|
||||
|
||||
Палитра шрифтов. Индексация 0-based.
|
||||
|
||||
```xml
|
||||
<!-- Абсолютный шрифт -->
|
||||
<font faceName="Arial" height="14" bold="true" italic="false"
|
||||
underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
|
||||
<!-- Ссылка на стиль -->
|
||||
<font ref="style:TextFont" kind="StyleItem"/>
|
||||
```
|
||||
|
||||
## Форматы
|
||||
|
||||
Палитра форматов — центральный элемент. **Индексация 1-based** (индекс 0 = формат не задан).
|
||||
|
||||
```xml
|
||||
<format>
|
||||
<font>0</font> <!-- индекс шрифта (0-based) -->
|
||||
<leftBorder>0</leftBorder> <!-- индекс линии левой границы -->
|
||||
<topBorder>1</topBorder> <!-- индекс линии верхней границы -->
|
||||
<rightBorder>0</rightBorder> <!-- индекс линии правой границы -->
|
||||
<bottomBorder>1</bottomBorder> <!-- индекс линии нижней границы -->
|
||||
<width>24</width> <!-- ширина (для колонок) -->
|
||||
<height>84</height> <!-- высота (для строк) -->
|
||||
<horizontalAlignment>Center</horizontalAlignment> <!-- Left | Center | Right -->
|
||||
<verticalAlignment>Center</verticalAlignment> <!-- Top | Center -->
|
||||
<textPlacement>Wrap</textPlacement> <!-- Wrap = перенос по словам -->
|
||||
<fillType>Parameter</fillType> <!-- Parameter | Template | Text -->
|
||||
<format> <!-- строка формата (опционально) -->
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>ЧЦ=15; ЧДЦ=2</v8:content>
|
||||
</v8:item>
|
||||
</format>
|
||||
<drawingBorder>1</drawingBorder> <!-- индекс линии для рисунка -->
|
||||
</format>
|
||||
```
|
||||
|
||||
Все свойства опциональны. Формат может содержать только `<width>` (для колонки) или только `<height>` (для строки).
|
||||
|
||||
### Связь формата с контекстом
|
||||
|
||||
| Контекст | Ссылка | Значимые свойства формата |
|
||||
|------------------|--------------------|--------------------------|
|
||||
| Колонка | `<formatIndex>` | `width` |
|
||||
| Строка | `<formatIndex>` | `height` |
|
||||
| Ячейка | `<f>` | Все остальные |
|
||||
| Рисунок | `<formatIndex>` | `drawingBorder` |
|
||||
| По умолчанию | `<defaultFormatIndex>` | `width` |
|
||||
|
||||
## Ресурсы картинок
|
||||
|
||||
```xml
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture ref="v8ui:Штрихкод"/> <!-- ссылка на предопределённую картинку -->
|
||||
</picture>
|
||||
```
|
||||
|
||||
## Типичная структура макета печатной формы
|
||||
|
||||
Печатная форма обычно состоит из именованных горизонтальных областей:
|
||||
|
||||
```
|
||||
Заголовок — шапка документа (название, номер, дата)
|
||||
Поставщик — реквизиты поставщика
|
||||
Покупатель — реквизиты покупателя
|
||||
ШапкаТаблицы — заголовок таблицы товаров
|
||||
Строка — строка товара (выводится в цикле)
|
||||
Итого — итоговая строка
|
||||
СуммаПрописью — сумма прописью
|
||||
Подписи — блок подписей
|
||||
```
|
||||
|
||||
Каждая область — диапазон строк, получаемый через `ПолучитьОбласть("Имя")` и выводимый через `Вывести()`.
|
||||
|
||||
Параметры в ячейках (`<parameter>`) заполняются программно:
|
||||
```bsl
|
||||
Область = Макет.ПолучитьОбласть("Строка");
|
||||
Область.Параметры.НомерСтроки = НомерСтроки;
|
||||
Область.Параметры.Товар = СтрокаТЧ.Номенклатура;
|
||||
ТабДок.Вывести(Область);
|
||||
```
|
||||
|
||||
## Совместимость версий платформы
|
||||
|
||||
Проведено сравнение выгрузок конфигурации «Бухгалтерия предприятия 3.0» на трёх версиях платформы: 8.3.20, 8.3.24, 8.3.27.
|
||||
|
||||
### Template.xml (табличный документ)
|
||||
|
||||
Содержимое `Template.xml` **побайтно идентично** на всех трёх версиях. Формат табличного документа стабилен — пространства имён, набор тегов и структура не менялись между 8.3.20 и 8.3.27.
|
||||
|
||||
### Метаданные (version в MetaDataObject)
|
||||
|
||||
Атрибут `version` корневого элемента `<MetaDataObject>` в XML-файлах метаданных (`.xml` объектов, форм, макетов):
|
||||
|
||||
| Платформа | version |
|
||||
|-----------|---------|
|
||||
| 8.3.20 | 2.17 |
|
||||
| 8.3.24 | 2.17 |
|
||||
| 8.3.27 | 2.20 |
|
||||
|
||||
### Form.xml (управляемая форма)
|
||||
|
||||
Содержимое `Form.xml` идентично между 8.3.20 и 8.3.24. Между 8.3.24 и 8.3.27 различается **только** атрибут `version` в корневом элементе `<Form>`: `"2.17"` → `"2.20"`. Пространства имён и структура не изменились.
|
||||
|
||||
### BSL-модули
|
||||
|
||||
Модули на встроенном языке (`ObjectModule.bsl`) полностью идентичны на всех трёх версиях.
|
||||
|
||||
### Обратная совместимость
|
||||
|
||||
Навыки генерируют XML с `version="2.17"`. Сборка EPF через `1cv8.exe` версии 8.3.27 проходит успешно — платформа принимает файлы с более старым номером версии без ошибок. Повышать `version` до `"2.20"` не требуется.
|
||||
# Спецификация XML-формата табличного документа (SpreadsheetDocument)
|
||||
|
||||
Формат файла `Template.xml` для макетов типа `SpreadsheetDocument` (табличный документ / MXL).
|
||||
|
||||
## Namespace
|
||||
|
||||
```xml
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet"
|
||||
xmlns:style="http://v8.1c.ru/8.1/data/ui/style"
|
||||
xmlns:v8="http://v8.1c.ru/8.1/data/core"
|
||||
xmlns:v8ui="http://v8.1c.ru/8.1/data/ui"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
```
|
||||
|
||||
## Структура документа
|
||||
|
||||
Элементы внутри `<document>` идут в фиксированном порядке:
|
||||
|
||||
```
|
||||
<document>
|
||||
<languageSettings> — языковые настройки
|
||||
<columns> ... — наборы колонок (один или несколько)
|
||||
<rowsItem> ... — строки с данными (повторяются)
|
||||
<drawing> ... — рисунки (опционально, повторяются)
|
||||
<templateMode>true — признак макета
|
||||
<defaultFormatIndex> — индекс формата по умолчанию
|
||||
<height> — общее количество строк
|
||||
<vgRows> — видимых строк (обычно = height)
|
||||
<merge> ... — объединения ячеек (повторяются)
|
||||
<verticalUnmerge> ... — отмена объединений (опционально)
|
||||
<namedItem> ... — именованные области (повторяются)
|
||||
<line> ... — стили линий (повторяются)
|
||||
<font> ... — шрифты (опционально, повторяются)
|
||||
<format> ... — форматы (повторяются)
|
||||
<picture> ... — ресурсы картинок (опционально)
|
||||
</document>
|
||||
```
|
||||
|
||||
## Индексация
|
||||
|
||||
Все палитры (линии, шрифты, форматы) — **плоские массивы**, на элементы которых ссылаются по индексу.
|
||||
|
||||
| Палитра | Индексация | Индекс 0 означает |
|
||||
|-----------|------------|--------------------------------------|
|
||||
| `<line>` | 0-based | Первый элемент `<line>` |
|
||||
| `<font>` | 0-based | Первый элемент `<font>` |
|
||||
| `<format>`| **1-based**| 0 = «формат по умолчанию» (не задан) |
|
||||
|
||||
Формат с индексом N — это N-й элемент `<format>` в документе (считая от 1).
|
||||
|
||||
## Языковые настройки
|
||||
|
||||
```xml
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
```
|
||||
|
||||
## Колонки
|
||||
|
||||
### Основной набор
|
||||
|
||||
```xml
|
||||
<columns>
|
||||
<size>33</size> <!-- общее количество колонок -->
|
||||
<columnsItem>
|
||||
<index>1</index> <!-- индекс колонки (0-based) -->
|
||||
<column>
|
||||
<formatIndex>1</formatIndex> <!-- ссылка на format[] -->
|
||||
</column>
|
||||
</columnsItem>
|
||||
...
|
||||
</columns>
|
||||
```
|
||||
|
||||
Перечисляются только колонки с нестандартной шириной. Формат колонки определяет ширину через свойство `<width>` в палитре форматов.
|
||||
|
||||
### Дополнительные наборы колонок
|
||||
|
||||
Некоторые строки документа могут использовать **собственную сетку колонок**, отличную от основной. Каждый дополнительный набор имеет UUID:
|
||||
|
||||
```xml
|
||||
<columns>
|
||||
<id>f01e015f-de4c-4f97-9fbe-a244c4c30c6c</id>
|
||||
<size>17</size>
|
||||
<columnsItem>
|
||||
<index>0</index>
|
||||
<column>
|
||||
<formatIndex>12</formatIndex>
|
||||
</column>
|
||||
</columnsItem>
|
||||
...
|
||||
</columns>
|
||||
```
|
||||
|
||||
- Первый `<columns>` — основной набор (без `<id>`)
|
||||
- Дополнительные наборы — с `<id>` (UUID), могут иметь другое количество и ширину колонок
|
||||
- Строки, merge и namedItem ссылаются на набор через `<columnsID>`
|
||||
|
||||
Типичное применение: сложные печатные формы (УПД, УКД), где шапка/подвал/табличная часть имеют разную разбивку на колонки.
|
||||
|
||||
## Строки и ячейки
|
||||
|
||||
### Строка
|
||||
|
||||
```xml
|
||||
<rowsItem>
|
||||
<index>3</index> <!-- индекс строки (0-based) -->
|
||||
<indexTo>5</indexTo> <!-- опц.: диапазон [index..indexTo] с одинаковым содержимым -->
|
||||
<row>
|
||||
<columnsID>f01e015f-...</columnsID> <!-- опц.: набор колонок (UUID) -->
|
||||
<formatIndex>5</formatIndex> <!-- опц.: формат строки (определяет высоту) -->
|
||||
<empty>true</empty> <!-- опц.: пустая строка -->
|
||||
<c>...</c> <!-- ячейки (повторяются) -->
|
||||
</row>
|
||||
</rowsItem>
|
||||
```
|
||||
|
||||
- Строки с одинаковым содержимым объединяются через `<indexTo>`
|
||||
- `<columnsID>` привязывает строку к дополнительному набору колонок. Без него — используется основной набор
|
||||
|
||||
### Ячейка
|
||||
|
||||
Ячейки внутри `<row>` — элементы `<c>` (cell group), каждый содержит `<c>` (cell content):
|
||||
|
||||
```xml
|
||||
<c> <!-- cell group -->
|
||||
<i>6</i> <!-- индекс колонки (0-based), опционален -->
|
||||
<c> <!-- cell content -->
|
||||
<f>9</f> <!-- индекс формата -->
|
||||
<parameter>Имя</parameter> <!-- параметр для заполнения -->
|
||||
<detailParameter>Расш</detailParameter> <!-- параметр расшифровки -->
|
||||
<tl> <!-- текст (локализованная строка) -->
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Итого:</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</c>
|
||||
</c>
|
||||
```
|
||||
|
||||
**Правила позиционирования `<i>`:**
|
||||
- Если `<i>` указан — ячейка в этой колонке
|
||||
- Если `<i>` не указан — колонка = предыдущая + 1
|
||||
- Первая ячейка без `<i>` идёт в колонку 0
|
||||
|
||||
### Типы заполнения ячеек
|
||||
|
||||
Тип заполнения определяется свойством `fillType` в формате ячейки:
|
||||
|
||||
| fillType | Данные ячейки | Описание |
|
||||
|-------------|-------------------------------|----------------------------------------|
|
||||
| `Parameter` | `<parameter>Имя</parameter>` | Значение подставляется программно |
|
||||
| `Template` | `<tl>Текст [Параметр]</tl>` | Шаблон — `[Имя]` заменяется на значение |
|
||||
| `Text` | `<tl>Текст</tl>` | Статический текст |
|
||||
| *(нет)* | — | Пустая ячейка или ячейка с форматированием |
|
||||
|
||||
`<detailParameter>` — имя параметра расшифровки (для навигации при клике на ячейку).
|
||||
|
||||
## Рисунки
|
||||
|
||||
```xml
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>1</id>
|
||||
<formatIndex>11</formatIndex>
|
||||
<beginRow>3</beginRow>
|
||||
<beginRowOffset>6</beginRowOffset>
|
||||
<endRow>4</endRow>
|
||||
<endRowOffset>33</endRowOffset>
|
||||
<beginColumn>2</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>4</endColumn>
|
||||
<endColumnOffset>183</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Proportionally</pictureSize>
|
||||
<zOrder>1</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
```
|
||||
|
||||
Позиция задаётся через начальную/конечную строку и колонку + смещения в пикселях. `pictureIndex` ссылается на ресурс из палитры `<picture>`.
|
||||
|
||||
## Объединения ячеек
|
||||
|
||||
```xml
|
||||
<merge>
|
||||
<r>3</r> <!-- строка (0-based), -1 = все строки -->
|
||||
<c>1</c> <!-- колонка (0-based) -->
|
||||
<h>1</h> <!-- доп. строк (опц., по умолчанию 0 = одна строка) -->
|
||||
<w>30</w> <!-- доп. колонок -->
|
||||
<columnsID>f01e015f-...</columnsID> <!-- опц.: набор колонок -->
|
||||
</merge>
|
||||
```
|
||||
|
||||
Размер объединения: `(h + 1)` строк × `(w + 1)` колонок. Если `<h>` не указан — объединение в пределах одной строки.
|
||||
|
||||
`<r>-1</r>` — объединение действует для всех строк, использующих данный набор колонок (аналог объединения колонок на уровне всего документа).
|
||||
|
||||
### Отмена объединений
|
||||
|
||||
`<verticalUnmerge>` отменяет вертикальное объединение для конкретной строки:
|
||||
|
||||
```xml
|
||||
<verticalUnmerge>
|
||||
<r>10</r> <!-- строка (0-based) -->
|
||||
<c>7</c> <!-- колонка (0-based) -->
|
||||
<w>12</w> <!-- доп. колонок -->
|
||||
</verticalUnmerge>
|
||||
```
|
||||
|
||||
Используется в сложных макетах, когда глобальное объединение колонок (`<r>-1</r>`) нужно разорвать в отдельных строках.
|
||||
|
||||
## Именованные области
|
||||
|
||||
Именованные области — аналог «имён» в табличном документе 1С. Используются для программного вывода секций.
|
||||
|
||||
Получение области:
|
||||
```bsl
|
||||
// Горизонтальная область (диапазон строк)
|
||||
Область = Макет.ПолучитьОбласть("Заголовок");
|
||||
|
||||
// Пересечение горизонтальной и вертикальной областей
|
||||
Область = Макет.ПолучитьОбласть("ВысотаЭтикетки|ШиринаЭтикетки");
|
||||
```
|
||||
|
||||
Пересечение через `|` типично для этикеток и ценников, где нужна область фиксированного размера (высота × ширина).
|
||||
|
||||
### Тип Rows — горизонтальная область
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>Заголовок</name>
|
||||
<area>
|
||||
<type>Rows</type>
|
||||
<beginRow>1</beginRow> <!-- 0-based -->
|
||||
<endRow>4</endRow>
|
||||
<beginColumn>-1</beginColumn> <!-- -1 = все колонки -->
|
||||
<endColumn>-1</endColumn>
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Тип Columns — вертикальная область
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>ШиринаЭтикетки</name>
|
||||
<area>
|
||||
<type>Columns</type>
|
||||
<beginRow>-1</beginRow> <!-- -1 = все строки -->
|
||||
<endRow>-1</endRow>
|
||||
<beginColumn>1</beginColumn> <!-- 0-based -->
|
||||
<endColumn>5</endColumn>
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Тип Rectangle — прямоугольная область
|
||||
|
||||
Область, ограниченная и по строкам, и по колонкам. Используется с дополнительными наборами колонок:
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>ОбластьЗаписьДо</name>
|
||||
<area>
|
||||
<type>Rectangle</type>
|
||||
<beginRow>22</beginRow> <!-- 0-based -->
|
||||
<endRow>22</endRow>
|
||||
<beginColumn>5</beginColumn> <!-- 0-based -->
|
||||
<endColumn>17</endColumn>
|
||||
<columnsID>c6cb0794-...</columnsID> <!-- набор колонок -->
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Привязка к набору колонок
|
||||
|
||||
Именованные области могут ссылаться на дополнительный набор колонок через `<columnsID>`:
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>НумерацияЛистов</name>
|
||||
<area>
|
||||
<type>Rows</type>
|
||||
<beginRow>59</beginRow>
|
||||
<endRow>59</endRow>
|
||||
<beginColumn>-1</beginColumn>
|
||||
<endColumn>-1</endColumn>
|
||||
<columnsID>0adf41ed-...</columnsID>
|
||||
</area>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
### Тип Drawing — именованный рисунок
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemDrawing">
|
||||
<name>Штрихкод</name>
|
||||
<drawingID>1</drawingID> <!-- ссылка на drawing/id -->
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
## Стили линий
|
||||
|
||||
Палитра линий для границ ячеек и рисунков. Индексация 0-based.
|
||||
|
||||
```xml
|
||||
<!-- Для границ ячеек -->
|
||||
<line width="2" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</line>
|
||||
|
||||
<!-- Для границ рисунков -->
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">None</v8ui:style>
|
||||
</line>
|
||||
```
|
||||
|
||||
| xsi:type | Значения |
|
||||
|-----------------------------------------|-------------|
|
||||
| `v8ui:SpreadsheetDocumentCellLineType` | Solid, None |
|
||||
| `v8ui:SpreadsheetDocumentDrawingLineType` | Solid, None |
|
||||
|
||||
Атрибут `width` — толщина линии (1 = тонкая, 2 = толстая).
|
||||
|
||||
## Шрифты
|
||||
|
||||
Палитра шрифтов. Индексация 0-based.
|
||||
|
||||
```xml
|
||||
<!-- Абсолютный шрифт -->
|
||||
<font faceName="Arial" height="14" bold="true" italic="false"
|
||||
underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
|
||||
<!-- Ссылка на стиль -->
|
||||
<font ref="style:TextFont" kind="StyleItem"/>
|
||||
```
|
||||
|
||||
## Форматы
|
||||
|
||||
Палитра форматов — центральный элемент. **Индексация 1-based** (индекс 0 = формат не задан).
|
||||
|
||||
```xml
|
||||
<format>
|
||||
<font>0</font> <!-- индекс шрифта (0-based) -->
|
||||
<leftBorder>0</leftBorder> <!-- индекс линии левой границы -->
|
||||
<topBorder>1</topBorder> <!-- индекс линии верхней границы -->
|
||||
<rightBorder>0</rightBorder> <!-- индекс линии правой границы -->
|
||||
<bottomBorder>1</bottomBorder> <!-- индекс линии нижней границы -->
|
||||
<width>24</width> <!-- ширина (для колонок) -->
|
||||
<height>84</height> <!-- высота (для строк) -->
|
||||
<horizontalAlignment>Center</horizontalAlignment> <!-- Left | Center | Right -->
|
||||
<verticalAlignment>Center</verticalAlignment> <!-- Top | Center -->
|
||||
<textPlacement>Wrap</textPlacement> <!-- Wrap = перенос по словам -->
|
||||
<fillType>Parameter</fillType> <!-- Parameter | Template | Text -->
|
||||
<format> <!-- строка формата (опционально) -->
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>ЧЦ=15; ЧДЦ=2</v8:content>
|
||||
</v8:item>
|
||||
</format>
|
||||
<drawingBorder>1</drawingBorder> <!-- индекс линии для рисунка -->
|
||||
</format>
|
||||
```
|
||||
|
||||
Все свойства опциональны. Формат может содержать только `<width>` (для колонки) или только `<height>` (для строки).
|
||||
|
||||
### Связь формата с контекстом
|
||||
|
||||
| Контекст | Ссылка | Значимые свойства формата |
|
||||
|------------------|--------------------|--------------------------|
|
||||
| Колонка | `<formatIndex>` | `width` |
|
||||
| Строка | `<formatIndex>` | `height` |
|
||||
| Ячейка | `<f>` | Все остальные |
|
||||
| Рисунок | `<formatIndex>` | `drawingBorder` |
|
||||
| По умолчанию | `<defaultFormatIndex>` | `width` |
|
||||
|
||||
## Ресурсы картинок
|
||||
|
||||
```xml
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture ref="v8ui:Штрихкод"/> <!-- ссылка на предопределённую картинку -->
|
||||
</picture>
|
||||
```
|
||||
|
||||
## Типичная структура макета печатной формы
|
||||
|
||||
Печатная форма обычно состоит из именованных горизонтальных областей:
|
||||
|
||||
```
|
||||
Заголовок — шапка документа (название, номер, дата)
|
||||
Поставщик — реквизиты поставщика
|
||||
Покупатель — реквизиты покупателя
|
||||
ШапкаТаблицы — заголовок таблицы товаров
|
||||
Строка — строка товара (выводится в цикле)
|
||||
Итого — итоговая строка
|
||||
СуммаПрописью — сумма прописью
|
||||
Подписи — блок подписей
|
||||
```
|
||||
|
||||
Каждая область — диапазон строк, получаемый через `ПолучитьОбласть("Имя")` и выводимый через `Вывести()`.
|
||||
|
||||
Параметры в ячейках (`<parameter>`) заполняются программно:
|
||||
```bsl
|
||||
Область = Макет.ПолучитьОбласть("Строка");
|
||||
Область.Параметры.НомерСтроки = НомерСтроки;
|
||||
Область.Параметры.Товар = СтрокаТЧ.Номенклатура;
|
||||
ТабДок.Вывести(Область);
|
||||
```
|
||||
|
||||
## Совместимость версий платформы
|
||||
|
||||
Проведено сравнение выгрузок конфигурации «Бухгалтерия предприятия 3.0» на трёх версиях платформы: 8.3.20, 8.3.24, 8.3.27.
|
||||
|
||||
### Template.xml (табличный документ)
|
||||
|
||||
Содержимое `Template.xml` **побайтно идентично** на всех трёх версиях. Формат табличного документа стабилен — пространства имён, набор тегов и структура не менялись между 8.3.20 и 8.3.27.
|
||||
|
||||
### Метаданные (version в MetaDataObject)
|
||||
|
||||
Атрибут `version` корневого элемента `<MetaDataObject>` в XML-файлах метаданных (`.xml` объектов, форм, макетов):
|
||||
|
||||
| Платформа | version |
|
||||
|-----------|---------|
|
||||
| 8.3.20 | 2.17 |
|
||||
| 8.3.24 | 2.17 |
|
||||
| 8.3.27 | 2.20 |
|
||||
|
||||
### Form.xml (управляемая форма)
|
||||
|
||||
Содержимое `Form.xml` идентично между 8.3.20 и 8.3.24. Между 8.3.24 и 8.3.27 различается **только** атрибут `version` в корневом элементе `<Form>`: `"2.17"` → `"2.20"`. Пространства имён и структура не изменились.
|
||||
|
||||
### BSL-модули
|
||||
|
||||
Модули на встроенном языке (`ObjectModule.bsl`) полностью идентичны на всех трёх версиях.
|
||||
|
||||
### Обратная совместимость
|
||||
|
||||
Навыки генерируют XML с `version="2.17"`. Сборка EPF через `1cv8.exe` версии 8.3.27 проходит успешно — платформа принимает файлы с более старым номером версии без ошибок. Повышать `version` до `"2.20"` не требуется.
|
||||
|
||||
+1022
-1022
File diff suppressed because it is too large
Load Diff
+182
-182
@@ -1,182 +1,182 @@
|
||||
# Корневые файлы конфигурации
|
||||
|
||||
Навыки группы `/cf-*` позволяют создавать, анализировать, редактировать и проверять корневые файлы конфигурации 1С — `Configuration.xml`, `ConfigDumpInfo.xml`, `Languages/`.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/cf-info` | `<ConfigPath> [-Mode overview\|brief\|full]` | Анализ конфигурации: свойства, состав, счётчики объектов (3 режима) |
|
||||
| `/cf-init` | `<Name> [-Synonym] [-OutputDir] [-Version] [-Vendor]` | Создание пустой конфигурации (scaffold XML-исходников) |
|
||||
| `/cf-validate` | `<ConfigPath> [-MaxErrors 30]` | Валидация структурной корректности (8 проверок) |
|
||||
| `/cf-edit` | `<ConfigPath> -Operation <op> -Value "<val>"` | Редактирование свойств, состава ChildObjects, ролей по умолчанию (6 операций) |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание (текст) → /cf-init → XML-исходники → /cf-validate
|
||||
↕ /cf-edit → /cf-info
|
||||
```
|
||||
|
||||
1. `/cf-init` создаёт scaffold пустой конфигурации (Configuration.xml, ConfigDumpInfo.xml, Languages/)
|
||||
2. `/cf-edit` вносит изменения: свойства, объекты в ChildObjects, роли по умолчанию
|
||||
3. `/cf-validate` проверяет корректность XML (структура, enum-значения, ссылки, каталоги)
|
||||
4. `/cf-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## cf-info — режимы вывода
|
||||
|
||||
### brief — одна строка
|
||||
|
||||
```
|
||||
Конфигурация: БухгалтерияПредприятия — "Бухгалтерия предприятия" v3.0.181.31 | 2847 объектов | Version8_3_24
|
||||
```
|
||||
|
||||
### overview (по умолчанию) — заголовок + ключевые свойства + счётчики
|
||||
|
||||
```
|
||||
Конфигурация: ТестКонфигурация — "Тестовая конфигурация"
|
||||
Version: 2.0.0.1
|
||||
Vendor: TestCompany
|
||||
Compatibility: Version8_3_24
|
||||
DefaultLanguage: Language.Русский
|
||||
|
||||
Объекты (4 шт.):
|
||||
Language 1
|
||||
Role 1
|
||||
Catalog 1
|
||||
Document 1
|
||||
```
|
||||
|
||||
### full — все свойства + полный список объектов
|
||||
|
||||
Выводит все свойства по категориям (скалярные, enum, ref), полный список ChildObjects поимённо, DefaultRoles и мобильные функциональности.
|
||||
|
||||
## cf-edit — операции
|
||||
|
||||
### Свойства
|
||||
|
||||
```powershell
|
||||
# Скалярные и enum
|
||||
-Operation modify-property -Value "Version=2.0.0.1 ;; Vendor=Фирма 1С ;; CompatibilityMode=Version8_3_27"
|
||||
|
||||
# Многоязычные (LocalString)
|
||||
-Operation modify-property -Value "Synonym=Моя конфигурация ;; Copyright=ООО Фирма"
|
||||
|
||||
# Ссылка
|
||||
-Operation modify-property -Value "DefaultLanguage=Language.Русский"
|
||||
```
|
||||
|
||||
Поддерживаемые свойства:
|
||||
|
||||
| Категория | Свойства |
|
||||
|-----------|----------|
|
||||
| Скалярные | `Name`, `Version`, `Vendor`, `Comment`, `NamePrefix`, `UpdateCatalogAddress` |
|
||||
| LocalString | `Synonym`, `BriefInformation`, `DetailedInformation`, `Copyright`, `VendorInformationAddress`, `ConfigurationInformationAddress` |
|
||||
| Enum | `CompatibilityMode`, `ConfigurationExtensionCompatibilityMode`, `DefaultRunMode`, `ScriptVariant`, `DataLockControlMode`, `ObjectAutonumerationMode`, `ModalityUseMode`, `SynchronousPlatformExtensionAndAddInCallUseMode`, `InterfaceCompatibilityMode`, `DatabaseTablespacesUseMode`, `MainClientApplicationWindowMode` |
|
||||
| Ref | `DefaultLanguage` |
|
||||
|
||||
### Состав объектов (ChildObjects)
|
||||
|
||||
```powershell
|
||||
# Добавить (вставляется в каноническую позицию — по типу, затем по алфавиту)
|
||||
-Operation add-childObject -Value "Catalog.Товары ;; Document.Заказ ;; Enum.ВидыОплат"
|
||||
|
||||
# Удалить
|
||||
-Operation remove-childObject -Value "Catalog.Устаревший"
|
||||
```
|
||||
|
||||
44 типа объектов поддерживаются в каноническом порядке: Language, Subsystem, StyleItem, CommonPicture, ... IntegrationService.
|
||||
|
||||
### Роли по умолчанию (DefaultRoles)
|
||||
|
||||
```powershell
|
||||
# Добавить
|
||||
-Operation add-defaultRole -Value "ПолныеПрава"
|
||||
|
||||
# Удалить
|
||||
-Operation remove-defaultRole -Value "ПолныеПрава"
|
||||
|
||||
# Заменить список целиком
|
||||
-Operation set-defaultRoles -Value "ПолныеПрава ;; Администратор"
|
||||
```
|
||||
|
||||
### JSON mode — комбинированные операции
|
||||
|
||||
```json
|
||||
[
|
||||
{ "operation": "modify-property", "value": "Version=2.0.0.1 ;; Vendor=Test" },
|
||||
{ "operation": "add-childObject", "value": "Catalog.Товары ;; Document.Заказ" },
|
||||
{ "operation": "add-defaultRole", "value": "ПолныеПрава" }
|
||||
]
|
||||
```
|
||||
|
||||
## cf-validate — проверки
|
||||
|
||||
| # | Проверка | Уровень |
|
||||
|---|----------|---------|
|
||||
| 1 | XML well-formedness, MetaDataObject/Configuration, version | ERROR |
|
||||
| 2 | InternalInfo: 7 ContainedObject, валидные ClassId | ERROR |
|
||||
| 3 | Properties: Name, Synonym, DefaultLanguage, DefaultRunMode | ERROR/WARN |
|
||||
| 4 | Enum-значения (11 свойств) | ERROR |
|
||||
| 5 | ChildObjects: валидные типы, нет дубликатов, порядок | ERROR/WARN |
|
||||
| 6 | DefaultLanguage ссылается на существующий Language | ERROR |
|
||||
| 7 | Файлы языков `Languages/<name>.xml` существуют | WARN |
|
||||
| 8 | Каталоги объектов из ChildObjects существуют | WARN |
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Обзор существующей конфигурации
|
||||
|
||||
```
|
||||
> Покажи структуру конфигурации C:\WS\cfsrc\acc_8.3.24
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-info` и покажет: имя, синоним, версию, поставщика, количество объектов по типам.
|
||||
|
||||
### Создание новой конфигурации
|
||||
|
||||
```
|
||||
> Создай пустую конфигурацию МойПроект, версия 1.0.0.1, поставщик "ООО Ромашка"
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-init` → `/cf-edit` (Version, Vendor) → `/cf-validate` → `/cf-info`.
|
||||
|
||||
### Добавление объектов в конфигурацию
|
||||
|
||||
```
|
||||
> Добавь в конфигурацию src/ справочник Контрагенты, документ ЗаказКлиента и перечисление ВидыОплат
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-edit` с `add-childObject`, объекты встанут в каноническом порядке.
|
||||
|
||||
### Проверка конфигурации после изменений
|
||||
|
||||
```
|
||||
> Проверь корректность конфигурации src/
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-validate` и покажет ошибки и предупреждения.
|
||||
|
||||
## Структура корневых файлов
|
||||
|
||||
```
|
||||
<OutputDir>/
|
||||
├── Configuration.xml # Свойства и состав конфигурации
|
||||
├── ConfigDumpInfo.xml # Служебный (версии объектов)
|
||||
├── Ext/ # Модули конфигурации
|
||||
│ ├── ManagedApplicationModule.bsl
|
||||
│ ├── SessionModule.bsl
|
||||
│ └── ...
|
||||
└── Languages/
|
||||
└── Русский.xml # Язык конфигурации
|
||||
```
|
||||
|
||||
## Связь с другими навыками
|
||||
|
||||
- `/meta-compile` — при создании объекта автоматически регистрирует его в `Configuration.xml` (вызывает логику `add-childObject`)
|
||||
- `/subsystem-edit` — при добавлении объекта в подсистему объект уже должен быть в ChildObjects
|
||||
- `/cf-edit` + `/meta-compile` — типичная связка: сначала добавить объект в конфигурацию, затем создать его исходники
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-configuration-spec.md](1c-configuration-spec.md) — XML-формат Configuration.xml, ConfigDumpInfo.xml, Languages/, свойства, 44 типа ChildObjects
|
||||
# Корневые файлы конфигурации
|
||||
|
||||
Навыки группы `/cf-*` позволяют создавать, анализировать, редактировать и проверять корневые файлы конфигурации 1С — `Configuration.xml`, `ConfigDumpInfo.xml`, `Languages/`.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/cf-info` | `<ConfigPath> [-Mode overview\|brief\|full]` | Анализ конфигурации: свойства, состав, счётчики объектов (3 режима) |
|
||||
| `/cf-init` | `<Name> [-Synonym] [-OutputDir] [-Version] [-Vendor]` | Создание пустой конфигурации (scaffold XML-исходников) |
|
||||
| `/cf-validate` | `<ConfigPath> [-MaxErrors 30]` | Валидация структурной корректности (8 проверок) |
|
||||
| `/cf-edit` | `<ConfigPath> -Operation <op> -Value "<val>"` | Редактирование свойств, состава ChildObjects, ролей по умолчанию (6 операций) |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание (текст) → /cf-init → XML-исходники → /cf-validate
|
||||
↕ /cf-edit → /cf-info
|
||||
```
|
||||
|
||||
1. `/cf-init` создаёт scaffold пустой конфигурации (Configuration.xml, ConfigDumpInfo.xml, Languages/)
|
||||
2. `/cf-edit` вносит изменения: свойства, объекты в ChildObjects, роли по умолчанию
|
||||
3. `/cf-validate` проверяет корректность XML (структура, enum-значения, ссылки, каталоги)
|
||||
4. `/cf-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## cf-info — режимы вывода
|
||||
|
||||
### brief — одна строка
|
||||
|
||||
```
|
||||
Конфигурация: БухгалтерияПредприятия — "Бухгалтерия предприятия" v3.0.181.31 | 2847 объектов | Version8_3_24
|
||||
```
|
||||
|
||||
### overview (по умолчанию) — заголовок + ключевые свойства + счётчики
|
||||
|
||||
```
|
||||
Конфигурация: ТестКонфигурация — "Тестовая конфигурация"
|
||||
Version: 2.0.0.1
|
||||
Vendor: TestCompany
|
||||
Compatibility: Version8_3_24
|
||||
DefaultLanguage: Language.Русский
|
||||
|
||||
Объекты (4 шт.):
|
||||
Language 1
|
||||
Role 1
|
||||
Catalog 1
|
||||
Document 1
|
||||
```
|
||||
|
||||
### full — все свойства + полный список объектов
|
||||
|
||||
Выводит все свойства по категориям (скалярные, enum, ref), полный список ChildObjects поимённо, DefaultRoles и мобильные функциональности.
|
||||
|
||||
## cf-edit — операции
|
||||
|
||||
### Свойства
|
||||
|
||||
```powershell
|
||||
# Скалярные и enum
|
||||
-Operation modify-property -Value "Version=2.0.0.1 ;; Vendor=Фирма 1С ;; CompatibilityMode=Version8_3_27"
|
||||
|
||||
# Многоязычные (LocalString)
|
||||
-Operation modify-property -Value "Synonym=Моя конфигурация ;; Copyright=ООО Фирма"
|
||||
|
||||
# Ссылка
|
||||
-Operation modify-property -Value "DefaultLanguage=Language.Русский"
|
||||
```
|
||||
|
||||
Поддерживаемые свойства:
|
||||
|
||||
| Категория | Свойства |
|
||||
|-----------|----------|
|
||||
| Скалярные | `Name`, `Version`, `Vendor`, `Comment`, `NamePrefix`, `UpdateCatalogAddress` |
|
||||
| LocalString | `Synonym`, `BriefInformation`, `DetailedInformation`, `Copyright`, `VendorInformationAddress`, `ConfigurationInformationAddress` |
|
||||
| Enum | `CompatibilityMode`, `ConfigurationExtensionCompatibilityMode`, `DefaultRunMode`, `ScriptVariant`, `DataLockControlMode`, `ObjectAutonumerationMode`, `ModalityUseMode`, `SynchronousPlatformExtensionAndAddInCallUseMode`, `InterfaceCompatibilityMode`, `DatabaseTablespacesUseMode`, `MainClientApplicationWindowMode` |
|
||||
| Ref | `DefaultLanguage` |
|
||||
|
||||
### Состав объектов (ChildObjects)
|
||||
|
||||
```powershell
|
||||
# Добавить (вставляется в каноническую позицию — по типу, затем по алфавиту)
|
||||
-Operation add-childObject -Value "Catalog.Товары ;; Document.Заказ ;; Enum.ВидыОплат"
|
||||
|
||||
# Удалить
|
||||
-Operation remove-childObject -Value "Catalog.Устаревший"
|
||||
```
|
||||
|
||||
44 типа объектов поддерживаются в каноническом порядке: Language, Subsystem, StyleItem, CommonPicture, ... IntegrationService.
|
||||
|
||||
### Роли по умолчанию (DefaultRoles)
|
||||
|
||||
```powershell
|
||||
# Добавить
|
||||
-Operation add-defaultRole -Value "ПолныеПрава"
|
||||
|
||||
# Удалить
|
||||
-Operation remove-defaultRole -Value "ПолныеПрава"
|
||||
|
||||
# Заменить список целиком
|
||||
-Operation set-defaultRoles -Value "ПолныеПрава ;; Администратор"
|
||||
```
|
||||
|
||||
### JSON mode — комбинированные операции
|
||||
|
||||
```json
|
||||
[
|
||||
{ "operation": "modify-property", "value": "Version=2.0.0.1 ;; Vendor=Test" },
|
||||
{ "operation": "add-childObject", "value": "Catalog.Товары ;; Document.Заказ" },
|
||||
{ "operation": "add-defaultRole", "value": "ПолныеПрава" }
|
||||
]
|
||||
```
|
||||
|
||||
## cf-validate — проверки
|
||||
|
||||
| # | Проверка | Уровень |
|
||||
|---|----------|---------|
|
||||
| 1 | XML well-formedness, MetaDataObject/Configuration, version | ERROR |
|
||||
| 2 | InternalInfo: 7 ContainedObject, валидные ClassId | ERROR |
|
||||
| 3 | Properties: Name, Synonym, DefaultLanguage, DefaultRunMode | ERROR/WARN |
|
||||
| 4 | Enum-значения (11 свойств) | ERROR |
|
||||
| 5 | ChildObjects: валидные типы, нет дубликатов, порядок | ERROR/WARN |
|
||||
| 6 | DefaultLanguage ссылается на существующий Language | ERROR |
|
||||
| 7 | Файлы языков `Languages/<name>.xml` существуют | WARN |
|
||||
| 8 | Каталоги объектов из ChildObjects существуют | WARN |
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Обзор существующей конфигурации
|
||||
|
||||
```
|
||||
> Покажи структуру конфигурации C:\WS\cfsrc\acc_8.3.24
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-info` и покажет: имя, синоним, версию, поставщика, количество объектов по типам.
|
||||
|
||||
### Создание новой конфигурации
|
||||
|
||||
```
|
||||
> Создай пустую конфигурацию МойПроект, версия 1.0.0.1, поставщик "ООО Ромашка"
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-init` → `/cf-edit` (Version, Vendor) → `/cf-validate` → `/cf-info`.
|
||||
|
||||
### Добавление объектов в конфигурацию
|
||||
|
||||
```
|
||||
> Добавь в конфигурацию src/ справочник Контрагенты, документ ЗаказКлиента и перечисление ВидыОплат
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-edit` с `add-childObject`, объекты встанут в каноническом порядке.
|
||||
|
||||
### Проверка конфигурации после изменений
|
||||
|
||||
```
|
||||
> Проверь корректность конфигурации src/
|
||||
```
|
||||
|
||||
Claude вызовет `/cf-validate` и покажет ошибки и предупреждения.
|
||||
|
||||
## Структура корневых файлов
|
||||
|
||||
```
|
||||
<OutputDir>/
|
||||
├── Configuration.xml # Свойства и состав конфигурации
|
||||
├── ConfigDumpInfo.xml # Служебный (версии объектов)
|
||||
├── Ext/ # Модули конфигурации
|
||||
│ ├── ManagedApplicationModule.bsl
|
||||
│ ├── SessionModule.bsl
|
||||
│ └── ...
|
||||
└── Languages/
|
||||
└── Русский.xml # Язык конфигурации
|
||||
```
|
||||
|
||||
## Связь с другими навыками
|
||||
|
||||
- `/meta-compile` — при создании объекта автоматически регистрирует его в `Configuration.xml` (вызывает логику `add-childObject`)
|
||||
- `/subsystem-edit` — при добавлении объекта в подсистему объект уже должен быть в ChildObjects
|
||||
- `/cf-edit` + `/meta-compile` — типичная связка: сначала добавить объект в конфигурацию, затем создать его исходники
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-configuration-spec.md](1c-configuration-spec.md) — XML-формат Configuration.xml, ConfigDumpInfo.xml, Languages/, свойства, 44 типа ChildObjects
|
||||
|
||||
+202
-202
@@ -1,202 +1,202 @@
|
||||
# Расширения конфигурации (CFE)
|
||||
|
||||
Навыки группы `/cfe-*` позволяют создавать, заимствовать объекты, перехватывать методы, проверять и анализировать расширения конфигурации 1С.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/cfe-init` | `<Name> [-Purpose Patch\|Customization\|AddOn] [-CompatibilityMode]` | Создание расширения (scaffold XML-исходников) |
|
||||
| `/cfe-borrow` | `-ExtensionPath <path> -ConfigPath <path> -Object "Type.Name" [-BorrowMainAttribute]` | Заимствование объектов из конфигурации |
|
||||
| `/cfe-patch-method` | `-ExtensionPath <path> -ModulePath "Type.Name.Module" -MethodName "X" -InterceptorType Before` | Генерация перехватчика метода |
|
||||
| `/cfe-validate` | `<ExtensionPath> [-MaxErrors 30]` | Валидация структурной корректности (9 проверок) |
|
||||
| `/cfe-diff` | `-ExtensionPath <path> -ConfigPath <path> [-Mode A\|B]` | Анализ расширения и проверка переноса |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
cf-info (версия, совместимость)
|
||||
↓
|
||||
/cfe-init → scaffold расширения
|
||||
↓
|
||||
/cfe-borrow → заимствование объектов из конфигурации
|
||||
↓
|
||||
/cfe-patch-method → перехват методов
|
||||
↓
|
||||
/cfe-validate → проверка корректности
|
||||
↓
|
||||
/cfe-diff Mode A → обзор изменений
|
||||
```
|
||||
|
||||
## Типичные сценарии
|
||||
|
||||
### Создание расширения для исправления бага
|
||||
|
||||
```
|
||||
> Создай расширение для исправления бага в справочнике Контрагенты,
|
||||
конфигурация ERP в C:\cfsrc\erp
|
||||
```
|
||||
|
||||
Claude выполнит:
|
||||
1. `/cf-info C:\cfsrc\erp -Mode brief` — получить версию и режим совместимости
|
||||
2. `/cfe-init` — создать расширение с нужным `CompatibilityMode`
|
||||
3. `/cfe-borrow` — заимствовать `Catalog.Контрагенты`
|
||||
4. `/cfe-patch-method` — создать перехватчик нужного метода
|
||||
5. `/cfe-validate` — проверить результат
|
||||
|
||||
### Добавление реквизита в объект и вывод на форму
|
||||
|
||||
```
|
||||
> Добавь реквизит "ОсновнойПоставщик" (тип СправочникСсылка.Партнеры)
|
||||
в справочник Номенклатура и выведи на форму элемента.
|
||||
Конфигурация ERP в C:\cfsrc\erp
|
||||
```
|
||||
|
||||
Claude выполнит:
|
||||
1. `/cfe-init` — создать расширение
|
||||
2. `/cfe-borrow -Object "Catalog.Номенклатура.Form.ФормаЭлемента" -BorrowMainAttribute` — заимствовать форму с реквизитами объекта
|
||||
3. `/meta-edit` — добавить новый реквизит `Расш1_ОсновнойПоставщик` в Номенклатура
|
||||
4. `/form-edit` — вывести реквизит на форму
|
||||
5. `/cfe-validate` — проверить результат
|
||||
|
||||
### Анализ существующего расширения
|
||||
|
||||
```
|
||||
> Покажи что изменено в расширении src/
|
||||
```
|
||||
|
||||
Claude вызовет `/cfe-diff -Mode A` и покажет: заимствованные объекты, перехватчики, собственные объекты.
|
||||
|
||||
### Проверка переноса изменений
|
||||
|
||||
```
|
||||
> Проверь, все ли изменения из расширения перенесены в конфигурацию
|
||||
```
|
||||
|
||||
Claude вызовет `/cfe-diff -Mode B` — найдёт блоки `#Вставка` и проверит их наличие в конфигурации.
|
||||
|
||||
## cfe-init — создание расширения
|
||||
|
||||
Параметры:
|
||||
|
||||
| Параметр | Описание | По умолчанию |
|
||||
|----------|----------|--------------|
|
||||
| `Name` | Имя расширения (обязат.) | — |
|
||||
| `Synonym` | Синоним | = Name |
|
||||
| `NamePrefix` | Префикс собственных объектов | = Name + "_" |
|
||||
| `OutputDir` | Каталог | `src` |
|
||||
| `Purpose` | Назначение | `Customization` |
|
||||
| `Version` | Версия | — |
|
||||
| `Vendor` | Поставщик | — |
|
||||
| `CompatibilityMode` | Режим совместимости | `Version8_3_24` |
|
||||
| `NoRole` | Без основной роли | false |
|
||||
|
||||
Создаёт:
|
||||
```
|
||||
<OutputDir>/
|
||||
├── Configuration.xml # Свойства расширения
|
||||
├── Languages/
|
||||
│ └── Русский.xml # Язык (Adopted)
|
||||
└── Roles/ # Если не -NoRole
|
||||
└── <Prefix>ОсновнаяРоль.xml
|
||||
```
|
||||
|
||||
Назначение расширения (`Purpose`):
|
||||
- `Patch` — исправление ошибок (минимальные изменения, только перехватчики)
|
||||
- `Customization` — доработка (реквизиты, формы, модули)
|
||||
- `AddOn` — дополнение (полноценный функционал)
|
||||
|
||||
## cfe-borrow — заимствование объектов
|
||||
|
||||
Заимствует объекты из основной конфигурации в расширение. Создаёт минимальные XML-файлы с `ObjectBelonging=Adopted` и `ExtendedConfigurationObject`.
|
||||
|
||||
Формат `-Object`:
|
||||
- `Catalog.Контрагенты` — справочник
|
||||
- `CommonModule.РаботаСФайлами` — общий модуль
|
||||
- `Enum.ВидыОплат` — перечисление
|
||||
- `Document.Заказ ;; Catalog.Товары` — несколько объектов через `;;`
|
||||
|
||||
Поддерживаемые типы: Catalog, Document, Enum, CommonModule, Report, DataProcessor, ExchangePlan, InformationRegister, AccumulationRegister, AccountingRegister, CalculationRegister, ChartOfAccounts, ChartOfCharacteristicTypes, ChartOfCalculationTypes, BusinessProcess, Task, и другие (44 типа).
|
||||
|
||||
### Заимствование формы с реквизитами объекта (-BorrowMainAttribute)
|
||||
|
||||
При добавлении нового реквизита на заимствованную форму нужна опция `-BorrowMainAttribute`:
|
||||
- Без неё форма заимствуется "пустой" — только визуальные элементы, без привязки к данным
|
||||
- С ней — форма сохраняет `DataPath` привязки к реквизитам объекта (`Объект.XXX`)
|
||||
|
||||
Два режима:
|
||||
- `Form` (по умолчанию) — заимствует только реквизиты, выведенные на форму
|
||||
- `All` — заимствует все реквизиты объекта (включая не выведенные на форму)
|
||||
|
||||
Каскадно заимствует зависимые объекты по типам реквизитов (справочники, перечисления, определяемые типы) как оболочки. Если зависимый объект уже заимствован с содержимым — не перезаписывает его.
|
||||
|
||||
## cfe-patch-method — перехват методов
|
||||
|
||||
Генерирует `.bsl` файл с декоратором перехвата для заимствованного объекта.
|
||||
|
||||
Параметры:
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `ModulePath` | `Catalog.X.ObjectModule`, `CommonModule.Y`, `Catalog.X.Form.Z` |
|
||||
| `MethodName` | Имя перехватываемого метода |
|
||||
| `InterceptorType` | `Before` / `After` / `ModificationAndControl` |
|
||||
| `Context` | `НаСервере` / `НаКлиенте` / `НаСервереБезКонтекста` |
|
||||
| `IsFunction` | Добавить `Возврат` |
|
||||
|
||||
Типы перехватчиков:
|
||||
|
||||
| Тип | Декоратор | Когда использовать |
|
||||
|-----|-----------|-------------------|
|
||||
| `Before` | `&Перед` | Выполнить код до вызова оригинального метода |
|
||||
| `After` | `&После` | Выполнить код после вызова оригинального метода |
|
||||
| `ModificationAndControl` | `&ИзменениеИКонтроль` | Полная замена тела метода с маркерами `#Вставка`/`#Удаление` |
|
||||
|
||||
Пример генерируемого кода (`Before`):
|
||||
```bsl
|
||||
&НаСервере
|
||||
&Перед("ПриЗаписи")
|
||||
Процедура Расш1_ПриЗаписи()
|
||||
// TODO: код перед вызовом оригинального метода
|
||||
КонецПроцедуры
|
||||
```
|
||||
|
||||
## cfe-validate — проверки
|
||||
|
||||
| # | Проверка | Уровень |
|
||||
|---|----------|---------|
|
||||
| 1 | XML well-formedness, MetaDataObject/Configuration, version | ERROR |
|
||||
| 2 | InternalInfo: 7 ContainedObject, валидные ClassId | ERROR |
|
||||
| 3 | Extension properties: ObjectBelonging=Adopted, Name, Purpose, NamePrefix, KeepMapping | ERROR |
|
||||
| 4 | Enum-значения (4 свойства) | ERROR |
|
||||
| 5 | ChildObjects: валидные типы, нет дубликатов, порядок | ERROR/WARN |
|
||||
| 6 | DefaultLanguage ссылается на существующий Language | ERROR |
|
||||
| 7 | Файлы языков существуют | WARN |
|
||||
| 8 | Каталоги объектов существуют | WARN |
|
||||
| 9 | Заимствованные объекты: ObjectBelonging=Adopted, ExtendedConfigurationObject UUID | ERROR/WARN |
|
||||
|
||||
## cfe-diff — режимы
|
||||
|
||||
### Mode A — обзор расширения
|
||||
|
||||
Для каждого объекта показывает:
|
||||
- `[BORROWED]` — заимствованный: перехватчики, собственные реквизиты/формы
|
||||
- `[OWN]` — собственный: количество реквизитов, ТЧ, форм
|
||||
|
||||
### Mode B — проверка переноса
|
||||
|
||||
Для каждого `&ИзменениеИКонтроль` проверяет, перенесены ли блоки `#Вставка` в конфигурацию:
|
||||
- `[TRANSFERRED]` — код найден в конфигурации
|
||||
- `[NOT_TRANSFERRED]` — код не найден
|
||||
- `[NEEDS_REVIEW]` — нет блоков `#Вставка` или модуль конфигурации не найден
|
||||
|
||||
## Связь с другими навыками
|
||||
|
||||
- `/cf-info` — получение версии и совместимости конфигурации перед `cfe-init`
|
||||
- `/meta-compile` — создание собственных объектов расширения (реквизиты, ТЧ)
|
||||
- `/form-compile`, `/form-edit` — создание и модификация форм расширения
|
||||
- `/cfe-validate` — всегда проверяйте расширение после изменений
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-extension-spec.md](1c-extension-spec.md) — XML-формат выгрузки расширений конфигурации (CFE)
|
||||
# Расширения конфигурации (CFE)
|
||||
|
||||
Навыки группы `/cfe-*` позволяют создавать, заимствовать объекты, перехватывать методы, проверять и анализировать расширения конфигурации 1С.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/cfe-init` | `<Name> [-Purpose Patch\|Customization\|AddOn] [-CompatibilityMode]` | Создание расширения (scaffold XML-исходников) |
|
||||
| `/cfe-borrow` | `-ExtensionPath <path> -ConfigPath <path> -Object "Type.Name" [-BorrowMainAttribute]` | Заимствование объектов из конфигурации |
|
||||
| `/cfe-patch-method` | `-ExtensionPath <path> -ModulePath "Type.Name.Module" -MethodName "X" -InterceptorType Before` | Генерация перехватчика метода |
|
||||
| `/cfe-validate` | `<ExtensionPath> [-MaxErrors 30]` | Валидация структурной корректности (9 проверок) |
|
||||
| `/cfe-diff` | `-ExtensionPath <path> -ConfigPath <path> [-Mode A\|B]` | Анализ расширения и проверка переноса |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
cf-info (версия, совместимость)
|
||||
↓
|
||||
/cfe-init → scaffold расширения
|
||||
↓
|
||||
/cfe-borrow → заимствование объектов из конфигурации
|
||||
↓
|
||||
/cfe-patch-method → перехват методов
|
||||
↓
|
||||
/cfe-validate → проверка корректности
|
||||
↓
|
||||
/cfe-diff Mode A → обзор изменений
|
||||
```
|
||||
|
||||
## Типичные сценарии
|
||||
|
||||
### Создание расширения для исправления бага
|
||||
|
||||
```
|
||||
> Создай расширение для исправления бага в справочнике Контрагенты,
|
||||
конфигурация ERP в C:\cfsrc\erp
|
||||
```
|
||||
|
||||
Claude выполнит:
|
||||
1. `/cf-info C:\cfsrc\erp -Mode brief` — получить версию и режим совместимости
|
||||
2. `/cfe-init` — создать расширение с нужным `CompatibilityMode`
|
||||
3. `/cfe-borrow` — заимствовать `Catalog.Контрагенты`
|
||||
4. `/cfe-patch-method` — создать перехватчик нужного метода
|
||||
5. `/cfe-validate` — проверить результат
|
||||
|
||||
### Добавление реквизита в объект и вывод на форму
|
||||
|
||||
```
|
||||
> Добавь реквизит "ОсновнойПоставщик" (тип СправочникСсылка.Партнеры)
|
||||
в справочник Номенклатура и выведи на форму элемента.
|
||||
Конфигурация ERP в C:\cfsrc\erp
|
||||
```
|
||||
|
||||
Claude выполнит:
|
||||
1. `/cfe-init` — создать расширение
|
||||
2. `/cfe-borrow -Object "Catalog.Номенклатура.Form.ФормаЭлемента" -BorrowMainAttribute` — заимствовать форму с реквизитами объекта
|
||||
3. `/meta-edit` — добавить новый реквизит `Расш1_ОсновнойПоставщик` в Номенклатура
|
||||
4. `/form-edit` — вывести реквизит на форму
|
||||
5. `/cfe-validate` — проверить результат
|
||||
|
||||
### Анализ существующего расширения
|
||||
|
||||
```
|
||||
> Покажи что изменено в расширении src/
|
||||
```
|
||||
|
||||
Claude вызовет `/cfe-diff -Mode A` и покажет: заимствованные объекты, перехватчики, собственные объекты.
|
||||
|
||||
### Проверка переноса изменений
|
||||
|
||||
```
|
||||
> Проверь, все ли изменения из расширения перенесены в конфигурацию
|
||||
```
|
||||
|
||||
Claude вызовет `/cfe-diff -Mode B` — найдёт блоки `#Вставка` и проверит их наличие в конфигурации.
|
||||
|
||||
## cfe-init — создание расширения
|
||||
|
||||
Параметры:
|
||||
|
||||
| Параметр | Описание | По умолчанию |
|
||||
|----------|----------|--------------|
|
||||
| `Name` | Имя расширения (обязат.) | — |
|
||||
| `Synonym` | Синоним | = Name |
|
||||
| `NamePrefix` | Префикс собственных объектов | = Name + "_" |
|
||||
| `OutputDir` | Каталог | `src` |
|
||||
| `Purpose` | Назначение | `Customization` |
|
||||
| `Version` | Версия | — |
|
||||
| `Vendor` | Поставщик | — |
|
||||
| `CompatibilityMode` | Режим совместимости | `Version8_3_24` |
|
||||
| `NoRole` | Без основной роли | false |
|
||||
|
||||
Создаёт:
|
||||
```
|
||||
<OutputDir>/
|
||||
├── Configuration.xml # Свойства расширения
|
||||
├── Languages/
|
||||
│ └── Русский.xml # Язык (Adopted)
|
||||
└── Roles/ # Если не -NoRole
|
||||
└── <Prefix>ОсновнаяРоль.xml
|
||||
```
|
||||
|
||||
Назначение расширения (`Purpose`):
|
||||
- `Patch` — исправление ошибок (минимальные изменения, только перехватчики)
|
||||
- `Customization` — доработка (реквизиты, формы, модули)
|
||||
- `AddOn` — дополнение (полноценный функционал)
|
||||
|
||||
## cfe-borrow — заимствование объектов
|
||||
|
||||
Заимствует объекты из основной конфигурации в расширение. Создаёт минимальные XML-файлы с `ObjectBelonging=Adopted` и `ExtendedConfigurationObject`.
|
||||
|
||||
Формат `-Object`:
|
||||
- `Catalog.Контрагенты` — справочник
|
||||
- `CommonModule.РаботаСФайлами` — общий модуль
|
||||
- `Enum.ВидыОплат` — перечисление
|
||||
- `Document.Заказ ;; Catalog.Товары` — несколько объектов через `;;`
|
||||
|
||||
Поддерживаемые типы: Catalog, Document, Enum, CommonModule, Report, DataProcessor, ExchangePlan, InformationRegister, AccumulationRegister, AccountingRegister, CalculationRegister, ChartOfAccounts, ChartOfCharacteristicTypes, ChartOfCalculationTypes, BusinessProcess, Task, и другие (44 типа).
|
||||
|
||||
### Заимствование формы с реквизитами объекта (-BorrowMainAttribute)
|
||||
|
||||
При добавлении нового реквизита на заимствованную форму нужна опция `-BorrowMainAttribute`:
|
||||
- Без неё форма заимствуется "пустой" — только визуальные элементы, без привязки к данным
|
||||
- С ней — форма сохраняет `DataPath` привязки к реквизитам объекта (`Объект.XXX`)
|
||||
|
||||
Два режима:
|
||||
- `Form` (по умолчанию) — заимствует только реквизиты, выведенные на форму
|
||||
- `All` — заимствует все реквизиты объекта (включая не выведенные на форму)
|
||||
|
||||
Каскадно заимствует зависимые объекты по типам реквизитов (справочники, перечисления, определяемые типы) как оболочки. Если зависимый объект уже заимствован с содержимым — не перезаписывает его.
|
||||
|
||||
## cfe-patch-method — перехват методов
|
||||
|
||||
Генерирует `.bsl` файл с декоратором перехвата для заимствованного объекта.
|
||||
|
||||
Параметры:
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `ModulePath` | `Catalog.X.ObjectModule`, `CommonModule.Y`, `Catalog.X.Form.Z` |
|
||||
| `MethodName` | Имя перехватываемого метода |
|
||||
| `InterceptorType` | `Before` / `After` / `ModificationAndControl` |
|
||||
| `Context` | `НаСервере` / `НаКлиенте` / `НаСервереБезКонтекста` |
|
||||
| `IsFunction` | Добавить `Возврат` |
|
||||
|
||||
Типы перехватчиков:
|
||||
|
||||
| Тип | Декоратор | Когда использовать |
|
||||
|-----|-----------|-------------------|
|
||||
| `Before` | `&Перед` | Выполнить код до вызова оригинального метода |
|
||||
| `After` | `&После` | Выполнить код после вызова оригинального метода |
|
||||
| `ModificationAndControl` | `&ИзменениеИКонтроль` | Полная замена тела метода с маркерами `#Вставка`/`#Удаление` |
|
||||
|
||||
Пример генерируемого кода (`Before`):
|
||||
```bsl
|
||||
&НаСервере
|
||||
&Перед("ПриЗаписи")
|
||||
Процедура Расш1_ПриЗаписи()
|
||||
// TODO: код перед вызовом оригинального метода
|
||||
КонецПроцедуры
|
||||
```
|
||||
|
||||
## cfe-validate — проверки
|
||||
|
||||
| # | Проверка | Уровень |
|
||||
|---|----------|---------|
|
||||
| 1 | XML well-formedness, MetaDataObject/Configuration, version | ERROR |
|
||||
| 2 | InternalInfo: 7 ContainedObject, валидные ClassId | ERROR |
|
||||
| 3 | Extension properties: ObjectBelonging=Adopted, Name, Purpose, NamePrefix, KeepMapping | ERROR |
|
||||
| 4 | Enum-значения (4 свойства) | ERROR |
|
||||
| 5 | ChildObjects: валидные типы, нет дубликатов, порядок | ERROR/WARN |
|
||||
| 6 | DefaultLanguage ссылается на существующий Language | ERROR |
|
||||
| 7 | Файлы языков существуют | WARN |
|
||||
| 8 | Каталоги объектов существуют | WARN |
|
||||
| 9 | Заимствованные объекты: ObjectBelonging=Adopted, ExtendedConfigurationObject UUID | ERROR/WARN |
|
||||
|
||||
## cfe-diff — режимы
|
||||
|
||||
### Mode A — обзор расширения
|
||||
|
||||
Для каждого объекта показывает:
|
||||
- `[BORROWED]` — заимствованный: перехватчики, собственные реквизиты/формы
|
||||
- `[OWN]` — собственный: количество реквизитов, ТЧ, форм
|
||||
|
||||
### Mode B — проверка переноса
|
||||
|
||||
Для каждого `&ИзменениеИКонтроль` проверяет, перенесены ли блоки `#Вставка` в конфигурацию:
|
||||
- `[TRANSFERRED]` — код найден в конфигурации
|
||||
- `[NOT_TRANSFERRED]` — код не найден
|
||||
- `[NEEDS_REVIEW]` — нет блоков `#Вставка` или модуль конфигурации не найден
|
||||
|
||||
## Связь с другими навыками
|
||||
|
||||
- `/cf-info` — получение версии и совместимости конфигурации перед `cfe-init`
|
||||
- `/meta-compile` — создание собственных объектов расширения (реквизиты, ТЧ)
|
||||
- `/form-compile`, `/form-edit` — создание и модификация форм расширения
|
||||
- `/cfe-validate` — всегда проверяйте расширение после изменений
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-extension-spec.md](1c-extension-spec.md) — XML-формат выгрузки расширений конфигурации (CFE)
|
||||
|
||||
+128
-128
@@ -1,128 +1,128 @@
|
||||
# Базы данных 1С
|
||||
|
||||
Навыки группы `/db-*` позволяют управлять информационными базами 1С из Claude Code: создавать базы, загружать и выгружать конфигурации, обновлять БД, запускать предприятие, загружать изменения из Git.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Скрипт | Описание |
|
||||
|-------|:------:|----------|
|
||||
| `/db-list` | — | Управление реестром баз (.v8-project.json) |
|
||||
| `/db-create` | — | Создание информационной базы |
|
||||
| `/db-dump-cf` | — | Выгрузка конфигурации в CF-файл |
|
||||
| `/db-load-cf` | — | Загрузка конфигурации из CF-файла |
|
||||
| `/db-dump-xml` | `.ps1` | Выгрузка конфигурации в XML-файлы (полная/инкрементальная/частичная) |
|
||||
| `/db-load-xml` | `.ps1` | Загрузка конфигурации из XML-файлов (полная/частичная) |
|
||||
| `/db-update` | — | Обновление конфигурации БД |
|
||||
| `/db-run` | — | Запуск 1С:Предприятие |
|
||||
| `/db-load-git` | `.ps1` | Загрузка изменений из Git в базу |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
.v8-project.json → /db-create → /db-load-cf или /db-load-xml → /db-update → /db-run
|
||||
↑
|
||||
/db-dump-xml ←→ правки в исходниках → /db-load-git → /db-update
|
||||
```
|
||||
|
||||
### Типичный цикл разработки
|
||||
|
||||
1. **Настройка** — `/db-list add` зарегистрировать базу в `.v8-project.json`
|
||||
2. **Создание** — `/db-create` создать базу (если нет)
|
||||
3. **Загрузка** — `/db-load-xml` или `/db-load-cf` загрузить конфигурацию
|
||||
4. **Обновление** — `/db-update` применить к БД
|
||||
5. **Работа** — редактирование XML-исходников
|
||||
6. **Синхронизация** — `/db-load-git` загрузить изменения из Git
|
||||
7. **Обновление** — `/db-update` применить
|
||||
8. **Запуск** — `/db-run` открыть предприятие
|
||||
|
||||
## Формат `.v8-project.json`
|
||||
|
||||
Полное описание формата — в [справочнике .v8-project.json](v8-project-guide.md).
|
||||
|
||||
### Разрешение базы
|
||||
|
||||
Все навыки `db-*` (а также `epf-build`, `epf-dump`, `erf-build`, `erf-dump`) используют единый алгоритм:
|
||||
|
||||
1. Если пользователь указал **параметры подключения** (путь, сервер) — используй напрямую
|
||||
2. Если указал **базу по имени** — ищи: `id` → `aliases` (с учётом морфологии) → `name` (нечёткое)
|
||||
3. Если **не указал** — сопоставь текущую ветку Git с `branches` (точно или по glob-паттерну)
|
||||
4. Fallback на `default`
|
||||
5. Если не найдено — спроси пользователя
|
||||
6. После выполнения: если использованная база не зарегистрирована — предложи добавить через `/db-list add`
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Создать базу и загрузить конфигурацию
|
||||
|
||||
```
|
||||
> Создай файловую базу C:\Bases\Test и загрузи в неё конфигурацию из C:\WS\cfsrc
|
||||
```
|
||||
|
||||
Claude вызовет `/db-create` → `/db-load-xml -Mode Full` → предложит `/db-update`.
|
||||
|
||||
### Загрузить изменения из Git
|
||||
|
||||
```
|
||||
> Загрузи мои последние правки в базу разработки
|
||||
```
|
||||
|
||||
Claude вызовет `/db-load-git dev -Source All` → предложит `/db-update`.
|
||||
|
||||
### Выгрузить конфигурацию
|
||||
|
||||
```
|
||||
> Выгрузи конфигурацию из тестовой базы в C:\WS\cfsrc
|
||||
```
|
||||
|
||||
Claude вызовет `/db-dump-xml test C:\WS\cfsrc -Mode Full`.
|
||||
|
||||
### Работа с расширениями
|
||||
|
||||
```
|
||||
> Выгрузи расширение МоёРасширение из базы dev в C:\WS\ext_src
|
||||
```
|
||||
|
||||
Claude вызовет `/db-dump-xml dev C:\WS\ext_src -Extension МоёРасширение`.
|
||||
|
||||
```
|
||||
> Загрузи расширение обратно в базу
|
||||
```
|
||||
|
||||
Claude вызовет `/db-load-xml C:\WS\ext_src dev -Extension МоёРасширение` → предложит `/db-update -Extension МоёРасширение`.
|
||||
|
||||
### Запустить предприятие
|
||||
|
||||
```
|
||||
> Запусти базу разработки
|
||||
```
|
||||
|
||||
Claude вызовет `/db-run dev`.
|
||||
|
||||
## Движок: 1cv8 или ibcmd
|
||||
|
||||
По умолчанию навыки группы работают через конфигуратор (`1cv8.exe`; путь к нему определяется
|
||||
автоматически по каталогу `v8path`) — менять это не нужно. При желании ту же операцию можно выполнить
|
||||
через автономный сервер `ibcmd`. Для этого навыку нужно передать путь к самому файлу `ibcmd.exe`
|
||||
(каталог `bin` всегда трактуется как `1cv8.exe`; отдельного поля-переключателя в `.v8-project.json` нет).
|
||||
Путь указывают одним из двух способов:
|
||||
|
||||
- **разово, в самой задаче** — назвать полный путь к `ibcmd.exe`:
|
||||
|
||||
```
|
||||
> Собери обработку, платформа C:\Program Files\1cv8\8.3.24.1691\bin\ibcmd.exe
|
||||
```
|
||||
- **в файле настроек** — прописать в `v8path` не каталог `bin`, а сам файл `...\bin\ibcmd.exe`
|
||||
(тогда через `ibcmd` пойдут все операции).
|
||||
|
||||
Через `ibcmd` работают: `db-create`, `db-load-xml`/`db-dump-xml` (в том числе по отдельным объектам
|
||||
и со всеми расширениями), `db-load-cf`/`db-dump-cf`, `db-load-dt`/`db-dump-dt`, `db-update`,
|
||||
`db-load-git`, `epf-build`/`epf-dump`, `erf-build`/`erf-dump`.
|
||||
|
||||
Ограничения:
|
||||
- только **файловые** базы (для серверных используйте конфигуратор);
|
||||
- если запрошен режим, который `ibcmd` не поддерживает (например, выгрузка в «плоском» формате),
|
||||
навык остановится с понятным сообщением и предложит конфигуратор.
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [build-spec.md](build-spec.md) — пакетный режим конфигуратора 1С (CREATEINFOBASE, DESIGNER, ENTERPRISE, параметры, коды возврата)
|
||||
# Базы данных 1С
|
||||
|
||||
Навыки группы `/db-*` позволяют управлять информационными базами 1С из Claude Code: создавать базы, загружать и выгружать конфигурации, обновлять БД, запускать предприятие, загружать изменения из Git.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Скрипт | Описание |
|
||||
|-------|:------:|----------|
|
||||
| `/db-list` | — | Управление реестром баз (.v8-project.json) |
|
||||
| `/db-create` | — | Создание информационной базы |
|
||||
| `/db-dump-cf` | — | Выгрузка конфигурации в CF-файл |
|
||||
| `/db-load-cf` | — | Загрузка конфигурации из CF-файла |
|
||||
| `/db-dump-xml` | `.ps1` | Выгрузка конфигурации в XML-файлы (полная/инкрементальная/частичная) |
|
||||
| `/db-load-xml` | `.ps1` | Загрузка конфигурации из XML-файлов (полная/частичная) |
|
||||
| `/db-update` | — | Обновление конфигурации БД |
|
||||
| `/db-run` | — | Запуск 1С:Предприятие |
|
||||
| `/db-load-git` | `.ps1` | Загрузка изменений из Git в базу |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
.v8-project.json → /db-create → /db-load-cf или /db-load-xml → /db-update → /db-run
|
||||
↑
|
||||
/db-dump-xml ←→ правки в исходниках → /db-load-git → /db-update
|
||||
```
|
||||
|
||||
### Типичный цикл разработки
|
||||
|
||||
1. **Настройка** — `/db-list add` зарегистрировать базу в `.v8-project.json`
|
||||
2. **Создание** — `/db-create` создать базу (если нет)
|
||||
3. **Загрузка** — `/db-load-xml` или `/db-load-cf` загрузить конфигурацию
|
||||
4. **Обновление** — `/db-update` применить к БД
|
||||
5. **Работа** — редактирование XML-исходников
|
||||
6. **Синхронизация** — `/db-load-git` загрузить изменения из Git
|
||||
7. **Обновление** — `/db-update` применить
|
||||
8. **Запуск** — `/db-run` открыть предприятие
|
||||
|
||||
## Формат `.v8-project.json`
|
||||
|
||||
Полное описание формата — в [справочнике .v8-project.json](v8-project-guide.md).
|
||||
|
||||
### Разрешение базы
|
||||
|
||||
Все навыки `db-*` (а также `epf-build`, `epf-dump`, `erf-build`, `erf-dump`) используют единый алгоритм:
|
||||
|
||||
1. Если пользователь указал **параметры подключения** (путь, сервер) — используй напрямую
|
||||
2. Если указал **базу по имени** — ищи: `id` → `aliases` (с учётом морфологии) → `name` (нечёткое)
|
||||
3. Если **не указал** — сопоставь текущую ветку Git с `branches` (точно или по glob-паттерну)
|
||||
4. Fallback на `default`
|
||||
5. Если не найдено — спроси пользователя
|
||||
6. После выполнения: если использованная база не зарегистрирована — предложи добавить через `/db-list add`
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Создать базу и загрузить конфигурацию
|
||||
|
||||
```
|
||||
> Создай файловую базу C:\Bases\Test и загрузи в неё конфигурацию из C:\WS\cfsrc
|
||||
```
|
||||
|
||||
Claude вызовет `/db-create` → `/db-load-xml -Mode Full` → предложит `/db-update`.
|
||||
|
||||
### Загрузить изменения из Git
|
||||
|
||||
```
|
||||
> Загрузи мои последние правки в базу разработки
|
||||
```
|
||||
|
||||
Claude вызовет `/db-load-git dev -Source All` → предложит `/db-update`.
|
||||
|
||||
### Выгрузить конфигурацию
|
||||
|
||||
```
|
||||
> Выгрузи конфигурацию из тестовой базы в C:\WS\cfsrc
|
||||
```
|
||||
|
||||
Claude вызовет `/db-dump-xml test C:\WS\cfsrc -Mode Full`.
|
||||
|
||||
### Работа с расширениями
|
||||
|
||||
```
|
||||
> Выгрузи расширение МоёРасширение из базы dev в C:\WS\ext_src
|
||||
```
|
||||
|
||||
Claude вызовет `/db-dump-xml dev C:\WS\ext_src -Extension МоёРасширение`.
|
||||
|
||||
```
|
||||
> Загрузи расширение обратно в базу
|
||||
```
|
||||
|
||||
Claude вызовет `/db-load-xml C:\WS\ext_src dev -Extension МоёРасширение` → предложит `/db-update -Extension МоёРасширение`.
|
||||
|
||||
### Запустить предприятие
|
||||
|
||||
```
|
||||
> Запусти базу разработки
|
||||
```
|
||||
|
||||
Claude вызовет `/db-run dev`.
|
||||
|
||||
## Движок: 1cv8 или ibcmd
|
||||
|
||||
По умолчанию навыки группы работают через конфигуратор (`1cv8.exe`; путь к нему определяется
|
||||
автоматически по каталогу `v8path`) — менять это не нужно. При желании ту же операцию можно выполнить
|
||||
через автономный сервер `ibcmd`. Для этого навыку нужно передать путь к самому файлу `ibcmd.exe`
|
||||
(каталог `bin` всегда трактуется как `1cv8.exe`; отдельного поля-переключателя в `.v8-project.json` нет).
|
||||
Путь указывают одним из двух способов:
|
||||
|
||||
- **разово, в самой задаче** — назвать полный путь к `ibcmd.exe`:
|
||||
|
||||
```
|
||||
> Собери обработку, платформа C:\Program Files\1cv8\8.3.24.1691\bin\ibcmd.exe
|
||||
```
|
||||
- **в файле настроек** — прописать в `v8path` не каталог `bin`, а сам файл `...\bin\ibcmd.exe`
|
||||
(тогда через `ibcmd` пойдут все операции).
|
||||
|
||||
Через `ibcmd` работают: `db-create`, `db-load-xml`/`db-dump-xml` (в том числе по отдельным объектам
|
||||
и со всеми расширениями), `db-load-cf`/`db-dump-cf`, `db-load-dt`/`db-dump-dt`, `db-update`,
|
||||
`db-load-git`, `epf-build`/`epf-dump`, `erf-build`/`erf-dump`.
|
||||
|
||||
Ограничения:
|
||||
- только **файловые** базы (для серверных используйте конфигуратор);
|
||||
- если запрошен режим, который `ibcmd` не поддерживает (например, выгрузка в «плоском» формате),
|
||||
навык остановится с понятным сообщением и предложит конфигуратор.
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [build-spec.md](build-spec.md) — пакетный режим конфигуратора 1С (CREATEINFOBASE, DESIGNER, ENTERPRISE, параметры, коды возврата)
|
||||
|
||||
+190
-190
@@ -1,190 +1,190 @@
|
||||
# Внешние обработки и отчёты (EPF / ERF)
|
||||
|
||||
Навыки для создания, модификации и сборки внешних обработок (`.epf`) и внешних отчётов (`.erf`) 1С:Предприятия 8.3 из XML-исходников.
|
||||
|
||||
## Навыки обработок (EPF)
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/epf-init` | `<Name> [Synonym]` | Создать новую обработку (корневой XML + модуль объекта) |
|
||||
| `/epf-build` | `<ProcessorName>` | Собрать EPF из XML (через 1cv8.exe) |
|
||||
| `/epf-dump` | `<EpfFile>` | Разобрать EPF в XML (через 1cv8.exe) |
|
||||
| `/epf-bsp-init` | `<ProcessorName> <Вид>` | Добавить регистрацию БСП (СведенияОВнешнейОбработке) |
|
||||
| `/epf-bsp-add-command` | `<ProcessorName> <Идентификатор>` | Добавить команду в дополнительную обработку БСП |
|
||||
| `/epf-validate` | `<ObjectPath> [-MaxErrors 30]` | Валидация структурной корректности обработки (10 проверок) |
|
||||
|
||||
## Внешние отчёты (ERF)
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/erf-init` | `<ReportName> [Synonym] [--WithSKD]` | Создать новый отчёт (корневой XML + модуль объекта + опционально СКД) |
|
||||
| `/erf-build` | `<ReportName>` | Собрать ERF из XML (через 1cv8.exe) |
|
||||
| `/erf-dump` | `<ErfFile>` | Разобрать ERF в XML (через 1cv8.exe) |
|
||||
| `/erf-validate` | `<ObjectPath> [-MaxErrors 30]` | Валидация структурной корректности отчёта (10 проверок) |
|
||||
|
||||
Флаг `--WithSKD` создаёт макет `ОсновнаяСхемаКомпоновкиДанных` и привязывает его к `MainDataCompositionSchema`.
|
||||
|
||||
## Универсальные навыки
|
||||
|
||||
Работают с любыми объектами — обработками, отчётами, справочниками, документами и др.
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/template-add` | `<ObjectName> <TemplateName> <TemplateType>` | Добавить макет (HTML, Text, SpreadsheetDocument, BinaryData, DataCompositionSchema) |
|
||||
| `/template-remove` | `<ObjectName> <TemplateName>` | Удалить макет |
|
||||
| `/help-add` | `<ObjectName>` | Добавить встроенную справку (Help.xml + HTML) |
|
||||
| `/form-remove` | `<ObjectName> <FormName>` | Удалить форму |
|
||||
|
||||
Для отчётов: при добавлении макета типа DataCompositionSchema автоматически заполняется `MainDataCompositionSchema` (если пуст).
|
||||
|
||||
Навыки удаления (`template-remove`, `form-remove`) не вызываются Claude автоматически — только по явной команде пользователя.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
Не обязательно запоминать команды и параметры. Просто опишите задачу своими словами — Claude сам подберёт нужные навыки.
|
||||
|
||||
### Обработка с формой
|
||||
|
||||
Типичная обработка для манипуляций с данными — форма для пользователя, модуль объекта для логики.
|
||||
|
||||
```
|
||||
> Создай обработку ЗагрузкаПрайса с формой
|
||||
```
|
||||
|
||||
Claude выполнит `/epf-init` и `/form-add` с правильными параметрами.
|
||||
|
||||
### Внешняя печатная форма
|
||||
|
||||
Обработка с макетом табличного документа, подключаемая через механизм дополнительных обработок БСП к конкретному документу.
|
||||
|
||||
```
|
||||
> Создай внешнюю печатную форму для документа Реализация. Макет — табличный документ.
|
||||
```
|
||||
|
||||
Claude создаст обработку, добавит макет SpreadsheetDocument, вызовет `/epf-bsp-init` с видом ПечатнаяФорма и назначением, сгенерирует `СведенияОВнешнейОбработке()` и процедуру `Печать()`.
|
||||
|
||||
### Внешний отчёт с СКД
|
||||
|
||||
```
|
||||
> Создай внешний отчёт ОстаткиНаСкладе с СКД
|
||||
```
|
||||
|
||||
Claude выполнит `/erf-init ОстаткиНаСкладе --WithSKD`, затем предложит заполнить схему компоновки через `/skd-compile`.
|
||||
|
||||
### Доработка существующей обработки
|
||||
|
||||
```
|
||||
> Добавь справку с описанием как пользоваться обработкой
|
||||
```
|
||||
|
||||
Claude вызовет `/help-add` и предложит отредактировать HTML.
|
||||
|
||||
```
|
||||
> Добавь ещё одну команду печати — накладная
|
||||
```
|
||||
|
||||
Claude вызовет `/epf-bsp-add-command`, добавит команду в `СведенияОВнешнейОбработке()` и блок обработки в процедуру `Печать()`.
|
||||
|
||||
```
|
||||
> Собери
|
||||
```
|
||||
|
||||
Claude вызовет `/epf-build` или `/erf-build` в зависимости от типа объекта.
|
||||
|
||||
### Примеры слеш-команд
|
||||
|
||||
Слеш-команды работают для случаев, когда хочется точного контроля:
|
||||
|
||||
```
|
||||
> /epf-init МояОбработка "Моя обработка"
|
||||
> /form-add МояОбработка.xml Форма
|
||||
> /template-add МояОбработка Макет HTML
|
||||
> /help-add МояОбработка
|
||||
> /epf-build МояОбработка
|
||||
|
||||
> /erf-init МойОтчёт --WithSKD
|
||||
> /template-add МойОтчёт ДопМакет SpreadsheetDocument
|
||||
> /erf-build МойОтчёт
|
||||
```
|
||||
|
||||
## Структура каталогов
|
||||
|
||||
После `/epf-init` создаётся структура:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МояОбработка.xml # Корневой файл метаданных
|
||||
└── МояОбработка/
|
||||
└── Ext/
|
||||
└── ObjectModule.bsl # Модуль объекта
|
||||
```
|
||||
|
||||
После `/form-add` и `/template-add`:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МояОбработка.xml
|
||||
└── МояОбработка/
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl
|
||||
├── Forms/
|
||||
│ ├── Форма.xml # Метаданные формы
|
||||
│ └── Форма/
|
||||
│ └── Ext/
|
||||
│ ├── Form.xml # Описание формы
|
||||
│ └── Form/
|
||||
│ └── Module.bsl # Модуль формы
|
||||
└── Templates/
|
||||
├── Макет.xml # Метаданные макета
|
||||
└── Макет/
|
||||
└── Ext/
|
||||
└── Template.html # Содержимое макета
|
||||
```
|
||||
|
||||
После `/erf-init МойОтчёт --WithSKD`:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МойОтчёт.xml # Корневой файл (ExternalReport)
|
||||
└── МойОтчёт/
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl # Модуль объекта
|
||||
└── Templates/
|
||||
├── ОсновнаяСхемаКомпоновкиДанных.xml
|
||||
└── ОсновнаяСхемаКомпоновкиДанных/
|
||||
└── Ext/
|
||||
└── Template.xml # Пустая СКД
|
||||
```
|
||||
|
||||
Первая добавленная форма автоматически становится основной (DefaultForm). Флаг `--main` нужен только для переназначения основной формы на другую.
|
||||
|
||||
## Сборка и разборка
|
||||
|
||||
### Сборка (`/epf-build`, `/erf-build`)
|
||||
|
||||
Если база не указана — автоматически создаётся временная база с заглушками метаданных для ссылочных типов. Явная база не обязательна, но предпочтительна — обеспечивает точное соответствие типов.
|
||||
|
||||
**Ограничение**: если на форме обработки выведены наборы записей регистров, в XML-исходниках нет информации о том, чем является поле регистра — измерением, ресурсом или реквизитом. Скрипт пытается угадать категорию по имени, но при ошибке 1С молча сбрасывает привязки колонок (DataPath). В таких случаях лучше использовать реальную базу с нужной конфигурацией.
|
||||
|
||||
### Разборка (`/epf-dump`, `/erf-dump`)
|
||||
|
||||
База с конфигурацией **обязательна**. Dump в пустой базе безвозвратно теряет ссылочные типы (`CatalogRef.XXX` → `xs:string`).
|
||||
|
||||
## Технические детали
|
||||
|
||||
- Все XML-файлы создаются в **UTF-8 с BOM** (как в реальных выгрузках 1С)
|
||||
- PowerShell-скрипты используют `System.Xml.XmlDocument` для модификации корневого XML
|
||||
- UUID генерируются через `[guid]::NewGuid()`
|
||||
- ClassId обработки: `c3831ec8-d8d5-4f93-8a22-f9bfae07327f`
|
||||
- ClassId отчёта: `e41aff26-25cf-4bb6-b6c1-3f478a75f374`
|
||||
- Порядок элементов в `ChildObjects`: TabularSections → Forms → Templates
|
||||
- Первая форма автоматически назначается основной (DefaultForm)
|
||||
- Навыки БСП (`epf-bsp-*`) не используют скрипты — Claude модифицирует код напрямую через Read/Edit
|
||||
- Для отчётов: `/template-add` с типом DataCompositionSchema автоматически заполняет `MainDataCompositionSchema`
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [XML-формат выгрузки обработок](1c-epf-spec.md) — структура XML-файлов, namespace, элементы форм
|
||||
- [XML-формат внешних отчётов](1c-erf-spec.md) — отличия ERF от EPF, Properties, MainDataCompositionSchema
|
||||
- [Встроенная справка](1c-help-spec.md) — Help.xml, HTML-страницы, кнопка справки на форме
|
||||
- [Сборка и разборка EPF/ERF](build-spec.md) — команды `1cv8.exe`, параметры, коды возврата
|
||||
# Внешние обработки и отчёты (EPF / ERF)
|
||||
|
||||
Навыки для создания, модификации и сборки внешних обработок (`.epf`) и внешних отчётов (`.erf`) 1С:Предприятия 8.3 из XML-исходников.
|
||||
|
||||
## Навыки обработок (EPF)
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/epf-init` | `<Name> [Synonym]` | Создать новую обработку (корневой XML + модуль объекта) |
|
||||
| `/epf-build` | `<ProcessorName>` | Собрать EPF из XML (через 1cv8.exe) |
|
||||
| `/epf-dump` | `<EpfFile>` | Разобрать EPF в XML (через 1cv8.exe) |
|
||||
| `/epf-bsp-init` | `<ProcessorName> <Вид>` | Добавить регистрацию БСП (СведенияОВнешнейОбработке) |
|
||||
| `/epf-bsp-add-command` | `<ProcessorName> <Идентификатор>` | Добавить команду в дополнительную обработку БСП |
|
||||
| `/epf-validate` | `<ObjectPath> [-MaxErrors 30]` | Валидация структурной корректности обработки (10 проверок) |
|
||||
|
||||
## Внешние отчёты (ERF)
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/erf-init` | `<ReportName> [Synonym] [--WithSKD]` | Создать новый отчёт (корневой XML + модуль объекта + опционально СКД) |
|
||||
| `/erf-build` | `<ReportName>` | Собрать ERF из XML (через 1cv8.exe) |
|
||||
| `/erf-dump` | `<ErfFile>` | Разобрать ERF в XML (через 1cv8.exe) |
|
||||
| `/erf-validate` | `<ObjectPath> [-MaxErrors 30]` | Валидация структурной корректности отчёта (10 проверок) |
|
||||
|
||||
Флаг `--WithSKD` создаёт макет `ОсновнаяСхемаКомпоновкиДанных` и привязывает его к `MainDataCompositionSchema`.
|
||||
|
||||
## Универсальные навыки
|
||||
|
||||
Работают с любыми объектами — обработками, отчётами, справочниками, документами и др.
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/template-add` | `<ObjectName> <TemplateName> <TemplateType>` | Добавить макет (HTML, Text, SpreadsheetDocument, BinaryData, DataCompositionSchema) |
|
||||
| `/template-remove` | `<ObjectName> <TemplateName>` | Удалить макет |
|
||||
| `/help-add` | `<ObjectName>` | Добавить встроенную справку (Help.xml + HTML) |
|
||||
| `/form-remove` | `<ObjectName> <FormName>` | Удалить форму |
|
||||
|
||||
Для отчётов: при добавлении макета типа DataCompositionSchema автоматически заполняется `MainDataCompositionSchema` (если пуст).
|
||||
|
||||
Навыки удаления (`template-remove`, `form-remove`) не вызываются Claude автоматически — только по явной команде пользователя.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
Не обязательно запоминать команды и параметры. Просто опишите задачу своими словами — Claude сам подберёт нужные навыки.
|
||||
|
||||
### Обработка с формой
|
||||
|
||||
Типичная обработка для манипуляций с данными — форма для пользователя, модуль объекта для логики.
|
||||
|
||||
```
|
||||
> Создай обработку ЗагрузкаПрайса с формой
|
||||
```
|
||||
|
||||
Claude выполнит `/epf-init` и `/form-add` с правильными параметрами.
|
||||
|
||||
### Внешняя печатная форма
|
||||
|
||||
Обработка с макетом табличного документа, подключаемая через механизм дополнительных обработок БСП к конкретному документу.
|
||||
|
||||
```
|
||||
> Создай внешнюю печатную форму для документа Реализация. Макет — табличный документ.
|
||||
```
|
||||
|
||||
Claude создаст обработку, добавит макет SpreadsheetDocument, вызовет `/epf-bsp-init` с видом ПечатнаяФорма и назначением, сгенерирует `СведенияОВнешнейОбработке()` и процедуру `Печать()`.
|
||||
|
||||
### Внешний отчёт с СКД
|
||||
|
||||
```
|
||||
> Создай внешний отчёт ОстаткиНаСкладе с СКД
|
||||
```
|
||||
|
||||
Claude выполнит `/erf-init ОстаткиНаСкладе --WithSKD`, затем предложит заполнить схему компоновки через `/skd-compile`.
|
||||
|
||||
### Доработка существующей обработки
|
||||
|
||||
```
|
||||
> Добавь справку с описанием как пользоваться обработкой
|
||||
```
|
||||
|
||||
Claude вызовет `/help-add` и предложит отредактировать HTML.
|
||||
|
||||
```
|
||||
> Добавь ещё одну команду печати — накладная
|
||||
```
|
||||
|
||||
Claude вызовет `/epf-bsp-add-command`, добавит команду в `СведенияОВнешнейОбработке()` и блок обработки в процедуру `Печать()`.
|
||||
|
||||
```
|
||||
> Собери
|
||||
```
|
||||
|
||||
Claude вызовет `/epf-build` или `/erf-build` в зависимости от типа объекта.
|
||||
|
||||
### Примеры слеш-команд
|
||||
|
||||
Слеш-команды работают для случаев, когда хочется точного контроля:
|
||||
|
||||
```
|
||||
> /epf-init МояОбработка "Моя обработка"
|
||||
> /form-add МояОбработка.xml Форма
|
||||
> /template-add МояОбработка Макет HTML
|
||||
> /help-add МояОбработка
|
||||
> /epf-build МояОбработка
|
||||
|
||||
> /erf-init МойОтчёт --WithSKD
|
||||
> /template-add МойОтчёт ДопМакет SpreadsheetDocument
|
||||
> /erf-build МойОтчёт
|
||||
```
|
||||
|
||||
## Структура каталогов
|
||||
|
||||
После `/epf-init` создаётся структура:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МояОбработка.xml # Корневой файл метаданных
|
||||
└── МояОбработка/
|
||||
└── Ext/
|
||||
└── ObjectModule.bsl # Модуль объекта
|
||||
```
|
||||
|
||||
После `/form-add` и `/template-add`:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МояОбработка.xml
|
||||
└── МояОбработка/
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl
|
||||
├── Forms/
|
||||
│ ├── Форма.xml # Метаданные формы
|
||||
│ └── Форма/
|
||||
│ └── Ext/
|
||||
│ ├── Form.xml # Описание формы
|
||||
│ └── Form/
|
||||
│ └── Module.bsl # Модуль формы
|
||||
└── Templates/
|
||||
├── Макет.xml # Метаданные макета
|
||||
└── Макет/
|
||||
└── Ext/
|
||||
└── Template.html # Содержимое макета
|
||||
```
|
||||
|
||||
После `/erf-init МойОтчёт --WithSKD`:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МойОтчёт.xml # Корневой файл (ExternalReport)
|
||||
└── МойОтчёт/
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl # Модуль объекта
|
||||
└── Templates/
|
||||
├── ОсновнаяСхемаКомпоновкиДанных.xml
|
||||
└── ОсновнаяСхемаКомпоновкиДанных/
|
||||
└── Ext/
|
||||
└── Template.xml # Пустая СКД
|
||||
```
|
||||
|
||||
Первая добавленная форма автоматически становится основной (DefaultForm). Флаг `--main` нужен только для переназначения основной формы на другую.
|
||||
|
||||
## Сборка и разборка
|
||||
|
||||
### Сборка (`/epf-build`, `/erf-build`)
|
||||
|
||||
Если база не указана — автоматически создаётся временная база с заглушками метаданных для ссылочных типов. Явная база не обязательна, но предпочтительна — обеспечивает точное соответствие типов.
|
||||
|
||||
**Ограничение**: если на форме обработки выведены наборы записей регистров, в XML-исходниках нет информации о том, чем является поле регистра — измерением, ресурсом или реквизитом. Скрипт пытается угадать категорию по имени, но при ошибке 1С молча сбрасывает привязки колонок (DataPath). В таких случаях лучше использовать реальную базу с нужной конфигурацией.
|
||||
|
||||
### Разборка (`/epf-dump`, `/erf-dump`)
|
||||
|
||||
База с конфигурацией **обязательна**. Dump в пустой базе безвозвратно теряет ссылочные типы (`CatalogRef.XXX` → `xs:string`).
|
||||
|
||||
## Технические детали
|
||||
|
||||
- Все XML-файлы создаются в **UTF-8 с BOM** (как в реальных выгрузках 1С)
|
||||
- PowerShell-скрипты используют `System.Xml.XmlDocument` для модификации корневого XML
|
||||
- UUID генерируются через `[guid]::NewGuid()`
|
||||
- ClassId обработки: `c3831ec8-d8d5-4f93-8a22-f9bfae07327f`
|
||||
- ClassId отчёта: `e41aff26-25cf-4bb6-b6c1-3f478a75f374`
|
||||
- Порядок элементов в `ChildObjects`: TabularSections → Forms → Templates
|
||||
- Первая форма автоматически назначается основной (DefaultForm)
|
||||
- Навыки БСП (`epf-bsp-*`) не используют скрипты — Claude модифицирует код напрямую через Read/Edit
|
||||
- Для отчётов: `/template-add` с типом DataCompositionSchema автоматически заполняет `MainDataCompositionSchema`
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [XML-формат выгрузки обработок](1c-epf-spec.md) — структура XML-файлов, namespace, элементы форм
|
||||
- [XML-формат внешних отчётов](1c-erf-spec.md) — отличия ERF от EPF, Properties, MainDataCompositionSchema
|
||||
- [Встроенная справка](1c-help-spec.md) — Help.xml, HTML-страницы, кнопка справки на форме
|
||||
- [Сборка и разборка EPF/ERF](build-spec.md) — команды `1cv8.exe`, параметры, коды возврата
|
||||
|
||||
+1306
-1306
File diff suppressed because it is too large
Load Diff
+266
-266
@@ -1,266 +1,266 @@
|
||||
# Управляемые формы (Form)
|
||||
|
||||
Навыки группы `/form-*` позволяют анализировать, генерировать и валидировать управляемые формы 1С:Предприятия 8.3 из XML-исходников, не читая тысячи строк XML.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/form-add` | `<ObjectPath> <FormName> [Purpose]` | Добавление формы к объекту конфигурации (Document, Catalog и др.) |
|
||||
| `/form-info` | `<FormPath>` | Компактная сводка: дерево элементов, реквизиты, команды, события |
|
||||
| `/form-compile` | `<JsonPath> <OutputPath>` | Генерация Form.xml из компактного JSON-определения |
|
||||
| `/form-validate` | `<FormPath>` | Валидация: уникальность ID, companions, DataPath, команды |
|
||||
| `/form-edit` | `<FormPath> <JsonPath>` | Добавление элементов, реквизитов, команд в существующую форму |
|
||||
| `/form-patterns` | (без параметров) | Справочник паттернов: архетипы, конвенции именования, продвинутые приёмы |
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Добавление новой формы к объекту конфигурации
|
||||
|
||||
`/form-add` создаёт каркас управляемой формы (metadata XML + Form.xml + Module.bsl) и регистрирует её в объекте конфигурации. Поддерживает Document, Catalog, DataProcessor, Report, InformationRegister и другие типы.
|
||||
|
||||
```
|
||||
> Добавь форму документа к Documents/АвансовыйОтчет.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/form-add` с нужными параметрами. Назначение формы (Purpose) определяет структуру: Object — форма объекта с реквизитом «Объект», List/Choice — форма списка с DynamicList, Record — форма записи регистра.
|
||||
|
||||
Типичный workflow:
|
||||
|
||||
1. `/form-add` — создать каркас (metadata + Form.xml + Module.bsl)
|
||||
2. `/form-compile` или `/form-edit` — наполнить Form.xml элементами
|
||||
3. `/form-validate` — проверить корректность
|
||||
4. `/form-info` — проанализировать результат
|
||||
|
||||
### Анализ формы перед модификацией
|
||||
|
||||
Файлы Form.xml содержат от сотен до десятков тысяч строк XML. 80% объёма — визуальный шум (цвета, шрифты, размеры, автогенерированные подсказки). `/form-info` извлекает суть.
|
||||
|
||||
```
|
||||
> Покажи структуру формы документа РеализацияТоваровУслуг
|
||||
```
|
||||
|
||||
Claude найдёт Form.xml и вызовет `/form-info`. Результат — компактная сводка (40–100 строк вместо тысяч):
|
||||
|
||||
```
|
||||
=== Form: ФормаДокумента — "Реализация товаров и услуг" (Documents.РеализацияТоваровУслуг) ===
|
||||
|
||||
Properties: AutoTitle=false, CommandBarLocation=None
|
||||
|
||||
Events:
|
||||
OnCreateAtServer -> ПриСозданииНаСервере
|
||||
OnOpen -> ПриОткрытии
|
||||
|
||||
Elements:
|
||||
├─ [Group:AH] ГруппаШапка
|
||||
│ ├─ [Input] Организация -> Объект.Организация {OnChange}
|
||||
│ └─ [Input] Контрагент -> Объект.Контрагент {OnChange, StartChoice}
|
||||
├─ [Table] Товары -> Объект.Товары
|
||||
│ ├─ [Input] Номенклатура -> Объект.Товары.Номенклатура {OnChange}
|
||||
│ └─ [Input] Сумма -> Объект.Товары.Сумма [ro]
|
||||
└─ [Pages] Страницы
|
||||
├─ [Page] Основное (5 items)
|
||||
└─ [Page] Печать (2 items)
|
||||
|
||||
Attributes:
|
||||
*Объект: DocumentObject.РеализацияТоваровУслуг (main)
|
||||
Валюта: CatalogRef.Валюты
|
||||
...
|
||||
|
||||
Commands:
|
||||
Печать -> ПечатьДокумента [Ctrl+P]
|
||||
```
|
||||
|
||||
### Добавление элементов в существующую форму
|
||||
|
||||
`/form-edit` добавляет элементы, реквизиты и команды в существующий Form.xml. Автоматически назначает ID, генерирует companion-элементы и обработчики событий.
|
||||
|
||||
```
|
||||
> Добавь поле "Склад" в шапку формы после "Контрагент"
|
||||
```
|
||||
|
||||
Claude вызовет `/form-info` для анализа структуры, создаст JSON и вызовет `/form-edit`:
|
||||
|
||||
```json
|
||||
{
|
||||
"into": "ГруппаШапка",
|
||||
"after": "Контрагент",
|
||||
"elements": [
|
||||
{ "input": "Склад", "path": "Объект.Склад", "on": ["OnChange"] }
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Склад", "type": "CatalogRef.Склады" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Позиционирование: `into` указывает группу-контейнер, `after` — элемент, после которого вставлять. Оба опциональны (по умолчанию — в конец корневого ChildItems).
|
||||
|
||||
Один вызов может содержать элементы, реквизиты и команды одновременно. Группы поддерживают `children` для вложенных элементов.
|
||||
|
||||
### Поиск обработчиков и привязок
|
||||
|
||||
Из сводки видно, какие события подключены к каким элементам:
|
||||
|
||||
```
|
||||
> Какие обработчики срабатывают при изменении контрагента?
|
||||
```
|
||||
|
||||
Claude вызовет `/form-info` и найдёт: `[Input] Контрагент -> Объект.Контрагент {OnChange, StartChoice}` — далее откроет модуль формы и найдёт процедуры по именам событий.
|
||||
|
||||
### Точечное погружение в детали
|
||||
|
||||
Сводка — это карта. Для деталей по конкретному элементу достаточно grep по имени из сводки:
|
||||
|
||||
```
|
||||
> Покажи все свойства элемента ДоговорКонтрагента
|
||||
```
|
||||
|
||||
Claude сделает grep по Form.xml и найдёт полный XML-блок с ChoiceParameters, ChoiceFoldersAndItems, стилями и прочими свойствами.
|
||||
|
||||
## Чтение вывода
|
||||
|
||||
### Дерево элементов
|
||||
|
||||
| Обозначение | Элемент |
|
||||
|---|---|
|
||||
| `[Group:V]` `[Group:H]` `[Group:AH]` `[Group:AV]` | Группа (Vertical / Horizontal / AlwaysHorizontal / AlwaysVertical) |
|
||||
| `[Input]` | Поле ввода |
|
||||
| `[Check]` | Флажок |
|
||||
| `[Label]` | Декоративная надпись |
|
||||
| `[LabelField]` | Поле надписи (привязанное к данным) |
|
||||
| `[Table]` | Таблица |
|
||||
| `[Pages]` / `[Page]` | Вкладки (страницы показывают количество элементов) |
|
||||
| `[Button]` | Кнопка |
|
||||
| `[CmdBar]` | Командная панель |
|
||||
| `[Popup]` | Выпадающее меню |
|
||||
| `[Picture]` | Декоративная картинка |
|
||||
| `[PicField]` | Поле картинки |
|
||||
| `[Calendar]` | Календарь |
|
||||
|
||||
### Флаги
|
||||
|
||||
Показываются только при отклонении от умолчания:
|
||||
- `[visible:false]` — элемент скрыт (Visible=false)
|
||||
- `[enabled:false]` — элемент недоступен (Enabled=false)
|
||||
- `[ro]` — только чтение (ReadOnly=true)
|
||||
- `,collapse` — сворачиваемая группа (Behavior=Collapsible)
|
||||
|
||||
### Привязки и события
|
||||
|
||||
- `-> Объект.Поле` — DataPath (привязка к данным)
|
||||
- `-> Имя [cmd]` — привязка к команде формы
|
||||
- `-> Close [std]` — привязка к стандартной команде
|
||||
- `{OnChange, StartChoice}` — имена подключённых событий
|
||||
- `[title:Текст]` — заголовок, если отличается от имени элемента
|
||||
|
||||
### Реквизиты
|
||||
|
||||
- `*Объект: DocumentObject.Реализация (main)` — основной реквизит формы
|
||||
- `Таблица: ValueTable [Кол1: тип, Кол2: тип]` — таблица значений с колонками
|
||||
- `Список: DynamicList -> Catalog.Пользователи` — динамический список с основной таблицей
|
||||
|
||||
## Генерация формы с нуля
|
||||
|
||||
`/form-compile` принимает компактное JSON-определение (20–50 строк) и генерирует полный Form.xml (100–500+ строк) с namespace-декларациями, companion-элементами и последовательными ID.
|
||||
|
||||
```
|
||||
> Создай форму загрузки данных с полями Организация, Контрагент, таблицей Товары и кнопкой Загрузить
|
||||
```
|
||||
|
||||
Claude создаст JSON-определение и вызовет `/form-compile`. Пример JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"properties": { "autoTitle": false },
|
||||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
||||
"elements": [
|
||||
{ "group": "horizontal", "name": "Шапка", "children": [
|
||||
{ "input": "Организация", "path": "Объект.Организация", "on": ["OnChange"] },
|
||||
{ "input": "Контрагент", "path": "Объект.Контрагент" }
|
||||
]},
|
||||
{ "table": "Товары", "path": "Объект.Товары", "columns": [
|
||||
{ "input": "Номенклатура", "path": "Объект.Товары.Номенклатура" },
|
||||
{ "input": "Сумма", "path": "Объект.Товары.Сумма", "readOnly": true }
|
||||
]},
|
||||
{ "button": "Загрузить", "command": "Загрузить" }
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Объект", "type": "DataProcessorObject.ЗагрузкаДанных", "main": true }
|
||||
],
|
||||
"commands": [
|
||||
{ "name": "Загрузить", "action": "ЗагрузитьОбработка" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Верификация результата
|
||||
|
||||
После компиляции используйте `/form-validate` и `/form-info` для проверки:
|
||||
|
||||
```
|
||||
> /form-validate src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
> /form-info src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
```
|
||||
|
||||
`/form-validate` проверит структурную корректность (ID, companions, ссылки), `/form-info` покажет результат в виде компактной сводки.
|
||||
|
||||
## Генерация из метаданных объекта
|
||||
|
||||
`/form-compile` умеет автоматически генерировать форму из метаданных объекта (XML-выгрузки). Скрипт читает реквизиты, табличные части, стандартные реквизиты и строит форму по стандарту ERP.
|
||||
|
||||
```
|
||||
> Создай форму документа ЗаказКлиенту
|
||||
```
|
||||
|
||||
Claude вызовет `/form-compile` с флагом `-FromObject`. Назначение формы (Purpose) автоматически определяется из имени формы (ФормаДокумента -> Item, ФормаСписка -> List, ФормаВыбора -> Choice).
|
||||
|
||||
Поддерживаемые типы: Document, Catalog, InformationRegister, AccumulationRegister, ChartOfCharacteristicTypes, ExchangePlan, ChartOfAccounts.
|
||||
|
||||
Не поддерживается: DataProcessor (реквизиты объекта пустые -- форма строится на реквизитах формы, используйте JSON DSL).
|
||||
|
||||
### Project-level пресеты
|
||||
|
||||
Раскладка формы управляется пресетом (по умолчанию `erp-standard`). Для настройки под проект создайте файл:
|
||||
|
||||
```
|
||||
<project-root>/presets/skills/form/erp-standard.json
|
||||
```
|
||||
|
||||
Файл накладывается поверх встроенного пресета через deep merge -- достаточно указать только переопределяемые ключи. Полная документация ключей: `.claude/skills/form-compile/presets/README.md`.
|
||||
|
||||
## Примеры слеш-команд
|
||||
|
||||
```
|
||||
> /form-info upload/acc_8.3.24/Documents/РеализацияТоваровУслуг/Forms/ФормаДокумента/Ext/Form.xml
|
||||
> /form-info src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
> /form-compile src/form.json src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
> /form-edit src/МояОбработка/Forms/Форма/Ext/Form.xml src/additions.json
|
||||
> /form-validate src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
```
|
||||
|
||||
## Связь с EPF-навыками
|
||||
|
||||
Навыки `/form-*` работают с формами из любых источников — конфигурации и внешних обработок.
|
||||
|
||||
При работе с объектами конфигурации:
|
||||
|
||||
1. `/form-add` — создать форму (каркас + регистрация в объекте)
|
||||
2. `/form-compile` или `/form-edit` — наполнить Form.xml элементами
|
||||
3. `/form-validate` — проверить корректность
|
||||
4. `/form-info` — проанализировать результат
|
||||
|
||||
При работе с внешними обработками:
|
||||
|
||||
1. `/form-add` — создать форму (каркас)
|
||||
2. `/form-compile` — сгенерировать Form.xml из JSON-определения
|
||||
3. `/form-edit` — добавить элементы/реквизиты/команды в существующую форму
|
||||
4. `/form-validate` — проверить корректность
|
||||
5. `/form-info` — проанализировать результат
|
||||
6. `/epf-build` — собрать EPF
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [Управляемая форма](1c-form-spec.md) — Form.xml, элементы, команды, реквизиты, система типов
|
||||
- [Form DSL](form-dsl-spec.md) — JSON-формат описания формы для `/form-compile` и `/form-edit`
|
||||
- [Паттерны компоновки](form-patterns.md) — типовые архетипы форм, конвенции именования, примеры DSL
|
||||
# Управляемые формы (Form)
|
||||
|
||||
Навыки группы `/form-*` позволяют анализировать, генерировать и валидировать управляемые формы 1С:Предприятия 8.3 из XML-исходников, не читая тысячи строк XML.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/form-add` | `<ObjectPath> <FormName> [Purpose]` | Добавление формы к объекту конфигурации (Document, Catalog и др.) |
|
||||
| `/form-info` | `<FormPath>` | Компактная сводка: дерево элементов, реквизиты, команды, события |
|
||||
| `/form-compile` | `<JsonPath> <OutputPath>` | Генерация Form.xml из компактного JSON-определения |
|
||||
| `/form-validate` | `<FormPath>` | Валидация: уникальность ID, companions, DataPath, команды |
|
||||
| `/form-edit` | `<FormPath> <JsonPath>` | Добавление элементов, реквизитов, команд в существующую форму |
|
||||
| `/form-patterns` | (без параметров) | Справочник паттернов: архетипы, конвенции именования, продвинутые приёмы |
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Добавление новой формы к объекту конфигурации
|
||||
|
||||
`/form-add` создаёт каркас управляемой формы (metadata XML + Form.xml + Module.bsl) и регистрирует её в объекте конфигурации. Поддерживает Document, Catalog, DataProcessor, Report, InformationRegister и другие типы.
|
||||
|
||||
```
|
||||
> Добавь форму документа к Documents/АвансовыйОтчет.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/form-add` с нужными параметрами. Назначение формы (Purpose) определяет структуру: Object — форма объекта с реквизитом «Объект», List/Choice — форма списка с DynamicList, Record — форма записи регистра.
|
||||
|
||||
Типичный workflow:
|
||||
|
||||
1. `/form-add` — создать каркас (metadata + Form.xml + Module.bsl)
|
||||
2. `/form-compile` или `/form-edit` — наполнить Form.xml элементами
|
||||
3. `/form-validate` — проверить корректность
|
||||
4. `/form-info` — проанализировать результат
|
||||
|
||||
### Анализ формы перед модификацией
|
||||
|
||||
Файлы Form.xml содержат от сотен до десятков тысяч строк XML. 80% объёма — визуальный шум (цвета, шрифты, размеры, автогенерированные подсказки). `/form-info` извлекает суть.
|
||||
|
||||
```
|
||||
> Покажи структуру формы документа РеализацияТоваровУслуг
|
||||
```
|
||||
|
||||
Claude найдёт Form.xml и вызовет `/form-info`. Результат — компактная сводка (40–100 строк вместо тысяч):
|
||||
|
||||
```
|
||||
=== Form: ФормаДокумента — "Реализация товаров и услуг" (Documents.РеализацияТоваровУслуг) ===
|
||||
|
||||
Properties: AutoTitle=false, CommandBarLocation=None
|
||||
|
||||
Events:
|
||||
OnCreateAtServer -> ПриСозданииНаСервере
|
||||
OnOpen -> ПриОткрытии
|
||||
|
||||
Elements:
|
||||
├─ [Group:AH] ГруппаШапка
|
||||
│ ├─ [Input] Организация -> Объект.Организация {OnChange}
|
||||
│ └─ [Input] Контрагент -> Объект.Контрагент {OnChange, StartChoice}
|
||||
├─ [Table] Товары -> Объект.Товары
|
||||
│ ├─ [Input] Номенклатура -> Объект.Товары.Номенклатура {OnChange}
|
||||
│ └─ [Input] Сумма -> Объект.Товары.Сумма [ro]
|
||||
└─ [Pages] Страницы
|
||||
├─ [Page] Основное (5 items)
|
||||
└─ [Page] Печать (2 items)
|
||||
|
||||
Attributes:
|
||||
*Объект: DocumentObject.РеализацияТоваровУслуг (main)
|
||||
Валюта: CatalogRef.Валюты
|
||||
...
|
||||
|
||||
Commands:
|
||||
Печать -> ПечатьДокумента [Ctrl+P]
|
||||
```
|
||||
|
||||
### Добавление элементов в существующую форму
|
||||
|
||||
`/form-edit` добавляет элементы, реквизиты и команды в существующий Form.xml. Автоматически назначает ID, генерирует companion-элементы и обработчики событий.
|
||||
|
||||
```
|
||||
> Добавь поле "Склад" в шапку формы после "Контрагент"
|
||||
```
|
||||
|
||||
Claude вызовет `/form-info` для анализа структуры, создаст JSON и вызовет `/form-edit`:
|
||||
|
||||
```json
|
||||
{
|
||||
"into": "ГруппаШапка",
|
||||
"after": "Контрагент",
|
||||
"elements": [
|
||||
{ "input": "Склад", "path": "Объект.Склад", "on": ["OnChange"] }
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Склад", "type": "CatalogRef.Склады" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Позиционирование: `into` указывает группу-контейнер, `after` — элемент, после которого вставлять. Оба опциональны (по умолчанию — в конец корневого ChildItems).
|
||||
|
||||
Один вызов может содержать элементы, реквизиты и команды одновременно. Группы поддерживают `children` для вложенных элементов.
|
||||
|
||||
### Поиск обработчиков и привязок
|
||||
|
||||
Из сводки видно, какие события подключены к каким элементам:
|
||||
|
||||
```
|
||||
> Какие обработчики срабатывают при изменении контрагента?
|
||||
```
|
||||
|
||||
Claude вызовет `/form-info` и найдёт: `[Input] Контрагент -> Объект.Контрагент {OnChange, StartChoice}` — далее откроет модуль формы и найдёт процедуры по именам событий.
|
||||
|
||||
### Точечное погружение в детали
|
||||
|
||||
Сводка — это карта. Для деталей по конкретному элементу достаточно grep по имени из сводки:
|
||||
|
||||
```
|
||||
> Покажи все свойства элемента ДоговорКонтрагента
|
||||
```
|
||||
|
||||
Claude сделает grep по Form.xml и найдёт полный XML-блок с ChoiceParameters, ChoiceFoldersAndItems, стилями и прочими свойствами.
|
||||
|
||||
## Чтение вывода
|
||||
|
||||
### Дерево элементов
|
||||
|
||||
| Обозначение | Элемент |
|
||||
|---|---|
|
||||
| `[Group:V]` `[Group:H]` `[Group:AH]` `[Group:AV]` | Группа (Vertical / Horizontal / AlwaysHorizontal / AlwaysVertical) |
|
||||
| `[Input]` | Поле ввода |
|
||||
| `[Check]` | Флажок |
|
||||
| `[Label]` | Декоративная надпись |
|
||||
| `[LabelField]` | Поле надписи (привязанное к данным) |
|
||||
| `[Table]` | Таблица |
|
||||
| `[Pages]` / `[Page]` | Вкладки (страницы показывают количество элементов) |
|
||||
| `[Button]` | Кнопка |
|
||||
| `[CmdBar]` | Командная панель |
|
||||
| `[Popup]` | Выпадающее меню |
|
||||
| `[Picture]` | Декоративная картинка |
|
||||
| `[PicField]` | Поле картинки |
|
||||
| `[Calendar]` | Календарь |
|
||||
|
||||
### Флаги
|
||||
|
||||
Показываются только при отклонении от умолчания:
|
||||
- `[visible:false]` — элемент скрыт (Visible=false)
|
||||
- `[enabled:false]` — элемент недоступен (Enabled=false)
|
||||
- `[ro]` — только чтение (ReadOnly=true)
|
||||
- `,collapse` — сворачиваемая группа (Behavior=Collapsible)
|
||||
|
||||
### Привязки и события
|
||||
|
||||
- `-> Объект.Поле` — DataPath (привязка к данным)
|
||||
- `-> Имя [cmd]` — привязка к команде формы
|
||||
- `-> Close [std]` — привязка к стандартной команде
|
||||
- `{OnChange, StartChoice}` — имена подключённых событий
|
||||
- `[title:Текст]` — заголовок, если отличается от имени элемента
|
||||
|
||||
### Реквизиты
|
||||
|
||||
- `*Объект: DocumentObject.Реализация (main)` — основной реквизит формы
|
||||
- `Таблица: ValueTable [Кол1: тип, Кол2: тип]` — таблица значений с колонками
|
||||
- `Список: DynamicList -> Catalog.Пользователи` — динамический список с основной таблицей
|
||||
|
||||
## Генерация формы с нуля
|
||||
|
||||
`/form-compile` принимает компактное JSON-определение (20–50 строк) и генерирует полный Form.xml (100–500+ строк) с namespace-декларациями, companion-элементами и последовательными ID.
|
||||
|
||||
```
|
||||
> Создай форму загрузки данных с полями Организация, Контрагент, таблицей Товары и кнопкой Загрузить
|
||||
```
|
||||
|
||||
Claude создаст JSON-определение и вызовет `/form-compile`. Пример JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"properties": { "autoTitle": false },
|
||||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
||||
"elements": [
|
||||
{ "group": "horizontal", "name": "Шапка", "children": [
|
||||
{ "input": "Организация", "path": "Объект.Организация", "on": ["OnChange"] },
|
||||
{ "input": "Контрагент", "path": "Объект.Контрагент" }
|
||||
]},
|
||||
{ "table": "Товары", "path": "Объект.Товары", "columns": [
|
||||
{ "input": "Номенклатура", "path": "Объект.Товары.Номенклатура" },
|
||||
{ "input": "Сумма", "path": "Объект.Товары.Сумма", "readOnly": true }
|
||||
]},
|
||||
{ "button": "Загрузить", "command": "Загрузить" }
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Объект", "type": "DataProcessorObject.ЗагрузкаДанных", "main": true }
|
||||
],
|
||||
"commands": [
|
||||
{ "name": "Загрузить", "action": "ЗагрузитьОбработка" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Верификация результата
|
||||
|
||||
После компиляции используйте `/form-validate` и `/form-info` для проверки:
|
||||
|
||||
```
|
||||
> /form-validate src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
> /form-info src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
```
|
||||
|
||||
`/form-validate` проверит структурную корректность (ID, companions, ссылки), `/form-info` покажет результат в виде компактной сводки.
|
||||
|
||||
## Генерация из метаданных объекта
|
||||
|
||||
`/form-compile` умеет автоматически генерировать форму из метаданных объекта (XML-выгрузки). Скрипт читает реквизиты, табличные части, стандартные реквизиты и строит форму по стандарту ERP.
|
||||
|
||||
```
|
||||
> Создай форму документа ЗаказКлиенту
|
||||
```
|
||||
|
||||
Claude вызовет `/form-compile` с флагом `-FromObject`. Назначение формы (Purpose) автоматически определяется из имени формы (ФормаДокумента -> Item, ФормаСписка -> List, ФормаВыбора -> Choice).
|
||||
|
||||
Поддерживаемые типы: Document, Catalog, InformationRegister, AccumulationRegister, ChartOfCharacteristicTypes, ExchangePlan, ChartOfAccounts.
|
||||
|
||||
Не поддерживается: DataProcessor (реквизиты объекта пустые -- форма строится на реквизитах формы, используйте JSON DSL).
|
||||
|
||||
### Project-level пресеты
|
||||
|
||||
Раскладка формы управляется пресетом (по умолчанию `erp-standard`). Для настройки под проект создайте файл:
|
||||
|
||||
```
|
||||
<project-root>/presets/skills/form/erp-standard.json
|
||||
```
|
||||
|
||||
Файл накладывается поверх встроенного пресета через deep merge -- достаточно указать только переопределяемые ключи. Полная документация ключей: `.claude/skills/form-compile/presets/README.md`.
|
||||
|
||||
## Примеры слеш-команд
|
||||
|
||||
```
|
||||
> /form-info upload/acc_8.3.24/Documents/РеализацияТоваровУслуг/Forms/ФормаДокумента/Ext/Form.xml
|
||||
> /form-info src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
> /form-compile src/form.json src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
> /form-edit src/МояОбработка/Forms/Форма/Ext/Form.xml src/additions.json
|
||||
> /form-validate src/МояОбработка/Forms/Форма/Ext/Form.xml
|
||||
```
|
||||
|
||||
## Связь с EPF-навыками
|
||||
|
||||
Навыки `/form-*` работают с формами из любых источников — конфигурации и внешних обработок.
|
||||
|
||||
При работе с объектами конфигурации:
|
||||
|
||||
1. `/form-add` — создать форму (каркас + регистрация в объекте)
|
||||
2. `/form-compile` или `/form-edit` — наполнить Form.xml элементами
|
||||
3. `/form-validate` — проверить корректность
|
||||
4. `/form-info` — проанализировать результат
|
||||
|
||||
При работе с внешними обработками:
|
||||
|
||||
1. `/form-add` — создать форму (каркас)
|
||||
2. `/form-compile` — сгенерировать Form.xml из JSON-определения
|
||||
3. `/form-edit` — добавить элементы/реквизиты/команды в существующую форму
|
||||
4. `/form-validate` — проверить корректность
|
||||
5. `/form-info` — проанализировать результат
|
||||
6. `/epf-build` — собрать EPF
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [Управляемая форма](1c-form-spec.md) — Form.xml, элементы, команды, реквизиты, система типов
|
||||
- [Form DSL](form-dsl-spec.md) — JSON-формат описания формы для `/form-compile` и `/form-edit`
|
||||
- [Паттерны компоновки](form-patterns.md) — типовые архетипы форм, конвенции именования, примеры DSL
|
||||
|
||||
+337
-337
@@ -1,337 +1,337 @@
|
||||
# Паттерны компоновки управляемых форм
|
||||
|
||||
Рекомендации по дизайну форм, извлечённые из типовых конфигураций 1С. Используйте при создании форм через `/form-compile`, когда требования пользователя не детализируют расположение элементов.
|
||||
|
||||
## Архетипы форм
|
||||
|
||||
### Форма документа
|
||||
|
||||
```
|
||||
Шапка (horizontal, 2 колонки)
|
||||
├─ Левая (vertical): НомерДата (H: Номер + Дата "от"), Контрагент, Договор
|
||||
├─ Правая (vertical): Организация, Подразделение, ЦеныИВалюта (надпись-ссылка)
|
||||
Страницы (pages)
|
||||
├─ Товары: таблица Объект.Товары
|
||||
├─ Услуги: таблица Объект.Услуги (опционально)
|
||||
└─ Дополнительно: прочие реквизиты
|
||||
Подвал (vertical)
|
||||
├─ Итоги (horizontal): Всего, НДС, Скидка
|
||||
└─ КомментарийОтветственный (horizontal): Комментарий + Ответственный
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnReadAtServer, OnOpen, BeforeWriteAtServer, AfterWriteAtServer, AfterWrite, NotificationProcessing
|
||||
|
||||
**Свойства:** autoTitle=false, командная панель со стандартными + глобальными командами
|
||||
|
||||
### Форма обработки (DataProcessor)
|
||||
|
||||
```
|
||||
Параметры (vertical)
|
||||
├─ Группа полей ввода (Организация, Период, режимы работы)
|
||||
├─ Информационные надписи (label, hyperlink)
|
||||
Рабочая область
|
||||
├─ Таблица данных или Pages с вкладками
|
||||
Кнопки действий
|
||||
├─ Выполнить / Применить (defaultButton)
|
||||
├─ Закрыть (stdCommand: Close)
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnOpen, NotificationProcessing
|
||||
|
||||
**Свойства:** windowOpeningMode=LockOwnerWindow (если диалог), autoTitle=false
|
||||
|
||||
### Форма списка
|
||||
|
||||
```
|
||||
Отборы (group: alwaysHorizontal)
|
||||
├─ ГруппаОтбор[Поле] (H): Флажок + Поле ввода (для каждого фильтра)
|
||||
Список (table, DynamicList)
|
||||
├─ Колонки: labelField (не input — данные только для чтения)
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnOpen, NotificationProcessing, OnLoadDataFromSettingsAtServer
|
||||
|
||||
**Свойства:** autoSaveDataInSettings=Use (запомнить отборы)
|
||||
|
||||
**Фильтры:** пара реквизитов на каждый фильтр — `Отбор[Поле]` (значение) + `Отбор[Поле]Использование` (boolean, флажок вкл/выкл)
|
||||
|
||||
### Форма элемента справочника
|
||||
|
||||
**Простая:**
|
||||
```
|
||||
ГруппаРеквизитов (horizontal)
|
||||
├─ Наименование -> Объект.Description
|
||||
└─ Код -> Объект.Code (если нужен)
|
||||
```
|
||||
|
||||
**Сложная:**
|
||||
```
|
||||
Главное (vertical)
|
||||
├─ Наименование -> Объект.Description
|
||||
├─ Параметры (horizontal, 2 колонки)
|
||||
│ ├─ Левая: основные реквизиты
|
||||
│ └─ Правая: дополнительные реквизиты
|
||||
└─ КонтактныеДанные / Дополнительно (vertical)
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnReadAtServer, BeforeWriteAtServer, NotificationProcessing
|
||||
|
||||
### Мастер (Wizard)
|
||||
|
||||
```
|
||||
Страницы (pages, OnCurrentPageChange)
|
||||
├─ Шаг1: описание + параметры
|
||||
├─ Шаг2: основная работа
|
||||
└─ Шаг3: результат
|
||||
Кнопки (horizontal)
|
||||
├─ Назад (command), Далее (command, defaultButton), Выполнить (command)
|
||||
└─ Закрыть (stdCommand: Close)
|
||||
```
|
||||
|
||||
**Свойства:** windowOpeningMode=LockOwnerWindow
|
||||
|
||||
## Конвенции именования
|
||||
|
||||
### Группы
|
||||
|
||||
| Назначение | Имя | Тип |
|
||||
|-----------|-----|-----|
|
||||
| Шапка | `ГруппаШапка` | horizontal |
|
||||
| Левая колонка | `ГруппаШапкаЛевая` | vertical |
|
||||
| Правая колонка | `ГруппаШапкаПравая` | vertical |
|
||||
| Номер+Дата | `ГруппаНомерДата` | horizontal |
|
||||
| Подвал | `ГруппаПодвал` | vertical |
|
||||
| Итоги | `ГруппаИтоги` | horizontal |
|
||||
| Кнопки | `ГруппаКнопок` | horizontal |
|
||||
| Страницы | `ГруппаСтраницы` / `Страницы` | pages |
|
||||
| Предупреждение | `ГруппаПредупреждение` | horizontal, visible:false |
|
||||
| Доп. секция | `ГруппаДополнительно` / `ГруппаПрочее` | vertical, collapse |
|
||||
|
||||
### Элементы
|
||||
|
||||
| Назначение | Имя | Суффикс |
|
||||
|-----------|-----|---------|
|
||||
| Поле в таблице | `[Таблица][Поле]` | — |
|
||||
| Итог | `Итоги[Поле]` | — |
|
||||
| Надпись-ссылка | `[Поле]Надпись` | — |
|
||||
| Фильтр | `Отбор[Поле]` | — |
|
||||
| Флажок фильтра | `Отбор[Поле]Использование` | — |
|
||||
| Кнопка команды | `[Команда]Кнопка` | — |
|
||||
| Баннер-картинка | `[Баннер]Картинка` | — |
|
||||
| Баннер-надпись | `[Баннер]Надпись` | — |
|
||||
| Подменю | `Подменю[Действие]` | — |
|
||||
|
||||
### Обработчики событий
|
||||
|
||||
Имя обработчика = имя элемента + суффикс события на русском:
|
||||
|
||||
| Событие | Суффикс | Пример |
|
||||
|---------|---------|--------|
|
||||
| OnChange | ПриИзменении | `ОрганизацияПриИзменении` |
|
||||
| StartChoice | НачалоВыбора | `КонтрагентНачалоВыбора` |
|
||||
| Click | Нажатие | `ЦеныИВалютаНажатие` |
|
||||
| OnEditEnd | ПриОкончанииРедактирования | `ТоварыПриОкончанииРедактирования` |
|
||||
| OnStartEdit | ПриНачалеРедактирования | `ТоварыПриНачалеРедактирования` |
|
||||
|
||||
Обработчики формы — стандартные имена: `ПриСозданииНаСервере`, `ПриОткрытии`, `ПередЗакрытием`, `ОбработкаОповещения`.
|
||||
|
||||
## Принципы компоновки
|
||||
|
||||
1. **Порядок чтения.** Сверху вниз, слева направо. Самое важное — вверху.
|
||||
2. **Двухколоночная шапка.** Основные реквизиты слева (контрагент, склад), организационные справа (организация, подразделение).
|
||||
3. **Кнопки действий внизу.** Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя.
|
||||
4. **Таблицы — основная область.** Табличные части занимают большую часть формы, обычно на Pages.
|
||||
5. **Итоги рядом с таблицей.** В подвале, горизонтальная группа, все поля readOnly.
|
||||
6. **Фильтры — отдельная зона.** Над списком, горизонтальная группа (alwaysHorizontal), пара "флажок + поле" на каждый фильтр.
|
||||
7. **Скрытые элементы для состояний.** Баннеры, предупреждения — `visible: false` по умолчанию, показываются программно.
|
||||
8. **Надписи-ссылки для диалогов.** `labelField` с `hyperlink: true` и событием Click — для открытия подформ (ЦеныИВалюта, УчётнаяПолитика).
|
||||
|
||||
## Продвинутые паттерны (ERP)
|
||||
|
||||
Извлечены из конфигурации «Управление предприятием» (ERP 8.3.24). Применяйте в сложных формах.
|
||||
|
||||
### Сворачиваемые группы (Collapsible)
|
||||
|
||||
Для необязательных секций — «Подписи», «Дополнительно», «Прочее». Сворачиваются по умолчанию, экономят место.
|
||||
|
||||
```
|
||||
ГруппаПодписи (vertical, collapse, collapsed)
|
||||
├─ Руководитель -> Объект.Руководитель
|
||||
└─ ГлавныйБухгалтер -> Объект.ГлавныйБухгалтер
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "group": "vertical", "name": "ГруппаПодписи", "title": "Подписи",
|
||||
"behavior": "Collapsible", "collapsed": true, "children": [
|
||||
{ "input": "Руководитель", "path": "Объект.Руководитель" },
|
||||
{ "input": "ГлавныйБухгалтер", "path": "Объект.ГлавныйБухгалтер" }
|
||||
]}
|
||||
```
|
||||
|
||||
### Баннер-предупреждение (Status Banner)
|
||||
|
||||
Группа «картинка + надпись» без заголовка, скрыта по умолчанию. Показывается программно при определённых условиях (просрочка, блокировка, информация).
|
||||
|
||||
```
|
||||
ГруппаПредупреждение (horizontal, showTitle:false, visible:false)
|
||||
├─ [Picture] ПредупреждениеКартинка -> StdPicture.Information
|
||||
└─ [Label] ПредупреждениеНадпись (maxWidth:76, textColor:style:ПоясняющийТекст)
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "group": "horizontal", "name": "ГруппаПредупреждение", "showTitle": false,
|
||||
"visible": false, "children": [
|
||||
{ "picture": "ПредупреждениеКартинка" },
|
||||
{ "label": "ПредупреждениеНадпись", "title": "Текст предупреждения",
|
||||
"maxWidth": 76, "autoMaxWidth": false }
|
||||
]}
|
||||
```
|
||||
|
||||
### Выпадающее меню в командной панели (Popup)
|
||||
|
||||
Группировка связанных команд (печать, отправка, выгрузка) в одну кнопку-меню с иконкой.
|
||||
|
||||
```
|
||||
[CmdBar] КоманднаяПанель
|
||||
├─ [Popup] ПодменюПечать (picture: StdPicture.Print, representation: Picture)
|
||||
│ ├─ [Button] ПечатьНакладная -> Печать [cmd]
|
||||
│ └─ [Button] ПечатьСчёт -> ПечатьСчёт [cmd]
|
||||
└─ [Popup] ПодменюОтправить (picture: StdPicture.SendByEmail)
|
||||
└─ [Button] ОтправитьПоПочте -> Отправить [cmd]
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "cmdBar": "КоманднаяПанель", "children": [
|
||||
{ "popup": "ПодменюПечать", "title": "Печать",
|
||||
"picture": "StdPicture.Print", "representation": "Picture", "children": [
|
||||
{ "button": "ПечатьНакладная", "command": "Печать" },
|
||||
{ "button": "ПечатьСчёт", "command": "ПечатьСчёт" }
|
||||
]},
|
||||
{ "popup": "ПодменюОтправить", "title": "Отправить",
|
||||
"picture": "StdPicture.SendByEmail", "representation": "Picture", "children": [
|
||||
{ "button": "ОтправитьПоПочте", "command": "Отправить" }
|
||||
]}
|
||||
]}
|
||||
```
|
||||
|
||||
### Форма без стандартной командной панели
|
||||
|
||||
Для модальных диалогов и мастеров — отключение стандартной командной панели, полностью ручное управление кнопками.
|
||||
|
||||
```
|
||||
properties: commandBarLocation=None, windowOpeningMode=LockWholeInterface
|
||||
Содержимое (vertical)
|
||||
├─ ... рабочая область ...
|
||||
ГруппаКнопок (horizontal)
|
||||
├─ Назад (command), Далее (command, defaultButton)
|
||||
└─ Закрыть (stdCommand: Close)
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{
|
||||
"properties": { "commandBarLocation": "None", "windowOpeningMode": "LockWholeInterface" },
|
||||
"elements": [
|
||||
{ "group": "vertical", "name": "Содержимое", "children": [ "..." ] },
|
||||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
||||
{ "button": "Назад", "command": "Назад" },
|
||||
{ "button": "Далее", "command": "Далее", "defaultButton": true },
|
||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Надпись-гиперссылка для открытия подформ
|
||||
|
||||
`labelField` с `hyperlink: true` и событием Click — вместо кнопки. Типичный приём для «ЦеныИВалюта», «УчётнаяПолитика» и подобных.
|
||||
|
||||
```
|
||||
[LabelField] ЦеныИВалютаНадпись -> ЦеныИВалюта (hyperlink) {Click}
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "labelField": "ЦеныИВалютаНадпись", "path": "ЦеныИВалюта",
|
||||
"hyperlink": true, "on": ["Click"] }
|
||||
```
|
||||
|
||||
## Примеры DSL
|
||||
|
||||
### Типичная форма обработки
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Загрузка данных из CSV",
|
||||
"properties": { "autoTitle": false, "windowOpeningMode": "LockOwnerWindow" },
|
||||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
||||
"elements": [
|
||||
{ "group": "vertical", "name": "ГруппаПараметры", "children": [
|
||||
{ "input": "ФайлЗагрузки", "path": "ФайлЗагрузки", "title": "Файл", "clearButton": true, "horizontalStretch": true, "on": ["StartChoice"] },
|
||||
{ "input": "Кодировка", "path": "Кодировка", "title": "Кодировка" },
|
||||
{ "input": "Разделитель", "path": "Разделитель", "title": "Разделитель колонок" }
|
||||
]},
|
||||
{ "table": "Данные", "path": "Объект.Данные", "on": ["OnStartEdit"], "columns": [
|
||||
{ "input": "ДанныеНомерСтроки", "path": "Объект.Данные.LineNumber", "readOnly": true, "title": "№" },
|
||||
{ "input": "ДанныеНаименование", "path": "Объект.Данные.Наименование" },
|
||||
{ "input": "ДанныеКоличество", "path": "Объект.Данные.Количество", "on": ["OnChange"] },
|
||||
{ "input": "ДанныеСумма", "path": "Объект.Данные.Сумма", "readOnly": true }
|
||||
]},
|
||||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
||||
{ "button": "Загрузить", "command": "Загрузить", "title": "Загрузить из файла", "defaultButton": true },
|
||||
{ "button": "Очистить", "command": "Очистить", "title": "Очистить таблицу" },
|
||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
||||
]}
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Объект", "type": "ExternalDataProcessorObject.ЗагрузкаИзCSV", "main": true },
|
||||
{ "name": "ФайлЗагрузки", "type": "string" },
|
||||
{ "name": "Кодировка", "type": "string(20)" },
|
||||
{ "name": "Разделитель", "type": "string(5)" }
|
||||
],
|
||||
"commands": [
|
||||
{ "name": "Загрузить", "action": "ЗагрузитьОбработка" },
|
||||
{ "name": "Очистить", "action": "ОчиститьОбработка" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Типичная форма со списком и фильтрами
|
||||
|
||||
```json
|
||||
{
|
||||
"properties": { "autoTitle": false, "autoSaveDataInSettings": "Use" },
|
||||
"events": {
|
||||
"OnCreateAtServer": "ПриСозданииНаСервере",
|
||||
"NotificationProcessing": "ОбработкаОповещения"
|
||||
},
|
||||
"elements": [
|
||||
{ "group": "alwaysHorizontal", "name": "ГруппаОтборы", "children": [
|
||||
{ "group": "horizontal", "name": "ГруппаОтборОрганизация", "children": [
|
||||
{ "check": "ОтборОрганизацияИспользование", "path": "ОтборОрганизацияИспользование", "titleLocation": "none", "on": ["OnChange"] },
|
||||
{ "input": "ОтборОрганизация", "path": "ОтборОрганизация", "title": "Организация", "on": ["OnChange"] }
|
||||
]},
|
||||
{ "group": "horizontal", "name": "ГруппаОтборКонтрагент", "children": [
|
||||
{ "check": "ОтборКонтрагентИспользование", "path": "ОтборКонтрагентИспользование", "titleLocation": "none", "on": ["OnChange"] },
|
||||
{ "input": "ОтборКонтрагент", "path": "ОтборКонтрагент", "title": "Контрагент", "on": ["OnChange"] }
|
||||
]}
|
||||
]},
|
||||
{ "table": "Список", "path": "Список", "on": ["Selection", "OnActivateRow"], "columns": [
|
||||
{ "labelField": "СписокДата", "path": "Список.Дата", "title": "Дата" },
|
||||
{ "labelField": "СписокНомер", "path": "Список.Номер", "title": "Номер" },
|
||||
{ "labelField": "СписокКонтрагент", "path": "Список.Контрагент" },
|
||||
{ "labelField": "СписокСумма", "path": "Список.Сумма" }
|
||||
]}
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Список", "type": "DynamicList", "mainTable": "Document.РеализацияТоваров" },
|
||||
{ "name": "ОтборОрганизация", "type": "CatalogRef.Организации" },
|
||||
{ "name": "ОтборОрганизацияИспользование", "type": "boolean" },
|
||||
{ "name": "ОтборКонтрагент", "type": "CatalogRef.Контрагенты" },
|
||||
{ "name": "ОтборКонтрагентИспользование", "type": "boolean" }
|
||||
]
|
||||
}
|
||||
```
|
||||
# Паттерны компоновки управляемых форм
|
||||
|
||||
Рекомендации по дизайну форм, извлечённые из типовых конфигураций 1С. Используйте при создании форм через `/form-compile`, когда требования пользователя не детализируют расположение элементов.
|
||||
|
||||
## Архетипы форм
|
||||
|
||||
### Форма документа
|
||||
|
||||
```
|
||||
Шапка (horizontal, 2 колонки)
|
||||
├─ Левая (vertical): НомерДата (H: Номер + Дата "от"), Контрагент, Договор
|
||||
├─ Правая (vertical): Организация, Подразделение, ЦеныИВалюта (надпись-ссылка)
|
||||
Страницы (pages)
|
||||
├─ Товары: таблица Объект.Товары
|
||||
├─ Услуги: таблица Объект.Услуги (опционально)
|
||||
└─ Дополнительно: прочие реквизиты
|
||||
Подвал (vertical)
|
||||
├─ Итоги (horizontal): Всего, НДС, Скидка
|
||||
└─ КомментарийОтветственный (horizontal): Комментарий + Ответственный
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnReadAtServer, OnOpen, BeforeWriteAtServer, AfterWriteAtServer, AfterWrite, NotificationProcessing
|
||||
|
||||
**Свойства:** autoTitle=false, командная панель со стандартными + глобальными командами
|
||||
|
||||
### Форма обработки (DataProcessor)
|
||||
|
||||
```
|
||||
Параметры (vertical)
|
||||
├─ Группа полей ввода (Организация, Период, режимы работы)
|
||||
├─ Информационные надписи (label, hyperlink)
|
||||
Рабочая область
|
||||
├─ Таблица данных или Pages с вкладками
|
||||
Кнопки действий
|
||||
├─ Выполнить / Применить (defaultButton)
|
||||
├─ Закрыть (stdCommand: Close)
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnOpen, NotificationProcessing
|
||||
|
||||
**Свойства:** windowOpeningMode=LockOwnerWindow (если диалог), autoTitle=false
|
||||
|
||||
### Форма списка
|
||||
|
||||
```
|
||||
Отборы (group: alwaysHorizontal)
|
||||
├─ ГруппаОтбор[Поле] (H): Флажок + Поле ввода (для каждого фильтра)
|
||||
Список (table, DynamicList)
|
||||
├─ Колонки: labelField (не input — данные только для чтения)
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnOpen, NotificationProcessing, OnLoadDataFromSettingsAtServer
|
||||
|
||||
**Свойства:** autoSaveDataInSettings=Use (запомнить отборы)
|
||||
|
||||
**Фильтры:** пара реквизитов на каждый фильтр — `Отбор[Поле]` (значение) + `Отбор[Поле]Использование` (boolean, флажок вкл/выкл)
|
||||
|
||||
### Форма элемента справочника
|
||||
|
||||
**Простая:**
|
||||
```
|
||||
ГруппаРеквизитов (horizontal)
|
||||
├─ Наименование -> Объект.Description
|
||||
└─ Код -> Объект.Code (если нужен)
|
||||
```
|
||||
|
||||
**Сложная:**
|
||||
```
|
||||
Главное (vertical)
|
||||
├─ Наименование -> Объект.Description
|
||||
├─ Параметры (horizontal, 2 колонки)
|
||||
│ ├─ Левая: основные реквизиты
|
||||
│ └─ Правая: дополнительные реквизиты
|
||||
└─ КонтактныеДанные / Дополнительно (vertical)
|
||||
```
|
||||
|
||||
**Типичные события:** OnCreateAtServer, OnReadAtServer, BeforeWriteAtServer, NotificationProcessing
|
||||
|
||||
### Мастер (Wizard)
|
||||
|
||||
```
|
||||
Страницы (pages, OnCurrentPageChange)
|
||||
├─ Шаг1: описание + параметры
|
||||
├─ Шаг2: основная работа
|
||||
└─ Шаг3: результат
|
||||
Кнопки (horizontal)
|
||||
├─ Назад (command), Далее (command, defaultButton), Выполнить (command)
|
||||
└─ Закрыть (stdCommand: Close)
|
||||
```
|
||||
|
||||
**Свойства:** windowOpeningMode=LockOwnerWindow
|
||||
|
||||
## Конвенции именования
|
||||
|
||||
### Группы
|
||||
|
||||
| Назначение | Имя | Тип |
|
||||
|-----------|-----|-----|
|
||||
| Шапка | `ГруппаШапка` | horizontal |
|
||||
| Левая колонка | `ГруппаШапкаЛевая` | vertical |
|
||||
| Правая колонка | `ГруппаШапкаПравая` | vertical |
|
||||
| Номер+Дата | `ГруппаНомерДата` | horizontal |
|
||||
| Подвал | `ГруппаПодвал` | vertical |
|
||||
| Итоги | `ГруппаИтоги` | horizontal |
|
||||
| Кнопки | `ГруппаКнопок` | horizontal |
|
||||
| Страницы | `ГруппаСтраницы` / `Страницы` | pages |
|
||||
| Предупреждение | `ГруппаПредупреждение` | horizontal, visible:false |
|
||||
| Доп. секция | `ГруппаДополнительно` / `ГруппаПрочее` | vertical, collapse |
|
||||
|
||||
### Элементы
|
||||
|
||||
| Назначение | Имя | Суффикс |
|
||||
|-----------|-----|---------|
|
||||
| Поле в таблице | `[Таблица][Поле]` | — |
|
||||
| Итог | `Итоги[Поле]` | — |
|
||||
| Надпись-ссылка | `[Поле]Надпись` | — |
|
||||
| Фильтр | `Отбор[Поле]` | — |
|
||||
| Флажок фильтра | `Отбор[Поле]Использование` | — |
|
||||
| Кнопка команды | `[Команда]Кнопка` | — |
|
||||
| Баннер-картинка | `[Баннер]Картинка` | — |
|
||||
| Баннер-надпись | `[Баннер]Надпись` | — |
|
||||
| Подменю | `Подменю[Действие]` | — |
|
||||
|
||||
### Обработчики событий
|
||||
|
||||
Имя обработчика = имя элемента + суффикс события на русском:
|
||||
|
||||
| Событие | Суффикс | Пример |
|
||||
|---------|---------|--------|
|
||||
| OnChange | ПриИзменении | `ОрганизацияПриИзменении` |
|
||||
| StartChoice | НачалоВыбора | `КонтрагентНачалоВыбора` |
|
||||
| Click | Нажатие | `ЦеныИВалютаНажатие` |
|
||||
| OnEditEnd | ПриОкончанииРедактирования | `ТоварыПриОкончанииРедактирования` |
|
||||
| OnStartEdit | ПриНачалеРедактирования | `ТоварыПриНачалеРедактирования` |
|
||||
|
||||
Обработчики формы — стандартные имена: `ПриСозданииНаСервере`, `ПриОткрытии`, `ПередЗакрытием`, `ОбработкаОповещения`.
|
||||
|
||||
## Принципы компоновки
|
||||
|
||||
1. **Порядок чтения.** Сверху вниз, слева направо. Самое важное — вверху.
|
||||
2. **Двухколоночная шапка.** Основные реквизиты слева (контрагент, склад), организационные справа (организация, подразделение).
|
||||
3. **Кнопки действий внизу.** Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя.
|
||||
4. **Таблицы — основная область.** Табличные части занимают большую часть формы, обычно на Pages.
|
||||
5. **Итоги рядом с таблицей.** В подвале, горизонтальная группа, все поля readOnly.
|
||||
6. **Фильтры — отдельная зона.** Над списком, горизонтальная группа (alwaysHorizontal), пара "флажок + поле" на каждый фильтр.
|
||||
7. **Скрытые элементы для состояний.** Баннеры, предупреждения — `visible: false` по умолчанию, показываются программно.
|
||||
8. **Надписи-ссылки для диалогов.** `labelField` с `hyperlink: true` и событием Click — для открытия подформ (ЦеныИВалюта, УчётнаяПолитика).
|
||||
|
||||
## Продвинутые паттерны (ERP)
|
||||
|
||||
Извлечены из конфигурации «Управление предприятием» (ERP 8.3.24). Применяйте в сложных формах.
|
||||
|
||||
### Сворачиваемые группы (Collapsible)
|
||||
|
||||
Для необязательных секций — «Подписи», «Дополнительно», «Прочее». Сворачиваются по умолчанию, экономят место.
|
||||
|
||||
```
|
||||
ГруппаПодписи (vertical, collapse, collapsed)
|
||||
├─ Руководитель -> Объект.Руководитель
|
||||
└─ ГлавныйБухгалтер -> Объект.ГлавныйБухгалтер
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "group": "vertical", "name": "ГруппаПодписи", "title": "Подписи",
|
||||
"behavior": "Collapsible", "collapsed": true, "children": [
|
||||
{ "input": "Руководитель", "path": "Объект.Руководитель" },
|
||||
{ "input": "ГлавныйБухгалтер", "path": "Объект.ГлавныйБухгалтер" }
|
||||
]}
|
||||
```
|
||||
|
||||
### Баннер-предупреждение (Status Banner)
|
||||
|
||||
Группа «картинка + надпись» без заголовка, скрыта по умолчанию. Показывается программно при определённых условиях (просрочка, блокировка, информация).
|
||||
|
||||
```
|
||||
ГруппаПредупреждение (horizontal, showTitle:false, visible:false)
|
||||
├─ [Picture] ПредупреждениеКартинка -> StdPicture.Information
|
||||
└─ [Label] ПредупреждениеНадпись (maxWidth:76, textColor:style:ПоясняющийТекст)
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "group": "horizontal", "name": "ГруппаПредупреждение", "showTitle": false,
|
||||
"visible": false, "children": [
|
||||
{ "picture": "ПредупреждениеКартинка" },
|
||||
{ "label": "ПредупреждениеНадпись", "title": "Текст предупреждения",
|
||||
"maxWidth": 76, "autoMaxWidth": false }
|
||||
]}
|
||||
```
|
||||
|
||||
### Выпадающее меню в командной панели (Popup)
|
||||
|
||||
Группировка связанных команд (печать, отправка, выгрузка) в одну кнопку-меню с иконкой.
|
||||
|
||||
```
|
||||
[CmdBar] КоманднаяПанель
|
||||
├─ [Popup] ПодменюПечать (picture: StdPicture.Print, representation: Picture)
|
||||
│ ├─ [Button] ПечатьНакладная -> Печать [cmd]
|
||||
│ └─ [Button] ПечатьСчёт -> ПечатьСчёт [cmd]
|
||||
└─ [Popup] ПодменюОтправить (picture: StdPicture.SendByEmail)
|
||||
└─ [Button] ОтправитьПоПочте -> Отправить [cmd]
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "cmdBar": "КоманднаяПанель", "children": [
|
||||
{ "popup": "ПодменюПечать", "title": "Печать",
|
||||
"picture": "StdPicture.Print", "representation": "Picture", "children": [
|
||||
{ "button": "ПечатьНакладная", "command": "Печать" },
|
||||
{ "button": "ПечатьСчёт", "command": "ПечатьСчёт" }
|
||||
]},
|
||||
{ "popup": "ПодменюОтправить", "title": "Отправить",
|
||||
"picture": "StdPicture.SendByEmail", "representation": "Picture", "children": [
|
||||
{ "button": "ОтправитьПоПочте", "command": "Отправить" }
|
||||
]}
|
||||
]}
|
||||
```
|
||||
|
||||
### Форма без стандартной командной панели
|
||||
|
||||
Для модальных диалогов и мастеров — отключение стандартной командной панели, полностью ручное управление кнопками.
|
||||
|
||||
```
|
||||
properties: commandBarLocation=None, windowOpeningMode=LockWholeInterface
|
||||
Содержимое (vertical)
|
||||
├─ ... рабочая область ...
|
||||
ГруппаКнопок (horizontal)
|
||||
├─ Назад (command), Далее (command, defaultButton)
|
||||
└─ Закрыть (stdCommand: Close)
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{
|
||||
"properties": { "commandBarLocation": "None", "windowOpeningMode": "LockWholeInterface" },
|
||||
"elements": [
|
||||
{ "group": "vertical", "name": "Содержимое", "children": [ "..." ] },
|
||||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
||||
{ "button": "Назад", "command": "Назад" },
|
||||
{ "button": "Далее", "command": "Далее", "defaultButton": true },
|
||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Надпись-гиперссылка для открытия подформ
|
||||
|
||||
`labelField` с `hyperlink: true` и событием Click — вместо кнопки. Типичный приём для «ЦеныИВалюта», «УчётнаяПолитика» и подобных.
|
||||
|
||||
```
|
||||
[LabelField] ЦеныИВалютаНадпись -> ЦеныИВалюта (hyperlink) {Click}
|
||||
```
|
||||
|
||||
DSL:
|
||||
```json
|
||||
{ "labelField": "ЦеныИВалютаНадпись", "path": "ЦеныИВалюта",
|
||||
"hyperlink": true, "on": ["Click"] }
|
||||
```
|
||||
|
||||
## Примеры DSL
|
||||
|
||||
### Типичная форма обработки
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Загрузка данных из CSV",
|
||||
"properties": { "autoTitle": false, "windowOpeningMode": "LockOwnerWindow" },
|
||||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
||||
"elements": [
|
||||
{ "group": "vertical", "name": "ГруппаПараметры", "children": [
|
||||
{ "input": "ФайлЗагрузки", "path": "ФайлЗагрузки", "title": "Файл", "clearButton": true, "horizontalStretch": true, "on": ["StartChoice"] },
|
||||
{ "input": "Кодировка", "path": "Кодировка", "title": "Кодировка" },
|
||||
{ "input": "Разделитель", "path": "Разделитель", "title": "Разделитель колонок" }
|
||||
]},
|
||||
{ "table": "Данные", "path": "Объект.Данные", "on": ["OnStartEdit"], "columns": [
|
||||
{ "input": "ДанныеНомерСтроки", "path": "Объект.Данные.LineNumber", "readOnly": true, "title": "№" },
|
||||
{ "input": "ДанныеНаименование", "path": "Объект.Данные.Наименование" },
|
||||
{ "input": "ДанныеКоличество", "path": "Объект.Данные.Количество", "on": ["OnChange"] },
|
||||
{ "input": "ДанныеСумма", "path": "Объект.Данные.Сумма", "readOnly": true }
|
||||
]},
|
||||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
||||
{ "button": "Загрузить", "command": "Загрузить", "title": "Загрузить из файла", "defaultButton": true },
|
||||
{ "button": "Очистить", "command": "Очистить", "title": "Очистить таблицу" },
|
||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
||||
]}
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Объект", "type": "ExternalDataProcessorObject.ЗагрузкаИзCSV", "main": true },
|
||||
{ "name": "ФайлЗагрузки", "type": "string" },
|
||||
{ "name": "Кодировка", "type": "string(20)" },
|
||||
{ "name": "Разделитель", "type": "string(5)" }
|
||||
],
|
||||
"commands": [
|
||||
{ "name": "Загрузить", "action": "ЗагрузитьОбработка" },
|
||||
{ "name": "Очистить", "action": "ОчиститьОбработка" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Типичная форма со списком и фильтрами
|
||||
|
||||
```json
|
||||
{
|
||||
"properties": { "autoTitle": false, "autoSaveDataInSettings": "Use" },
|
||||
"events": {
|
||||
"OnCreateAtServer": "ПриСозданииНаСервере",
|
||||
"NotificationProcessing": "ОбработкаОповещения"
|
||||
},
|
||||
"elements": [
|
||||
{ "group": "alwaysHorizontal", "name": "ГруппаОтборы", "children": [
|
||||
{ "group": "horizontal", "name": "ГруппаОтборОрганизация", "children": [
|
||||
{ "check": "ОтборОрганизацияИспользование", "path": "ОтборОрганизацияИспользование", "titleLocation": "none", "on": ["OnChange"] },
|
||||
{ "input": "ОтборОрганизация", "path": "ОтборОрганизация", "title": "Организация", "on": ["OnChange"] }
|
||||
]},
|
||||
{ "group": "horizontal", "name": "ГруппаОтборКонтрагент", "children": [
|
||||
{ "check": "ОтборКонтрагентИспользование", "path": "ОтборКонтрагентИспользование", "titleLocation": "none", "on": ["OnChange"] },
|
||||
{ "input": "ОтборКонтрагент", "path": "ОтборКонтрагент", "title": "Контрагент", "on": ["OnChange"] }
|
||||
]}
|
||||
]},
|
||||
{ "table": "Список", "path": "Список", "on": ["Selection", "OnActivateRow"], "columns": [
|
||||
{ "labelField": "СписокДата", "path": "Список.Дата", "title": "Дата" },
|
||||
{ "labelField": "СписокНомер", "path": "Список.Номер", "title": "Номер" },
|
||||
{ "labelField": "СписокКонтрагент", "path": "Список.Контрагент" },
|
||||
{ "labelField": "СписокСумма", "path": "Список.Сумма" }
|
||||
]}
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Список", "type": "DynamicList", "mainTable": "Document.РеализацияТоваров" },
|
||||
{ "name": "ОтборОрганизация", "type": "CatalogRef.Организации" },
|
||||
{ "name": "ОтборОрганизацияИспользование", "type": "boolean" },
|
||||
{ "name": "ОтборКонтрагент", "type": "CatalogRef.Контрагенты" },
|
||||
{ "name": "ОтборКонтрагентИспользование", "type": "boolean" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
+1113
-1113
File diff suppressed because it is too large
Load Diff
+187
-187
@@ -1,187 +1,187 @@
|
||||
# Объекты метаданных конфигурации
|
||||
|
||||
Навыки группы `/meta-*` позволяют создавать, анализировать, редактировать и проверять объекты метаданных конфигурации 1С — справочники, документы, регистры, перечисления и ещё 19 типов объектов из XML-выгрузки.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/meta-info` | `<ObjectPath> [-Mode] [-Name]` | Анализ структуры объекта: реквизиты, ТЧ, формы, движения, типы (8 режимов) |
|
||||
| `/meta-compile` | `<JsonPath> <OutputPath>` | Создание объекта метаданных из JSON DSL: реквизиты, ТЧ, свойства, формы |
|
||||
| `/meta-edit` | `<ObjectPath> -Operation <op> -Value "<val>"` | Точечное редактирование: 30+ атомарных операций (add/remove/modify/set) |
|
||||
| `/meta-remove` | `<ConfigDir> -Object <Type.Name> [-DryRun] [-Force]` | Безопасное удаление объекта с проверкой ссылок (блокирует при наличии) |
|
||||
| `/meta-validate` | `<ObjectPath> [-MaxErrors 20]` | Валидация структурной корректности: ~40 проверок |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание объекта (текст) → JSON DSL → /meta-compile → XML-исходники → /meta-validate
|
||||
↕ /meta-edit → /meta-info
|
||||
↕ /meta-remove (безопасное удаление)
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение объекта (тип, реквизиты, ТЧ, свойства)
|
||||
2. `/meta-compile` генерирует XML-исходники с корректными UUID, namespace, структурой ChildObjects
|
||||
3. `/meta-edit` вносит точечные изменения: добавление/удаление реквизитов, ТЧ, владельцев, движений и т.д.
|
||||
4. `/meta-remove` безопасно удаляет объект (проверяет ссылки в реквизитах, коде, формах; чистит Configuration.xml и подсистемы)
|
||||
5. `/meta-validate` проверяет корректность XML
|
||||
6. `/meta-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## Поддерживаемые типы объектов (23 типа)
|
||||
|
||||
| Группа | Типы |
|
||||
|--------|------|
|
||||
| Прикладные | Catalog, Document, Enum, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes |
|
||||
| Процессы | BusinessProcess, Task |
|
||||
| Регистры | InformationRegister, AccumulationRegister, AccountingRegister, CalculationRegister |
|
||||
| Отчёты/обработки | Report, DataProcessor |
|
||||
| Интеграция | ExchangePlan, HTTPService, WebService |
|
||||
| Журналы | DocumentJournal, Sequence |
|
||||
| Прочие | Constant, CommonModule, SessionParameter, FunctionalOption, DefinedType |
|
||||
|
||||
## Inline mode — типовые операции
|
||||
|
||||
### Реквизиты
|
||||
|
||||
```powershell
|
||||
# Добавить
|
||||
-Operation add-attribute -Value "Комментарий: Строка(200) ;; Сумма: Число(15,2) | req, index"
|
||||
|
||||
# С позиционной вставкой
|
||||
-Operation add-attribute -Value "Склад: CatalogRef.Склады >> after Организация"
|
||||
|
||||
# Удалить
|
||||
-Operation remove-attribute -Value "УстаревшийРеквизит"
|
||||
|
||||
# Переименовать + сменить тип
|
||||
-Operation modify-attribute -Value "СтароеИмя: name=НовоеИмя, type=Строка(500)"
|
||||
```
|
||||
|
||||
### Табличные части
|
||||
|
||||
```powershell
|
||||
# Создать ТЧ с реквизитами
|
||||
-Operation add-ts -Value "Товары: Ном: CatalogRef.Ном | req, Кол: Число(15,3), Цена: Число(15,2)"
|
||||
|
||||
# Добавить реквизит в существующую ТЧ
|
||||
-Operation add-ts-attribute -Value "Товары.СтавкаНДС: EnumRef.СтавкиНДС"
|
||||
|
||||
# Изменить свойства ТЧ
|
||||
-Operation modify-ts -Value "Товары: synonym=Товарный состав"
|
||||
```
|
||||
|
||||
### Свойства объекта
|
||||
|
||||
```powershell
|
||||
# Скалярные свойства
|
||||
-Operation modify-property -Value "CodeLength=11 ;; DescriptionLength=150"
|
||||
|
||||
# Владельцы справочника
|
||||
-Operation set-owners -Value "Catalog.Контрагенты ;; Catalog.Организации"
|
||||
|
||||
# Движения документа
|
||||
-Operation add-registerRecord -Value "AccumulationRegister.Продажи ;; AccumulationRegister.ОстаткиТоваров"
|
||||
```
|
||||
|
||||
### Регистры
|
||||
|
||||
```powershell
|
||||
-Operation add-dimension -Value "Организация: CatalogRef.Организации | master, mainFilter"
|
||||
-Operation add-resource -Value "Сумма: Число(15,2)"
|
||||
```
|
||||
|
||||
## JSON mode — комбинированные операции
|
||||
|
||||
Для сложных сценариев (несколько типов изменений в одном вызове) используйте JSON-файл:
|
||||
|
||||
```json
|
||||
{
|
||||
"add": {
|
||||
"attributes": ["Комментарий: Строка(200)"],
|
||||
"tabularSections": [{
|
||||
"name": "Товары",
|
||||
"attrs": ["Ном: CatalogRef.Ном | req", "Кол: Число(15,3)"]
|
||||
}]
|
||||
},
|
||||
"remove": { "attributes": ["УстаревшийРеквизит"] },
|
||||
"modify": {
|
||||
"properties": { "DescriptionLength": 150 },
|
||||
"attributes": { "СтароеИмя": { "name": "НовоеИмя" } }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
JSON поддерживает русские синонимы ключей (`реквизиты`, `тч`, `измерения` и др.) и типов (`Строка`, `Число`, `СправочникСсылка` и др.).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ существующего объекта
|
||||
|
||||
```
|
||||
> Покажи структуру справочника Catalogs/Номенклатура
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-info` и покажет: реквизиты с типами, табличные части, формы, владельцев, ввод по строке.
|
||||
|
||||
### Создание нового объекта
|
||||
|
||||
```
|
||||
> Создай справочник Контрагенты: код 9, наименование 150, реквизиты ИНН(12), КПП(9),
|
||||
> иерархический с группами, владелец — Catalog.Организации
|
||||
```
|
||||
|
||||
Claude сформирует JSON и вызовет `/meta-compile` → `/meta-validate` → `/meta-info`.
|
||||
|
||||
### Добавление реквизитов к существующему объекту
|
||||
|
||||
```
|
||||
> Добавь в документ Documents/ЗаказКлиента реквизиты Склад (CatalogRef.Склады)
|
||||
> и ТЧ Товары с реквизитами Номенклатура, Количество, Цена, Сумма
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-edit` дважды: `add-attribute` для реквизита и `add-ts` для ТЧ.
|
||||
|
||||
### Настройка движений документа
|
||||
|
||||
```
|
||||
> Документ Documents/ПриходТоваров должен делать движения
|
||||
> по AccumulationRegister.ОстаткиТоваров и AccumulationRegister.Партии
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-edit` с операцией `set-registerRecords`.
|
||||
|
||||
### Удаление неиспользуемого объекта
|
||||
|
||||
```
|
||||
> Удали справочник Catalogs/Устаревший из конфигурации src/
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-remove` с `-DryRun`, покажет что будет удалено и проверит ссылки. Если объект нигде не используется — удалит файлы, уберёт из Configuration.xml и подсистем. Если есть ссылки — покажет список и заблокирует удаление.
|
||||
|
||||
### Проверка объекта после изменений
|
||||
|
||||
```
|
||||
> Проверь корректность Documents/ЗаказКлиента
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-validate` и покажет ошибки и предупреждения.
|
||||
|
||||
## Структура файлов объекта метаданных
|
||||
|
||||
```
|
||||
<MetaType>/<ObjectName>/
|
||||
├── <ObjectName>.xml # Основной XML (Properties, ChildObjects)
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl # Модуль объекта (опционально)
|
||||
├── Forms/
|
||||
│ └── <FormName>/ # Формы объекта
|
||||
├── Templates/
|
||||
│ └── <TemplateName>/ # Макеты
|
||||
└── Commands/
|
||||
└── <CommandName>/ # Команды
|
||||
```
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-config-objects-spec.md](1c-config-objects-spec.md) — XML-формат объектов метаданных, Properties, ChildObjects, типы
|
||||
- [meta-dsl-spec.md](meta-dsl-spec.md) — JSON DSL для описания объектов (`/meta-compile`)
|
||||
# Объекты метаданных конфигурации
|
||||
|
||||
Навыки группы `/meta-*` позволяют создавать, анализировать, редактировать и проверять объекты метаданных конфигурации 1С — справочники, документы, регистры, перечисления и ещё 19 типов объектов из XML-выгрузки.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/meta-info` | `<ObjectPath> [-Mode] [-Name]` | Анализ структуры объекта: реквизиты, ТЧ, формы, движения, типы (8 режимов) |
|
||||
| `/meta-compile` | `<JsonPath> <OutputPath>` | Создание объекта метаданных из JSON DSL: реквизиты, ТЧ, свойства, формы |
|
||||
| `/meta-edit` | `<ObjectPath> -Operation <op> -Value "<val>"` | Точечное редактирование: 30+ атомарных операций (add/remove/modify/set) |
|
||||
| `/meta-remove` | `<ConfigDir> -Object <Type.Name> [-DryRun] [-Force]` | Безопасное удаление объекта с проверкой ссылок (блокирует при наличии) |
|
||||
| `/meta-validate` | `<ObjectPath> [-MaxErrors 20]` | Валидация структурной корректности: ~40 проверок |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание объекта (текст) → JSON DSL → /meta-compile → XML-исходники → /meta-validate
|
||||
↕ /meta-edit → /meta-info
|
||||
↕ /meta-remove (безопасное удаление)
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение объекта (тип, реквизиты, ТЧ, свойства)
|
||||
2. `/meta-compile` генерирует XML-исходники с корректными UUID, namespace, структурой ChildObjects
|
||||
3. `/meta-edit` вносит точечные изменения: добавление/удаление реквизитов, ТЧ, владельцев, движений и т.д.
|
||||
4. `/meta-remove` безопасно удаляет объект (проверяет ссылки в реквизитах, коде, формах; чистит Configuration.xml и подсистемы)
|
||||
5. `/meta-validate` проверяет корректность XML
|
||||
6. `/meta-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## Поддерживаемые типы объектов (23 типа)
|
||||
|
||||
| Группа | Типы |
|
||||
|--------|------|
|
||||
| Прикладные | Catalog, Document, Enum, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes |
|
||||
| Процессы | BusinessProcess, Task |
|
||||
| Регистры | InformationRegister, AccumulationRegister, AccountingRegister, CalculationRegister |
|
||||
| Отчёты/обработки | Report, DataProcessor |
|
||||
| Интеграция | ExchangePlan, HTTPService, WebService |
|
||||
| Журналы | DocumentJournal, Sequence |
|
||||
| Прочие | Constant, CommonModule, SessionParameter, FunctionalOption, DefinedType |
|
||||
|
||||
## Inline mode — типовые операции
|
||||
|
||||
### Реквизиты
|
||||
|
||||
```powershell
|
||||
# Добавить
|
||||
-Operation add-attribute -Value "Комментарий: Строка(200) ;; Сумма: Число(15,2) | req, index"
|
||||
|
||||
# С позиционной вставкой
|
||||
-Operation add-attribute -Value "Склад: CatalogRef.Склады >> after Организация"
|
||||
|
||||
# Удалить
|
||||
-Operation remove-attribute -Value "УстаревшийРеквизит"
|
||||
|
||||
# Переименовать + сменить тип
|
||||
-Operation modify-attribute -Value "СтароеИмя: name=НовоеИмя, type=Строка(500)"
|
||||
```
|
||||
|
||||
### Табличные части
|
||||
|
||||
```powershell
|
||||
# Создать ТЧ с реквизитами
|
||||
-Operation add-ts -Value "Товары: Ном: CatalogRef.Ном | req, Кол: Число(15,3), Цена: Число(15,2)"
|
||||
|
||||
# Добавить реквизит в существующую ТЧ
|
||||
-Operation add-ts-attribute -Value "Товары.СтавкаНДС: EnumRef.СтавкиНДС"
|
||||
|
||||
# Изменить свойства ТЧ
|
||||
-Operation modify-ts -Value "Товары: synonym=Товарный состав"
|
||||
```
|
||||
|
||||
### Свойства объекта
|
||||
|
||||
```powershell
|
||||
# Скалярные свойства
|
||||
-Operation modify-property -Value "CodeLength=11 ;; DescriptionLength=150"
|
||||
|
||||
# Владельцы справочника
|
||||
-Operation set-owners -Value "Catalog.Контрагенты ;; Catalog.Организации"
|
||||
|
||||
# Движения документа
|
||||
-Operation add-registerRecord -Value "AccumulationRegister.Продажи ;; AccumulationRegister.ОстаткиТоваров"
|
||||
```
|
||||
|
||||
### Регистры
|
||||
|
||||
```powershell
|
||||
-Operation add-dimension -Value "Организация: CatalogRef.Организации | master, mainFilter"
|
||||
-Operation add-resource -Value "Сумма: Число(15,2)"
|
||||
```
|
||||
|
||||
## JSON mode — комбинированные операции
|
||||
|
||||
Для сложных сценариев (несколько типов изменений в одном вызове) используйте JSON-файл:
|
||||
|
||||
```json
|
||||
{
|
||||
"add": {
|
||||
"attributes": ["Комментарий: Строка(200)"],
|
||||
"tabularSections": [{
|
||||
"name": "Товары",
|
||||
"attrs": ["Ном: CatalogRef.Ном | req", "Кол: Число(15,3)"]
|
||||
}]
|
||||
},
|
||||
"remove": { "attributes": ["УстаревшийРеквизит"] },
|
||||
"modify": {
|
||||
"properties": { "DescriptionLength": 150 },
|
||||
"attributes": { "СтароеИмя": { "name": "НовоеИмя" } }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
JSON поддерживает русские синонимы ключей (`реквизиты`, `тч`, `измерения` и др.) и типов (`Строка`, `Число`, `СправочникСсылка` и др.).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ существующего объекта
|
||||
|
||||
```
|
||||
> Покажи структуру справочника Catalogs/Номенклатура
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-info` и покажет: реквизиты с типами, табличные части, формы, владельцев, ввод по строке.
|
||||
|
||||
### Создание нового объекта
|
||||
|
||||
```
|
||||
> Создай справочник Контрагенты: код 9, наименование 150, реквизиты ИНН(12), КПП(9),
|
||||
> иерархический с группами, владелец — Catalog.Организации
|
||||
```
|
||||
|
||||
Claude сформирует JSON и вызовет `/meta-compile` → `/meta-validate` → `/meta-info`.
|
||||
|
||||
### Добавление реквизитов к существующему объекту
|
||||
|
||||
```
|
||||
> Добавь в документ Documents/ЗаказКлиента реквизиты Склад (CatalogRef.Склады)
|
||||
> и ТЧ Товары с реквизитами Номенклатура, Количество, Цена, Сумма
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-edit` дважды: `add-attribute` для реквизита и `add-ts` для ТЧ.
|
||||
|
||||
### Настройка движений документа
|
||||
|
||||
```
|
||||
> Документ Documents/ПриходТоваров должен делать движения
|
||||
> по AccumulationRegister.ОстаткиТоваров и AccumulationRegister.Партии
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-edit` с операцией `set-registerRecords`.
|
||||
|
||||
### Удаление неиспользуемого объекта
|
||||
|
||||
```
|
||||
> Удали справочник Catalogs/Устаревший из конфигурации src/
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-remove` с `-DryRun`, покажет что будет удалено и проверит ссылки. Если объект нигде не используется — удалит файлы, уберёт из Configuration.xml и подсистем. Если есть ссылки — покажет список и заблокирует удаление.
|
||||
|
||||
### Проверка объекта после изменений
|
||||
|
||||
```
|
||||
> Проверь корректность Documents/ЗаказКлиента
|
||||
```
|
||||
|
||||
Claude вызовет `/meta-validate` и покажет ошибки и предупреждения.
|
||||
|
||||
## Структура файлов объекта метаданных
|
||||
|
||||
```
|
||||
<MetaType>/<ObjectName>/
|
||||
├── <ObjectName>.xml # Основной XML (Properties, ChildObjects)
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl # Модуль объекта (опционально)
|
||||
├── Forms/
|
||||
│ └── <FormName>/ # Формы объекта
|
||||
├── Templates/
|
||||
│ └── <TemplateName>/ # Макеты
|
||||
└── Commands/
|
||||
└── <CommandName>/ # Команды
|
||||
```
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-config-objects-spec.md](1c-config-objects-spec.md) — XML-формат объектов метаданных, Properties, ChildObjects, типы
|
||||
- [meta-dsl-spec.md](meta-dsl-spec.md) — JSON DSL для описания объектов (`/meta-compile`)
|
||||
|
||||
+160
-160
@@ -1,160 +1,160 @@
|
||||
# Спецификация MXL DSL — JSON-формат описания табличного документа
|
||||
|
||||
Компактный JSON-формат для описания макетов табличных документов 1С (SpreadsheetDocument). Используется навыками `/mxl-compile` (JSON → XML) и `/mxl-decompile` (XML → JSON).
|
||||
|
||||
## Пример
|
||||
|
||||
```json
|
||||
{
|
||||
"columns": 10,
|
||||
"defaultWidth": 30,
|
||||
"columnWidths": { "1": 15, "2-8": 40, "9-10": 50 },
|
||||
|
||||
"fonts": {
|
||||
"default": { "face": "Arial", "size": 10 },
|
||||
"bold": { "face": "Arial", "size": 10, "bold": true },
|
||||
"header": { "face": "Arial", "size": 14, "bold": true }
|
||||
},
|
||||
|
||||
"styles": {
|
||||
"default": {},
|
||||
"header": { "font": "header", "align": "center" },
|
||||
"label": { "font": "bold" },
|
||||
"bordered": { "border": "all" },
|
||||
"bordered-right": { "border": "all", "align": "right" },
|
||||
"total-right": { "font": "bold", "border": "top", "align": "right" }
|
||||
},
|
||||
|
||||
"areas": [
|
||||
{
|
||||
"name": "Заголовок",
|
||||
"rows": [
|
||||
{ "height": 20, "cells": [
|
||||
{ "col": 1, "span": 10, "style": "header", "param": "ТекстЗаголовка" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ШапкаТаблицы",
|
||||
"rows": [
|
||||
{ "rowStyle": "bordered", "cells": [
|
||||
{ "col": 1, "text": "№" },
|
||||
{ "col": 2, "span": 6, "text": "Наименование" },
|
||||
{ "col": 9, "text": "Кол-во" },
|
||||
{ "col": 10, "text": "Сумма" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Строка",
|
||||
"rows": [
|
||||
{ "rowStyle": "bordered", "cells": [
|
||||
{ "col": 1, "param": "НомерСтроки" },
|
||||
{ "col": 2, "span": 6, "param": "Товар", "detail": "Номенклатура" },
|
||||
{ "col": 9, "style": "bordered-right", "param": "Количество" },
|
||||
{ "col": 10, "style": "bordered-right", "param": "Сумма" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Итого",
|
||||
"rows": [
|
||||
{ "cells": [
|
||||
{ "col": 8, "span": 2, "style": "total-right", "text": "Итого:" },
|
||||
{ "col": 10, "style": "total-right", "param": "Всего" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Верхний уровень
|
||||
|
||||
| Поле | Обяз. | По умолч. | Описание |
|
||||
|------|:-----:|-----------|----------|
|
||||
| `columns` | да | — | Количество колонок |
|
||||
| `page` | нет | — | Формат страницы: `"A4-landscape"` (780), `"A4-portrait"` (540) или число. Автоматически вычисляет `defaultWidth` из суммы пропорций `"Nx"` |
|
||||
| `defaultWidth` | нет | 10 | Ширина колонок по умолчанию. Игнорируется если задан `page` и все колонки используют `"Nx"` |
|
||||
| `columnWidths` | нет | `{}` | Ширины колонок. Ключи 1-based: `"1"`, `"3-14"`, `"5,7,9"`. Значения: число (абсолют) или `"Nx"` (множитель от defaultWidth, напр. `"2x"`, `"0.5x"`) |
|
||||
| `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) |
|
||||
| `styles` | нет | `{}` | Именованные стили |
|
||||
| `areas` | да | — | Массив именованных областей (порядок = порядок в документе) |
|
||||
|
||||
## Шрифты (`fonts.<name>`)
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `face` | `"Arial"` | Имя шрифта |
|
||||
| `size` | `10` | Размер |
|
||||
| `bold` | `false` | Жирный |
|
||||
| `italic` | `false` | Курсив |
|
||||
| `underline` | `false` | Подчёркнутый |
|
||||
| `strikeout` | `false` | Зачёркнутый |
|
||||
|
||||
Шрифт `"default"` используется когда стиль не указывает шрифт явно. Если не определён, создаётся автоматически (Arial 10).
|
||||
|
||||
## Стили (`styles.<name>`)
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `font` | `"default"` | Ссылка на имя шрифта |
|
||||
| `align` | — | `left`, `center`, `right` |
|
||||
| `valign` | — | `top`, `center` |
|
||||
| `border` | — | Стороны рамки: `all`, `top`, `bottom`, `left`, `right`, `none`. Через запятую: `"top,bottom"` |
|
||||
| `borderWidth` | `"thin"` | Толщина рамки: `thin` (1px) или `thick` (2px) |
|
||||
| `wrap` | `false` | Перенос текста |
|
||||
| `format` | — | Формат данных 1С: `"ЧЦ=15; ЧДЦ=2"`, `"ДФ=dd.MM.yyyy"` и т.д. |
|
||||
|
||||
## Области (`areas[]`)
|
||||
|
||||
| Поле | Обяз. | Описание |
|
||||
|------|:-----:|----------|
|
||||
| `name` | да | Имя области для `Макет.ПолучитьОбласть("Имя")` |
|
||||
| `rows` | да | Массив строк |
|
||||
|
||||
## Строки (`rows[]`)
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `height` | — | Высота строки (если не задана, используется авто) |
|
||||
| `rowStyle` | — | Стиль для ВСЕХ колонок (заполняет пустоты рамками) |
|
||||
| `cells` | `[]` | Массив ячеек |
|
||||
| `empty` | — | Количество подряд идущих пустых строк (заменяет N отдельных `{}`) |
|
||||
|
||||
Строка без `cells` и `rowStyle` → пустая строка. `{ "empty": 3 }` эквивалентно трём `{}`.
|
||||
|
||||
## Ячейки (`cells[]`)
|
||||
|
||||
| Поле | Обяз. | По умолч. | Описание |
|
||||
|------|:-----:|-----------|----------|
|
||||
| `col` | да | — | Позиция колонки (1-based) |
|
||||
| `span` | нет | `1` | Объединение по горизонтали (количество колонок) |
|
||||
| `rowspan` | нет | `1` | Объединение по вертикали (количество строк) |
|
||||
| `style` | нет | rowStyle | Стиль ячейки (переопределяет rowStyle) |
|
||||
| `param` | нет | — | Параметр заполнения |
|
||||
| `detail` | нет | — | Параметр расшифровки (только с `param`) |
|
||||
| `text` | нет | — | Статический текст |
|
||||
| `template` | нет | — | Шаблонный текст с `[Параметр]` |
|
||||
|
||||
### Тип заполнения
|
||||
|
||||
Определяется автоматически по содержимому ячейки:
|
||||
- `param` → fillType=Parameter
|
||||
- `template` → fillType=Template
|
||||
- `text` → fillType=Text
|
||||
- ничего → без fillType (пустая ячейка или рамка)
|
||||
|
||||
## `rowStyle` — автозаполнение
|
||||
|
||||
Когда задан `rowStyle`, компилятор создаёт ячейки для ВСЕХ колонок строки. Позиции без явных ячеек заполняются пустыми ячейками с указанным стилем. Это обеспечивает сплошные рамки в табличных строках.
|
||||
|
||||
Если в предыдущих строках той же области есть ячейки с `rowspan`, их колонки при автозаполнении пропускаются.
|
||||
|
||||
## Ограничения
|
||||
|
||||
Текущая версия не поддерживает:
|
||||
- Множественные наборы колонок (`columnsID`)
|
||||
- Области типа Columns / Rectangle
|
||||
- Рисунки (штрихкоды, картинки)
|
||||
- Фон ячеек
|
||||
# Спецификация MXL DSL — JSON-формат описания табличного документа
|
||||
|
||||
Компактный JSON-формат для описания макетов табличных документов 1С (SpreadsheetDocument). Используется навыками `/mxl-compile` (JSON → XML) и `/mxl-decompile` (XML → JSON).
|
||||
|
||||
## Пример
|
||||
|
||||
```json
|
||||
{
|
||||
"columns": 10,
|
||||
"defaultWidth": 30,
|
||||
"columnWidths": { "1": 15, "2-8": 40, "9-10": 50 },
|
||||
|
||||
"fonts": {
|
||||
"default": { "face": "Arial", "size": 10 },
|
||||
"bold": { "face": "Arial", "size": 10, "bold": true },
|
||||
"header": { "face": "Arial", "size": 14, "bold": true }
|
||||
},
|
||||
|
||||
"styles": {
|
||||
"default": {},
|
||||
"header": { "font": "header", "align": "center" },
|
||||
"label": { "font": "bold" },
|
||||
"bordered": { "border": "all" },
|
||||
"bordered-right": { "border": "all", "align": "right" },
|
||||
"total-right": { "font": "bold", "border": "top", "align": "right" }
|
||||
},
|
||||
|
||||
"areas": [
|
||||
{
|
||||
"name": "Заголовок",
|
||||
"rows": [
|
||||
{ "height": 20, "cells": [
|
||||
{ "col": 1, "span": 10, "style": "header", "param": "ТекстЗаголовка" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ШапкаТаблицы",
|
||||
"rows": [
|
||||
{ "rowStyle": "bordered", "cells": [
|
||||
{ "col": 1, "text": "№" },
|
||||
{ "col": 2, "span": 6, "text": "Наименование" },
|
||||
{ "col": 9, "text": "Кол-во" },
|
||||
{ "col": 10, "text": "Сумма" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Строка",
|
||||
"rows": [
|
||||
{ "rowStyle": "bordered", "cells": [
|
||||
{ "col": 1, "param": "НомерСтроки" },
|
||||
{ "col": 2, "span": 6, "param": "Товар", "detail": "Номенклатура" },
|
||||
{ "col": 9, "style": "bordered-right", "param": "Количество" },
|
||||
{ "col": 10, "style": "bordered-right", "param": "Сумма" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Итого",
|
||||
"rows": [
|
||||
{ "cells": [
|
||||
{ "col": 8, "span": 2, "style": "total-right", "text": "Итого:" },
|
||||
{ "col": 10, "style": "total-right", "param": "Всего" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Верхний уровень
|
||||
|
||||
| Поле | Обяз. | По умолч. | Описание |
|
||||
|------|:-----:|-----------|----------|
|
||||
| `columns` | да | — | Количество колонок |
|
||||
| `page` | нет | — | Формат страницы: `"A4-landscape"` (780), `"A4-portrait"` (540) или число. Автоматически вычисляет `defaultWidth` из суммы пропорций `"Nx"` |
|
||||
| `defaultWidth` | нет | 10 | Ширина колонок по умолчанию. Игнорируется если задан `page` и все колонки используют `"Nx"` |
|
||||
| `columnWidths` | нет | `{}` | Ширины колонок. Ключи 1-based: `"1"`, `"3-14"`, `"5,7,9"`. Значения: число (абсолют) или `"Nx"` (множитель от defaultWidth, напр. `"2x"`, `"0.5x"`) |
|
||||
| `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) |
|
||||
| `styles` | нет | `{}` | Именованные стили |
|
||||
| `areas` | да | — | Массив именованных областей (порядок = порядок в документе) |
|
||||
|
||||
## Шрифты (`fonts.<name>`)
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `face` | `"Arial"` | Имя шрифта |
|
||||
| `size` | `10` | Размер |
|
||||
| `bold` | `false` | Жирный |
|
||||
| `italic` | `false` | Курсив |
|
||||
| `underline` | `false` | Подчёркнутый |
|
||||
| `strikeout` | `false` | Зачёркнутый |
|
||||
|
||||
Шрифт `"default"` используется когда стиль не указывает шрифт явно. Если не определён, создаётся автоматически (Arial 10).
|
||||
|
||||
## Стили (`styles.<name>`)
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `font` | `"default"` | Ссылка на имя шрифта |
|
||||
| `align` | — | `left`, `center`, `right` |
|
||||
| `valign` | — | `top`, `center` |
|
||||
| `border` | — | Стороны рамки: `all`, `top`, `bottom`, `left`, `right`, `none`. Через запятую: `"top,bottom"` |
|
||||
| `borderWidth` | `"thin"` | Толщина рамки: `thin` (1px) или `thick` (2px) |
|
||||
| `wrap` | `false` | Перенос текста |
|
||||
| `format` | — | Формат данных 1С: `"ЧЦ=15; ЧДЦ=2"`, `"ДФ=dd.MM.yyyy"` и т.д. |
|
||||
|
||||
## Области (`areas[]`)
|
||||
|
||||
| Поле | Обяз. | Описание |
|
||||
|------|:-----:|----------|
|
||||
| `name` | да | Имя области для `Макет.ПолучитьОбласть("Имя")` |
|
||||
| `rows` | да | Массив строк |
|
||||
|
||||
## Строки (`rows[]`)
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `height` | — | Высота строки (если не задана, используется авто) |
|
||||
| `rowStyle` | — | Стиль для ВСЕХ колонок (заполняет пустоты рамками) |
|
||||
| `cells` | `[]` | Массив ячеек |
|
||||
| `empty` | — | Количество подряд идущих пустых строк (заменяет N отдельных `{}`) |
|
||||
|
||||
Строка без `cells` и `rowStyle` → пустая строка. `{ "empty": 3 }` эквивалентно трём `{}`.
|
||||
|
||||
## Ячейки (`cells[]`)
|
||||
|
||||
| Поле | Обяз. | По умолч. | Описание |
|
||||
|------|:-----:|-----------|----------|
|
||||
| `col` | да | — | Позиция колонки (1-based) |
|
||||
| `span` | нет | `1` | Объединение по горизонтали (количество колонок) |
|
||||
| `rowspan` | нет | `1` | Объединение по вертикали (количество строк) |
|
||||
| `style` | нет | rowStyle | Стиль ячейки (переопределяет rowStyle) |
|
||||
| `param` | нет | — | Параметр заполнения |
|
||||
| `detail` | нет | — | Параметр расшифровки (только с `param`) |
|
||||
| `text` | нет | — | Статический текст |
|
||||
| `template` | нет | — | Шаблонный текст с `[Параметр]` |
|
||||
|
||||
### Тип заполнения
|
||||
|
||||
Определяется автоматически по содержимому ячейки:
|
||||
- `param` → fillType=Parameter
|
||||
- `template` → fillType=Template
|
||||
- `text` → fillType=Text
|
||||
- ничего → без fillType (пустая ячейка или рамка)
|
||||
|
||||
## `rowStyle` — автозаполнение
|
||||
|
||||
Когда задан `rowStyle`, компилятор создаёт ячейки для ВСЕХ колонок строки. Позиции без явных ячеек заполняются пустыми ячейками с указанным стилем. Это обеспечивает сплошные рамки в табличных строках.
|
||||
|
||||
Если в предыдущих строках той же области есть ячейки с `rowspan`, их колонки при автозаполнении пропускаются.
|
||||
|
||||
## Ограничения
|
||||
|
||||
Текущая версия не поддерживает:
|
||||
- Множественные наборы колонок (`columnsID`)
|
||||
- Области типа Columns / Rectangle
|
||||
- Рисунки (штрихкоды, картинки)
|
||||
- Фон ячеек
|
||||
|
||||
+112
-112
@@ -1,112 +1,112 @@
|
||||
# Табличный документ (MXL)
|
||||
|
||||
Навыки группы `/mxl-*` позволяют анализировать, создавать и модифицировать макеты табличных документов 1С — основной формат печатных форм в конфигурациях 1С:Предприятия.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/mxl-info` | `<TemplatePath>` или `<ProcessorName> <TemplateName>` | Анализ структуры: области, параметры, наборы колонок |
|
||||
| `/mxl-validate` | `<TemplatePath>` или `<ProcessorName> <TemplateName>` | Валидация: индексы, ссылки, границы |
|
||||
| `/mxl-compile` | `<JsonPath> <OutputPath>` | Компиляция макета из JSON-определения в Template.xml |
|
||||
| `/mxl-decompile` | `<TemplatePath> [OutputPath]` | Декомпиляция Template.xml в JSON-определение |
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Создание макета печатной формы с нуля
|
||||
|
||||
Вы описываете макет словами или через JSON DSL, Claude компилирует его в Template.xml.
|
||||
|
||||
```
|
||||
> Создай макет накладной М-11: шапка с реквизитами организации и склада,
|
||||
> таблица с колонками (номер, наименование, единица, количество, цена, сумма),
|
||||
> итоговая строка, подписи.
|
||||
```
|
||||
|
||||
Claude напишет JSON-определение с областями, параметрами и стилями, вызовет `/mxl-compile` для генерации XML, затем `/mxl-validate` и `/mxl-info` для проверки.
|
||||
|
||||
Рабочий цикл:
|
||||
1. Claude пишет JSON-определение макета
|
||||
2. `/mxl-compile` → Template.xml
|
||||
3. `/mxl-validate` → проверка корректности
|
||||
4. `/mxl-info` → верификация структуры (области, параметры)
|
||||
|
||||
### Создание макета по изображению
|
||||
|
||||
Если есть скриншот или скан печатной формы, `/img-grid` поможет точно определить пропорции колонок.
|
||||
|
||||
```
|
||||
> Вот изображение формы М-11. Создай макет по нему.
|
||||
```
|
||||
|
||||
Рабочий цикл:
|
||||
1. `/img-grid` → изображение с пронумерованной сеткой
|
||||
2. Claude считает координаты границ колонок по сетке
|
||||
3. Объединяет границы всех таблиц → базовая решётка
|
||||
4. Пишет JSON DSL с пропорциями `"Nx"` и `"page": "A4-landscape"`
|
||||
5. `/mxl-compile` автоматически вычисляет абсолютные ширины из пропорций и формата страницы
|
||||
6. `/mxl-validate` → `/mxl-info` → проверка
|
||||
|
||||
### Анализ существующего макета
|
||||
|
||||
Быстрый обзор структуры макета без чтения тысяч строк XML.
|
||||
|
||||
```
|
||||
> Покажи структуру макета ПФ_MXL_М11
|
||||
```
|
||||
|
||||
Claude вызовет `/mxl-info` и выведет области, параметры и наборы колонок. С флагом `-WithText` покажет ещё и текстовое содержимое ячеек (заголовки колонок, надписи).
|
||||
|
||||
### Модификация существующего макета
|
||||
|
||||
Декомпиляция в JSON, правка, компиляция обратно.
|
||||
|
||||
```
|
||||
> Добавь в макет М-11 колонку "Примечание"
|
||||
```
|
||||
|
||||
Claude вызовет `/mxl-decompile` для получения JSON, добавит колонку в определение, вызовет `/mxl-compile` и `/mxl-validate`.
|
||||
|
||||
Рабочий цикл:
|
||||
1. `/mxl-decompile` → JSON из существующего Template.xml
|
||||
2. Claude модифицирует JSON (добавляет области, меняет стили, параметры)
|
||||
3. `/mxl-compile` → обновлённый Template.xml
|
||||
4. `/mxl-validate` → проверка
|
||||
|
||||
> **Ограничения:** Этот сценарий подразумевает полную перегенерацию макета, а не точечную правку XML. Поэтому diff может показать больше изменений, чем фактическая доработка. Кроме того, DSL пока поддерживает не все конструкции табличного документа — для сложных макетов с рисунками, штрихкодами или нестандартным форматированием часть информации может быть потеряна при round-trip.
|
||||
|
||||
### Валидация макета
|
||||
|
||||
Проверка структурной корректности после любых изменений.
|
||||
|
||||
```
|
||||
> Проверь макет ПФ_MXL_М11
|
||||
```
|
||||
|
||||
Claude вызовет `/mxl-validate`, который проверит индексы палитр, ссылки на наборы колонок, границы областей и другие структурные зависимости.
|
||||
|
||||
### Примеры слеш-команд
|
||||
|
||||
```
|
||||
> /mxl-info src/МояОбработка/Templates/ПФ_MXL_Накладная/Ext/Template.xml
|
||||
> /mxl-info МояОбработка ПФ_MXL_Накладная
|
||||
> /mxl-validate МояОбработка ПФ_MXL_Накладная
|
||||
> /mxl-compile макет.json src/МояОбработка/Templates/ПФ_MXL_Накладная/Ext/Template.xml
|
||||
> /mxl-decompile src/МояОбработка/Templates/ПФ_MXL_Накладная/Ext/Template.xml макет.json
|
||||
```
|
||||
|
||||
## Связь с EPF-навыками
|
||||
|
||||
Макет табличного документа — часть обработки. Типичный сценарий создания печатной формы:
|
||||
|
||||
1. `/epf-init` — создать обработку
|
||||
2. `/template-add` — добавить макет SpreadsheetDocument (с именем `ПФ_MXL_...`)
|
||||
3. `/mxl-compile` — заполнить макет содержимым из JSON-определения
|
||||
4. `/epf-bsp-init` — добавить регистрацию БСП с видом ПечатнаяФорма
|
||||
5. `/epf-bsp-add-command` — добавить команду печати
|
||||
6. `/epf-build` — собрать EPF
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [Табличный документ (MXL)](1c-spreadsheet-spec.md) — XML-формат SpreadsheetDocument, совместимость версий
|
||||
- [MXL DSL](mxl-dsl-spec.md) — JSON-формат описания макета для `/mxl-compile` и `/mxl-decompile`
|
||||
# Табличный документ (MXL)
|
||||
|
||||
Навыки группы `/mxl-*` позволяют анализировать, создавать и модифицировать макеты табличных документов 1С — основной формат печатных форм в конфигурациях 1С:Предприятия.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/mxl-info` | `<TemplatePath>` или `<ProcessorName> <TemplateName>` | Анализ структуры: области, параметры, наборы колонок |
|
||||
| `/mxl-validate` | `<TemplatePath>` или `<ProcessorName> <TemplateName>` | Валидация: индексы, ссылки, границы |
|
||||
| `/mxl-compile` | `<JsonPath> <OutputPath>` | Компиляция макета из JSON-определения в Template.xml |
|
||||
| `/mxl-decompile` | `<TemplatePath> [OutputPath]` | Декомпиляция Template.xml в JSON-определение |
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Создание макета печатной формы с нуля
|
||||
|
||||
Вы описываете макет словами или через JSON DSL, Claude компилирует его в Template.xml.
|
||||
|
||||
```
|
||||
> Создай макет накладной М-11: шапка с реквизитами организации и склада,
|
||||
> таблица с колонками (номер, наименование, единица, количество, цена, сумма),
|
||||
> итоговая строка, подписи.
|
||||
```
|
||||
|
||||
Claude напишет JSON-определение с областями, параметрами и стилями, вызовет `/mxl-compile` для генерации XML, затем `/mxl-validate` и `/mxl-info` для проверки.
|
||||
|
||||
Рабочий цикл:
|
||||
1. Claude пишет JSON-определение макета
|
||||
2. `/mxl-compile` → Template.xml
|
||||
3. `/mxl-validate` → проверка корректности
|
||||
4. `/mxl-info` → верификация структуры (области, параметры)
|
||||
|
||||
### Создание макета по изображению
|
||||
|
||||
Если есть скриншот или скан печатной формы, `/img-grid` поможет точно определить пропорции колонок.
|
||||
|
||||
```
|
||||
> Вот изображение формы М-11. Создай макет по нему.
|
||||
```
|
||||
|
||||
Рабочий цикл:
|
||||
1. `/img-grid` → изображение с пронумерованной сеткой
|
||||
2. Claude считает координаты границ колонок по сетке
|
||||
3. Объединяет границы всех таблиц → базовая решётка
|
||||
4. Пишет JSON DSL с пропорциями `"Nx"` и `"page": "A4-landscape"`
|
||||
5. `/mxl-compile` автоматически вычисляет абсолютные ширины из пропорций и формата страницы
|
||||
6. `/mxl-validate` → `/mxl-info` → проверка
|
||||
|
||||
### Анализ существующего макета
|
||||
|
||||
Быстрый обзор структуры макета без чтения тысяч строк XML.
|
||||
|
||||
```
|
||||
> Покажи структуру макета ПФ_MXL_М11
|
||||
```
|
||||
|
||||
Claude вызовет `/mxl-info` и выведет области, параметры и наборы колонок. С флагом `-WithText` покажет ещё и текстовое содержимое ячеек (заголовки колонок, надписи).
|
||||
|
||||
### Модификация существующего макета
|
||||
|
||||
Декомпиляция в JSON, правка, компиляция обратно.
|
||||
|
||||
```
|
||||
> Добавь в макет М-11 колонку "Примечание"
|
||||
```
|
||||
|
||||
Claude вызовет `/mxl-decompile` для получения JSON, добавит колонку в определение, вызовет `/mxl-compile` и `/mxl-validate`.
|
||||
|
||||
Рабочий цикл:
|
||||
1. `/mxl-decompile` → JSON из существующего Template.xml
|
||||
2. Claude модифицирует JSON (добавляет области, меняет стили, параметры)
|
||||
3. `/mxl-compile` → обновлённый Template.xml
|
||||
4. `/mxl-validate` → проверка
|
||||
|
||||
> **Ограничения:** Этот сценарий подразумевает полную перегенерацию макета, а не точечную правку XML. Поэтому diff может показать больше изменений, чем фактическая доработка. Кроме того, DSL пока поддерживает не все конструкции табличного документа — для сложных макетов с рисунками, штрихкодами или нестандартным форматированием часть информации может быть потеряна при round-trip.
|
||||
|
||||
### Валидация макета
|
||||
|
||||
Проверка структурной корректности после любых изменений.
|
||||
|
||||
```
|
||||
> Проверь макет ПФ_MXL_М11
|
||||
```
|
||||
|
||||
Claude вызовет `/mxl-validate`, который проверит индексы палитр, ссылки на наборы колонок, границы областей и другие структурные зависимости.
|
||||
|
||||
### Примеры слеш-команд
|
||||
|
||||
```
|
||||
> /mxl-info src/МояОбработка/Templates/ПФ_MXL_Накладная/Ext/Template.xml
|
||||
> /mxl-info МояОбработка ПФ_MXL_Накладная
|
||||
> /mxl-validate МояОбработка ПФ_MXL_Накладная
|
||||
> /mxl-compile макет.json src/МояОбработка/Templates/ПФ_MXL_Накладная/Ext/Template.xml
|
||||
> /mxl-decompile src/МояОбработка/Templates/ПФ_MXL_Накладная/Ext/Template.xml макет.json
|
||||
```
|
||||
|
||||
## Связь с EPF-навыками
|
||||
|
||||
Макет табличного документа — часть обработки. Типичный сценарий создания печатной формы:
|
||||
|
||||
1. `/epf-init` — создать обработку
|
||||
2. `/template-add` — добавить макет SpreadsheetDocument (с именем `ПФ_MXL_...`)
|
||||
3. `/mxl-compile` — заполнить макет содержимым из JSON-определения
|
||||
4. `/epf-bsp-init` — добавить регистрацию БСП с видом ПечатнаяФорма
|
||||
5. `/epf-bsp-add-command` — добавить команду печати
|
||||
6. `/epf-build` — собрать EPF
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [Табличный документ (MXL)](1c-spreadsheet-spec.md) — XML-формат SpreadsheetDocument, совместимость версий
|
||||
- [MXL DSL](mxl-dsl-spec.md) — JSON-формат описания макета для `/mxl-compile` и `/mxl-decompile`
|
||||
|
||||
+235
-235
@@ -1,235 +1,235 @@
|
||||
# Python Porting Guide
|
||||
|
||||
Руководство по Python-портам навыков 1С (PS1 → Python).
|
||||
|
||||
## Зачем Python рядом с PS1
|
||||
|
||||
PowerShell 5.1 доступен только на Windows. Python-порты обеспечивают кроссплатформенность (Linux, Mac). Модель opt-in: PS1 — по умолчанию, Python — переключается скриптами.
|
||||
|
||||
## PS1 — мастер-версия
|
||||
|
||||
**Приоритет при разработке, доработке, отладке и тестировании — у PS1-скриптов.** Python-порты являются производными копиями. Порядок работы:
|
||||
|
||||
1. Вносите изменения в `.ps1`
|
||||
2. Тестируйте и отлаживайте `.ps1`
|
||||
3. Переносите готовые изменения в `.py`
|
||||
|
||||
Не дорабатывайте `.py` без аналогичного изменения в `.ps1` — они должны оставаться функционально идентичными.
|
||||
|
||||
## Переключение рантайма
|
||||
|
||||
```bash
|
||||
# Переключить все .md в навыках на Python
|
||||
python scripts/switch-to-python.py
|
||||
|
||||
# Вернуть на PowerShell
|
||||
python scripts/switch-to-powershell.py
|
||||
```
|
||||
|
||||
Скрипты обрабатывают все `.md` файлы в `.claude/skills/*/` (SKILL.md, json-dsl.md и др.). Идемпотентны — повторный запуск безопасен. Python-only навыки (img-grid) пропускаются при переключении на PowerShell.
|
||||
|
||||
## Принцип самодостаточности
|
||||
|
||||
Каждый `.py` — полностью автономен, как и его `.ps1`-аналог. Нет общих модулей. Это соответствует [рекомендациям Anthropic](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) и зеркалит существующую архитектуру PS1.
|
||||
|
||||
Общие утилиты (5-15 строк) дублируются в каждом скрипте:
|
||||
|
||||
```python
|
||||
def esc_xml(s):
|
||||
return s.replace('&','&').replace('<','<').replace('>','>').replace('"','"')
|
||||
|
||||
def emit_mltext(lines, indent, tag, text):
|
||||
if not text:
|
||||
lines.append(f"{indent}<{tag}/>")
|
||||
return
|
||||
lines.append(f"{indent}<{tag}>")
|
||||
lines.append(f"{indent}\t<v8:item>")
|
||||
lines.append(f"{indent}\t\t<v8:lang>ru</v8:lang>")
|
||||
lines.append(f"{indent}\t\t<v8:content>{esc_xml(text)}</v8:content>")
|
||||
lines.append(f"{indent}\t</v8:item>")
|
||||
lines.append(f"{indent}</{tag}>")
|
||||
|
||||
def new_uuid():
|
||||
import uuid
|
||||
return str(uuid.uuid4())
|
||||
|
||||
def read_utf8(path):
|
||||
with open(path, 'r', encoding='utf-8-sig') as f:
|
||||
return f.read()
|
||||
|
||||
def write_utf8_bom(path, content):
|
||||
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
|
||||
f.write(content)
|
||||
```
|
||||
|
||||
Большие словари данных (синонимы типов, карты объектов) тоже inline — как `$script:typeSynonyms` в PS1.
|
||||
|
||||
## Конвенция параметров
|
||||
|
||||
Формат `-ParamName` сохранён для минимальных различий в SKILL.md:
|
||||
|
||||
```python
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False)
|
||||
parser.add_argument('-JsonPath', dest='JsonPath', required=True)
|
||||
parser.add_argument('-NoValidate', dest='NoValidate', action='store_true')
|
||||
```
|
||||
|
||||
Switch-параметры (`-NoValidate`) → `action='store_true'`.
|
||||
|
||||
## Таблица маппинга PS → Python
|
||||
|
||||
| PS1 | Python |
|
||||
|-----|--------|
|
||||
| `$script:xml = New-Object StringBuilder` | `lines = []` |
|
||||
| `$xml.AppendLine($text)` | `lines.append(text)` |
|
||||
| `$xml.ToString()` | `'\n'.join(lines)` |
|
||||
| `[System.Xml.XmlDocument] + PreserveWhitespace` | `lxml.etree.XMLParser(remove_blank_text=False)` |
|
||||
| `$xmlDoc.SelectSingleNode(xpath, $ns)` | `root.find(xpath, namespaces=NSMAP)` |
|
||||
| `$xmlDoc.SelectNodes(xpath, $ns)` | `root.findall(xpath, namespaces=NSMAP)` |
|
||||
| `XmlWriter + MemoryStream + BOM fix` | `etree.tostring(root, xml_declaration=True, encoding='UTF-8')` + declaration fix |
|
||||
| `[System.Guid]::NewGuid().ToString()` | `str(uuid.uuid4())` |
|
||||
| `$json \| ConvertFrom-Json` | `json.loads(text)` |
|
||||
| `ConvertTo-Json -Depth 10` | `json.dumps(obj, ensure_ascii=False, indent=2)` |
|
||||
| `New-Object System.Text.UTF8Encoding($true)` | `encoding='utf-8-sig'` |
|
||||
| `Start-Process -Wait -PassThru` | `subprocess.run([...], capture_output=True)` |
|
||||
| `Start-Process` (без -Wait) | `subprocess.Popen([...])` |
|
||||
| `[switch]$NoValidate` | `parser.add_argument('-NoValidate', action='store_true')` |
|
||||
| `[ValidateSet("a","b")]` | `choices=["a","b"]` |
|
||||
| `Get-ChildItem "path\*\..."` | `glob.glob(...)` |
|
||||
| `Get-Process httpd` | `psutil.process_iter(['pid','name','exe'])` |
|
||||
| `Test-Path $path` | `os.path.exists(path)` |
|
||||
| `Resolve-Path` | `os.path.abspath()` |
|
||||
| `Join-Path $a $b` | `os.path.join(a, b)` |
|
||||
| `New-Item -ItemType Directory -Force` | `os.makedirs(path, exist_ok=True)` |
|
||||
| `Remove-Item -Recurse -Force` | `shutil.rmtree(path)` |
|
||||
| `Write-Host "text"` | `print("text")` |
|
||||
| `Write-Error "text"` | `print("text", file=sys.stderr)` |
|
||||
|
||||
## lxml vs stdlib
|
||||
|
||||
- **Compile/init скрипты** (строковая сборка): только stdlib
|
||||
- **DOM-скрипты** (edit/validate/info): `lxml` с `XMLParser(remove_blank_text=False)` для сохранения whitespace
|
||||
- **Web-скрипты**: `psutil` для работы с процессами Apache
|
||||
|
||||
Зависимости:
|
||||
- `lxml>=4.9.0` — ~25 DOM-скриптов
|
||||
- `psutil>=5.9.0` — 4 web-скрипта
|
||||
|
||||
## Работа с BOM (UTF-8)
|
||||
|
||||
Кодек Python `utf-8-sig` — точный аналог `New-Object System.Text.UTF8Encoding($true)`:
|
||||
- Запись: добавляет BOM (EF BB BF)
|
||||
- Чтение: убирает BOM автоматически
|
||||
|
||||
```python
|
||||
# Чтение (BOM убирается)
|
||||
with open(path, 'r', encoding='utf-8-sig') as f:
|
||||
content = f.read()
|
||||
|
||||
# Запись (BOM добавляется)
|
||||
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
|
||||
f.write(content)
|
||||
```
|
||||
|
||||
Параметр `newline=''` предотвращает двойные `\r\n` на Windows.
|
||||
|
||||
## Сохранение XML с lxml
|
||||
|
||||
```python
|
||||
from lxml import etree
|
||||
|
||||
# Загрузка с сохранением whitespace
|
||||
parser = etree.XMLParser(remove_blank_text=False)
|
||||
tree = etree.parse(path, parser)
|
||||
root = tree.getroot()
|
||||
|
||||
# Сохранение с BOM
|
||||
xml_bytes = etree.tostring(tree, xml_declaration=True, encoding='UTF-8')
|
||||
# Fix declaration: etree пишет одинарные кавычки и uppercase encoding,
|
||||
# PS1 XmlWriter пишет двойные кавычки и lowercase encoding
|
||||
xml_bytes = xml_bytes.replace(
|
||||
b"<?xml version='1.0' encoding='UTF-8'?>",
|
||||
b'<?xml version="1.0" encoding="utf-8"?>')
|
||||
# Trailing newline (PS1 XmlWriter добавляет, etree — нет)
|
||||
if not xml_bytes.endswith(b"\n"):
|
||||
xml_bytes += b"\n"
|
||||
with open(path, 'wb') as f:
|
||||
f.write(b'\xef\xbb\xbf') # BOM
|
||||
f.write(xml_bytes)
|
||||
```
|
||||
|
||||
## Известные подводные камни
|
||||
|
||||
### Namespace в XPath
|
||||
lxml требует явный namespace map. В PS1 используется `XmlNamespaceManager`:
|
||||
```python
|
||||
NSMAP = {'md': 'http://v8.1c.ru/8.3/MDClasses'}
|
||||
node = root.find('.//md:ChildObjects/md:Form', NSMAP)
|
||||
```
|
||||
|
||||
### d5p1: для ссылочных типов
|
||||
В DCS-файлах ссылочные типы используют `d5p1:`, не `cfg:`:
|
||||
```xml
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.XXX</v8:Type>
|
||||
```
|
||||
|
||||
### XML declaration кавычки и encoding
|
||||
lxml/etree пишут `<?xml version='1.0' encoding='UTF-8'?>` (одинарные кавычки, uppercase). PS1 XmlWriter пишет `<?xml version="1.0" encoding="utf-8"?>` (двойные, lowercase). 1C принимает оба варианта, но одинарные кавычки — нестандартны. Замена всего declaration — в секции "Сохранение XML с lxml".
|
||||
|
||||
### etree vs XmlDocument — различия сериализации
|
||||
|
||||
Python etree (lxml и stdlib) сериализует XML иначе, чем PS1 XmlDocument:
|
||||
|
||||
| Аспект | PS1 XmlDocument | Python etree | Влияние |
|
||||
|--------|----------------|--------------|---------|
|
||||
| Declaration кавычки | `version="1.0"` | `version='1.0'` | Нестандартные одинарные кавычки |
|
||||
| Encoding case | `encoding="utf-8"` | `encoding='UTF-8'` | Косметическое |
|
||||
| Self-closing space | `<Tag />` | `<Tag/>` | Косметическое, 1C принимает оба |
|
||||
| Trailing newline | Да | Нет | Расхождение при побайтовом сравнении |
|
||||
| Unused xmlns | Сохраняет | Удаляет | Файл валиден, но отличается от канона |
|
||||
| CR в text content | `\r` as-is | ` ` entity | Разный формат, одинаковый смысл |
|
||||
| Пустые элементы | `<Tag>\n</Tag>` | `<Tag/>` | Косметическое |
|
||||
|
||||
Все эти различия обрабатываются `normalizeXmlContent()` в тест-раннере (только для `--runtime python`). PS1 тесты остаются строгими.
|
||||
|
||||
### Hashtable vs dict — порядок итерации
|
||||
|
||||
PS1 `@{}` (Hashtable) итерирует ключи в порядке хэш-кодов. Python `dict` — в порядке вставки. Если порядок элементов влияет на вывод (присвоение индексов, генерация UUID), используйте `sorted()` в Python **и** `| Sort-Object` в PS1 для детерминизма.
|
||||
|
||||
### Regex: (?i) inline flag в Python 3.11+
|
||||
|
||||
PS1: `'^(?i)desc$'` — работает. Python 3.11+: `r'^(?i)desc$'` — ошибка. Inline-флаг `(?i)` должен быть в начале строки паттерна: `r'(?i)^desc$'` или `re.IGNORECASE`.
|
||||
|
||||
### Обращение к отсутствующим свойствам
|
||||
|
||||
PS1 молча возвращает `$null` при обращении к несуществующему свойству (`.empty` на массиве). Python падает с `AttributeError`. Добавляйте `isinstance()` проверки при портировании.
|
||||
|
||||
## Платформозависимые заметки
|
||||
|
||||
Скрипты `db-*` и `web-*` используют платформу 1С (Designer CLI, Apache) — работают только на Windows. Но синтаксических ошибок на других ОС не будет: скрипт корректно сообщит об отсутствии платформы.
|
||||
|
||||
## Добавление нового навыка
|
||||
|
||||
Чеклист:
|
||||
1. Создать `.ps1` скрипт
|
||||
2. Создать `.py` скрипт с идентичными параметрами
|
||||
3. В SKILL.md указать `powershell.exe -NoProfile -File ... .ps1` (по умолчанию)
|
||||
4. Скрипт переключения автоматически подхватит новый навык
|
||||
|
||||
## Обновление существующего навыка
|
||||
|
||||
При доработке `.ps1`:
|
||||
1. Применить аналогичные изменения в `.py`
|
||||
2. Если затронуты inline-утилиты — обновить во всех скриптах: `grep -r "def esc_xml" .claude/skills/`
|
||||
|
||||
## Inline-утилиты — полный список
|
||||
|
||||
| Функция | Где используется |
|
||||
|---------|-----------------|
|
||||
| `esc_xml()` | compile, init, edit, add скрипты |
|
||||
| `emit_mltext()` | compile, init, add скрипты |
|
||||
| `new_uuid()` | init, add, compile скрипты |
|
||||
| `read_utf8()` | все скрипты |
|
||||
| `write_utf8_bom()` | все скрипты с записью |
|
||||
| `paginate()` | info скрипты |
|
||||
| `split_camelcase()` | info скрипты |
|
||||
# Python Porting Guide
|
||||
|
||||
Руководство по Python-портам навыков 1С (PS1 → Python).
|
||||
|
||||
## Зачем Python рядом с PS1
|
||||
|
||||
PowerShell 5.1 доступен только на Windows. Python-порты обеспечивают кроссплатформенность (Linux, Mac). Модель opt-in: PS1 — по умолчанию, Python — переключается скриптами.
|
||||
|
||||
## PS1 — мастер-версия
|
||||
|
||||
**Приоритет при разработке, доработке, отладке и тестировании — у PS1-скриптов.** Python-порты являются производными копиями. Порядок работы:
|
||||
|
||||
1. Вносите изменения в `.ps1`
|
||||
2. Тестируйте и отлаживайте `.ps1`
|
||||
3. Переносите готовые изменения в `.py`
|
||||
|
||||
Не дорабатывайте `.py` без аналогичного изменения в `.ps1` — они должны оставаться функционально идентичными.
|
||||
|
||||
## Переключение рантайма
|
||||
|
||||
```bash
|
||||
# Переключить все .md в навыках на Python
|
||||
python scripts/switch-to-python.py
|
||||
|
||||
# Вернуть на PowerShell
|
||||
python scripts/switch-to-powershell.py
|
||||
```
|
||||
|
||||
Скрипты обрабатывают все `.md` файлы в `.claude/skills/*/` (SKILL.md, json-dsl.md и др.). Идемпотентны — повторный запуск безопасен. Python-only навыки (img-grid) пропускаются при переключении на PowerShell.
|
||||
|
||||
## Принцип самодостаточности
|
||||
|
||||
Каждый `.py` — полностью автономен, как и его `.ps1`-аналог. Нет общих модулей. Это соответствует [рекомендациям Anthropic](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) и зеркалит существующую архитектуру PS1.
|
||||
|
||||
Общие утилиты (5-15 строк) дублируются в каждом скрипте:
|
||||
|
||||
```python
|
||||
def esc_xml(s):
|
||||
return s.replace('&','&').replace('<','<').replace('>','>').replace('"','"')
|
||||
|
||||
def emit_mltext(lines, indent, tag, text):
|
||||
if not text:
|
||||
lines.append(f"{indent}<{tag}/>")
|
||||
return
|
||||
lines.append(f"{indent}<{tag}>")
|
||||
lines.append(f"{indent}\t<v8:item>")
|
||||
lines.append(f"{indent}\t\t<v8:lang>ru</v8:lang>")
|
||||
lines.append(f"{indent}\t\t<v8:content>{esc_xml(text)}</v8:content>")
|
||||
lines.append(f"{indent}\t</v8:item>")
|
||||
lines.append(f"{indent}</{tag}>")
|
||||
|
||||
def new_uuid():
|
||||
import uuid
|
||||
return str(uuid.uuid4())
|
||||
|
||||
def read_utf8(path):
|
||||
with open(path, 'r', encoding='utf-8-sig') as f:
|
||||
return f.read()
|
||||
|
||||
def write_utf8_bom(path, content):
|
||||
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
|
||||
f.write(content)
|
||||
```
|
||||
|
||||
Большие словари данных (синонимы типов, карты объектов) тоже inline — как `$script:typeSynonyms` в PS1.
|
||||
|
||||
## Конвенция параметров
|
||||
|
||||
Формат `-ParamName` сохранён для минимальных различий в SKILL.md:
|
||||
|
||||
```python
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False)
|
||||
parser.add_argument('-JsonPath', dest='JsonPath', required=True)
|
||||
parser.add_argument('-NoValidate', dest='NoValidate', action='store_true')
|
||||
```
|
||||
|
||||
Switch-параметры (`-NoValidate`) → `action='store_true'`.
|
||||
|
||||
## Таблица маппинга PS → Python
|
||||
|
||||
| PS1 | Python |
|
||||
|-----|--------|
|
||||
| `$script:xml = New-Object StringBuilder` | `lines = []` |
|
||||
| `$xml.AppendLine($text)` | `lines.append(text)` |
|
||||
| `$xml.ToString()` | `'\n'.join(lines)` |
|
||||
| `[System.Xml.XmlDocument] + PreserveWhitespace` | `lxml.etree.XMLParser(remove_blank_text=False)` |
|
||||
| `$xmlDoc.SelectSingleNode(xpath, $ns)` | `root.find(xpath, namespaces=NSMAP)` |
|
||||
| `$xmlDoc.SelectNodes(xpath, $ns)` | `root.findall(xpath, namespaces=NSMAP)` |
|
||||
| `XmlWriter + MemoryStream + BOM fix` | `etree.tostring(root, xml_declaration=True, encoding='UTF-8')` + declaration fix |
|
||||
| `[System.Guid]::NewGuid().ToString()` | `str(uuid.uuid4())` |
|
||||
| `$json \| ConvertFrom-Json` | `json.loads(text)` |
|
||||
| `ConvertTo-Json -Depth 10` | `json.dumps(obj, ensure_ascii=False, indent=2)` |
|
||||
| `New-Object System.Text.UTF8Encoding($true)` | `encoding='utf-8-sig'` |
|
||||
| `Start-Process -Wait -PassThru` | `subprocess.run([...], capture_output=True)` |
|
||||
| `Start-Process` (без -Wait) | `subprocess.Popen([...])` |
|
||||
| `[switch]$NoValidate` | `parser.add_argument('-NoValidate', action='store_true')` |
|
||||
| `[ValidateSet("a","b")]` | `choices=["a","b"]` |
|
||||
| `Get-ChildItem "path\*\..."` | `glob.glob(...)` |
|
||||
| `Get-Process httpd` | `psutil.process_iter(['pid','name','exe'])` |
|
||||
| `Test-Path $path` | `os.path.exists(path)` |
|
||||
| `Resolve-Path` | `os.path.abspath()` |
|
||||
| `Join-Path $a $b` | `os.path.join(a, b)` |
|
||||
| `New-Item -ItemType Directory -Force` | `os.makedirs(path, exist_ok=True)` |
|
||||
| `Remove-Item -Recurse -Force` | `shutil.rmtree(path)` |
|
||||
| `Write-Host "text"` | `print("text")` |
|
||||
| `Write-Error "text"` | `print("text", file=sys.stderr)` |
|
||||
|
||||
## lxml vs stdlib
|
||||
|
||||
- **Compile/init скрипты** (строковая сборка): только stdlib
|
||||
- **DOM-скрипты** (edit/validate/info): `lxml` с `XMLParser(remove_blank_text=False)` для сохранения whitespace
|
||||
- **Web-скрипты**: `psutil` для работы с процессами Apache
|
||||
|
||||
Зависимости:
|
||||
- `lxml>=4.9.0` — ~25 DOM-скриптов
|
||||
- `psutil>=5.9.0` — 4 web-скрипта
|
||||
|
||||
## Работа с BOM (UTF-8)
|
||||
|
||||
Кодек Python `utf-8-sig` — точный аналог `New-Object System.Text.UTF8Encoding($true)`:
|
||||
- Запись: добавляет BOM (EF BB BF)
|
||||
- Чтение: убирает BOM автоматически
|
||||
|
||||
```python
|
||||
# Чтение (BOM убирается)
|
||||
with open(path, 'r', encoding='utf-8-sig') as f:
|
||||
content = f.read()
|
||||
|
||||
# Запись (BOM добавляется)
|
||||
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
|
||||
f.write(content)
|
||||
```
|
||||
|
||||
Параметр `newline=''` предотвращает двойные `\r\n` на Windows.
|
||||
|
||||
## Сохранение XML с lxml
|
||||
|
||||
```python
|
||||
from lxml import etree
|
||||
|
||||
# Загрузка с сохранением whitespace
|
||||
parser = etree.XMLParser(remove_blank_text=False)
|
||||
tree = etree.parse(path, parser)
|
||||
root = tree.getroot()
|
||||
|
||||
# Сохранение с BOM
|
||||
xml_bytes = etree.tostring(tree, xml_declaration=True, encoding='UTF-8')
|
||||
# Fix declaration: etree пишет одинарные кавычки и uppercase encoding,
|
||||
# PS1 XmlWriter пишет двойные кавычки и lowercase encoding
|
||||
xml_bytes = xml_bytes.replace(
|
||||
b"<?xml version='1.0' encoding='UTF-8'?>",
|
||||
b'<?xml version="1.0" encoding="utf-8"?>')
|
||||
# Trailing newline (PS1 XmlWriter добавляет, etree — нет)
|
||||
if not xml_bytes.endswith(b"\n"):
|
||||
xml_bytes += b"\n"
|
||||
with open(path, 'wb') as f:
|
||||
f.write(b'\xef\xbb\xbf') # BOM
|
||||
f.write(xml_bytes)
|
||||
```
|
||||
|
||||
## Известные подводные камни
|
||||
|
||||
### Namespace в XPath
|
||||
lxml требует явный namespace map. В PS1 используется `XmlNamespaceManager`:
|
||||
```python
|
||||
NSMAP = {'md': 'http://v8.1c.ru/8.3/MDClasses'}
|
||||
node = root.find('.//md:ChildObjects/md:Form', NSMAP)
|
||||
```
|
||||
|
||||
### d5p1: для ссылочных типов
|
||||
В DCS-файлах ссылочные типы используют `d5p1:`, не `cfg:`:
|
||||
```xml
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.XXX</v8:Type>
|
||||
```
|
||||
|
||||
### XML declaration кавычки и encoding
|
||||
lxml/etree пишут `<?xml version='1.0' encoding='UTF-8'?>` (одинарные кавычки, uppercase). PS1 XmlWriter пишет `<?xml version="1.0" encoding="utf-8"?>` (двойные, lowercase). 1C принимает оба варианта, но одинарные кавычки — нестандартны. Замена всего declaration — в секции "Сохранение XML с lxml".
|
||||
|
||||
### etree vs XmlDocument — различия сериализации
|
||||
|
||||
Python etree (lxml и stdlib) сериализует XML иначе, чем PS1 XmlDocument:
|
||||
|
||||
| Аспект | PS1 XmlDocument | Python etree | Влияние |
|
||||
|--------|----------------|--------------|---------|
|
||||
| Declaration кавычки | `version="1.0"` | `version='1.0'` | Нестандартные одинарные кавычки |
|
||||
| Encoding case | `encoding="utf-8"` | `encoding='UTF-8'` | Косметическое |
|
||||
| Self-closing space | `<Tag />` | `<Tag/>` | Косметическое, 1C принимает оба |
|
||||
| Trailing newline | Да | Нет | Расхождение при побайтовом сравнении |
|
||||
| Unused xmlns | Сохраняет | Удаляет | Файл валиден, но отличается от канона |
|
||||
| CR в text content | `\r` as-is | ` ` entity | Разный формат, одинаковый смысл |
|
||||
| Пустые элементы | `<Tag>\n</Tag>` | `<Tag/>` | Косметическое |
|
||||
|
||||
Все эти различия обрабатываются `normalizeXmlContent()` в тест-раннере (только для `--runtime python`). PS1 тесты остаются строгими.
|
||||
|
||||
### Hashtable vs dict — порядок итерации
|
||||
|
||||
PS1 `@{}` (Hashtable) итерирует ключи в порядке хэш-кодов. Python `dict` — в порядке вставки. Если порядок элементов влияет на вывод (присвоение индексов, генерация UUID), используйте `sorted()` в Python **и** `| Sort-Object` в PS1 для детерминизма.
|
||||
|
||||
### Regex: (?i) inline flag в Python 3.11+
|
||||
|
||||
PS1: `'^(?i)desc$'` — работает. Python 3.11+: `r'^(?i)desc$'` — ошибка. Inline-флаг `(?i)` должен быть в начале строки паттерна: `r'(?i)^desc$'` или `re.IGNORECASE`.
|
||||
|
||||
### Обращение к отсутствующим свойствам
|
||||
|
||||
PS1 молча возвращает `$null` при обращении к несуществующему свойству (`.empty` на массиве). Python падает с `AttributeError`. Добавляйте `isinstance()` проверки при портировании.
|
||||
|
||||
## Платформозависимые заметки
|
||||
|
||||
Скрипты `db-*` и `web-*` используют платформу 1С (Designer CLI, Apache) — работают только на Windows. Но синтаксических ошибок на других ОС не будет: скрипт корректно сообщит об отсутствии платформы.
|
||||
|
||||
## Добавление нового навыка
|
||||
|
||||
Чеклист:
|
||||
1. Создать `.ps1` скрипт
|
||||
2. Создать `.py` скрипт с идентичными параметрами
|
||||
3. В SKILL.md указать `powershell.exe -NoProfile -File ... .ps1` (по умолчанию)
|
||||
4. Скрипт переключения автоматически подхватит новый навык
|
||||
|
||||
## Обновление существующего навыка
|
||||
|
||||
При доработке `.ps1`:
|
||||
1. Применить аналогичные изменения в `.py`
|
||||
2. Если затронуты inline-утилиты — обновить во всех скриптах: `grep -r "def esc_xml" .claude/skills/`
|
||||
|
||||
## Inline-утилиты — полный список
|
||||
|
||||
| Функция | Где используется |
|
||||
|---------|-----------------|
|
||||
| `esc_xml()` | compile, init, edit, add скрипты |
|
||||
| `emit_mltext()` | compile, init, add скрипты |
|
||||
| `new_uuid()` | init, add, compile скрипты |
|
||||
| `read_utf8()` | все скрипты |
|
||||
| `write_utf8_bom()` | все скрипты с записью |
|
||||
| `paginate()` | info скрипты |
|
||||
| `split_camelcase()` | info скрипты |
|
||||
|
||||
+112
-112
@@ -1,112 +1,112 @@
|
||||
# Спецификация Role JSON DSL
|
||||
|
||||
Формат JSON для описания ролей 1С, используемый навыком `/role-compile`.
|
||||
|
||||
## Обзор
|
||||
|
||||
Role JSON DSL — компактный JSON-формат, транслируемый скриптом в XML-файлы роли 1С:Предприятия (метаданные + Rights.xml). Поддерживает пресеты прав, русские синонимы типов и прав, шаблоны ограничений (RLS).
|
||||
|
||||
## Корневой объект
|
||||
|
||||
| Поле | Тип | Обяз. | По умолчанию | Описание |
|
||||
|------|-----|:-----:|:------------:|----------|
|
||||
| `name` | string | да | — | Программное имя роли |
|
||||
| `synonym` | string | нет | = name | Отображаемое имя |
|
||||
| `comment` | string | нет | `""` | Комментарий |
|
||||
| `setForNewObjects` | bool | нет | `false` | Устанавливать для новых объектов |
|
||||
| `setForAttributesByDefault` | bool | нет | `true` | Устанавливать для реквизитов по умолчанию |
|
||||
| `independentRightsOfChildObjects` | bool | нет | `false` | Независимые права подчинённых объектов |
|
||||
| `objects` | array | нет | `[]` | Массив объектов метаданных с правами |
|
||||
| `templates` | array | нет | `[]` | Шаблоны ограничений (RLS) |
|
||||
|
||||
## Элементы `objects`
|
||||
|
||||
Массив принимает два формата, которые можно смешивать.
|
||||
|
||||
### Строковый shorthand
|
||||
|
||||
```
|
||||
"Тип.Имя: @пресет"
|
||||
"Тип.Имя: Право1, Право2"
|
||||
```
|
||||
|
||||
Тип — английский (Catalog) или русский (Справочник). Права — английские (Read) или русские (Чтение).
|
||||
|
||||
### Объектная форма
|
||||
|
||||
| Поле | Тип | Обяз. | Описание |
|
||||
|------|-----|:-----:|----------|
|
||||
| `name` | string | да | Полное имя объекта: `Тип.Имя` |
|
||||
| `preset` | string | нет | Пресет: `"view"`, `"edit"` (без `@`) |
|
||||
| `rights` | object\|array | нет | Переопределения: `{"Right": bool}` или `["Right1", "Right2"]` |
|
||||
| `rls` | object | нет | RLS: `{"ИмяПрава": "текст условия или #шаблон"}` |
|
||||
|
||||
При наличии `preset` + `rights` — сначала применяется пресет, затем `rights` переопределяют отдельные права.
|
||||
|
||||
## Пресеты
|
||||
|
||||
Три встроенных пресета определяют набор прав в зависимости от типа объекта:
|
||||
|
||||
| Пресет | Назначение |
|
||||
|--------|------------|
|
||||
| `view` | Просмотр: Read, View (+InputByString для справочников/документов; Use+View для обработок/отчётов) |
|
||||
| `edit` | Полное редактирование: CRUD + Interactive* + Posting (документы) |
|
||||
|
||||
Подробные таблицы прав для каждого типа объекта — в `.claude/skills/role-compile/dsl-reference.md`.
|
||||
|
||||
## Шаблоны ограничений (RLS)
|
||||
|
||||
Элементы массива `templates`:
|
||||
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| `name` | string | Имя шаблона с параметрами: `"ДляОбъекта(Модификатор)"` |
|
||||
| `condition` | string | Текст условия. `&` экранируется в `&` автоматически |
|
||||
|
||||
Ссылка на шаблон в `rls`: `"#ИмяШаблона(\"параметры\")"` — начинается с `#`.
|
||||
|
||||
## Русские синонимы
|
||||
|
||||
DSL принимает русские имена типов и прав, транслируя их в английские. Полные таблицы соответствий — в `.claude/skills/role-compile/dsl-reference.md`.
|
||||
|
||||
Примеры: `Справочник` → Catalog, `Документ` → Document, `Чтение` → Read, `Просмотр` → View.
|
||||
|
||||
## Пример
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "МенеджерПродаж",
|
||||
"synonym": "Менеджер продаж",
|
||||
"objects": [
|
||||
"Document.РеализацияТоваровУслуг: @edit",
|
||||
"Catalog.Контрагенты: @view",
|
||||
"Catalog.Номенклатура: @view",
|
||||
{
|
||||
"name": "Document.ЗаказКлиента",
|
||||
"preset": "view",
|
||||
"rls": { "Read": "#ДляОбъекта(\"\")" }
|
||||
}
|
||||
],
|
||||
"templates": [
|
||||
{
|
||||
"name": "ДляОбъекта(Модификатор)",
|
||||
"condition": "ГДЕ Организация = &ТекущаяОрганизация"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Генерируемые файлы
|
||||
|
||||
```
|
||||
Roles/
|
||||
ИмяРоли.xml # Метаданные (UUID, синоним, флаги)
|
||||
ИмяРоли/
|
||||
└── Ext/
|
||||
└── Rights.xml # Права доступа (объекты, права, RLS)
|
||||
```
|
||||
|
||||
## См. также
|
||||
|
||||
- [Роли (Rights.xml)](1c-role-spec.md) — XML-формат прав роли, типы объектов, RLS
|
||||
- [Гайд по ролям](role-guide.md) — сценарии использования, рабочий цикл
|
||||
# Спецификация Role JSON DSL
|
||||
|
||||
Формат JSON для описания ролей 1С, используемый навыком `/role-compile`.
|
||||
|
||||
## Обзор
|
||||
|
||||
Role JSON DSL — компактный JSON-формат, транслируемый скриптом в XML-файлы роли 1С:Предприятия (метаданные + Rights.xml). Поддерживает пресеты прав, русские синонимы типов и прав, шаблоны ограничений (RLS).
|
||||
|
||||
## Корневой объект
|
||||
|
||||
| Поле | Тип | Обяз. | По умолчанию | Описание |
|
||||
|------|-----|:-----:|:------------:|----------|
|
||||
| `name` | string | да | — | Программное имя роли |
|
||||
| `synonym` | string | нет | = name | Отображаемое имя |
|
||||
| `comment` | string | нет | `""` | Комментарий |
|
||||
| `setForNewObjects` | bool | нет | `false` | Устанавливать для новых объектов |
|
||||
| `setForAttributesByDefault` | bool | нет | `true` | Устанавливать для реквизитов по умолчанию |
|
||||
| `independentRightsOfChildObjects` | bool | нет | `false` | Независимые права подчинённых объектов |
|
||||
| `objects` | array | нет | `[]` | Массив объектов метаданных с правами |
|
||||
| `templates` | array | нет | `[]` | Шаблоны ограничений (RLS) |
|
||||
|
||||
## Элементы `objects`
|
||||
|
||||
Массив принимает два формата, которые можно смешивать.
|
||||
|
||||
### Строковый shorthand
|
||||
|
||||
```
|
||||
"Тип.Имя: @пресет"
|
||||
"Тип.Имя: Право1, Право2"
|
||||
```
|
||||
|
||||
Тип — английский (Catalog) или русский (Справочник). Права — английские (Read) или русские (Чтение).
|
||||
|
||||
### Объектная форма
|
||||
|
||||
| Поле | Тип | Обяз. | Описание |
|
||||
|------|-----|:-----:|----------|
|
||||
| `name` | string | да | Полное имя объекта: `Тип.Имя` |
|
||||
| `preset` | string | нет | Пресет: `"view"`, `"edit"` (без `@`) |
|
||||
| `rights` | object\|array | нет | Переопределения: `{"Right": bool}` или `["Right1", "Right2"]` |
|
||||
| `rls` | object | нет | RLS: `{"ИмяПрава": "текст условия или #шаблон"}` |
|
||||
|
||||
При наличии `preset` + `rights` — сначала применяется пресет, затем `rights` переопределяют отдельные права.
|
||||
|
||||
## Пресеты
|
||||
|
||||
Три встроенных пресета определяют набор прав в зависимости от типа объекта:
|
||||
|
||||
| Пресет | Назначение |
|
||||
|--------|------------|
|
||||
| `view` | Просмотр: Read, View (+InputByString для справочников/документов; Use+View для обработок/отчётов) |
|
||||
| `edit` | Полное редактирование: CRUD + Interactive* + Posting (документы) |
|
||||
|
||||
Подробные таблицы прав для каждого типа объекта — в `.claude/skills/role-compile/dsl-reference.md`.
|
||||
|
||||
## Шаблоны ограничений (RLS)
|
||||
|
||||
Элементы массива `templates`:
|
||||
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| `name` | string | Имя шаблона с параметрами: `"ДляОбъекта(Модификатор)"` |
|
||||
| `condition` | string | Текст условия. `&` экранируется в `&` автоматически |
|
||||
|
||||
Ссылка на шаблон в `rls`: `"#ИмяШаблона(\"параметры\")"` — начинается с `#`.
|
||||
|
||||
## Русские синонимы
|
||||
|
||||
DSL принимает русские имена типов и прав, транслируя их в английские. Полные таблицы соответствий — в `.claude/skills/role-compile/dsl-reference.md`.
|
||||
|
||||
Примеры: `Справочник` → Catalog, `Документ` → Document, `Чтение` → Read, `Просмотр` → View.
|
||||
|
||||
## Пример
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "МенеджерПродаж",
|
||||
"synonym": "Менеджер продаж",
|
||||
"objects": [
|
||||
"Document.РеализацияТоваровУслуг: @edit",
|
||||
"Catalog.Контрагенты: @view",
|
||||
"Catalog.Номенклатура: @view",
|
||||
{
|
||||
"name": "Document.ЗаказКлиента",
|
||||
"preset": "view",
|
||||
"rls": { "Read": "#ДляОбъекта(\"\")" }
|
||||
}
|
||||
],
|
||||
"templates": [
|
||||
{
|
||||
"name": "ДляОбъекта(Модификатор)",
|
||||
"condition": "ГДЕ Организация = &ТекущаяОрганизация"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Генерируемые файлы
|
||||
|
||||
```
|
||||
Roles/
|
||||
ИмяРоли.xml # Метаданные (UUID, синоним, флаги)
|
||||
ИмяРоли/
|
||||
└── Ext/
|
||||
└── Rights.xml # Права доступа (объекты, права, RLS)
|
||||
```
|
||||
|
||||
## См. также
|
||||
|
||||
- [Роли (Rights.xml)](1c-role-spec.md) — XML-формат прав роли, типы объектов, RLS
|
||||
- [Гайд по ролям](role-guide.md) — сценарии использования, рабочий цикл
|
||||
|
||||
+155
-155
@@ -1,155 +1,155 @@
|
||||
# Роли (Role)
|
||||
|
||||
Навыки группы `/role-*` позволяют анализировать, создавать и проверять роли 1С — XML-файлы прав доступа (Rights.xml) и метаданных.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/role-info` | `<RightsPath>` | Компактная сводка прав: объекты по типам, только разрешённые, RLS, шаблоны |
|
||||
| `/role-compile` | `<JsonPath> <RolesDir>` | Генерация роли из JSON DSL: метаданные + Rights.xml, UUID автоматически |
|
||||
| `/role-validate` | `<RightsPath> [MetadataPath]` | Валидация структурной корректности: XML, namespace, права, RLS, шаблоны |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание прав (текст) → JSON DSL → /role-compile → XML-исходники → /role-validate
|
||||
→ /role-info
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение роли (с пресетами или явными правами)
|
||||
2. `/role-compile` генерирует `Roles/ИмяРоли.xml` + `Roles/ИмяРоли/Ext/Rights.xml`
|
||||
3. `/role-validate` проверяет корректность сгенерированного XML
|
||||
4. `/role-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## JSON DSL — компактный формат
|
||||
|
||||
Роли описываются в JSON с двумя уровнями детализации:
|
||||
|
||||
### Строковый shorthand (простые роли)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "ЧтениеНоменклатуры",
|
||||
"synonym": "Чтение номенклатуры",
|
||||
"objects": [
|
||||
"Catalog.Номенклатура: @view",
|
||||
"Catalog.Контрагенты: @view",
|
||||
"DataProcessor.Загрузка: @view"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Формат строки: `Тип.Имя: @пресет` или `Тип.Имя: Право1, Право2`.
|
||||
|
||||
### Объектная форма (RLS, переопределения)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Document.Реализация",
|
||||
"preset": "view",
|
||||
"rights": { "Delete": false },
|
||||
"rls": { "Read": "#ДляОбъекта(\"\")" }
|
||||
}
|
||||
```
|
||||
|
||||
Форматы можно смешивать в одном массиве `objects`.
|
||||
|
||||
### Пресеты
|
||||
|
||||
| Пресет | Действие |
|
||||
|--------|----------|
|
||||
| `@view` | Просмотр: Read, View (+InputByString для справочников/документов; Use+View для обработок/отчётов) |
|
||||
| `@edit` | Полное редактирование: CRUD + Interactive* + Posting (для документов) |
|
||||
|
||||
`@` обязателен в строковом shorthand. В объектной форме — ключ `preset` без `@`.
|
||||
|
||||
### Русские синонимы
|
||||
|
||||
Скрипт принимает русские имена типов и прав: `Справочник` → Catalog, `Чтение` → Read, `Проведение` → Posting и т.д. Полный список — в [спецификации Role DSL](role-dsl-spec.md).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ существующей роли
|
||||
|
||||
```
|
||||
> Проанализируй права роли Roles/БазовыеПраваБП/Ext/Rights.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/role-info`, получит компактную сводку (тысячи строк XML → 50–300 строк текста) и опишет:
|
||||
- какие объекты доступны и с какими правами
|
||||
- где есть ограничения RLS
|
||||
- какие шаблоны ограничений используются
|
||||
|
||||
### Создание роли по описанию
|
||||
|
||||
```
|
||||
> Создай роль МенеджерПродаж с правами:
|
||||
> - Документ РеализацияТоваровУслуг: полные права
|
||||
> - Справочник Контрагенты: чтение
|
||||
> - Справочник Номенклатура: чтение
|
||||
> - Регистр ЦеныНоменклатуры: чтение
|
||||
```
|
||||
|
||||
Claude сформирует JSON с пресетами:
|
||||
```json
|
||||
{
|
||||
"name": "МенеджерПродаж",
|
||||
"synonym": "Менеджер продаж",
|
||||
"objects": [
|
||||
"Document.РеализацияТоваровУслуг: @edit",
|
||||
"Catalog.Контрагенты: @view",
|
||||
"Catalog.Номенклатура: @view",
|
||||
"InformationRegister.ЦеныНоменклатуры: @view"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
И вызовет `/role-compile` → `/role-validate` → `/role-info`.
|
||||
|
||||
### Создание роли для регламентного задания
|
||||
|
||||
```
|
||||
> Проанализируй модуль регламентного задания ОбновлениеКурсовВалют
|
||||
> и создай роль с минимальными правами для его выполнения
|
||||
```
|
||||
|
||||
Claude проанализирует код, определит используемые объекты, создаст JSON с точечными правами (без пресетов — только нужные права), и скомпилирует роль.
|
||||
|
||||
### Создание роли с RLS
|
||||
|
||||
```
|
||||
> Создай роль для чтения документов с ограничением по организации
|
||||
```
|
||||
|
||||
Claude использует объектную форму JSON с шаблонами ограничений.
|
||||
|
||||
### Проверка существующей роли
|
||||
|
||||
```
|
||||
> Проверь корректность роли Roles/МояРоль/Ext/Rights.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/role-validate` и покажет результат: ошибки (невалидный XML, отсутствующие элементы) и предупреждения (неизвестные типы объектов, подозрительные имена прав с подсказками).
|
||||
|
||||
## Структура файлов роли
|
||||
|
||||
```
|
||||
Roles/
|
||||
├── ИмяРоли.xml # Метаданные (UUID, синоним)
|
||||
└── ИмяРоли/
|
||||
└── Ext/
|
||||
└── Rights.xml # Права доступа
|
||||
```
|
||||
|
||||
Регистрация в `Configuration.xml`:
|
||||
```xml
|
||||
<ChildObjects>
|
||||
<Role>ИмяРоли</Role>
|
||||
</ChildObjects>
|
||||
```
|
||||
|
||||
## Спецификация
|
||||
|
||||
- [1c-role-spec.md](1c-role-spec.md) — XML-формат прав роли, типы объектов, RLS, шаблоны ограничений
|
||||
- [role-dsl-spec.md](role-dsl-spec.md) — JSON DSL для описания ролей (формат входных данных `/role-compile`)
|
||||
# Роли (Role)
|
||||
|
||||
Навыки группы `/role-*` позволяют анализировать, создавать и проверять роли 1С — XML-файлы прав доступа (Rights.xml) и метаданных.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/role-info` | `<RightsPath>` | Компактная сводка прав: объекты по типам, только разрешённые, RLS, шаблоны |
|
||||
| `/role-compile` | `<JsonPath> <RolesDir>` | Генерация роли из JSON DSL: метаданные + Rights.xml, UUID автоматически |
|
||||
| `/role-validate` | `<RightsPath> [MetadataPath]` | Валидация структурной корректности: XML, namespace, права, RLS, шаблоны |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание прав (текст) → JSON DSL → /role-compile → XML-исходники → /role-validate
|
||||
→ /role-info
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение роли (с пресетами или явными правами)
|
||||
2. `/role-compile` генерирует `Roles/ИмяРоли.xml` + `Roles/ИмяРоли/Ext/Rights.xml`
|
||||
3. `/role-validate` проверяет корректность сгенерированного XML
|
||||
4. `/role-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## JSON DSL — компактный формат
|
||||
|
||||
Роли описываются в JSON с двумя уровнями детализации:
|
||||
|
||||
### Строковый shorthand (простые роли)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "ЧтениеНоменклатуры",
|
||||
"synonym": "Чтение номенклатуры",
|
||||
"objects": [
|
||||
"Catalog.Номенклатура: @view",
|
||||
"Catalog.Контрагенты: @view",
|
||||
"DataProcessor.Загрузка: @view"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Формат строки: `Тип.Имя: @пресет` или `Тип.Имя: Право1, Право2`.
|
||||
|
||||
### Объектная форма (RLS, переопределения)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Document.Реализация",
|
||||
"preset": "view",
|
||||
"rights": { "Delete": false },
|
||||
"rls": { "Read": "#ДляОбъекта(\"\")" }
|
||||
}
|
||||
```
|
||||
|
||||
Форматы можно смешивать в одном массиве `objects`.
|
||||
|
||||
### Пресеты
|
||||
|
||||
| Пресет | Действие |
|
||||
|--------|----------|
|
||||
| `@view` | Просмотр: Read, View (+InputByString для справочников/документов; Use+View для обработок/отчётов) |
|
||||
| `@edit` | Полное редактирование: CRUD + Interactive* + Posting (для документов) |
|
||||
|
||||
`@` обязателен в строковом shorthand. В объектной форме — ключ `preset` без `@`.
|
||||
|
||||
### Русские синонимы
|
||||
|
||||
Скрипт принимает русские имена типов и прав: `Справочник` → Catalog, `Чтение` → Read, `Проведение` → Posting и т.д. Полный список — в [спецификации Role DSL](role-dsl-spec.md).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ существующей роли
|
||||
|
||||
```
|
||||
> Проанализируй права роли Roles/БазовыеПраваБП/Ext/Rights.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/role-info`, получит компактную сводку (тысячи строк XML → 50–300 строк текста) и опишет:
|
||||
- какие объекты доступны и с какими правами
|
||||
- где есть ограничения RLS
|
||||
- какие шаблоны ограничений используются
|
||||
|
||||
### Создание роли по описанию
|
||||
|
||||
```
|
||||
> Создай роль МенеджерПродаж с правами:
|
||||
> - Документ РеализацияТоваровУслуг: полные права
|
||||
> - Справочник Контрагенты: чтение
|
||||
> - Справочник Номенклатура: чтение
|
||||
> - Регистр ЦеныНоменклатуры: чтение
|
||||
```
|
||||
|
||||
Claude сформирует JSON с пресетами:
|
||||
```json
|
||||
{
|
||||
"name": "МенеджерПродаж",
|
||||
"synonym": "Менеджер продаж",
|
||||
"objects": [
|
||||
"Document.РеализацияТоваровУслуг: @edit",
|
||||
"Catalog.Контрагенты: @view",
|
||||
"Catalog.Номенклатура: @view",
|
||||
"InformationRegister.ЦеныНоменклатуры: @view"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
И вызовет `/role-compile` → `/role-validate` → `/role-info`.
|
||||
|
||||
### Создание роли для регламентного задания
|
||||
|
||||
```
|
||||
> Проанализируй модуль регламентного задания ОбновлениеКурсовВалют
|
||||
> и создай роль с минимальными правами для его выполнения
|
||||
```
|
||||
|
||||
Claude проанализирует код, определит используемые объекты, создаст JSON с точечными правами (без пресетов — только нужные права), и скомпилирует роль.
|
||||
|
||||
### Создание роли с RLS
|
||||
|
||||
```
|
||||
> Создай роль для чтения документов с ограничением по организации
|
||||
```
|
||||
|
||||
Claude использует объектную форму JSON с шаблонами ограничений.
|
||||
|
||||
### Проверка существующей роли
|
||||
|
||||
```
|
||||
> Проверь корректность роли Roles/МояРоль/Ext/Rights.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/role-validate` и покажет результат: ошибки (невалидный XML, отсутствующие элементы) и предупреждения (неизвестные типы объектов, подозрительные имена прав с подсказками).
|
||||
|
||||
## Структура файлов роли
|
||||
|
||||
```
|
||||
Roles/
|
||||
├── ИмяРоли.xml # Метаданные (UUID, синоним)
|
||||
└── ИмяРоли/
|
||||
└── Ext/
|
||||
└── Rights.xml # Права доступа
|
||||
```
|
||||
|
||||
Регистрация в `Configuration.xml`:
|
||||
```xml
|
||||
<ChildObjects>
|
||||
<Role>ИмяРоли</Role>
|
||||
</ChildObjects>
|
||||
```
|
||||
|
||||
## Спецификация
|
||||
|
||||
- [1c-role-spec.md](1c-role-spec.md) — XML-формат прав роли, типы объектов, RLS, шаблоны ограничений
|
||||
- [role-dsl-spec.md](role-dsl-spec.md) — JSON DSL для описания ролей (формат входных данных `/role-compile`)
|
||||
|
||||
+1348
-1348
File diff suppressed because it is too large
Load Diff
+226
-226
@@ -1,226 +1,226 @@
|
||||
# Схема компоновки данных (СКД)
|
||||
|
||||
Навыки группы `/skd-*` позволяют анализировать, создавать, редактировать и проверять схемы компоновки данных 1С — XML-файлы DataCompositionSchema (Template.xml).
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/skd-info` | `<TemplatePath> [-Mode] [-Name]` | Анализ структуры СКД: наборы, поля, параметры, ресурсы, варианты (11 режимов, включая full) |
|
||||
| `/skd-compile` | `[-DefinitionFile <json> \| -Value <json-string>] -OutputPath <Template.xml>` | Генерация Template.xml из JSON DSL: наборы, поля, итоги, параметры, варианты |
|
||||
| `/skd-decompile` | `<TemplatePath> [-OutputPath <out.json>]` | Преобразование Template.xml в JSON-черновик в формате `/skd-compile` — для нового отчёта по образцу или структурной переработки существующего. Из соображений предосторожности исключён из автоматического подбора моделью — вызывается только явной командой |
|
||||
| `/skd-edit` | `<TemplatePath> -Operation <op> -Value "<value>"` | Точечное редактирование: 26 атомарных операций (add/set/patch/modify/clear/remove) |
|
||||
| `/skd-validate` | `<TemplatePath> [-MaxErrors 20]` | Валидация структурной корректности: ~30 проверок |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание отчёта (текст) → JSON DSL → /skd-compile → Template.xml → /skd-validate
|
||||
↑ ↕ /skd-edit → /skd-info
|
||||
└──── /skd-decompile ──────┘
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение СКД (shorthand-поля, параметры, итоги, варианты) — либо с нуля по описанию, либо `/skd-decompile` готовит черновик по существующему Template.xml
|
||||
2. `/skd-compile` генерирует Template.xml с корректными namespace, типами, группировками
|
||||
3. `/skd-edit` вносит точечные изменения: добавление полей, фильтров, наборов данных, вариантов, условного оформления и т.д.
|
||||
4. `/skd-validate` проверяет корректность XML
|
||||
5. `/skd-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
### Когда `/skd-decompile`, а когда `/skd-edit`
|
||||
|
||||
- **`/skd-edit`** — точечные правки готового отчёта (добавить поле, фильтр, итог, переименовать параметр). Меняет XML адресно, без полной реконструкции, не задевает непокрытые конструкции.
|
||||
- **`/skd-decompile` → правка JSON → `/skd-compile`** — сценарии, где правки структурны: новый отчёт по образцу существующего, переработка варианта, перерисовка макета, перебор набора полей. Цикл переписывает Template.xml целиком.
|
||||
|
||||
**Полнота не гарантируется.** Известные декомпилятору непокрытые конструкции явно отмечаются маркерами в JSON и собираются в файл предупреждений — компилятор откажется собирать такой черновик, пока маркеры не разрешены вручную или не удалены. Но возможны и **тихие потери** — мелкое оформление, редкие настройки, незнакомые декомпилятору расширения. Это даёт валидный XML без части функциональности, и Конфигуратор такой результат не отбракует. Именно поэтому навык не предназначен для точечных правок (для них есть `/skd-edit`) и исключён из автоматического подбора моделью — вызывается только явной командой пользователя. Решение использовать пересобранный Template.xml — на стороне пользователя, и сверка с оригиналом перед коммитом остаётся его ответственностью.
|
||||
|
||||
## JSON DSL — компактный формат
|
||||
|
||||
СКД описываются в JSON с двумя уровнями детализации для каждой секции:
|
||||
|
||||
### Минимальный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"dataSets": [{
|
||||
"query": "ВЫБРАТЬ Номенклатура.Наименование ИЗ Справочник.Номенклатура КАК Номенклатура",
|
||||
"fields": ["Наименование"]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
Умолчания: dataSource создаётся автоматически (`ИсточникДанных1/Local`), набор получает имя `НаборДанных1`, вариант настроек "Основной" с деталями.
|
||||
|
||||
### Поля — shorthand
|
||||
|
||||
```json
|
||||
"fields": [
|
||||
"Наименование",
|
||||
"Количество: decimal(15,2)",
|
||||
"Организация: CatalogRef.Организации @dimension",
|
||||
"Служебное: string #noFilter #noOrder"
|
||||
]
|
||||
```
|
||||
|
||||
Формат: `Имя[: Тип] [@роль...] [#ограничение...]`. Роли: `@dimension`, `@account`, `@balance`, `@period`. Ограничения: `#noField`, `#noFilter`, `#noGroup`, `#noOrder`.
|
||||
|
||||
### Итоги — shorthand
|
||||
|
||||
```json
|
||||
"totalFields": ["Количество: Сумма", "Стоимость: Сумма(Кол * Цена)"]
|
||||
```
|
||||
|
||||
Формат: `Поле: Функция` или `Поле: Функция(выражение)`. Объектная форма поддерживает привязку к группировкам: `{ "dataPath": "X", "expression": "Сумма(X)", "group": ["Группа1", "ОбщийИтог"] }`.
|
||||
|
||||
### Параметры — shorthand + @autoDates
|
||||
|
||||
```json
|
||||
"parameters": [
|
||||
"Период: StandardPeriod = LastMonth @autoDates",
|
||||
"Организация: CatalogRef.Организации"
|
||||
]
|
||||
```
|
||||
|
||||
Флаги: `@autoDates` (авто ДатаНачала/ДатаОкончания), `@valueList` (разрешить список значений), `@hidden` (скрыть параметр, исключить из `dataParameters: auto`).
|
||||
|
||||
### Вычисляемые поля — shorthand
|
||||
|
||||
```json
|
||||
"calculatedFields": ["Итого = Количество * Цена"]
|
||||
```
|
||||
|
||||
### Варианты настроек — shorthand
|
||||
|
||||
```json
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": ["Номенклатура", "Количество", "Сумма"],
|
||||
"filter": ["Организация = _ @off @user"],
|
||||
"order": ["Сумма desc"],
|
||||
"dataParameters": ["Период = LastMonth @user"],
|
||||
"outputParameters": { "Заголовок": "Мой отчёт" },
|
||||
"structure": "Организация > details"
|
||||
}
|
||||
}]
|
||||
```
|
||||
|
||||
- **filter shorthand**: `"Поле оператор значение @флаги"` — флаги `@off`, `@user`, `@quickAccess`, `@normal`, `@inaccessible`
|
||||
- **dataParameters shorthand**: `"Имя = значение @флаги"`, или `"auto"` — автогенерация для всех не-hidden параметров
|
||||
- **structure shorthand**: `"Поле1 > Поле2 > details"` — `>` разделяет уровни группировки
|
||||
- **conditionalAppearance**: условное оформление с автоопределением типов (Color, Boolean, LocalStringType для Формат/Текст/Заголовок, DesignTimeValue для ссылок), OrGroup через `{"group": "Or", "items": [...]}`
|
||||
- **selection**: поддержка `{"folder": "Название", "items": [...]}` для группировки полей (SelectedItemFolder)
|
||||
- **parameters**: `availableValues`, `denyIncompleteValues`, `use: "Always"` в объектной форме
|
||||
|
||||
### Шаблоны вывода — компактный DSL
|
||||
|
||||
Для отчётов с фиксированным оформлением (ФСД, ведомости) — табличное описание вместо raw XML:
|
||||
|
||||
```json
|
||||
"templates": [
|
||||
{
|
||||
"name": "Макет1", "style": "header",
|
||||
"widths": [36, 33, 16, 17], "minHeight": 24.75,
|
||||
"rows": [
|
||||
["Виды кассы", "Валюта", "Остаток на начало\nпериода", "Остаток на конец периода"],
|
||||
["|", "|", "|", "|"],
|
||||
["К1", "К2", "К3", "К4"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Макет2", "style": "data",
|
||||
"widths": [36, 33, 16, 17],
|
||||
"rows": [["{ВидКассы}", "{Валюта}", "{Остаток}", "{ОстатокКонец}"]],
|
||||
"parameters": [
|
||||
{ "name": "ВидКассы", "expression": "Представление(Счет)" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"groupTemplates": [
|
||||
{ "groupName": "ДанныеОтчета", "templateType": "GroupHeader", "template": "Макет1" },
|
||||
{ "groupField": "Счет", "templateType": "Header", "template": "Макет2" }
|
||||
]
|
||||
```
|
||||
|
||||
Синтаксис ячеек: `"текст"` — статика, `"{Имя}"` — параметр, `"|"` — объединение с ячейкой выше, `null` — пустая.
|
||||
|
||||
Привязки: `groupField` — к полю, `groupName` — к именованной группировке. `templateType`: `Header`/`OverallHeader` → `<groupTemplate>`, `GroupHeader` → `<groupHeaderTemplate>`.
|
||||
|
||||
Расшифровка (drilldown): ключ `drilldown` в параметре шаблона генерирует `DetailsAreaTemplateParameter` и привязку `Расшифровка` в appearance ячеек.
|
||||
|
||||
Встроенные стили: `header` (фон, центр, перенос), `data` (фон группы), `subheader` (без фона, центр), `total` (без фона). Все — Arial 10, рамки Solid 1px, цвета через стили платформы. Пользовательские стили — через `skd-styles.json` в директории проекта.
|
||||
|
||||
### Объектная форма
|
||||
|
||||
Все секции поддерживают полную объектную форму для сложных случаев (title, appearance, role с выражениями, userSettingID, userSettingPresentation, conditionalAppearance, группы фильтров And/Or/Not и т.д.). Подробности — в [спецификации SKD DSL](skd-dsl-spec.md).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ существующей СКД
|
||||
|
||||
```
|
||||
> Проанализируй схему компоновки отчёта Reports/АнализНДФЛ/Templates/ОсновнаяСхемаКомпоновкиДанных
|
||||
```
|
||||
|
||||
Claude вызовет `/skd-info` (overview → trace → query → variant) и опишет:
|
||||
- наборы данных и их поля
|
||||
- параметры и значения по умолчанию
|
||||
- ресурсы и формулы агрегации
|
||||
- структуру группировок в вариантах настроек
|
||||
|
||||
### Создание СКД по описанию
|
||||
|
||||
```
|
||||
> Создай СКД для отчёта по продажам: группировка по организациям,
|
||||
> поля Номенклатура, Количество, Сумма. Период — параметр.
|
||||
```
|
||||
|
||||
Claude сформирует JSON (запрос можно вынести в файл: `"query": "@queries/sales.sql"`):
|
||||
```json
|
||||
{
|
||||
"dataSets": [{
|
||||
"name": "Продажи",
|
||||
"query": "ВЫБРАТЬ ...",
|
||||
"fields": [
|
||||
"Организация: CatalogRef.Организации @dimension",
|
||||
"Номенклатура: CatalogRef.Номенклатура @dimension",
|
||||
"Количество: decimal(15,3)",
|
||||
"Сумма: decimal(15,2)"
|
||||
]
|
||||
}],
|
||||
"totalFields": ["Количество: Сумма", "Сумма: Сумма"],
|
||||
"parameters": ["Период: StandardPeriod = LastMonth @autoDates"],
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": ["Номенклатура", "Количество", "Сумма"],
|
||||
"dataParameters": ["Период = LastMonth @user"],
|
||||
"structure": "Организация > details"
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
И вызовет `/skd-compile` → `/skd-validate` → `/skd-info`.
|
||||
|
||||
### Проверка существующей СКД
|
||||
|
||||
```
|
||||
> Проверь корректность СКД Reports/МойОтчёт/Templates/ОсновнаяСхемаКомпоновкиДанных/Ext/Template.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/skd-validate` и покажет результат: ошибки (битые ссылки, дубликаты, невалидные типы) и предупреждения.
|
||||
|
||||
## Структура файлов СКД
|
||||
|
||||
```
|
||||
<Объект>/Templates/
|
||||
├── ИмяМакета.xml # Метаданные (UUID, TemplateType=DataCompositionSchema)
|
||||
└── ИмяМакета/
|
||||
└── Ext/
|
||||
└── Template.xml # Тело схемы (DataCompositionSchema)
|
||||
```
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-dcs-spec.md](1c-dcs-spec.md) — XML-формат DataCompositionSchema, namespace, элементы, типы
|
||||
- [skd-dsl-spec.md](skd-dsl-spec.md) — JSON DSL для описания СКД (формат входных данных `/skd-compile`)
|
||||
# Схема компоновки данных (СКД)
|
||||
|
||||
Навыки группы `/skd-*` позволяют анализировать, создавать, редактировать и проверять схемы компоновки данных 1С — XML-файлы DataCompositionSchema (Template.xml).
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/skd-info` | `<TemplatePath> [-Mode] [-Name]` | Анализ структуры СКД: наборы, поля, параметры, ресурсы, варианты (11 режимов, включая full) |
|
||||
| `/skd-compile` | `[-DefinitionFile <json> \| -Value <json-string>] -OutputPath <Template.xml>` | Генерация Template.xml из JSON DSL: наборы, поля, итоги, параметры, варианты |
|
||||
| `/skd-decompile` | `<TemplatePath> [-OutputPath <out.json>]` | Преобразование Template.xml в JSON-черновик в формате `/skd-compile` — для нового отчёта по образцу или структурной переработки существующего. Из соображений предосторожности исключён из автоматического подбора моделью — вызывается только явной командой |
|
||||
| `/skd-edit` | `<TemplatePath> -Operation <op> -Value "<value>"` | Точечное редактирование: 26 атомарных операций (add/set/patch/modify/clear/remove) |
|
||||
| `/skd-validate` | `<TemplatePath> [-MaxErrors 20]` | Валидация структурной корректности: ~30 проверок |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание отчёта (текст) → JSON DSL → /skd-compile → Template.xml → /skd-validate
|
||||
↑ ↕ /skd-edit → /skd-info
|
||||
└──── /skd-decompile ──────┘
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение СКД (shorthand-поля, параметры, итоги, варианты) — либо с нуля по описанию, либо `/skd-decompile` готовит черновик по существующему Template.xml
|
||||
2. `/skd-compile` генерирует Template.xml с корректными namespace, типами, группировками
|
||||
3. `/skd-edit` вносит точечные изменения: добавление полей, фильтров, наборов данных, вариантов, условного оформления и т.д.
|
||||
4. `/skd-validate` проверяет корректность XML
|
||||
5. `/skd-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
### Когда `/skd-decompile`, а когда `/skd-edit`
|
||||
|
||||
- **`/skd-edit`** — точечные правки готового отчёта (добавить поле, фильтр, итог, переименовать параметр). Меняет XML адресно, без полной реконструкции, не задевает непокрытые конструкции.
|
||||
- **`/skd-decompile` → правка JSON → `/skd-compile`** — сценарии, где правки структурны: новый отчёт по образцу существующего, переработка варианта, перерисовка макета, перебор набора полей. Цикл переписывает Template.xml целиком.
|
||||
|
||||
**Полнота не гарантируется.** Известные декомпилятору непокрытые конструкции явно отмечаются маркерами в JSON и собираются в файл предупреждений — компилятор откажется собирать такой черновик, пока маркеры не разрешены вручную или не удалены. Но возможны и **тихие потери** — мелкое оформление, редкие настройки, незнакомые декомпилятору расширения. Это даёт валидный XML без части функциональности, и Конфигуратор такой результат не отбракует. Именно поэтому навык не предназначен для точечных правок (для них есть `/skd-edit`) и исключён из автоматического подбора моделью — вызывается только явной командой пользователя. Решение использовать пересобранный Template.xml — на стороне пользователя, и сверка с оригиналом перед коммитом остаётся его ответственностью.
|
||||
|
||||
## JSON DSL — компактный формат
|
||||
|
||||
СКД описываются в JSON с двумя уровнями детализации для каждой секции:
|
||||
|
||||
### Минимальный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"dataSets": [{
|
||||
"query": "ВЫБРАТЬ Номенклатура.Наименование ИЗ Справочник.Номенклатура КАК Номенклатура",
|
||||
"fields": ["Наименование"]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
Умолчания: dataSource создаётся автоматически (`ИсточникДанных1/Local`), набор получает имя `НаборДанных1`, вариант настроек "Основной" с деталями.
|
||||
|
||||
### Поля — shorthand
|
||||
|
||||
```json
|
||||
"fields": [
|
||||
"Наименование",
|
||||
"Количество: decimal(15,2)",
|
||||
"Организация: CatalogRef.Организации @dimension",
|
||||
"Служебное: string #noFilter #noOrder"
|
||||
]
|
||||
```
|
||||
|
||||
Формат: `Имя[: Тип] [@роль...] [#ограничение...]`. Роли: `@dimension`, `@account`, `@balance`, `@period`. Ограничения: `#noField`, `#noFilter`, `#noGroup`, `#noOrder`.
|
||||
|
||||
### Итоги — shorthand
|
||||
|
||||
```json
|
||||
"totalFields": ["Количество: Сумма", "Стоимость: Сумма(Кол * Цена)"]
|
||||
```
|
||||
|
||||
Формат: `Поле: Функция` или `Поле: Функция(выражение)`. Объектная форма поддерживает привязку к группировкам: `{ "dataPath": "X", "expression": "Сумма(X)", "group": ["Группа1", "ОбщийИтог"] }`.
|
||||
|
||||
### Параметры — shorthand + @autoDates
|
||||
|
||||
```json
|
||||
"parameters": [
|
||||
"Период: StandardPeriod = LastMonth @autoDates",
|
||||
"Организация: CatalogRef.Организации"
|
||||
]
|
||||
```
|
||||
|
||||
Флаги: `@autoDates` (авто ДатаНачала/ДатаОкончания), `@valueList` (разрешить список значений), `@hidden` (скрыть параметр, исключить из `dataParameters: auto`).
|
||||
|
||||
### Вычисляемые поля — shorthand
|
||||
|
||||
```json
|
||||
"calculatedFields": ["Итого = Количество * Цена"]
|
||||
```
|
||||
|
||||
### Варианты настроек — shorthand
|
||||
|
||||
```json
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": ["Номенклатура", "Количество", "Сумма"],
|
||||
"filter": ["Организация = _ @off @user"],
|
||||
"order": ["Сумма desc"],
|
||||
"dataParameters": ["Период = LastMonth @user"],
|
||||
"outputParameters": { "Заголовок": "Мой отчёт" },
|
||||
"structure": "Организация > details"
|
||||
}
|
||||
}]
|
||||
```
|
||||
|
||||
- **filter shorthand**: `"Поле оператор значение @флаги"` — флаги `@off`, `@user`, `@quickAccess`, `@normal`, `@inaccessible`
|
||||
- **dataParameters shorthand**: `"Имя = значение @флаги"`, или `"auto"` — автогенерация для всех не-hidden параметров
|
||||
- **structure shorthand**: `"Поле1 > Поле2 > details"` — `>` разделяет уровни группировки
|
||||
- **conditionalAppearance**: условное оформление с автоопределением типов (Color, Boolean, LocalStringType для Формат/Текст/Заголовок, DesignTimeValue для ссылок), OrGroup через `{"group": "Or", "items": [...]}`
|
||||
- **selection**: поддержка `{"folder": "Название", "items": [...]}` для группировки полей (SelectedItemFolder)
|
||||
- **parameters**: `availableValues`, `denyIncompleteValues`, `use: "Always"` в объектной форме
|
||||
|
||||
### Шаблоны вывода — компактный DSL
|
||||
|
||||
Для отчётов с фиксированным оформлением (ФСД, ведомости) — табличное описание вместо raw XML:
|
||||
|
||||
```json
|
||||
"templates": [
|
||||
{
|
||||
"name": "Макет1", "style": "header",
|
||||
"widths": [36, 33, 16, 17], "minHeight": 24.75,
|
||||
"rows": [
|
||||
["Виды кассы", "Валюта", "Остаток на начало\nпериода", "Остаток на конец периода"],
|
||||
["|", "|", "|", "|"],
|
||||
["К1", "К2", "К3", "К4"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Макет2", "style": "data",
|
||||
"widths": [36, 33, 16, 17],
|
||||
"rows": [["{ВидКассы}", "{Валюта}", "{Остаток}", "{ОстатокКонец}"]],
|
||||
"parameters": [
|
||||
{ "name": "ВидКассы", "expression": "Представление(Счет)" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"groupTemplates": [
|
||||
{ "groupName": "ДанныеОтчета", "templateType": "GroupHeader", "template": "Макет1" },
|
||||
{ "groupField": "Счет", "templateType": "Header", "template": "Макет2" }
|
||||
]
|
||||
```
|
||||
|
||||
Синтаксис ячеек: `"текст"` — статика, `"{Имя}"` — параметр, `"|"` — объединение с ячейкой выше, `null` — пустая.
|
||||
|
||||
Привязки: `groupField` — к полю, `groupName` — к именованной группировке. `templateType`: `Header`/`OverallHeader` → `<groupTemplate>`, `GroupHeader` → `<groupHeaderTemplate>`.
|
||||
|
||||
Расшифровка (drilldown): ключ `drilldown` в параметре шаблона генерирует `DetailsAreaTemplateParameter` и привязку `Расшифровка` в appearance ячеек.
|
||||
|
||||
Встроенные стили: `header` (фон, центр, перенос), `data` (фон группы), `subheader` (без фона, центр), `total` (без фона). Все — Arial 10, рамки Solid 1px, цвета через стили платформы. Пользовательские стили — через `skd-styles.json` в директории проекта.
|
||||
|
||||
### Объектная форма
|
||||
|
||||
Все секции поддерживают полную объектную форму для сложных случаев (title, appearance, role с выражениями, userSettingID, userSettingPresentation, conditionalAppearance, группы фильтров And/Or/Not и т.д.). Подробности — в [спецификации SKD DSL](skd-dsl-spec.md).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ существующей СКД
|
||||
|
||||
```
|
||||
> Проанализируй схему компоновки отчёта Reports/АнализНДФЛ/Templates/ОсновнаяСхемаКомпоновкиДанных
|
||||
```
|
||||
|
||||
Claude вызовет `/skd-info` (overview → trace → query → variant) и опишет:
|
||||
- наборы данных и их поля
|
||||
- параметры и значения по умолчанию
|
||||
- ресурсы и формулы агрегации
|
||||
- структуру группировок в вариантах настроек
|
||||
|
||||
### Создание СКД по описанию
|
||||
|
||||
```
|
||||
> Создай СКД для отчёта по продажам: группировка по организациям,
|
||||
> поля Номенклатура, Количество, Сумма. Период — параметр.
|
||||
```
|
||||
|
||||
Claude сформирует JSON (запрос можно вынести в файл: `"query": "@queries/sales.sql"`):
|
||||
```json
|
||||
{
|
||||
"dataSets": [{
|
||||
"name": "Продажи",
|
||||
"query": "ВЫБРАТЬ ...",
|
||||
"fields": [
|
||||
"Организация: CatalogRef.Организации @dimension",
|
||||
"Номенклатура: CatalogRef.Номенклатура @dimension",
|
||||
"Количество: decimal(15,3)",
|
||||
"Сумма: decimal(15,2)"
|
||||
]
|
||||
}],
|
||||
"totalFields": ["Количество: Сумма", "Сумма: Сумма"],
|
||||
"parameters": ["Период: StandardPeriod = LastMonth @autoDates"],
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": ["Номенклатура", "Количество", "Сумма"],
|
||||
"dataParameters": ["Период = LastMonth @user"],
|
||||
"structure": "Организация > details"
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
И вызовет `/skd-compile` → `/skd-validate` → `/skd-info`.
|
||||
|
||||
### Проверка существующей СКД
|
||||
|
||||
```
|
||||
> Проверь корректность СКД Reports/МойОтчёт/Templates/ОсновнаяСхемаКомпоновкиДанных/Ext/Template.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/skd-validate` и покажет результат: ошибки (битые ссылки, дубликаты, невалидные типы) и предупреждения.
|
||||
|
||||
## Структура файлов СКД
|
||||
|
||||
```
|
||||
<Объект>/Templates/
|
||||
├── ИмяМакета.xml # Метаданные (UUID, TemplateType=DataCompositionSchema)
|
||||
└── ИмяМакета/
|
||||
└── Ext/
|
||||
└── Template.xml # Тело схемы (DataCompositionSchema)
|
||||
```
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [1c-dcs-spec.md](1c-dcs-spec.md) — XML-формат DataCompositionSchema, namespace, элементы, типы
|
||||
- [skd-dsl-spec.md](skd-dsl-spec.md) — JSON DSL для описания СКД (формат входных данных `/skd-compile`)
|
||||
|
||||
+205
-205
@@ -1,205 +1,205 @@
|
||||
# Подсистемы и командный интерфейс
|
||||
|
||||
Навыки групп `/subsystem-*` и `/interface-*` позволяют анализировать, создавать, редактировать и проверять подсистемы 1С и их командный интерфейс — XML-файлы Subsystem и CommandInterface.xml из выгрузки конфигурации.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/subsystem-info` | `<SubsystemPath> [-Mode] [-Name]` | Анализ структуры подсистемы: состав, дочерние, CI, дерево иерархии (5 режимов, включая full) |
|
||||
| `/subsystem-compile` | `<JsonPath> <OutputDir> [-Parent]` | Генерация подсистемы из JSON DSL: XML + регистрация в Configuration.xml |
|
||||
| `/subsystem-edit` | `<SubsystemPath> -Operation <op> -Value "<value>"` | Точечное редактирование: 5 операций (add/remove content/child, set-property) |
|
||||
| `/subsystem-validate` | `<SubsystemPath> [-MaxErrors 30]` | Валидация структурной корректности: 13 проверок |
|
||||
| `/interface-edit` | `<CIPath> -Operation <op> -Value "<value>"` | Настройка CommandInterface.xml: 6 операций (hide/show/place/order) |
|
||||
| `/interface-validate` | `<CIPath> [-MaxErrors 30]` | Валидация CommandInterface.xml: 13 проверок |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание раздела (текст) → JSON DSL → /subsystem-compile → XML → /subsystem-validate
|
||||
↕ /subsystem-edit → /subsystem-info
|
||||
/interface-edit → CommandInterface.xml → /interface-validate
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение подсистемы (имя, состав, дочерние, картинка)
|
||||
2. `/subsystem-compile` генерирует XML-файл подсистемы и регистрирует в Configuration.xml
|
||||
3. `/subsystem-edit` вносит точечные изменения: добавление объектов, дочерних подсистем, изменение свойств
|
||||
4. `/interface-edit` настраивает командный интерфейс: скрытие/показ команд, размещение в группах, порядок
|
||||
5. `/subsystem-validate` и `/interface-validate` проверяют корректность XML
|
||||
6. `/subsystem-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## JSON DSL — формат подсистемы
|
||||
|
||||
Подсистемы описываются в JSON:
|
||||
|
||||
### Минимальный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Тест"
|
||||
}
|
||||
```
|
||||
|
||||
Умолчания: `includeInCommandInterface = true`, `useOneCommand = false`, synonym генерируется из name.
|
||||
|
||||
### Полный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Продажи",
|
||||
"synonym": "Продажи",
|
||||
"comment": "",
|
||||
"includeInCommandInterface": true,
|
||||
"useOneCommand": false,
|
||||
"explanation": "Управление продажами и взаимодействием с клиентами",
|
||||
"picture": "CommonPicture.Продажи",
|
||||
"content": ["Catalog.Товары", "Document.Заказ", "Report.Продажи"],
|
||||
"children": ["Настройки", "Отчёты"]
|
||||
}
|
||||
```
|
||||
|
||||
### Свойства
|
||||
|
||||
| Свойство | Тип | Умолчание | Описание |
|
||||
|----------|-----|-----------|----------|
|
||||
| `name` | string | *(обязательно)* | Идентификатор подсистемы |
|
||||
| `synonym` | string | из name | Отображаемое имя |
|
||||
| `comment` | string | `""` | Комментарий |
|
||||
| `includeInCommandInterface` | bool | `true` | Включать в командный интерфейс |
|
||||
| `useOneCommand` | bool | `false` | Режим одной команды (требует ровно 1 элемент в content) |
|
||||
| `explanation` | string | `""` | Описание раздела (подсказка) |
|
||||
| `picture` | string | — | Ссылка на общую картинку (`CommonPicture.Имя`) |
|
||||
| `content` | string[] | `[]` | Состав: `"Тип.Имя"` (Catalog.X, Document.Y, Report.Z, ...) |
|
||||
| `children` | string[] | `[]` | Имена дочерних подсистем |
|
||||
|
||||
## Командный интерфейс — операции
|
||||
|
||||
Навык `/interface-edit` управляет файлом `CommandInterface.xml` подсистемы.
|
||||
|
||||
### Форматы ссылок на команды
|
||||
|
||||
| Формат | Пример |
|
||||
|--------|--------|
|
||||
| StandardCommand | `Catalog.Товары.StandardCommand.OpenList` |
|
||||
| Command | `Report.Продажи.Command.Отчёт` |
|
||||
| CommonCommand | `CommonCommand.МояКоманда` |
|
||||
|
||||
### Операции
|
||||
|
||||
| Операция | Значение | Описание |
|
||||
|----------|----------|----------|
|
||||
| `hide` | `"Cmd.Name"` или массив | Скрыть команду (CommandsVisibility, false) |
|
||||
| `show` | `"Cmd.Name"` или массив | Показать команду (CommandsVisibility, true) |
|
||||
| `place` | `{"command":"...","group":"CommandGroup.X"}` | Разместить команду в группе |
|
||||
| `order` | `{"group":"...","commands":[...]}` | Задать порядок команд в группе |
|
||||
| `subsystem-order` | `["Subsystem.X.Subsystem.A",...]` | Порядок дочерних подсистем |
|
||||
| `group-order` | `["NavigationPanelOrdinary",...]` | Порядок групп |
|
||||
|
||||
### Примеры
|
||||
|
||||
```powershell
|
||||
# Скрыть команду
|
||||
... -CIPath Subsystems/Продажи/Ext/CommandInterface.xml -Operation hide -Value "Catalog.Товары.StandardCommand.OpenList"
|
||||
|
||||
# Показать команду
|
||||
... -Operation show -Value "Report.Продажи.Command.Отчёт"
|
||||
|
||||
# Разместить в группе
|
||||
... -Operation place -Value '{"command":"Report.X.Command.Y","group":"CommandGroup.Отчеты"}'
|
||||
|
||||
# Задать порядок подсистем
|
||||
... -Operation subsystem-order -Value '["Subsystem.X.Subsystem.A","Subsystem.X.Subsystem.B"]'
|
||||
```
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ структуры подсистем
|
||||
|
||||
```
|
||||
> Покажи дерево подсистем конфигурации
|
||||
```
|
||||
|
||||
Claude вызовет `/subsystem-info` (tree → overview → ci) и опишет:
|
||||
- иерархию подсистем с маркерами [CI], [OneCmd], [Скрыт]
|
||||
- состав каждой подсистемы (объекты по типам)
|
||||
- настройки командного интерфейса (видимость, размещение, порядок)
|
||||
|
||||
### Создание подсистемы по описанию
|
||||
|
||||
```
|
||||
> Создай подсистему Продажи: справочник Товары, документ Заказ, отчёт Продажи.
|
||||
> Дочерние подсистемы: Настройки, Отчёты. Картинка — CommonPicture.Продажи.
|
||||
```
|
||||
|
||||
Claude сформирует JSON:
|
||||
```json
|
||||
{
|
||||
"name": "Продажи",
|
||||
"synonym": "Продажи",
|
||||
"content": ["Catalog.Товары", "Document.Заказ", "Report.Продажи"],
|
||||
"children": ["Настройки", "Отчёты"],
|
||||
"picture": "CommonPicture.Продажи"
|
||||
}
|
||||
```
|
||||
|
||||
И вызовет `/subsystem-compile` → `/subsystem-validate` → `/subsystem-info`.
|
||||
|
||||
### Добавление объектов в подсистему
|
||||
|
||||
```
|
||||
> Добавь Document.Счёт и Report.Задолженность в подсистему Продажи
|
||||
```
|
||||
|
||||
Claude вызовет `/subsystem-edit` с операцией `add-content`:
|
||||
```powershell
|
||||
... -SubsystemPath Subsystems/Продажи.xml -Operation add-content -Value '["Document.Счёт","Report.Задолженность"]'
|
||||
```
|
||||
|
||||
### Настройка командного интерфейса
|
||||
|
||||
```
|
||||
> Скрой команду открытия списка товаров и размести отчёт Продажи в группе Отчёты
|
||||
```
|
||||
|
||||
Claude вызовет `/interface-edit`:
|
||||
```powershell
|
||||
# Скрыть команду
|
||||
... -CIPath Subsystems/Продажи/Ext/CommandInterface.xml -Operation hide -Value "Catalog.Товары.StandardCommand.OpenList"
|
||||
|
||||
# Разместить в группе
|
||||
... -Operation place -Value '{"command":"Report.Продажи.Command.Отчёт","group":"CommandGroup.Отчёты"}'
|
||||
```
|
||||
|
||||
### Проверка подсистемы
|
||||
|
||||
```
|
||||
> Проверь подсистему Subsystems/Продажи.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/subsystem-validate` и `/interface-validate`, покажет результат: ошибки (невалидный XML, отсутствующие файлы, дубликаты) и предупреждения.
|
||||
|
||||
## Структура файлов подсистемы
|
||||
|
||||
```
|
||||
Subsystems/
|
||||
├── ИмяПодсистемы.xml # Определение подсистемы (UUID, свойства, Content)
|
||||
└── ИмяПодсистемы/
|
||||
├── Ext/
|
||||
│ └── CommandInterface.xml # Командный интерфейс (видимость, размещение, порядок)
|
||||
└── Subsystems/ # Вложенные подсистемы
|
||||
├── Дочерняя.xml
|
||||
└── Дочерняя/
|
||||
└── Ext/
|
||||
└── CommandInterface.xml
|
||||
```
|
||||
|
||||
Регистрация в `Configuration.xml`:
|
||||
```xml
|
||||
<ChildObjects>
|
||||
<Subsystem>ИмяПодсистемы</Subsystem>
|
||||
</ChildObjects>
|
||||
```
|
||||
|
||||
## Спецификация
|
||||
|
||||
- [1c-subsystem-spec.md](1c-subsystem-spec.md) — XML-формат подсистем, CommandInterface.xml, namespace, элементы
|
||||
# Подсистемы и командный интерфейс
|
||||
|
||||
Навыки групп `/subsystem-*` и `/interface-*` позволяют анализировать, создавать, редактировать и проверять подсистемы 1С и их командный интерфейс — XML-файлы Subsystem и CommandInterface.xml из выгрузки конфигурации.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Параметры | Описание |
|
||||
|-------|-----------|----------|
|
||||
| `/subsystem-info` | `<SubsystemPath> [-Mode] [-Name]` | Анализ структуры подсистемы: состав, дочерние, CI, дерево иерархии (5 режимов, включая full) |
|
||||
| `/subsystem-compile` | `<JsonPath> <OutputDir> [-Parent]` | Генерация подсистемы из JSON DSL: XML + регистрация в Configuration.xml |
|
||||
| `/subsystem-edit` | `<SubsystemPath> -Operation <op> -Value "<value>"` | Точечное редактирование: 5 операций (add/remove content/child, set-property) |
|
||||
| `/subsystem-validate` | `<SubsystemPath> [-MaxErrors 30]` | Валидация структурной корректности: 13 проверок |
|
||||
| `/interface-edit` | `<CIPath> -Operation <op> -Value "<value>"` | Настройка CommandInterface.xml: 6 операций (hide/show/place/order) |
|
||||
| `/interface-validate` | `<CIPath> [-MaxErrors 30]` | Валидация CommandInterface.xml: 13 проверок |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
Описание раздела (текст) → JSON DSL → /subsystem-compile → XML → /subsystem-validate
|
||||
↕ /subsystem-edit → /subsystem-info
|
||||
/interface-edit → CommandInterface.xml → /interface-validate
|
||||
```
|
||||
|
||||
1. Claude формирует JSON-определение подсистемы (имя, состав, дочерние, картинка)
|
||||
2. `/subsystem-compile` генерирует XML-файл подсистемы и регистрирует в Configuration.xml
|
||||
3. `/subsystem-edit` вносит точечные изменения: добавление объектов, дочерних подсистем, изменение свойств
|
||||
4. `/interface-edit` настраивает командный интерфейс: скрытие/показ команд, размещение в группах, порядок
|
||||
5. `/subsystem-validate` и `/interface-validate` проверяют корректность XML
|
||||
6. `/subsystem-info` выводит компактную сводку для визуальной проверки
|
||||
|
||||
## JSON DSL — формат подсистемы
|
||||
|
||||
Подсистемы описываются в JSON:
|
||||
|
||||
### Минимальный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Тест"
|
||||
}
|
||||
```
|
||||
|
||||
Умолчания: `includeInCommandInterface = true`, `useOneCommand = false`, synonym генерируется из name.
|
||||
|
||||
### Полный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Продажи",
|
||||
"synonym": "Продажи",
|
||||
"comment": "",
|
||||
"includeInCommandInterface": true,
|
||||
"useOneCommand": false,
|
||||
"explanation": "Управление продажами и взаимодействием с клиентами",
|
||||
"picture": "CommonPicture.Продажи",
|
||||
"content": ["Catalog.Товары", "Document.Заказ", "Report.Продажи"],
|
||||
"children": ["Настройки", "Отчёты"]
|
||||
}
|
||||
```
|
||||
|
||||
### Свойства
|
||||
|
||||
| Свойство | Тип | Умолчание | Описание |
|
||||
|----------|-----|-----------|----------|
|
||||
| `name` | string | *(обязательно)* | Идентификатор подсистемы |
|
||||
| `synonym` | string | из name | Отображаемое имя |
|
||||
| `comment` | string | `""` | Комментарий |
|
||||
| `includeInCommandInterface` | bool | `true` | Включать в командный интерфейс |
|
||||
| `useOneCommand` | bool | `false` | Режим одной команды (требует ровно 1 элемент в content) |
|
||||
| `explanation` | string | `""` | Описание раздела (подсказка) |
|
||||
| `picture` | string | — | Ссылка на общую картинку (`CommonPicture.Имя`) |
|
||||
| `content` | string[] | `[]` | Состав: `"Тип.Имя"` (Catalog.X, Document.Y, Report.Z, ...) |
|
||||
| `children` | string[] | `[]` | Имена дочерних подсистем |
|
||||
|
||||
## Командный интерфейс — операции
|
||||
|
||||
Навык `/interface-edit` управляет файлом `CommandInterface.xml` подсистемы.
|
||||
|
||||
### Форматы ссылок на команды
|
||||
|
||||
| Формат | Пример |
|
||||
|--------|--------|
|
||||
| StandardCommand | `Catalog.Товары.StandardCommand.OpenList` |
|
||||
| Command | `Report.Продажи.Command.Отчёт` |
|
||||
| CommonCommand | `CommonCommand.МояКоманда` |
|
||||
|
||||
### Операции
|
||||
|
||||
| Операция | Значение | Описание |
|
||||
|----------|----------|----------|
|
||||
| `hide` | `"Cmd.Name"` или массив | Скрыть команду (CommandsVisibility, false) |
|
||||
| `show` | `"Cmd.Name"` или массив | Показать команду (CommandsVisibility, true) |
|
||||
| `place` | `{"command":"...","group":"CommandGroup.X"}` | Разместить команду в группе |
|
||||
| `order` | `{"group":"...","commands":[...]}` | Задать порядок команд в группе |
|
||||
| `subsystem-order` | `["Subsystem.X.Subsystem.A",...]` | Порядок дочерних подсистем |
|
||||
| `group-order` | `["NavigationPanelOrdinary",...]` | Порядок групп |
|
||||
|
||||
### Примеры
|
||||
|
||||
```powershell
|
||||
# Скрыть команду
|
||||
... -CIPath Subsystems/Продажи/Ext/CommandInterface.xml -Operation hide -Value "Catalog.Товары.StandardCommand.OpenList"
|
||||
|
||||
# Показать команду
|
||||
... -Operation show -Value "Report.Продажи.Command.Отчёт"
|
||||
|
||||
# Разместить в группе
|
||||
... -Operation place -Value '{"command":"Report.X.Command.Y","group":"CommandGroup.Отчеты"}'
|
||||
|
||||
# Задать порядок подсистем
|
||||
... -Operation subsystem-order -Value '["Subsystem.X.Subsystem.A","Subsystem.X.Subsystem.B"]'
|
||||
```
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Анализ структуры подсистем
|
||||
|
||||
```
|
||||
> Покажи дерево подсистем конфигурации
|
||||
```
|
||||
|
||||
Claude вызовет `/subsystem-info` (tree → overview → ci) и опишет:
|
||||
- иерархию подсистем с маркерами [CI], [OneCmd], [Скрыт]
|
||||
- состав каждой подсистемы (объекты по типам)
|
||||
- настройки командного интерфейса (видимость, размещение, порядок)
|
||||
|
||||
### Создание подсистемы по описанию
|
||||
|
||||
```
|
||||
> Создай подсистему Продажи: справочник Товары, документ Заказ, отчёт Продажи.
|
||||
> Дочерние подсистемы: Настройки, Отчёты. Картинка — CommonPicture.Продажи.
|
||||
```
|
||||
|
||||
Claude сформирует JSON:
|
||||
```json
|
||||
{
|
||||
"name": "Продажи",
|
||||
"synonym": "Продажи",
|
||||
"content": ["Catalog.Товары", "Document.Заказ", "Report.Продажи"],
|
||||
"children": ["Настройки", "Отчёты"],
|
||||
"picture": "CommonPicture.Продажи"
|
||||
}
|
||||
```
|
||||
|
||||
И вызовет `/subsystem-compile` → `/subsystem-validate` → `/subsystem-info`.
|
||||
|
||||
### Добавление объектов в подсистему
|
||||
|
||||
```
|
||||
> Добавь Document.Счёт и Report.Задолженность в подсистему Продажи
|
||||
```
|
||||
|
||||
Claude вызовет `/subsystem-edit` с операцией `add-content`:
|
||||
```powershell
|
||||
... -SubsystemPath Subsystems/Продажи.xml -Operation add-content -Value '["Document.Счёт","Report.Задолженность"]'
|
||||
```
|
||||
|
||||
### Настройка командного интерфейса
|
||||
|
||||
```
|
||||
> Скрой команду открытия списка товаров и размести отчёт Продажи в группе Отчёты
|
||||
```
|
||||
|
||||
Claude вызовет `/interface-edit`:
|
||||
```powershell
|
||||
# Скрыть команду
|
||||
... -CIPath Subsystems/Продажи/Ext/CommandInterface.xml -Operation hide -Value "Catalog.Товары.StandardCommand.OpenList"
|
||||
|
||||
# Разместить в группе
|
||||
... -Operation place -Value '{"command":"Report.Продажи.Command.Отчёт","group":"CommandGroup.Отчёты"}'
|
||||
```
|
||||
|
||||
### Проверка подсистемы
|
||||
|
||||
```
|
||||
> Проверь подсистему Subsystems/Продажи.xml
|
||||
```
|
||||
|
||||
Claude вызовет `/subsystem-validate` и `/interface-validate`, покажет результат: ошибки (невалидный XML, отсутствующие файлы, дубликаты) и предупреждения.
|
||||
|
||||
## Структура файлов подсистемы
|
||||
|
||||
```
|
||||
Subsystems/
|
||||
├── ИмяПодсистемы.xml # Определение подсистемы (UUID, свойства, Content)
|
||||
└── ИмяПодсистемы/
|
||||
├── Ext/
|
||||
│ └── CommandInterface.xml # Командный интерфейс (видимость, размещение, порядок)
|
||||
└── Subsystems/ # Вложенные подсистемы
|
||||
├── Дочерняя.xml
|
||||
└── Дочерняя/
|
||||
└── Ext/
|
||||
└── CommandInterface.xml
|
||||
```
|
||||
|
||||
Регистрация в `Configuration.xml`:
|
||||
```xml
|
||||
<ChildObjects>
|
||||
<Subsystem>ИмяПодсистемы</Subsystem>
|
||||
</ChildObjects>
|
||||
```
|
||||
|
||||
## Спецификация
|
||||
|
||||
- [1c-subsystem-spec.md](1c-subsystem-spec.md) — XML-формат подсистем, CommandInterface.xml, namespace, элементы
|
||||
|
||||
+251
-251
@@ -1,251 +1,251 @@
|
||||
# Конфигурация проекта (.v8-project.json)
|
||||
|
||||
Файл `.v8-project.json` — единый конфиг проекта для всех навыков Claude Code. Хранит пути к платформе 1С, список баз данных и настройки инструментов (Apache, ffmpeg, TTS).
|
||||
|
||||
Размещается в корне проекта (рядом с `.git/`). Создаётся навыком `/db-list add` или вручную.
|
||||
|
||||
> **Шаблон**: в корне репозитория лежит `.v8-project.example.json` — скопируйте его в `.v8-project.json` и поправьте пути под свою машину.
|
||||
|
||||
> **Безопасность**: файл содержит секреты (пароли баз данных, API-ключи TTS) и добавлен в `.gitignore` — он не попадает в репозиторий. Каждый разработчик заводит свой `.v8-project.json` локально. Пример (`.v8-project.example.json`) секретов не содержит и хранится в репозитории.
|
||||
|
||||
## Полная схема
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// === Платформа ===
|
||||
"v8path": "C:\\Program Files\\1cv8\\8.3.24.1691\\bin",
|
||||
|
||||
// === Базы данных ===
|
||||
"databases": [
|
||||
{
|
||||
"id": "dev", // уникальный идентификатор
|
||||
"name": "Разработка", // отображаемое имя
|
||||
"type": "file", // "file" или "server"
|
||||
"path": "C:\\Bases\\MyApp_Dev", // каталог (для file)
|
||||
"user": "Admin", // пользователь 1С
|
||||
"password": "", // пароль
|
||||
"aliases": ["dev", "разработка"], // альтернативные имена
|
||||
"branches": ["dev", "feature/*"], // привязка к Git-веткам
|
||||
"configSrc": "src\\cf", // каталог XML-выгрузки конфигурации (см. структуру ниже)
|
||||
"webUrl": "http://localhost:8081/dev" // URL веб-клиента (для /web-test)
|
||||
},
|
||||
{
|
||||
"id": "test",
|
||||
"name": "Тестовая",
|
||||
"type": "server", // серверная база
|
||||
"server": "srv01", // адрес сервера 1С
|
||||
"ref": "MyApp_Test", // имя базы на сервере
|
||||
"user": "Admin",
|
||||
"password": "123",
|
||||
"aliases": ["test", "тест"]
|
||||
}
|
||||
],
|
||||
"default": "dev",
|
||||
|
||||
// === Инструменты ===
|
||||
"webPath": "C:\\tools\\apache24", // каталог Apache
|
||||
"ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe", // путь к ffmpeg
|
||||
"tts": { // настройки озвучки
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Корневые поля
|
||||
|
||||
| Поле | Тип | Обяз. | По умолчанию | Описание | Кто заполняет |
|
||||
|------|-----|:-----:|-------------|----------|---------------|
|
||||
| `v8path` | string | да | — | Путь к каталогу `bin` платформы 1С (или к файлу `1cv8.exe`/`ibcmd.exe`, см. ниже) | `/db-list add` или руками |
|
||||
| `databases` | array | да | — | Список баз данных | `/db-list add` |
|
||||
| `default` | string | нет | — | `id` базы по умолчанию | `/db-list` |
|
||||
| `editingAllowedCheck` | `"deny"`/`"warn"`/`"off"` | нет | `deny` | Глобальная реакция support-guard на правку объектов на замке (см. ниже) | Руками |
|
||||
| `skillSuggester` | `"on"`/`"off"` | нет | `on` | Подсказки навыков от хука skill-suggester (только если хук включён, см. ниже) | Руками |
|
||||
| `webPath` | string | нет | `tools/apache24` | Каталог Apache HTTP Server | Руками |
|
||||
| `ffmpegPath` | string | нет | `tools/ffmpeg/bin/ffmpeg.exe` | Путь к ffmpeg | Руками |
|
||||
| `tts` | object | нет | Edge TTS, DmitryNeural | Настройки озвучки видео | Руками |
|
||||
|
||||
## Базы данных (`databases[]`)
|
||||
|
||||
| Поле | Тип | Обяз. | Описание | Кто заполняет |
|
||||
|------|-----|:-----:|----------|---------------|
|
||||
| `id` | string | да | Уникальный идентификатор | `/db-list add` |
|
||||
| `name` | string | да | Отображаемое имя | `/db-list add` |
|
||||
| `type` | `"file"` / `"server"` | да | Тип подключения | `/db-list add` |
|
||||
| `path` | string | для file | Каталог файловой базы | `/db-list add` |
|
||||
| `server` | string | для server | Адрес сервера 1С | `/db-list add` |
|
||||
| `ref` | string | для server | Имя базы на сервере | `/db-list add` |
|
||||
| `user` | string | нет | Пользователь 1С | `/db-list add` или руками |
|
||||
| `password` | string | нет | Пароль | `/db-list add` или руками |
|
||||
| `aliases` | string[] | нет | Альтернативные имена для обращения к базе | `/db-list add` или руками |
|
||||
| `branches` | string[] | нет | Git-ветки или glob-паттерны (`release/*`, `feature/*`) | Руками |
|
||||
| `configSrc` | string | нет | Каталог XML-выгрузки конфигурации (рекомендуется `src/cf`, см. структуру ниже). Путь относительный — от корня проекта | Руками |
|
||||
| `editingAllowedCheck` | `"deny"`/`"warn"`/`"off"` | нет | Override реакции support-guard для этой базы (см. ниже) | Руками |
|
||||
| `skillSuggester` | `"on"`/`"off"` | нет | Override подсказок навыков для этой базы (см. ниже) | Руками |
|
||||
| `webUrl` | string | нет | URL веб-клиента для `/web-test` | Руками |
|
||||
|
||||
### Support-guard и `editingAllowedCheck`
|
||||
|
||||
Навыки-мутаторы (`meta-edit`, `meta-compile`, `meta-remove` и др.) перед изменением исходников проверяют состояние поддержки конфигурации (`Ext/ParentConfigurations.bin`, см. [1c-support-state-spec.md](1c-support-state-spec.md)). Если объект «на замке» поставщика (или вся конфигурация read-only, или удаляется не снятый с поддержки объект), правка по умолчанию **блокируется** — прямое изменение сломало бы обновления.
|
||||
|
||||
Реакцию задаёт `editingAllowedCheck`:
|
||||
- `deny` (по умолчанию, в т.ч. когда поле не задано) — блокировать с диагностикой;
|
||||
- `warn` — пропускать, но писать предупреждение;
|
||||
- `off` — проверку не выполнять.
|
||||
|
||||
Триггер проверки — наличие `ParentConfigurations.bin` (конфигурация на поддержке), а не регистрация в `.v8-project.json`. Поле лишь меняет реакцию. Берётся `databases[].editingAllowedCheck` базы, чей `configSrc` охватывает редактируемый путь; иначе — корневое `editingAllowedCheck`; иначе `deny`.
|
||||
|
||||
### Хуки и `skillSuggester` (экспериментально)
|
||||
|
||||
Помимо встроенной в навыки проверки (выше), есть **опциональные хуки Claude Code** (каталог `hooks/`), которые по умолчанию **выключены** и подключаются вручную (см. `hooks/README.md`):
|
||||
- **support-guard** — перехватывает правки исходников на поддержке **в обход навыков** (прямые `Edit`/`Write`); реакцию берёт из того же `editingAllowedCheck`;
|
||||
- **skill-suggester** — ненавязчиво подсказывает профильный навык, когда модель работает с исходниками напрямую.
|
||||
|
||||
`skillSuggester` (`on`/`off`, по умолчанию `on`) включает/выключает подсказки skill-suggester. Действует только когда хук подключён; раскладка та же — `databases[].skillSuggester` для базы по `configSrc`, иначе корневое, иначе `on`.
|
||||
|
||||
### Разрешение базы
|
||||
|
||||
Все навыки `/db-*`, `/epf-build`, `/epf-dump`, `/erf-build`, `/erf-dump`, `/web-publish` используют единый алгоритм:
|
||||
|
||||
1. Если пользователь указал **параметры подключения** (путь, сервер) — используются напрямую
|
||||
2. Если указал **базу по имени** — поиск: `id` → `aliases` (с учётом морфологии) → `name` (нечёткое)
|
||||
3. Если **не указал** — сопоставление текущей ветки Git с `branches` (точно или по glob-паттерну)
|
||||
4. Fallback на `default`
|
||||
5. Если не найдено — Claude спросит пользователя
|
||||
6. Если база не зарегистрирована — Claude предложит `/db-list add`
|
||||
|
||||
## Настройки инструментов
|
||||
|
||||
### `webPath` — Apache HTTP Server
|
||||
|
||||
Путь к каталогу Apache. Используется навыками `/web-publish`, `/web-info`, `/web-stop`, `/web-unpublish`.
|
||||
|
||||
Если не задан — ищется в `tools/apache24` от корня проекта. При первом вызове `/web-publish` Apache скачивается автоматически.
|
||||
|
||||
Подробнее — в [гайде по веб-публикации](web-guide.md).
|
||||
|
||||
### `ffmpegPath` — ffmpeg
|
||||
|
||||
Путь к исполняемому файлу ffmpeg. Используется навыком `/web-test` для записи видео.
|
||||
|
||||
Если не задан — ищется по порядку:
|
||||
1. `tools/ffmpeg/bin/ffmpeg.exe` (от корня проекта)
|
||||
2. `ffmpeg` в системном PATH
|
||||
|
||||
Подробнее — в [гайде по записи видео](web-test-recording-guide.md).
|
||||
|
||||
### `tts` — озвучка видеоинструкций
|
||||
|
||||
| Поле | Тип | По умолчанию | Описание |
|
||||
|------|-----|-------------|----------|
|
||||
| `provider` | string | `"edge"` | Провайдер: `"edge"`, `"elevenlabs"`, `"openai"` |
|
||||
| `voice` | string | `"ru-RU-DmitryNeural"` | Голос (имя или ID в зависимости от провайдера) |
|
||||
| `apiKey` | string | — | API-ключ (для elevenlabs, openai) |
|
||||
| `apiUrl` | string | — | URL сервиса (для openai-совместимых) |
|
||||
| `model` | string | — | Модель (для openai) |
|
||||
|
||||
Подробнее о выборе провайдера и голосов — в [гайде по записи видео](web-test-recording-guide.md#доступные-голоса-и-провайдеры).
|
||||
|
||||
### `webUrl` — URL веб-клиента (per-database)
|
||||
|
||||
URL для открытия базы в браузере через `/web-test`. Задаётся в записи конкретной базы.
|
||||
|
||||
Если не задан — `/web-test` берёт URL из активной веб-публикации (`/web-publish`).
|
||||
|
||||
Полезно, если веб-клиент доступен по нестандартному адресу (другой порт, внешний сервер, reverse proxy).
|
||||
|
||||
## Рекомендуемая структура проекта
|
||||
|
||||
Исходники 1С удобно держать под единым каталогом `src/`:
|
||||
|
||||
```
|
||||
src/
|
||||
cf/ # XML-выгрузка конфигурации (configSrc базы → "src\\cf")
|
||||
cfe/<ИмяРасширения>/ # исходники расширения (CFE)
|
||||
epf/<ИмяОбработки>/ # исходники внешней обработки (EPF)
|
||||
erf/<ИмяОтчёта>/ # исходники внешнего отчёта (ERF)
|
||||
```
|
||||
|
||||
В `.v8-project.json` напрямую участвует только `cf` — через поле `configSrc` базы (`"src\\cf"`).
|
||||
Каталоги `cfe`/`epf`/`erf` в конфиг не прописываются: их пути передаются соответствующим навыкам
|
||||
аргументами при сборке/разборке (`epf-build -SourceFile src\\epf\\<Имя>\\<Имя>.xml`,
|
||||
`cfe-borrow -SrcDir src\\cfe\\<Имя>` и т.п.). Структура — соглашение, а не требование; навыки работают
|
||||
с любыми путями.
|
||||
|
||||
## Движок: 1cv8 или ibcmd
|
||||
|
||||
По умолчанию навыки `/db-*`, `/epf-*`, `/erf-*` работают через конфигуратор (`1cv8.exe`; путь к нему
|
||||
определяется автоматически по каталогу `v8path`) — менять это не нужно.
|
||||
|
||||
При желании ту же операцию можно выполнить через автономный сервер `ibcmd`. Для этого навык должен
|
||||
получить путь к самому файлу `ibcmd.exe` (каталог `bin` всегда трактуется как `1cv8.exe`). Путь
|
||||
указывают одним из двух способов:
|
||||
- **разово, в самой задаче** — назвать полный путь к `ibcmd.exe`, например
|
||||
`C:\\Program Files\\1cv8\\8.3.24.1691\\bin\\ibcmd.exe`;
|
||||
- **в файле настроек** — прописать в `v8path` не каталог `bin`, а сам файл `...\\bin\\ibcmd.exe` (тогда через
|
||||
`ibcmd` пойдут все операции).
|
||||
|
||||
Через `ibcmd` поддерживаются только файловые базы. Какие именно навыки это умеют — в [руководстве по базам](db-guide.md#движок-1cv8-или-ibcmd).
|
||||
|
||||
## Минимальный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"v8path": "C:\\Program Files\\1cv8\\8.3.24.1691\\bin",
|
||||
"databases": [
|
||||
{
|
||||
"id": "dev",
|
||||
"name": "Разработка",
|
||||
"type": "file",
|
||||
"path": "C:\\Bases\\MyApp"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Полный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"v8path": "C:\\Program Files\\1cv8\\8.3.24.1691\\bin",
|
||||
"databases": [
|
||||
{
|
||||
"id": "dev",
|
||||
"name": "Разработка",
|
||||
"type": "file",
|
||||
"path": "C:\\Bases\\MyApp_Dev",
|
||||
"user": "Admin",
|
||||
"password": "",
|
||||
"aliases": ["dev", "разработка"],
|
||||
"branches": ["dev", "develop", "feature/*"],
|
||||
"configSrc": "src\\cf",
|
||||
"webUrl": "http://localhost:8081/dev"
|
||||
},
|
||||
{
|
||||
"id": "test",
|
||||
"name": "Тестовая",
|
||||
"type": "server",
|
||||
"server": "srv01",
|
||||
"ref": "MyApp_Test",
|
||||
"user": "Администратор",
|
||||
"password": "",
|
||||
"aliases": ["test", "тест", "тестовая"],
|
||||
"branches": ["main", "release/*"]
|
||||
}
|
||||
],
|
||||
"default": "dev",
|
||||
"webPath": "C:\\tools\\apache24",
|
||||
"ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe",
|
||||
"tts": {
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Базы данных](db-guide.md) — `/db-list`, `/db-create`, `/db-load-xml`, `/db-dump-xml` и другие
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`
|
||||
- [Тестирование в браузере](web-test-guide.md) — `/web-test`
|
||||
- [Запись видеоинструкций](web-test-recording-guide.md) — запись видео, субтитры, озвучка
|
||||
# Конфигурация проекта (.v8-project.json)
|
||||
|
||||
Файл `.v8-project.json` — единый конфиг проекта для всех навыков Claude Code. Хранит пути к платформе 1С, список баз данных и настройки инструментов (Apache, ffmpeg, TTS).
|
||||
|
||||
Размещается в корне проекта (рядом с `.git/`). Создаётся навыком `/db-list add` или вручную.
|
||||
|
||||
> **Шаблон**: в корне репозитория лежит `.v8-project.example.json` — скопируйте его в `.v8-project.json` и поправьте пути под свою машину.
|
||||
|
||||
> **Безопасность**: файл содержит секреты (пароли баз данных, API-ключи TTS) и добавлен в `.gitignore` — он не попадает в репозиторий. Каждый разработчик заводит свой `.v8-project.json` локально. Пример (`.v8-project.example.json`) секретов не содержит и хранится в репозитории.
|
||||
|
||||
## Полная схема
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// === Платформа ===
|
||||
"v8path": "C:\\Program Files\\1cv8\\8.3.24.1691\\bin",
|
||||
|
||||
// === Базы данных ===
|
||||
"databases": [
|
||||
{
|
||||
"id": "dev", // уникальный идентификатор
|
||||
"name": "Разработка", // отображаемое имя
|
||||
"type": "file", // "file" или "server"
|
||||
"path": "C:\\Bases\\MyApp_Dev", // каталог (для file)
|
||||
"user": "Admin", // пользователь 1С
|
||||
"password": "", // пароль
|
||||
"aliases": ["dev", "разработка"], // альтернативные имена
|
||||
"branches": ["dev", "feature/*"], // привязка к Git-веткам
|
||||
"configSrc": "src\\cf", // каталог XML-выгрузки конфигурации (см. структуру ниже)
|
||||
"webUrl": "http://localhost:8081/dev" // URL веб-клиента (для /web-test)
|
||||
},
|
||||
{
|
||||
"id": "test",
|
||||
"name": "Тестовая",
|
||||
"type": "server", // серверная база
|
||||
"server": "srv01", // адрес сервера 1С
|
||||
"ref": "MyApp_Test", // имя базы на сервере
|
||||
"user": "Admin",
|
||||
"password": "123",
|
||||
"aliases": ["test", "тест"]
|
||||
}
|
||||
],
|
||||
"default": "dev",
|
||||
|
||||
// === Инструменты ===
|
||||
"webPath": "C:\\tools\\apache24", // каталог Apache
|
||||
"ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe", // путь к ffmpeg
|
||||
"tts": { // настройки озвучки
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Корневые поля
|
||||
|
||||
| Поле | Тип | Обяз. | По умолчанию | Описание | Кто заполняет |
|
||||
|------|-----|:-----:|-------------|----------|---------------|
|
||||
| `v8path` | string | да | — | Путь к каталогу `bin` платформы 1С (или к файлу `1cv8.exe`/`ibcmd.exe`, см. ниже) | `/db-list add` или руками |
|
||||
| `databases` | array | да | — | Список баз данных | `/db-list add` |
|
||||
| `default` | string | нет | — | `id` базы по умолчанию | `/db-list` |
|
||||
| `editingAllowedCheck` | `"deny"`/`"warn"`/`"off"` | нет | `deny` | Глобальная реакция support-guard на правку объектов на замке (см. ниже) | Руками |
|
||||
| `skillSuggester` | `"on"`/`"off"` | нет | `on` | Подсказки навыков от хука skill-suggester (только если хук включён, см. ниже) | Руками |
|
||||
| `webPath` | string | нет | `tools/apache24` | Каталог Apache HTTP Server | Руками |
|
||||
| `ffmpegPath` | string | нет | `tools/ffmpeg/bin/ffmpeg.exe` | Путь к ffmpeg | Руками |
|
||||
| `tts` | object | нет | Edge TTS, DmitryNeural | Настройки озвучки видео | Руками |
|
||||
|
||||
## Базы данных (`databases[]`)
|
||||
|
||||
| Поле | Тип | Обяз. | Описание | Кто заполняет |
|
||||
|------|-----|:-----:|----------|---------------|
|
||||
| `id` | string | да | Уникальный идентификатор | `/db-list add` |
|
||||
| `name` | string | да | Отображаемое имя | `/db-list add` |
|
||||
| `type` | `"file"` / `"server"` | да | Тип подключения | `/db-list add` |
|
||||
| `path` | string | для file | Каталог файловой базы | `/db-list add` |
|
||||
| `server` | string | для server | Адрес сервера 1С | `/db-list add` |
|
||||
| `ref` | string | для server | Имя базы на сервере | `/db-list add` |
|
||||
| `user` | string | нет | Пользователь 1С | `/db-list add` или руками |
|
||||
| `password` | string | нет | Пароль | `/db-list add` или руками |
|
||||
| `aliases` | string[] | нет | Альтернативные имена для обращения к базе | `/db-list add` или руками |
|
||||
| `branches` | string[] | нет | Git-ветки или glob-паттерны (`release/*`, `feature/*`) | Руками |
|
||||
| `configSrc` | string | нет | Каталог XML-выгрузки конфигурации (рекомендуется `src/cf`, см. структуру ниже). Путь относительный — от корня проекта | Руками |
|
||||
| `editingAllowedCheck` | `"deny"`/`"warn"`/`"off"` | нет | Override реакции support-guard для этой базы (см. ниже) | Руками |
|
||||
| `skillSuggester` | `"on"`/`"off"` | нет | Override подсказок навыков для этой базы (см. ниже) | Руками |
|
||||
| `webUrl` | string | нет | URL веб-клиента для `/web-test` | Руками |
|
||||
|
||||
### Support-guard и `editingAllowedCheck`
|
||||
|
||||
Навыки-мутаторы (`meta-edit`, `meta-compile`, `meta-remove` и др.) перед изменением исходников проверяют состояние поддержки конфигурации (`Ext/ParentConfigurations.bin`, см. [1c-support-state-spec.md](1c-support-state-spec.md)). Если объект «на замке» поставщика (или вся конфигурация read-only, или удаляется не снятый с поддержки объект), правка по умолчанию **блокируется** — прямое изменение сломало бы обновления.
|
||||
|
||||
Реакцию задаёт `editingAllowedCheck`:
|
||||
- `deny` (по умолчанию, в т.ч. когда поле не задано) — блокировать с диагностикой;
|
||||
- `warn` — пропускать, но писать предупреждение;
|
||||
- `off` — проверку не выполнять.
|
||||
|
||||
Триггер проверки — наличие `ParentConfigurations.bin` (конфигурация на поддержке), а не регистрация в `.v8-project.json`. Поле лишь меняет реакцию. Берётся `databases[].editingAllowedCheck` базы, чей `configSrc` охватывает редактируемый путь; иначе — корневое `editingAllowedCheck`; иначе `deny`.
|
||||
|
||||
### Хуки и `skillSuggester` (экспериментально)
|
||||
|
||||
Помимо встроенной в навыки проверки (выше), есть **опциональные хуки Claude Code** (каталог `hooks/`), которые по умолчанию **выключены** и подключаются вручную (см. `hooks/README.md`):
|
||||
- **support-guard** — перехватывает правки исходников на поддержке **в обход навыков** (прямые `Edit`/`Write`); реакцию берёт из того же `editingAllowedCheck`;
|
||||
- **skill-suggester** — ненавязчиво подсказывает профильный навык, когда модель работает с исходниками напрямую.
|
||||
|
||||
`skillSuggester` (`on`/`off`, по умолчанию `on`) включает/выключает подсказки skill-suggester. Действует только когда хук подключён; раскладка та же — `databases[].skillSuggester` для базы по `configSrc`, иначе корневое, иначе `on`.
|
||||
|
||||
### Разрешение базы
|
||||
|
||||
Все навыки `/db-*`, `/epf-build`, `/epf-dump`, `/erf-build`, `/erf-dump`, `/web-publish` используют единый алгоритм:
|
||||
|
||||
1. Если пользователь указал **параметры подключения** (путь, сервер) — используются напрямую
|
||||
2. Если указал **базу по имени** — поиск: `id` → `aliases` (с учётом морфологии) → `name` (нечёткое)
|
||||
3. Если **не указал** — сопоставление текущей ветки Git с `branches` (точно или по glob-паттерну)
|
||||
4. Fallback на `default`
|
||||
5. Если не найдено — Claude спросит пользователя
|
||||
6. Если база не зарегистрирована — Claude предложит `/db-list add`
|
||||
|
||||
## Настройки инструментов
|
||||
|
||||
### `webPath` — Apache HTTP Server
|
||||
|
||||
Путь к каталогу Apache. Используется навыками `/web-publish`, `/web-info`, `/web-stop`, `/web-unpublish`.
|
||||
|
||||
Если не задан — ищется в `tools/apache24` от корня проекта. При первом вызове `/web-publish` Apache скачивается автоматически.
|
||||
|
||||
Подробнее — в [гайде по веб-публикации](web-guide.md).
|
||||
|
||||
### `ffmpegPath` — ffmpeg
|
||||
|
||||
Путь к исполняемому файлу ffmpeg. Используется навыком `/web-test` для записи видео.
|
||||
|
||||
Если не задан — ищется по порядку:
|
||||
1. `tools/ffmpeg/bin/ffmpeg.exe` (от корня проекта)
|
||||
2. `ffmpeg` в системном PATH
|
||||
|
||||
Подробнее — в [гайде по записи видео](web-test-recording-guide.md).
|
||||
|
||||
### `tts` — озвучка видеоинструкций
|
||||
|
||||
| Поле | Тип | По умолчанию | Описание |
|
||||
|------|-----|-------------|----------|
|
||||
| `provider` | string | `"edge"` | Провайдер: `"edge"`, `"elevenlabs"`, `"openai"` |
|
||||
| `voice` | string | `"ru-RU-DmitryNeural"` | Голос (имя или ID в зависимости от провайдера) |
|
||||
| `apiKey` | string | — | API-ключ (для elevenlabs, openai) |
|
||||
| `apiUrl` | string | — | URL сервиса (для openai-совместимых) |
|
||||
| `model` | string | — | Модель (для openai) |
|
||||
|
||||
Подробнее о выборе провайдера и голосов — в [гайде по записи видео](web-test-recording-guide.md#доступные-голоса-и-провайдеры).
|
||||
|
||||
### `webUrl` — URL веб-клиента (per-database)
|
||||
|
||||
URL для открытия базы в браузере через `/web-test`. Задаётся в записи конкретной базы.
|
||||
|
||||
Если не задан — `/web-test` берёт URL из активной веб-публикации (`/web-publish`).
|
||||
|
||||
Полезно, если веб-клиент доступен по нестандартному адресу (другой порт, внешний сервер, reverse proxy).
|
||||
|
||||
## Рекомендуемая структура проекта
|
||||
|
||||
Исходники 1С удобно держать под единым каталогом `src/`:
|
||||
|
||||
```
|
||||
src/
|
||||
cf/ # XML-выгрузка конфигурации (configSrc базы → "src\\cf")
|
||||
cfe/<ИмяРасширения>/ # исходники расширения (CFE)
|
||||
epf/<ИмяОбработки>/ # исходники внешней обработки (EPF)
|
||||
erf/<ИмяОтчёта>/ # исходники внешнего отчёта (ERF)
|
||||
```
|
||||
|
||||
В `.v8-project.json` напрямую участвует только `cf` — через поле `configSrc` базы (`"src\\cf"`).
|
||||
Каталоги `cfe`/`epf`/`erf` в конфиг не прописываются: их пути передаются соответствующим навыкам
|
||||
аргументами при сборке/разборке (`epf-build -SourceFile src\\epf\\<Имя>\\<Имя>.xml`,
|
||||
`cfe-borrow -SrcDir src\\cfe\\<Имя>` и т.п.). Структура — соглашение, а не требование; навыки работают
|
||||
с любыми путями.
|
||||
|
||||
## Движок: 1cv8 или ibcmd
|
||||
|
||||
По умолчанию навыки `/db-*`, `/epf-*`, `/erf-*` работают через конфигуратор (`1cv8.exe`; путь к нему
|
||||
определяется автоматически по каталогу `v8path`) — менять это не нужно.
|
||||
|
||||
При желании ту же операцию можно выполнить через автономный сервер `ibcmd`. Для этого навык должен
|
||||
получить путь к самому файлу `ibcmd.exe` (каталог `bin` всегда трактуется как `1cv8.exe`). Путь
|
||||
указывают одним из двух способов:
|
||||
- **разово, в самой задаче** — назвать полный путь к `ibcmd.exe`, например
|
||||
`C:\\Program Files\\1cv8\\8.3.24.1691\\bin\\ibcmd.exe`;
|
||||
- **в файле настроек** — прописать в `v8path` не каталог `bin`, а сам файл `...\\bin\\ibcmd.exe` (тогда через
|
||||
`ibcmd` пойдут все операции).
|
||||
|
||||
Через `ibcmd` поддерживаются только файловые базы. Какие именно навыки это умеют — в [руководстве по базам](db-guide.md#движок-1cv8-или-ibcmd).
|
||||
|
||||
## Минимальный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"v8path": "C:\\Program Files\\1cv8\\8.3.24.1691\\bin",
|
||||
"databases": [
|
||||
{
|
||||
"id": "dev",
|
||||
"name": "Разработка",
|
||||
"type": "file",
|
||||
"path": "C:\\Bases\\MyApp"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Полный пример
|
||||
|
||||
```json
|
||||
{
|
||||
"v8path": "C:\\Program Files\\1cv8\\8.3.24.1691\\bin",
|
||||
"databases": [
|
||||
{
|
||||
"id": "dev",
|
||||
"name": "Разработка",
|
||||
"type": "file",
|
||||
"path": "C:\\Bases\\MyApp_Dev",
|
||||
"user": "Admin",
|
||||
"password": "",
|
||||
"aliases": ["dev", "разработка"],
|
||||
"branches": ["dev", "develop", "feature/*"],
|
||||
"configSrc": "src\\cf",
|
||||
"webUrl": "http://localhost:8081/dev"
|
||||
},
|
||||
{
|
||||
"id": "test",
|
||||
"name": "Тестовая",
|
||||
"type": "server",
|
||||
"server": "srv01",
|
||||
"ref": "MyApp_Test",
|
||||
"user": "Администратор",
|
||||
"password": "",
|
||||
"aliases": ["test", "тест", "тестовая"],
|
||||
"branches": ["main", "release/*"]
|
||||
}
|
||||
],
|
||||
"default": "dev",
|
||||
"webPath": "C:\\tools\\apache24",
|
||||
"ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe",
|
||||
"tts": {
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Базы данных](db-guide.md) — `/db-list`, `/db-create`, `/db-load-xml`, `/db-dump-xml` и другие
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`
|
||||
- [Тестирование в браузере](web-test-guide.md) — `/web-test`
|
||||
- [Запись видеоинструкций](web-test-recording-guide.md) — запись видео, субтитры, озвучка
|
||||
|
||||
+147
-147
@@ -1,147 +1,147 @@
|
||||
# Веб-публикация 1С
|
||||
|
||||
Навыки группы `/web-*` позволяют публиковать информационные базы 1С через Apache HTTP Server для доступа из браузера (веб-клиент). Это замыкает цикл разработки: правка исходников → загрузка → обновление БД → **открытие в браузере**.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Скрипт | Описание |
|
||||
|-------|:------:|----------|
|
||||
| `/web-publish` | `.ps1` | Публикация базы (VRD + httpd.conf + запуск Apache) |
|
||||
| `/web-info` | `.ps1` | Статус Apache и список публикаций |
|
||||
| `/web-stop` | `.ps1` | Остановка Apache |
|
||||
| `/web-unpublish` | `.ps1` | Удаление публикации (одной или всех `--all`) |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
правки в исходниках → /db-load-xml → /db-update → /web-publish → браузер
|
||||
↑
|
||||
/web-info ← статус |
|
||||
/web-stop ← остановка|
|
||||
/web-unpublish ← удаление
|
||||
```
|
||||
|
||||
### Типичный цикл разработки
|
||||
|
||||
1. **Настройка** — `/db-list add` зарегистрировать базу в `.v8-project.json`
|
||||
2. **Загрузка** — `/db-load-xml` загрузить конфигурацию
|
||||
3. **Обновление** — `/db-update` применить к БД
|
||||
4. **Публикация** — `/web-publish` опубликовать базу (при первом запуске скачает Apache)
|
||||
5. **Проверка** — открыть `http://localhost:8081/{appname}` в браузере
|
||||
6. **Правка** — изменить исходники
|
||||
7. **Синхронизация** — `/db-load-git` + `/db-update`
|
||||
8. **Проверка** — обновить страницу в браузере
|
||||
9. **Завершение** — `/web-stop` остановить Apache
|
||||
|
||||
## Конфигурация в `.v8-project.json`
|
||||
|
||||
Поле `webPath` указывает путь к каталогу Apache. Если не задано, используется `tools/apache24` от корня проекта.
|
||||
|
||||
Полное описание формата — в [справочнике .v8-project.json](v8-project-guide.md).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Опубликовать базу
|
||||
|
||||
```
|
||||
> Опубликуй базу bp-demo
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish bp-demo` → скачает Apache (если нет) → сгенерирует VRD → настроит httpd.conf → запустит Apache → выдаст URL.
|
||||
|
||||
### Проверить статус
|
||||
|
||||
```
|
||||
> Что с веб-сервером?
|
||||
```
|
||||
|
||||
Claude вызовет `/web-info` → покажет состояние Apache, порт, список публикаций, последние ошибки.
|
||||
|
||||
### Опубликовать на другом порту
|
||||
|
||||
```
|
||||
> Опубликуй ERP на порту 9090
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish erp --port 9090`.
|
||||
|
||||
### Сменить пользователя публикации
|
||||
|
||||
```
|
||||
> Переключи публикацию bp-demo на пользователя Иванов
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish bp-demo` с `-UserName "Иванов"` — перезапишет VRD с новым пользователем.
|
||||
|
||||
### Параллельные публикации под разными пользователями
|
||||
|
||||
```
|
||||
> Добавь ещё одну публикацию bp-demo под Ивановым, Admin оставь
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish bp-demo --appname bpdemo-ivanov --user Иванов` — создаст вторую публикацию. Обе будут доступны одновременно по разным URL.
|
||||
|
||||
### Остановить сервер
|
||||
|
||||
```
|
||||
> Останови Apache
|
||||
```
|
||||
|
||||
Claude вызовет `/web-stop`.
|
||||
|
||||
### Удалить публикацию
|
||||
|
||||
```
|
||||
> Убери публикацию bpdemo
|
||||
```
|
||||
|
||||
Claude вызовет `/web-unpublish bpdemo` → удалит блок из httpd.conf → удалит каталог → перезапустит Apache (если есть другие публикации).
|
||||
|
||||
### Удалить все публикации
|
||||
|
||||
```
|
||||
> Удали все веб-публикации
|
||||
```
|
||||
|
||||
Claude вызовет `/web-unpublish --all` → удалит все блоки из httpd.conf → удалит все каталоги → остановит Apache.
|
||||
|
||||
## Работа с сервисами
|
||||
|
||||
### Протестировать HTTP-сервис
|
||||
```
|
||||
> Вызови HTTP-сервис ОбменДанными метод ПолучитьСтатус
|
||||
```
|
||||
|
||||
Claude составит curl/Invoke-WebRequest к `http://localhost:8081/appname/hs/exchange/status`
|
||||
|
||||
### Проверить OData
|
||||
```
|
||||
> Покажи список справочников через OData
|
||||
```
|
||||
|
||||
Claude вызовет `http://localhost:8081/appname/odata/standard.odata/$metadata`
|
||||
|
||||
### Получить WSDL web-сервиса
|
||||
```
|
||||
> Покажи WSDL сервиса ОбменСВнешнимиСистемами
|
||||
```
|
||||
|
||||
Claude откроет `http://localhost:8081/appname/ws/ExchangeWithExternalSystems?wsdl`
|
||||
|
||||
## Ручная установка Apache
|
||||
|
||||
Если автоматическая загрузка невозможна (прокси, firewall), используйте флаг `--manual`:
|
||||
|
||||
```
|
||||
> Опубликуй базу --manual
|
||||
```
|
||||
|
||||
Скрипт выдаст инструкцию:
|
||||
1. Скачайте Apache Lounge (x64 VS17) с https://www.apachelounge.com/download/
|
||||
2. Распакуйте содержимое `Apache24/` в `tools/apache24` (или путь из `webPath`)
|
||||
3. Запустите команду повторно
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [web-spec.md](web-spec.md) — техническая спецификация (VRD, httpd.conf, wsap24.dll, portable Apache)
|
||||
- [build-spec.md](build-spec.md) — пакетный режим конфигуратора 1С
|
||||
# Веб-публикация 1С
|
||||
|
||||
Навыки группы `/web-*` позволяют публиковать информационные базы 1С через Apache HTTP Server для доступа из браузера (веб-клиент). Это замыкает цикл разработки: правка исходников → загрузка → обновление БД → **открытие в браузере**.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Скрипт | Описание |
|
||||
|-------|:------:|----------|
|
||||
| `/web-publish` | `.ps1` | Публикация базы (VRD + httpd.conf + запуск Apache) |
|
||||
| `/web-info` | `.ps1` | Статус Apache и список публикаций |
|
||||
| `/web-stop` | `.ps1` | Остановка Apache |
|
||||
| `/web-unpublish` | `.ps1` | Удаление публикации (одной или всех `--all`) |
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
правки в исходниках → /db-load-xml → /db-update → /web-publish → браузер
|
||||
↑
|
||||
/web-info ← статус |
|
||||
/web-stop ← остановка|
|
||||
/web-unpublish ← удаление
|
||||
```
|
||||
|
||||
### Типичный цикл разработки
|
||||
|
||||
1. **Настройка** — `/db-list add` зарегистрировать базу в `.v8-project.json`
|
||||
2. **Загрузка** — `/db-load-xml` загрузить конфигурацию
|
||||
3. **Обновление** — `/db-update` применить к БД
|
||||
4. **Публикация** — `/web-publish` опубликовать базу (при первом запуске скачает Apache)
|
||||
5. **Проверка** — открыть `http://localhost:8081/{appname}` в браузере
|
||||
6. **Правка** — изменить исходники
|
||||
7. **Синхронизация** — `/db-load-git` + `/db-update`
|
||||
8. **Проверка** — обновить страницу в браузере
|
||||
9. **Завершение** — `/web-stop` остановить Apache
|
||||
|
||||
## Конфигурация в `.v8-project.json`
|
||||
|
||||
Поле `webPath` указывает путь к каталогу Apache. Если не задано, используется `tools/apache24` от корня проекта.
|
||||
|
||||
Полное описание формата — в [справочнике .v8-project.json](v8-project-guide.md).
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Опубликовать базу
|
||||
|
||||
```
|
||||
> Опубликуй базу bp-demo
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish bp-demo` → скачает Apache (если нет) → сгенерирует VRD → настроит httpd.conf → запустит Apache → выдаст URL.
|
||||
|
||||
### Проверить статус
|
||||
|
||||
```
|
||||
> Что с веб-сервером?
|
||||
```
|
||||
|
||||
Claude вызовет `/web-info` → покажет состояние Apache, порт, список публикаций, последние ошибки.
|
||||
|
||||
### Опубликовать на другом порту
|
||||
|
||||
```
|
||||
> Опубликуй ERP на порту 9090
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish erp --port 9090`.
|
||||
|
||||
### Сменить пользователя публикации
|
||||
|
||||
```
|
||||
> Переключи публикацию bp-demo на пользователя Иванов
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish bp-demo` с `-UserName "Иванов"` — перезапишет VRD с новым пользователем.
|
||||
|
||||
### Параллельные публикации под разными пользователями
|
||||
|
||||
```
|
||||
> Добавь ещё одну публикацию bp-demo под Ивановым, Admin оставь
|
||||
```
|
||||
|
||||
Claude вызовет `/web-publish bp-demo --appname bpdemo-ivanov --user Иванов` — создаст вторую публикацию. Обе будут доступны одновременно по разным URL.
|
||||
|
||||
### Остановить сервер
|
||||
|
||||
```
|
||||
> Останови Apache
|
||||
```
|
||||
|
||||
Claude вызовет `/web-stop`.
|
||||
|
||||
### Удалить публикацию
|
||||
|
||||
```
|
||||
> Убери публикацию bpdemo
|
||||
```
|
||||
|
||||
Claude вызовет `/web-unpublish bpdemo` → удалит блок из httpd.conf → удалит каталог → перезапустит Apache (если есть другие публикации).
|
||||
|
||||
### Удалить все публикации
|
||||
|
||||
```
|
||||
> Удали все веб-публикации
|
||||
```
|
||||
|
||||
Claude вызовет `/web-unpublish --all` → удалит все блоки из httpd.conf → удалит все каталоги → остановит Apache.
|
||||
|
||||
## Работа с сервисами
|
||||
|
||||
### Протестировать HTTP-сервис
|
||||
```
|
||||
> Вызови HTTP-сервис ОбменДанными метод ПолучитьСтатус
|
||||
```
|
||||
|
||||
Claude составит curl/Invoke-WebRequest к `http://localhost:8081/appname/hs/exchange/status`
|
||||
|
||||
### Проверить OData
|
||||
```
|
||||
> Покажи список справочников через OData
|
||||
```
|
||||
|
||||
Claude вызовет `http://localhost:8081/appname/odata/standard.odata/$metadata`
|
||||
|
||||
### Получить WSDL web-сервиса
|
||||
```
|
||||
> Покажи WSDL сервиса ОбменСВнешнимиСистемами
|
||||
```
|
||||
|
||||
Claude откроет `http://localhost:8081/appname/ws/ExchangeWithExternalSystems?wsdl`
|
||||
|
||||
## Ручная установка Apache
|
||||
|
||||
Если автоматическая загрузка невозможна (прокси, firewall), используйте флаг `--manual`:
|
||||
|
||||
```
|
||||
> Опубликуй базу --manual
|
||||
```
|
||||
|
||||
Скрипт выдаст инструкцию:
|
||||
1. Скачайте Apache Lounge (x64 VS17) с https://www.apachelounge.com/download/
|
||||
2. Распакуйте содержимое `Apache24/` в `tools/apache24` (или путь из `webPath`)
|
||||
3. Запустите команду повторно
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [web-spec.md](web-spec.md) — техническая спецификация (VRD, httpd.conf, wsap24.dll, portable Apache)
|
||||
- [build-spec.md](build-spec.md) — пакетный режим конфигуратора 1С
|
||||
|
||||
+203
-203
@@ -1,203 +1,203 @@
|
||||
# Веб-публикация 1С — техническая спецификация
|
||||
|
||||
Описание артефактов, необходимых для публикации информационной базы 1С через Apache HTTP Server.
|
||||
|
||||
## default.vrd
|
||||
|
||||
Дескриптор виртуального ресурса. XML-файл, описывающий подключение к информационной базе.
|
||||
|
||||
### Формат
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
base="/appname"
|
||||
ib="connection-string">
|
||||
<standardOdata enable="true"/>
|
||||
<ws pointEnableCommon="true"/>
|
||||
<httpServices publishByDefault="true"/>
|
||||
</point>
|
||||
```
|
||||
|
||||
### Атрибут `base`
|
||||
|
||||
URL-путь публикации. Должен начинаться с `/`, совпадает с `Alias` в httpd.conf.
|
||||
|
||||
### Атрибут `ib`
|
||||
|
||||
Строка подключения к информационной базе.
|
||||
|
||||
**Файловая база:**
|
||||
```
|
||||
File="C:\Bases\MyDB";
|
||||
```
|
||||
|
||||
**Серверная база:**
|
||||
```
|
||||
Srvr="server01";Ref="MyDB";
|
||||
```
|
||||
|
||||
**С авторизацией:**
|
||||
```
|
||||
File="C:\Bases\MyDB";Usr="Admin";Pwd="123";
|
||||
```
|
||||
|
||||
> Кавычки внутри значения `ib` экранируются как `"` (XML-сущность).
|
||||
|
||||
### Дочерние элементы
|
||||
|
||||
#### `<standardOdata>`
|
||||
Стандартный OData-интерфейс платформы. `<standardOdata enable="true"/>` открывает REST-доступ к опубликованным объектам (состав настраивается в «Настройка автоматического REST-сервиса» → вкладка «Состав»; при пустом составе сервис-документ отдаёт HTTP 404).
|
||||
URL: `/{AppName}/odata/standard.odata`
|
||||
|
||||
> **Регистр важен.** Рабочая форма — строчная `<standardOdata enable="true"/>` (проверено E2E на 8.3.24 и 8.3.27: отдаёт HTTP 200). Заглавная `<standardOData>` из «Руководства администратора» парсером vrd **не распознаётся** → OData 404. Старый атрибут `enableStandardOdata="true"` на `<point>` (до 8.3.9) также не работает.
|
||||
|
||||
#### `<ws>`
|
||||
Публикация SOAP web-сервисов. `pointEnableCommon="true"` публикует все сервисы из конфигурации.
|
||||
URL: `/{AppName}/ws/{WebServiceName}?wsdl`
|
||||
|
||||
#### `<httpServices>`
|
||||
Публикация HTTP-сервисов. `publishByDefault="true"` публикует все сервисы из конфигурации.
|
||||
URL: `/{AppName}/hs/{RootUrl}/...`
|
||||
|
||||
### Расположение
|
||||
|
||||
`{ApachePath}/publish/{AppName}/default.vrd`
|
||||
|
||||
## httpd.conf для 1С
|
||||
|
||||
### LoadModule
|
||||
|
||||
Apache загружает модуль расширения 1С:
|
||||
|
||||
```apache
|
||||
LoadModule _1cws_module "C:/Program Files/1cv8/8.3.24.1691/bin/wsap24.dll"
|
||||
```
|
||||
|
||||
- Модуль `wsap24.dll` — 64-разрядный, требует x64-версию Apache
|
||||
- Путь использует forward slashes
|
||||
|
||||
### Listen
|
||||
|
||||
```apache
|
||||
Listen 8081
|
||||
```
|
||||
|
||||
Порт для веб-клиента. По умолчанию `8081` (стандартный `80` может быть занят).
|
||||
|
||||
### Alias + Directory
|
||||
|
||||
Для каждой публикации добавляется блок:
|
||||
|
||||
```apache
|
||||
Alias "/appname" "C:/path/to/apache/publish/appname"
|
||||
<Directory "C:/path/to/apache/publish/appname">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
SetHandler 1c-application
|
||||
ManagedApplicationDescriptor "C:/path/to/apache/publish/appname/default.vrd"
|
||||
</Directory>
|
||||
```
|
||||
|
||||
- `Alias` — URL-путь → физический каталог
|
||||
- `SetHandler 1c-application` — делегирование обработки запросов модулю wsap24
|
||||
- `ManagedApplicationDescriptor` — путь к default.vrd
|
||||
|
||||
### Маркерный подход
|
||||
|
||||
Скрипты используют маркерные комментарии для идемпотентного управления блоками:
|
||||
|
||||
```apache
|
||||
# --- 1C: global ---
|
||||
Listen 8081
|
||||
LoadModule _1cws_module "C:/Program Files/1cv8/8.3.24.1691/bin/wsap24.dll"
|
||||
# --- End: global ---
|
||||
|
||||
# --- 1C Publication: mydb ---
|
||||
Alias "/mydb" "C:/tools/apache24/publish/mydb"
|
||||
<Directory "C:/tools/apache24/publish/mydb">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
SetHandler 1c-application
|
||||
ManagedApplicationDescriptor "C:/tools/apache24/publish/mydb/default.vrd"
|
||||
</Directory>
|
||||
# --- End: mydb ---
|
||||
```
|
||||
|
||||
При повторном запуске блок между маркерами заменяется целиком.
|
||||
|
||||
## wsap24.dll
|
||||
|
||||
Модуль расширения Apache для 1С:Предприятие 8.3.
|
||||
|
||||
- Расположение: `{V8Path}/wsap24.dll` (в каталоге `bin` платформы)
|
||||
- Архитектура: x64 (Apache тоже должен быть x64)
|
||||
- Имя модуля: `_1cws_module`
|
||||
|
||||
## Portable Apache
|
||||
|
||||
### Дистрибутив
|
||||
|
||||
Apache Lounge — Windows-сборка Apache HTTP Server (x64):
|
||||
- Сайт: `https://www.apachelounge.com/download/`
|
||||
- Прямая ссылка (2.4.62, VS17): `https://www.apachelounge.com/download/VS17/binaries/httpd-2.4.62-240904-win64-VS17.zip`
|
||||
- Внутри ZIP: каталог `Apache24/` с полной структурой
|
||||
|
||||
### Структура после установки
|
||||
|
||||
```
|
||||
tools/apache24/
|
||||
├── bin/
|
||||
│ ├── httpd.exe
|
||||
│ └── ...
|
||||
├── conf/
|
||||
│ ├── httpd.conf
|
||||
│ └── ...
|
||||
├── logs/
|
||||
│ ├── error.log
|
||||
│ └── access.log
|
||||
├── modules/
|
||||
│ └── ...
|
||||
└── publish/
|
||||
└── {appname}/
|
||||
└── default.vrd
|
||||
```
|
||||
|
||||
### Пост-распаковка
|
||||
|
||||
1. `Expand-Archive` распаковывает ZIP во временный каталог
|
||||
2. Содержимое `Apache24/` перемещается в `{ApachePath}`
|
||||
3. В `httpd.conf` патчится `ServerRoot`:
|
||||
|
||||
```apache
|
||||
Define SRVROOT "C:/path/to/apache24"
|
||||
ServerRoot "${SRVROOT}"
|
||||
```
|
||||
|
||||
Путь `SRVROOT` — абсолютный, с forward slashes.
|
||||
|
||||
### Запуск
|
||||
|
||||
```
|
||||
httpd.exe # foreground (для отладки)
|
||||
httpd.exe -k start # фоновый запуск (не работает без установки сервиса)
|
||||
```
|
||||
|
||||
> Portable Apache запускается напрямую через `Start-Process httpd.exe` без установки Windows-сервиса.
|
||||
|
||||
### Остановка
|
||||
|
||||
```
|
||||
httpd.exe -k stop # graceful shutdown (требует сервис)
|
||||
Stop-Process -Name httpd # принудительная остановка (portable)
|
||||
```
|
||||
|
||||
### Перезагрузка
|
||||
|
||||
```
|
||||
httpd.exe -k restart # graceful restart (требует сервис)
|
||||
```
|
||||
|
||||
Для portable варианта: остановка + запуск.
|
||||
# Веб-публикация 1С — техническая спецификация
|
||||
|
||||
Описание артефактов, необходимых для публикации информационной базы 1С через Apache HTTP Server.
|
||||
|
||||
## default.vrd
|
||||
|
||||
Дескриптор виртуального ресурса. XML-файл, описывающий подключение к информационной базе.
|
||||
|
||||
### Формат
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
base="/appname"
|
||||
ib="connection-string">
|
||||
<standardOdata enable="true"/>
|
||||
<ws pointEnableCommon="true"/>
|
||||
<httpServices publishByDefault="true"/>
|
||||
</point>
|
||||
```
|
||||
|
||||
### Атрибут `base`
|
||||
|
||||
URL-путь публикации. Должен начинаться с `/`, совпадает с `Alias` в httpd.conf.
|
||||
|
||||
### Атрибут `ib`
|
||||
|
||||
Строка подключения к информационной базе.
|
||||
|
||||
**Файловая база:**
|
||||
```
|
||||
File="C:\Bases\MyDB";
|
||||
```
|
||||
|
||||
**Серверная база:**
|
||||
```
|
||||
Srvr="server01";Ref="MyDB";
|
||||
```
|
||||
|
||||
**С авторизацией:**
|
||||
```
|
||||
File="C:\Bases\MyDB";Usr="Admin";Pwd="123";
|
||||
```
|
||||
|
||||
> Кавычки внутри значения `ib` экранируются как `"` (XML-сущность).
|
||||
|
||||
### Дочерние элементы
|
||||
|
||||
#### `<standardOdata>`
|
||||
Стандартный OData-интерфейс платформы. `<standardOdata enable="true"/>` открывает REST-доступ к опубликованным объектам (состав настраивается в «Настройка автоматического REST-сервиса» → вкладка «Состав»; при пустом составе сервис-документ отдаёт HTTP 404).
|
||||
URL: `/{AppName}/odata/standard.odata`
|
||||
|
||||
> **Регистр важен.** Рабочая форма — строчная `<standardOdata enable="true"/>` (проверено E2E на 8.3.24 и 8.3.27: отдаёт HTTP 200). Заглавная `<standardOData>` из «Руководства администратора» парсером vrd **не распознаётся** → OData 404. Старый атрибут `enableStandardOdata="true"` на `<point>` (до 8.3.9) также не работает.
|
||||
|
||||
#### `<ws>`
|
||||
Публикация SOAP web-сервисов. `pointEnableCommon="true"` публикует все сервисы из конфигурации.
|
||||
URL: `/{AppName}/ws/{WebServiceName}?wsdl`
|
||||
|
||||
#### `<httpServices>`
|
||||
Публикация HTTP-сервисов. `publishByDefault="true"` публикует все сервисы из конфигурации.
|
||||
URL: `/{AppName}/hs/{RootUrl}/...`
|
||||
|
||||
### Расположение
|
||||
|
||||
`{ApachePath}/publish/{AppName}/default.vrd`
|
||||
|
||||
## httpd.conf для 1С
|
||||
|
||||
### LoadModule
|
||||
|
||||
Apache загружает модуль расширения 1С:
|
||||
|
||||
```apache
|
||||
LoadModule _1cws_module "C:/Program Files/1cv8/8.3.24.1691/bin/wsap24.dll"
|
||||
```
|
||||
|
||||
- Модуль `wsap24.dll` — 64-разрядный, требует x64-версию Apache
|
||||
- Путь использует forward slashes
|
||||
|
||||
### Listen
|
||||
|
||||
```apache
|
||||
Listen 8081
|
||||
```
|
||||
|
||||
Порт для веб-клиента. По умолчанию `8081` (стандартный `80` может быть занят).
|
||||
|
||||
### Alias + Directory
|
||||
|
||||
Для каждой публикации добавляется блок:
|
||||
|
||||
```apache
|
||||
Alias "/appname" "C:/path/to/apache/publish/appname"
|
||||
<Directory "C:/path/to/apache/publish/appname">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
SetHandler 1c-application
|
||||
ManagedApplicationDescriptor "C:/path/to/apache/publish/appname/default.vrd"
|
||||
</Directory>
|
||||
```
|
||||
|
||||
- `Alias` — URL-путь → физический каталог
|
||||
- `SetHandler 1c-application` — делегирование обработки запросов модулю wsap24
|
||||
- `ManagedApplicationDescriptor` — путь к default.vrd
|
||||
|
||||
### Маркерный подход
|
||||
|
||||
Скрипты используют маркерные комментарии для идемпотентного управления блоками:
|
||||
|
||||
```apache
|
||||
# --- 1C: global ---
|
||||
Listen 8081
|
||||
LoadModule _1cws_module "C:/Program Files/1cv8/8.3.24.1691/bin/wsap24.dll"
|
||||
# --- End: global ---
|
||||
|
||||
# --- 1C Publication: mydb ---
|
||||
Alias "/mydb" "C:/tools/apache24/publish/mydb"
|
||||
<Directory "C:/tools/apache24/publish/mydb">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
SetHandler 1c-application
|
||||
ManagedApplicationDescriptor "C:/tools/apache24/publish/mydb/default.vrd"
|
||||
</Directory>
|
||||
# --- End: mydb ---
|
||||
```
|
||||
|
||||
При повторном запуске блок между маркерами заменяется целиком.
|
||||
|
||||
## wsap24.dll
|
||||
|
||||
Модуль расширения Apache для 1С:Предприятие 8.3.
|
||||
|
||||
- Расположение: `{V8Path}/wsap24.dll` (в каталоге `bin` платформы)
|
||||
- Архитектура: x64 (Apache тоже должен быть x64)
|
||||
- Имя модуля: `_1cws_module`
|
||||
|
||||
## Portable Apache
|
||||
|
||||
### Дистрибутив
|
||||
|
||||
Apache Lounge — Windows-сборка Apache HTTP Server (x64):
|
||||
- Сайт: `https://www.apachelounge.com/download/`
|
||||
- Прямая ссылка (2.4.62, VS17): `https://www.apachelounge.com/download/VS17/binaries/httpd-2.4.62-240904-win64-VS17.zip`
|
||||
- Внутри ZIP: каталог `Apache24/` с полной структурой
|
||||
|
||||
### Структура после установки
|
||||
|
||||
```
|
||||
tools/apache24/
|
||||
├── bin/
|
||||
│ ├── httpd.exe
|
||||
│ └── ...
|
||||
├── conf/
|
||||
│ ├── httpd.conf
|
||||
│ └── ...
|
||||
├── logs/
|
||||
│ ├── error.log
|
||||
│ └── access.log
|
||||
├── modules/
|
||||
│ └── ...
|
||||
└── publish/
|
||||
└── {appname}/
|
||||
└── default.vrd
|
||||
```
|
||||
|
||||
### Пост-распаковка
|
||||
|
||||
1. `Expand-Archive` распаковывает ZIP во временный каталог
|
||||
2. Содержимое `Apache24/` перемещается в `{ApachePath}`
|
||||
3. В `httpd.conf` патчится `ServerRoot`:
|
||||
|
||||
```apache
|
||||
Define SRVROOT "C:/path/to/apache24"
|
||||
ServerRoot "${SRVROOT}"
|
||||
```
|
||||
|
||||
Путь `SRVROOT` — абсолютный, с forward slashes.
|
||||
|
||||
### Запуск
|
||||
|
||||
```
|
||||
httpd.exe # foreground (для отладки)
|
||||
httpd.exe -k start # фоновый запуск (не работает без установки сервиса)
|
||||
```
|
||||
|
||||
> Portable Apache запускается напрямую через `Start-Process httpd.exe` без установки Windows-сервиса.
|
||||
|
||||
### Остановка
|
||||
|
||||
```
|
||||
httpd.exe -k stop # graceful shutdown (требует сервис)
|
||||
Stop-Process -Name httpd # принудительная остановка (portable)
|
||||
```
|
||||
|
||||
### Перезагрузка
|
||||
|
||||
```
|
||||
httpd.exe -k restart # graceful restart (требует сервис)
|
||||
```
|
||||
|
||||
Для portable варианта: остановка + запуск.
|
||||
|
||||
+411
-411
@@ -1,411 +1,411 @@
|
||||
# Тестирование через веб-клиент 1С
|
||||
|
||||
Навык `/web-test` автоматизирует действия в веб-клиенте 1С через Playwright — навигация по разделам, заполнение форм, чтение таблиц и отчётов, фильтрация списков. Замыкает цикл: правка исходников → загрузка → обновление → публикация → **автоматическое тестирование**.
|
||||
|
||||
## Навык
|
||||
|
||||
| Навык | Скрипт | Описание |
|
||||
|-------|:------:|----------|
|
||||
| `/web-test` | `.mjs` (Node.js) | Автоматизация 1С через браузер — навигация, формы, таблицы, отчёты |
|
||||
|
||||
## Предусловия
|
||||
|
||||
- База опубликована через Apache (`/web-publish`)
|
||||
- Node.js 18+ установлен
|
||||
- Зависимости установлены: `cd .claude/skills/web-test/scripts && npm install`
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
/web-publish → /web-test → результат
|
||||
↑ |
|
||||
└── правки → /db-load-xml → /db-update ──┘
|
||||
```
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Навигация и чтение данных
|
||||
|
||||
```
|
||||
> Открой базу erp в браузере, перейди в раздел Склад и покажи какие команды там есть
|
||||
```
|
||||
|
||||
Claude откроет браузер, перейдёт в раздел и покажет список команд.
|
||||
|
||||
```
|
||||
> Открой список поступлений товаров и покажи первые 10 строк
|
||||
```
|
||||
|
||||
Claude откроет список и прочитает таблицу.
|
||||
|
||||
### Поиск и открытие элементов
|
||||
|
||||
```
|
||||
> Найди в списке номенклатуры товар "Вентилятор" и открой его карточку
|
||||
```
|
||||
|
||||
Claude отфильтрует список, откроет найденный элемент двойным кликом и прочитает реквизиты формы.
|
||||
|
||||
```
|
||||
> Открой справочник Контрагенты и найди "Торговый дом"
|
||||
```
|
||||
|
||||
Claude может работать с иерархическими справочниками — поиск автоматически сглаживает иерархию.
|
||||
|
||||
### Создание документа
|
||||
|
||||
```
|
||||
> Создай заказ клиента: организация "Андромеда Плюс", контрагент "Торговый дом Комплексный",
|
||||
> добавь строку: номенклатура "Вентилятор", количество 5
|
||||
```
|
||||
|
||||
Claude откроет форму создания, заполнит шапку и добавит строку в табличную часть.
|
||||
|
||||
### Работа с отчётами
|
||||
|
||||
```
|
||||
> Открой отчёт "Остатки и доступность товаров",
|
||||
> установи отбор Склад = "Склад бытовой техники", сформируй и прочитай результат
|
||||
```
|
||||
|
||||
Claude заполнит фильтры отчёта по человекочитаемым именам (не надо знать технические имена DCS), нажмёт "Сформировать" и прочитает структурированные данные: заголовки, строки, итоги.
|
||||
|
||||
### Сравнение данных
|
||||
|
||||
```
|
||||
> Сформируй отчёт по остаткам для "Склад бытовой техники" и "Западный склад",
|
||||
> сравни итоги по доступным товарам
|
||||
```
|
||||
|
||||
Claude напишет сценарий, который сформирует отчёт дважды с разными фильтрами и сравнит результаты.
|
||||
|
||||
### Проверка после загрузки расширения
|
||||
|
||||
```
|
||||
> Загрузи расширение ТестОшибки и проверь через браузер, что при создании заказа клиента
|
||||
> появляется ошибка "Тестовая ошибка из расширения"
|
||||
```
|
||||
|
||||
Claude загрузит расширение через `/db-load-xml`, затем через `/web-test` откроет форму и проверит ожидаемое поведение.
|
||||
|
||||
### Открытие внешней обработки
|
||||
|
||||
```
|
||||
> Открой обработку build/РедакторДвижений.epf в веб-клиенте и покажи что на форме
|
||||
```
|
||||
|
||||
Claude откроет EPF через Ctrl+O, автоматически обработает диалог безопасности (если есть) и прочитает форму.
|
||||
|
||||
### Пошаговая отладка
|
||||
|
||||
```
|
||||
> Запусти браузер на базе erp
|
||||
> Перейди в раздел Продажи
|
||||
> Посмотри что на форме
|
||||
> Открой первый заказ
|
||||
> Какие реквизиты заполнены?
|
||||
```
|
||||
|
||||
Claude будет выполнять команды по одной, показывая состояние формы между шагами.
|
||||
|
||||
## Режимы работы
|
||||
|
||||
### Автономный режим (run)
|
||||
|
||||
Одна команда: открывает браузер → логинится → выполняет сценарий → закрывает браузер → завершает процесс. Не оставляет висящих процессов.
|
||||
|
||||
```bash
|
||||
RUN=".claude/skills/web-test/scripts/run.mjs"
|
||||
node $RUN run http://localhost:8081/erp scenario.js
|
||||
```
|
||||
|
||||
Claude пишет `.js` файл со сценарием и запускает его. Ответ — JSON:
|
||||
```json
|
||||
{ "ok": true, "output": "...console.log output...", "elapsed": 12.3 }
|
||||
```
|
||||
|
||||
При ошибке — автоматический скриншот (пока модалка ещё видна) и стек вызова:
|
||||
```json
|
||||
{ "ok": false, "error": "Тестовая проверка: запись запрещена", "screenshot": "error-shot.png",
|
||||
"stack": { "raw": "...", "entries": [{"location": "Модуль(4)", "code": "ВызватьИсключение..."}] } }
|
||||
```
|
||||
Стек извлекается автоматически — через OpenReport (платформенные исключения) или "О программе" → "Информация для техподдержки" (ВызватьИсключение).
|
||||
|
||||
### Интерактивный режим (start/exec/stop)
|
||||
|
||||
Браузер остаётся открытым между командами. Состояние (открытые вкладки, формы) сохраняется.
|
||||
|
||||
```bash
|
||||
node $RUN start http://localhost:8081/erp # запустить сессию (фоновый процесс)
|
||||
cat <<'SCRIPT' | node $RUN exec - # выполнить скрипт
|
||||
await navigateSection('Продажи');
|
||||
SCRIPT
|
||||
node $RUN shot current-state.png # скриншот
|
||||
node $RUN stop # завершить сессию
|
||||
```
|
||||
|
||||
### Когда какой
|
||||
|
||||
| Режим | Когда использовать |
|
||||
|-------|-------------------|
|
||||
| Автономный (`run`) | Готовый сценарий целиком, субагенты, CI |
|
||||
| Интерактивный (`start/exec`) | Пошаговое исследование, отладка, разговор с пользователем |
|
||||
|
||||
## Пример: автономный сценарий
|
||||
|
||||
Сравнение остатков по двум складам — один файл, один запуск:
|
||||
|
||||
```js
|
||||
// scenario-compare-stocks.js
|
||||
|
||||
// 1. Открыть отчёт
|
||||
await navigateSection('Склад и доставка');
|
||||
await openCommand('Отчеты по складу');
|
||||
await clickElement('Остатки и доступность товаров', { dblclick: true });
|
||||
|
||||
// 2. Первый склад
|
||||
await fillFields({ 'Склад': 'Склад бытовой техники' });
|
||||
await clickElement('Сформировать');
|
||||
await wait(5);
|
||||
const report1 = await readSpreadsheet();
|
||||
console.log('=== Склад бытовой техники ===');
|
||||
console.log('Строк:', report1.data?.length, '| Доступно:', report1.totals?.['Доступно']);
|
||||
|
||||
// 3. Второй склад
|
||||
await fillFields({ 'Склад': 'Западный склад' });
|
||||
await clickElement('Сформировать');
|
||||
await wait(5);
|
||||
const report2 = await readSpreadsheet();
|
||||
console.log('=== Западный склад ===');
|
||||
console.log('Строк:', report2.data?.length, '| Доступно:', report2.totals?.['Доступно']);
|
||||
|
||||
// 4. Сравнение
|
||||
const parse = s => parseFloat((s || '0').replace(/\s/g, '').replace(',', '.'));
|
||||
const diff = parse(report1.totals?.['Доступно']) - parse(report2.totals?.['Доступно']);
|
||||
console.log('Разница:', diff.toFixed(0));
|
||||
|
||||
await closeForm({ save: false });
|
||||
```
|
||||
|
||||
Запуск: `node $RUN run http://localhost:8081/erp scenario-compare-stocks.js`
|
||||
|
||||
### Расшифровка отчёта
|
||||
|
||||
```js
|
||||
// 1. Сформировать отчёт
|
||||
await clickElement('Сформировать');
|
||||
await wait(5);
|
||||
const report = await readSpreadsheet();
|
||||
|
||||
// 2. Двойной клик по ячейке → диалог "Выбор поля"
|
||||
await clickElement({ row: 0, column: 'К6' }, { dblclick: true });
|
||||
|
||||
// 3. Выбрать поле расшифровки
|
||||
await clickElement('Регистратор');
|
||||
await clickElement('Выбрать');
|
||||
await wait(10);
|
||||
|
||||
// 4. Прочитать результат
|
||||
const drilldown = await readSpreadsheet();
|
||||
console.log('Расшифровка:', JSON.stringify(drilldown.rows));
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Все функции доступны как глобальные переменные в скриптах. `console.log()` выводит данные в ответ.
|
||||
|
||||
### Навигация
|
||||
|
||||
| Функция | Описание | Возвращает |
|
||||
|---------|----------|------------|
|
||||
| `navigateSection(name)` | Перейти в раздел (fuzzy match) | form state с `navigated`, `sections`, `commands` |
|
||||
| `openCommand(name)` | Открыть команду из панели функций | form state |
|
||||
| `navigateLink(path)` | Открыть по пути метаданных (`Документ.ЗаказКлиента`) | form state |
|
||||
| `openFile(path)` | Открыть внешнюю обработку/отчёт (EPF/ERF) через «Файл → Открыть» | form state |
|
||||
| `switchTab(name)` | Переключить открытую вкладку | form state |
|
||||
|
||||
### Чтение
|
||||
|
||||
| Функция | Описание | Возвращает |
|
||||
|---------|----------|------------|
|
||||
| `getFormState()` | Структура формы: поля, кнопки, таблица, фильтры, состояние окон | `{ form, formCount, openForms, fields, buttons, tabs, table, filters, reportSettings? }` |
|
||||
| `readTable({ maxRows?, offset? })` | Данные таблицы с пагинацией | `{ columns, rows: [{col: val}], total }` |
|
||||
| `readSpreadsheet()` | Результат отчёта | `{ title?, headers?, data?, totals?, total }` |
|
||||
| `getSections()` | Разделы и команды | `{ activeSection, sections, commands }` |
|
||||
| `getPageState()` | Разделы + открытые вкладки | `{ activeSection, activeTab, sections, tabs }` |
|
||||
|
||||
#### getFormState — подробнее
|
||||
|
||||
Основной способ «увидеть» что на экране:
|
||||
|
||||
- **form** — номер активной формы, `null` когда ничего не открыто (десктоп)
|
||||
- **formCount** — количество открытых форм. `0` = десктоп. Работает даже если панель открытых окон скрыта
|
||||
- **openForms** — `[0, 1, 2]` — номера всех открытых форм в DOM
|
||||
- **modal** — `true` когда активная форма — модальный диалог, блокирующий интерфейс
|
||||
- **openTabs** — `[{ name, active? }]` из панели открытых окон (только когда панель включена в настройках 1С)
|
||||
- **fields** — `[{ name, value, label?, actions?, required? }]`. `actions` = select/clear/open. `required: true` = незаполненное обязательное поле
|
||||
- **table** — `{ name, columns, rowCount }` (метаданные; для данных — `readTable()`)
|
||||
- **reportSettings** — DCS-фильтры в читаемом виде: `[{ name: "Склад", enabled: true, value: "..." }]`
|
||||
- **errorModal** — 1С показала ошибку
|
||||
- **confirmation** — диалог Да/Нет, вызовите `clickElement('Да')` или `clickElement('Нет')`
|
||||
- **platformDialogs** — `[{ type, title }]` — платформенные диалоги (О программе, Информация для техподдержки). Невидимы для обычного определения форм, но блокируют интерфейс. `closeForm()` закрывает их. Автоочистка через `dismissPendingErrors` перед каждым action
|
||||
|
||||
#### readTable — подробнее
|
||||
|
||||
Каждая строка — объект `{ columnName: value }`. Специальные поля для иерархии и дерева:
|
||||
|
||||
- `_kind: 'group'` — группа в иерархическом списке
|
||||
- `_tree: 'expanded'|'collapsed'` — состояние узла дерева
|
||||
- `_level: N` — уровень вложенности
|
||||
- `_selected: true` — строка выделена (подсвечена). Используйте с `clickElement({ modifier: 'ctrl'|'shift' })` для проверки мультиселекции
|
||||
- На объекте результата: `hierarchical: true`, `viewMode: 'tree'`
|
||||
|
||||
**Виртуализация и `hasMore`.** 1С виртуализирует и динамические списки, и табличные части — в DOM лежит только окно видимых строк. Поля `total` / `shown` — это размер DOM-окна, а **не** размер коллекции. Чтобы понять, есть ли строки за пределами окна, используйте `hasMore`:
|
||||
|
||||
```js
|
||||
const t = await readTable();
|
||||
// t.hasMore = { above: false, below: true } — открыли список, есть строки ниже
|
||||
// t.hasMore = { above: true, below: false } — пролистали в конец
|
||||
// t.hasMore = { above: false, below: false } — всё помещается / нет страниц
|
||||
```
|
||||
|
||||
`hasMore.below` присутствует всегда. `hasMore.above` тоже обычно есть — определяется по кнопкам пагинации (`vertButtonScroll`, есть у большинства дин-списков) или треку скроллбара (у табчастей). Отсутствует только в редких случаях, когда у грида нет ни кнопок, ни видимого скроллбара — тогда трактуйте отсутствие как «неизвестно».
|
||||
|
||||
**Колонки-картинки.** Ячейки, где выводится иконка (статусы, этапы, индикатор ЭДО, скрепка «есть файл»), читаются как `'pic:<N>'` при наличии иконки (`N` — индекс кадра/состояния) и `''` при её отсутствии. Присутствие читается как truthy, разные иконки различаются по индексу:
|
||||
|
||||
```js
|
||||
const t = await readTable();
|
||||
if (t.rows[0]['Присоединенные файлы']) { /* у строки есть прикреплённый файл */ }
|
||||
t.rows[0]['ЭДО'] === 'pic:1'; // подключён к 1С-ЭДО ('pic:0' = нет)
|
||||
```
|
||||
|
||||
Колонки без текста в заголовке (одна иконка) тоже попадают в `columns`, именуются по тултипу заголовка или `'(picture)'` — служебное имя колонки 1С в браузер не передаёт. Картиночные значения — **только для чтения и ассертов**: отбирать/фильтровать строки по `'pic:N'` нельзя (фильтр по такому значению бросает понятную ошибку, расширенный поиск 1С такое поле не покажет). Для выбора строки фильтруйте по текстовой колонке; кликать по картиночной ячейке можно по индексу строки.
|
||||
|
||||
#### clickElement — клик по ячейке (spreadsheet или грид формы)
|
||||
|
||||
Первый аргумент `clickElement` принимает объект `{ row, column }` вместо текста. Маршрутизация автоматическая: если на форме отрисован SpreadsheetDocument (отчёт) — кликаем туда (drill-down), иначе — по ячейке грида (табчасть, список). Параметр `table: 'ИмяГрида'` принудительно указывает грид, если на форме одновременно есть отчёт и таблицы.
|
||||
|
||||
**SpreadsheetDocument (drill-down отчёта).** Координаты соответствуют выводу `readSpreadsheet()`:
|
||||
|
||||
```js
|
||||
const report = await readSpreadsheet();
|
||||
// report.data[0] = { 'К1': 'Материалы строительные', 'К6': '150 000' }
|
||||
|
||||
await clickElement({ row: 0, column: 'К6' }, { dblclick: true }); // по индексу
|
||||
await clickElement({ row: { 'К1': 'Материалы' }, column: 'К6' }, { dblclick: true }); // по фильтру
|
||||
await clickElement({ row: 'totals', column: 'К6' }, { dblclick: true }); // итоги
|
||||
await clickElement('150 000', { dblclick: true }); // fallback: по тексту в iframe'ах
|
||||
```
|
||||
|
||||
**Грид формы (табчасть документа, список каталога/журнала).** Колонка вне viewport — авто-скролл по горизонтали (с учётом frozen-колонок). `scroll: true | number` включает reveal-loop через PageDown для filter-row за пределами DOM-окна:
|
||||
|
||||
```js
|
||||
await clickElement({ row: 0, column: 'Количество' }, { table: 'Товары', dblclick: true });
|
||||
await clickElement({ row: { 'Номенклатура': 'Бумага' }, column: 'Цена' }, { table: 'Товары' });
|
||||
await clickElement(
|
||||
{ row: { 'Номер': '0000-000601' }, column: 'Сумма' },
|
||||
{ table: 'Реализации', scroll: true } // PageDown loop, лимит по умолчанию 50
|
||||
);
|
||||
```
|
||||
|
||||
**Подводные камни:**
|
||||
- `row: <число>` — индекс в **текущем DOM-окне**, не абсолютный (1С виртуализирует длинные списки). Для произвольной строки в длинном списке — `row: { col: val }` + `scroll: true`.
|
||||
- `scroll: true` идёт только **вниз** (PageDown). Для вверх — `page.keyboard.press('Home')` через `getPage()` или сначала `filterList`.
|
||||
- На дубликаты при фильтре — первая подходящая строка. Уточняйте фильтр для disambiguation.
|
||||
|
||||
### Действия
|
||||
|
||||
Все action-функции возвращают **плоский form state** (как `getFormState()`) с action-specific extras (`clicked`, `focused`, `selected`, `filled`, `notFilled`, `closed`, `opened`, `navigated`, `deleted`, `filtered`, `unfiltered`). Errors всегда на верхнем уровне `.errors` — exec-wrapper автоматически throw'ает на soft validation errors (`modal`/`balloon`).
|
||||
|
||||
| Функция | Описание | Возвращает |
|
||||
|---------|----------|------------|
|
||||
| `clickElement(text, {dblclick?, modifier?, table?, scroll?})` | Клик по кнопке/ссылке/строке. `{dblclick: true}` для открытия, `{modifier: 'ctrl'\|'shift'}` для мультиселекции. Первый аргумент может быть `{row, column}` для клика по ячейке spreadsheet или грида формы (`table` форсит грид; `scroll: true \| number` включает reveal-loop через PageDown — см. выше). Если `text` не совпал ни с одним контролом и `table` не задан — как последний fallback фокусирует одноимённое поле ввода (без изменения значения), см. раздел про клавиши | form state (`clicked` / `focused` / `submenu`) |
|
||||
| `fillFields({name: value})` | Заполнить поля (текст, чекбокс, радио, ссылки, DCS-фильтры). Пустое значение (`''`/`null`) = очистка | form state с `filled` |
|
||||
| `selectValue(field, search, opts?)` | Выбрать из справочника. search: текст, `{поле: значение}` или `''`/`null` для очистки. `{ type }` для составного типа | form state с `selected` |
|
||||
| `fillTableRow(fields, {tab?, add?, row?})` | Заполнить строку. Значение: строка, `{ value, type }` для составного типа, `''`/`null` для очистки | form state с `filled` (per-field ошибки как items `ok: false`, см. ниже) + `notFilled?` |
|
||||
| `deleteTableRow(row, {tab?})` | Удалить строку по индексу | form state |
|
||||
| `closeForm({save?})` | Закрыть форму. `save: false` = "Нет", `save: true` = "Да". Возвращает `closed: true/false` | form state с `closed` |
|
||||
| `filterList(text, {field?, exact?})` | Фильтр списка. Без field = все колонки, с field = расширенный поиск | form state |
|
||||
| `unfilterList({field?})` | Снять фильтры (все или конкретный) | form state |
|
||||
|
||||
#### fillFields — типы полей
|
||||
|
||||
| Значение | Тип поля | Метод |
|
||||
|----------|---------|--------|
|
||||
| `'Андромеда Плюс'` | Ссылочное | clipboard paste + typeahead |
|
||||
| `'5000'` | Текст | clipboard paste |
|
||||
| `'true'` / `'да'` | Чекбокс | toggle |
|
||||
| `'Оплата поставщику'` | Радио | fuzzy match по меткам |
|
||||
| `'Склад бытовой техники'` (DCS) | Фильтр отчёта | авто-включение чекбокса + заполнение |
|
||||
| `''` / `null` | Любое (кроме чекбокс/радио) | очистка через Shift+F4 |
|
||||
|
||||
### Утилиты
|
||||
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| `screenshot()` | Скриншот (PNG Buffer) |
|
||||
| `wait(seconds)` | Пауза, возвращает form state |
|
||||
| `getPage()` | Сырой Playwright Page для горячих клавиш и нестандартных операций |
|
||||
| `startRecording(path, opts?)` | Начать запись видео (CDP screencast → ffmpeg → MP4) |
|
||||
| `stopRecording()` | Остановить запись, вернуть `{ file, duration, size }` |
|
||||
| `showCaption(text, opts?)` | Текстовая подпись поверх страницы (`speech` — текст озвучки) |
|
||||
| `hideCaption()` | Убрать подпись |
|
||||
| `showTitleSlide(text, opts?)` | Полноэкранный титульный слайд (`subtitle`, `background`, `speech`) |
|
||||
| `hideTitleSlide()` | Убрать титульный слайд |
|
||||
| `showImage(path, opts?)` | Полноэкранное изображение (`style`: blur/dark/light/full, `speech`) |
|
||||
| `hideImage()` | Убрать изображение |
|
||||
| `addNarration(videoPath, opts?)` | Озвучка видео по субтитрам (Edge TTS / ElevenLabs / OpenAI) |
|
||||
| `getCaptions()` | Субтитры из текущей/последней записи |
|
||||
| `isRecording()` | Идёт ли запись (boolean) |
|
||||
| `setHighlight(on)` | Включить/выключить авто-выделение элементов при действиях |
|
||||
| `isHighlightMode()` | Активен ли режим авто-выделения (boolean) |
|
||||
| `highlight(text)` | Ручное выделение элемента (по имени, fuzzy match) |
|
||||
| `unhighlight()` | Снять выделение |
|
||||
|
||||
## Клавиатурные сочетания
|
||||
|
||||
Чтобы клавиша применилась к нужному полю, его сперва надо сфокусировать. `clickElement('ИмяПоля')` (без `table`) ставит фокус, ничего не меняя, и возвращает `focused: { field, id, ok }` — после этого жмём клавишу через `getPage()`:
|
||||
|
||||
```js
|
||||
await clickElement('Контрагент'); // фокус на ссылочное поле (focused.ok)
|
||||
const page = await getPage();
|
||||
await page.keyboard.press('F4'); // открыть форму выбора
|
||||
```
|
||||
|
||||
| Клавиша | Контекст | Действие |
|
||||
|---------|----------|----------|
|
||||
| `F8` | Ссылочное поле | Создать новый элемент (может требовать прав/настройки в 1С) |
|
||||
| `Shift+F4` | Любое поле | Очистить значение (автоматизировано: `fillFields({ поле: '' })`) |
|
||||
| `F4` | Ссылочное поле | Форма выбора |
|
||||
| `Alt+F` | Список/таблица | Расширенный поиск |
|
||||
|
||||
## Типичные ошибки
|
||||
|
||||
Большинство функций бросают исключение при ошибке. Сценарий прерывается на проблемном шаге с информативным сообщением. В интерактиве — `try/catch` для обработки.
|
||||
|
||||
**Исключение — `fillTableRow`**: на per-field ошибках не throws, а возвращает их в `filled[]` как items с `ok: false` (`{ field, ok: false, error: 'code', message: '...' }`). Это позволяет частичное восстановление: например при `error: 'composite_type'` модель может retry'нуть конкретную ячейку с `{ value, type }` синтаксисом, не перезаполняя всю строку. Проверка — `r.filled.filter(f => !f.ok)`. Жёсткие ошибки (нет формы, table не найдена) и soft validation errors от 1С (balloon/modal) — всё равно throws.
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `no form found` — форма не открыта | Добавьте `await wait(2)` после навигации |
|
||||
| `not found. Available: ...` — элемент не найден | Проверьте имя через `getFormState()`, используйте вариант из Available |
|
||||
| `fillFields: N of M field(s) failed` | Текст ошибки содержит список проблемных полей и доступные варианты |
|
||||
| `fillTableRow` вернул item с `ok: false` | См. поле `error` — `composite_type` → retry с `{value, type}`; `column_not_found` → проверьте имя поля через `readTable`; `not_found` → уточните значение поиска |
|
||||
| Пустой `readSpreadsheet()` | Увеличьте `await wait(N)` перед чтением |
|
||||
|
||||
## Особенности
|
||||
|
||||
- **Headed mode** — 1С требует видимый браузер, headless не поддерживается
|
||||
- **Время запуска** — первое подключение к 1С занимает 30-60 секунд (ожидание встроено)
|
||||
- **Fuzzy matching** — все поиски: точное совпадение → начало строки → вхождение. Буквы ё и е считаются эквивалентными
|
||||
- **Clipboard paste** — поля заполняются через Ctrl+V (корректно триггерит события 1С)
|
||||
- **Неразрывные пробелы** — 1С использует `\u00a0`, внутри API нормализация автоматическая
|
||||
- **Ошибки** — все функции бросают исключение при ошибке (сценарий прерывается), `try/catch` для обработки
|
||||
- **Панель разделов** — `navigateSection()` работает при любом расположении панели (сбоку, сверху), но требует режим «Картинка и текст» или «Текст». Режим «Только картинки» не поддерживается — API не может прочитать имена разделов из иконок
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Запись видеоинструкций](web-test-recording-guide.md) — запись видео, субтитры, подсветка, TTS-озвучка
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`, `/web-unpublish`
|
||||
- [Базы данных](db-guide.md) — `/db-load-xml`, `/db-update`, `/db-run`
|
||||
- [Расширения](cfe-guide.md) — `/cfe-init`, `/cfe-borrow`, `/cfe-patch-method`
|
||||
# Тестирование через веб-клиент 1С
|
||||
|
||||
Навык `/web-test` автоматизирует действия в веб-клиенте 1С через Playwright — навигация по разделам, заполнение форм, чтение таблиц и отчётов, фильтрация списков. Замыкает цикл: правка исходников → загрузка → обновление → публикация → **автоматическое тестирование**.
|
||||
|
||||
## Навык
|
||||
|
||||
| Навык | Скрипт | Описание |
|
||||
|-------|:------:|----------|
|
||||
| `/web-test` | `.mjs` (Node.js) | Автоматизация 1С через браузер — навигация, формы, таблицы, отчёты |
|
||||
|
||||
## Предусловия
|
||||
|
||||
- База опубликована через Apache (`/web-publish`)
|
||||
- Node.js 18+ установлен
|
||||
- Зависимости установлены: `cd .claude/skills/web-test/scripts && npm install`
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
```
|
||||
/web-publish → /web-test → результат
|
||||
↑ |
|
||||
└── правки → /db-load-xml → /db-update ──┘
|
||||
```
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Навигация и чтение данных
|
||||
|
||||
```
|
||||
> Открой базу erp в браузере, перейди в раздел Склад и покажи какие команды там есть
|
||||
```
|
||||
|
||||
Claude откроет браузер, перейдёт в раздел и покажет список команд.
|
||||
|
||||
```
|
||||
> Открой список поступлений товаров и покажи первые 10 строк
|
||||
```
|
||||
|
||||
Claude откроет список и прочитает таблицу.
|
||||
|
||||
### Поиск и открытие элементов
|
||||
|
||||
```
|
||||
> Найди в списке номенклатуры товар "Вентилятор" и открой его карточку
|
||||
```
|
||||
|
||||
Claude отфильтрует список, откроет найденный элемент двойным кликом и прочитает реквизиты формы.
|
||||
|
||||
```
|
||||
> Открой справочник Контрагенты и найди "Торговый дом"
|
||||
```
|
||||
|
||||
Claude может работать с иерархическими справочниками — поиск автоматически сглаживает иерархию.
|
||||
|
||||
### Создание документа
|
||||
|
||||
```
|
||||
> Создай заказ клиента: организация "Андромеда Плюс", контрагент "Торговый дом Комплексный",
|
||||
> добавь строку: номенклатура "Вентилятор", количество 5
|
||||
```
|
||||
|
||||
Claude откроет форму создания, заполнит шапку и добавит строку в табличную часть.
|
||||
|
||||
### Работа с отчётами
|
||||
|
||||
```
|
||||
> Открой отчёт "Остатки и доступность товаров",
|
||||
> установи отбор Склад = "Склад бытовой техники", сформируй и прочитай результат
|
||||
```
|
||||
|
||||
Claude заполнит фильтры отчёта по человекочитаемым именам (не надо знать технические имена DCS), нажмёт "Сформировать" и прочитает структурированные данные: заголовки, строки, итоги.
|
||||
|
||||
### Сравнение данных
|
||||
|
||||
```
|
||||
> Сформируй отчёт по остаткам для "Склад бытовой техники" и "Западный склад",
|
||||
> сравни итоги по доступным товарам
|
||||
```
|
||||
|
||||
Claude напишет сценарий, который сформирует отчёт дважды с разными фильтрами и сравнит результаты.
|
||||
|
||||
### Проверка после загрузки расширения
|
||||
|
||||
```
|
||||
> Загрузи расширение ТестОшибки и проверь через браузер, что при создании заказа клиента
|
||||
> появляется ошибка "Тестовая ошибка из расширения"
|
||||
```
|
||||
|
||||
Claude загрузит расширение через `/db-load-xml`, затем через `/web-test` откроет форму и проверит ожидаемое поведение.
|
||||
|
||||
### Открытие внешней обработки
|
||||
|
||||
```
|
||||
> Открой обработку build/РедакторДвижений.epf в веб-клиенте и покажи что на форме
|
||||
```
|
||||
|
||||
Claude откроет EPF через Ctrl+O, автоматически обработает диалог безопасности (если есть) и прочитает форму.
|
||||
|
||||
### Пошаговая отладка
|
||||
|
||||
```
|
||||
> Запусти браузер на базе erp
|
||||
> Перейди в раздел Продажи
|
||||
> Посмотри что на форме
|
||||
> Открой первый заказ
|
||||
> Какие реквизиты заполнены?
|
||||
```
|
||||
|
||||
Claude будет выполнять команды по одной, показывая состояние формы между шагами.
|
||||
|
||||
## Режимы работы
|
||||
|
||||
### Автономный режим (run)
|
||||
|
||||
Одна команда: открывает браузер → логинится → выполняет сценарий → закрывает браузер → завершает процесс. Не оставляет висящих процессов.
|
||||
|
||||
```bash
|
||||
RUN=".claude/skills/web-test/scripts/run.mjs"
|
||||
node $RUN run http://localhost:8081/erp scenario.js
|
||||
```
|
||||
|
||||
Claude пишет `.js` файл со сценарием и запускает его. Ответ — JSON:
|
||||
```json
|
||||
{ "ok": true, "output": "...console.log output...", "elapsed": 12.3 }
|
||||
```
|
||||
|
||||
При ошибке — автоматический скриншот (пока модалка ещё видна) и стек вызова:
|
||||
```json
|
||||
{ "ok": false, "error": "Тестовая проверка: запись запрещена", "screenshot": "error-shot.png",
|
||||
"stack": { "raw": "...", "entries": [{"location": "Модуль(4)", "code": "ВызватьИсключение..."}] } }
|
||||
```
|
||||
Стек извлекается автоматически — через OpenReport (платформенные исключения) или "О программе" → "Информация для техподдержки" (ВызватьИсключение).
|
||||
|
||||
### Интерактивный режим (start/exec/stop)
|
||||
|
||||
Браузер остаётся открытым между командами. Состояние (открытые вкладки, формы) сохраняется.
|
||||
|
||||
```bash
|
||||
node $RUN start http://localhost:8081/erp # запустить сессию (фоновый процесс)
|
||||
cat <<'SCRIPT' | node $RUN exec - # выполнить скрипт
|
||||
await navigateSection('Продажи');
|
||||
SCRIPT
|
||||
node $RUN shot current-state.png # скриншот
|
||||
node $RUN stop # завершить сессию
|
||||
```
|
||||
|
||||
### Когда какой
|
||||
|
||||
| Режим | Когда использовать |
|
||||
|-------|-------------------|
|
||||
| Автономный (`run`) | Готовый сценарий целиком, субагенты, CI |
|
||||
| Интерактивный (`start/exec`) | Пошаговое исследование, отладка, разговор с пользователем |
|
||||
|
||||
## Пример: автономный сценарий
|
||||
|
||||
Сравнение остатков по двум складам — один файл, один запуск:
|
||||
|
||||
```js
|
||||
// scenario-compare-stocks.js
|
||||
|
||||
// 1. Открыть отчёт
|
||||
await navigateSection('Склад и доставка');
|
||||
await openCommand('Отчеты по складу');
|
||||
await clickElement('Остатки и доступность товаров', { dblclick: true });
|
||||
|
||||
// 2. Первый склад
|
||||
await fillFields({ 'Склад': 'Склад бытовой техники' });
|
||||
await clickElement('Сформировать');
|
||||
await wait(5);
|
||||
const report1 = await readSpreadsheet();
|
||||
console.log('=== Склад бытовой техники ===');
|
||||
console.log('Строк:', report1.data?.length, '| Доступно:', report1.totals?.['Доступно']);
|
||||
|
||||
// 3. Второй склад
|
||||
await fillFields({ 'Склад': 'Западный склад' });
|
||||
await clickElement('Сформировать');
|
||||
await wait(5);
|
||||
const report2 = await readSpreadsheet();
|
||||
console.log('=== Западный склад ===');
|
||||
console.log('Строк:', report2.data?.length, '| Доступно:', report2.totals?.['Доступно']);
|
||||
|
||||
// 4. Сравнение
|
||||
const parse = s => parseFloat((s || '0').replace(/\s/g, '').replace(',', '.'));
|
||||
const diff = parse(report1.totals?.['Доступно']) - parse(report2.totals?.['Доступно']);
|
||||
console.log('Разница:', diff.toFixed(0));
|
||||
|
||||
await closeForm({ save: false });
|
||||
```
|
||||
|
||||
Запуск: `node $RUN run http://localhost:8081/erp scenario-compare-stocks.js`
|
||||
|
||||
### Расшифровка отчёта
|
||||
|
||||
```js
|
||||
// 1. Сформировать отчёт
|
||||
await clickElement('Сформировать');
|
||||
await wait(5);
|
||||
const report = await readSpreadsheet();
|
||||
|
||||
// 2. Двойной клик по ячейке → диалог "Выбор поля"
|
||||
await clickElement({ row: 0, column: 'К6' }, { dblclick: true });
|
||||
|
||||
// 3. Выбрать поле расшифровки
|
||||
await clickElement('Регистратор');
|
||||
await clickElement('Выбрать');
|
||||
await wait(10);
|
||||
|
||||
// 4. Прочитать результат
|
||||
const drilldown = await readSpreadsheet();
|
||||
console.log('Расшифровка:', JSON.stringify(drilldown.rows));
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Все функции доступны как глобальные переменные в скриптах. `console.log()` выводит данные в ответ.
|
||||
|
||||
### Навигация
|
||||
|
||||
| Функция | Описание | Возвращает |
|
||||
|---------|----------|------------|
|
||||
| `navigateSection(name)` | Перейти в раздел (fuzzy match) | form state с `navigated`, `sections`, `commands` |
|
||||
| `openCommand(name)` | Открыть команду из панели функций | form state |
|
||||
| `navigateLink(path)` | Открыть по пути метаданных (`Документ.ЗаказКлиента`) | form state |
|
||||
| `openFile(path)` | Открыть внешнюю обработку/отчёт (EPF/ERF) через «Файл → Открыть» | form state |
|
||||
| `switchTab(name)` | Переключить открытую вкладку | form state |
|
||||
|
||||
### Чтение
|
||||
|
||||
| Функция | Описание | Возвращает |
|
||||
|---------|----------|------------|
|
||||
| `getFormState()` | Структура формы: поля, кнопки, таблица, фильтры, состояние окон | `{ form, formCount, openForms, fields, buttons, tabs, table, filters, reportSettings? }` |
|
||||
| `readTable({ maxRows?, offset? })` | Данные таблицы с пагинацией | `{ columns, rows: [{col: val}], total }` |
|
||||
| `readSpreadsheet()` | Результат отчёта | `{ title?, headers?, data?, totals?, total }` |
|
||||
| `getSections()` | Разделы и команды | `{ activeSection, sections, commands }` |
|
||||
| `getPageState()` | Разделы + открытые вкладки | `{ activeSection, activeTab, sections, tabs }` |
|
||||
|
||||
#### getFormState — подробнее
|
||||
|
||||
Основной способ «увидеть» что на экране:
|
||||
|
||||
- **form** — номер активной формы, `null` когда ничего не открыто (десктоп)
|
||||
- **formCount** — количество открытых форм. `0` = десктоп. Работает даже если панель открытых окон скрыта
|
||||
- **openForms** — `[0, 1, 2]` — номера всех открытых форм в DOM
|
||||
- **modal** — `true` когда активная форма — модальный диалог, блокирующий интерфейс
|
||||
- **openTabs** — `[{ name, active? }]` из панели открытых окон (только когда панель включена в настройках 1С)
|
||||
- **fields** — `[{ name, value, label?, actions?, required? }]`. `actions` = select/clear/open. `required: true` = незаполненное обязательное поле
|
||||
- **table** — `{ name, columns, rowCount }` (метаданные; для данных — `readTable()`)
|
||||
- **reportSettings** — DCS-фильтры в читаемом виде: `[{ name: "Склад", enabled: true, value: "..." }]`
|
||||
- **errorModal** — 1С показала ошибку
|
||||
- **confirmation** — диалог Да/Нет, вызовите `clickElement('Да')` или `clickElement('Нет')`
|
||||
- **platformDialogs** — `[{ type, title }]` — платформенные диалоги (О программе, Информация для техподдержки). Невидимы для обычного определения форм, но блокируют интерфейс. `closeForm()` закрывает их. Автоочистка через `dismissPendingErrors` перед каждым action
|
||||
|
||||
#### readTable — подробнее
|
||||
|
||||
Каждая строка — объект `{ columnName: value }`. Специальные поля для иерархии и дерева:
|
||||
|
||||
- `_kind: 'group'` — группа в иерархическом списке
|
||||
- `_tree: 'expanded'|'collapsed'` — состояние узла дерева
|
||||
- `_level: N` — уровень вложенности
|
||||
- `_selected: true` — строка выделена (подсвечена). Используйте с `clickElement({ modifier: 'ctrl'|'shift' })` для проверки мультиселекции
|
||||
- На объекте результата: `hierarchical: true`, `viewMode: 'tree'`
|
||||
|
||||
**Виртуализация и `hasMore`.** 1С виртуализирует и динамические списки, и табличные части — в DOM лежит только окно видимых строк. Поля `total` / `shown` — это размер DOM-окна, а **не** размер коллекции. Чтобы понять, есть ли строки за пределами окна, используйте `hasMore`:
|
||||
|
||||
```js
|
||||
const t = await readTable();
|
||||
// t.hasMore = { above: false, below: true } — открыли список, есть строки ниже
|
||||
// t.hasMore = { above: true, below: false } — пролистали в конец
|
||||
// t.hasMore = { above: false, below: false } — всё помещается / нет страниц
|
||||
```
|
||||
|
||||
`hasMore.below` присутствует всегда. `hasMore.above` тоже обычно есть — определяется по кнопкам пагинации (`vertButtonScroll`, есть у большинства дин-списков) или треку скроллбара (у табчастей). Отсутствует только в редких случаях, когда у грида нет ни кнопок, ни видимого скроллбара — тогда трактуйте отсутствие как «неизвестно».
|
||||
|
||||
**Колонки-картинки.** Ячейки, где выводится иконка (статусы, этапы, индикатор ЭДО, скрепка «есть файл»), читаются как `'pic:<N>'` при наличии иконки (`N` — индекс кадра/состояния) и `''` при её отсутствии. Присутствие читается как truthy, разные иконки различаются по индексу:
|
||||
|
||||
```js
|
||||
const t = await readTable();
|
||||
if (t.rows[0]['Присоединенные файлы']) { /* у строки есть прикреплённый файл */ }
|
||||
t.rows[0]['ЭДО'] === 'pic:1'; // подключён к 1С-ЭДО ('pic:0' = нет)
|
||||
```
|
||||
|
||||
Колонки без текста в заголовке (одна иконка) тоже попадают в `columns`, именуются по тултипу заголовка или `'(picture)'` — служебное имя колонки 1С в браузер не передаёт. Картиночные значения — **только для чтения и ассертов**: отбирать/фильтровать строки по `'pic:N'` нельзя (фильтр по такому значению бросает понятную ошибку, расширенный поиск 1С такое поле не покажет). Для выбора строки фильтруйте по текстовой колонке; кликать по картиночной ячейке можно по индексу строки.
|
||||
|
||||
#### clickElement — клик по ячейке (spreadsheet или грид формы)
|
||||
|
||||
Первый аргумент `clickElement` принимает объект `{ row, column }` вместо текста. Маршрутизация автоматическая: если на форме отрисован SpreadsheetDocument (отчёт) — кликаем туда (drill-down), иначе — по ячейке грида (табчасть, список). Параметр `table: 'ИмяГрида'` принудительно указывает грид, если на форме одновременно есть отчёт и таблицы.
|
||||
|
||||
**SpreadsheetDocument (drill-down отчёта).** Координаты соответствуют выводу `readSpreadsheet()`:
|
||||
|
||||
```js
|
||||
const report = await readSpreadsheet();
|
||||
// report.data[0] = { 'К1': 'Материалы строительные', 'К6': '150 000' }
|
||||
|
||||
await clickElement({ row: 0, column: 'К6' }, { dblclick: true }); // по индексу
|
||||
await clickElement({ row: { 'К1': 'Материалы' }, column: 'К6' }, { dblclick: true }); // по фильтру
|
||||
await clickElement({ row: 'totals', column: 'К6' }, { dblclick: true }); // итоги
|
||||
await clickElement('150 000', { dblclick: true }); // fallback: по тексту в iframe'ах
|
||||
```
|
||||
|
||||
**Грид формы (табчасть документа, список каталога/журнала).** Колонка вне viewport — авто-скролл по горизонтали (с учётом frozen-колонок). `scroll: true | number` включает reveal-loop через PageDown для filter-row за пределами DOM-окна:
|
||||
|
||||
```js
|
||||
await clickElement({ row: 0, column: 'Количество' }, { table: 'Товары', dblclick: true });
|
||||
await clickElement({ row: { 'Номенклатура': 'Бумага' }, column: 'Цена' }, { table: 'Товары' });
|
||||
await clickElement(
|
||||
{ row: { 'Номер': '0000-000601' }, column: 'Сумма' },
|
||||
{ table: 'Реализации', scroll: true } // PageDown loop, лимит по умолчанию 50
|
||||
);
|
||||
```
|
||||
|
||||
**Подводные камни:**
|
||||
- `row: <число>` — индекс в **текущем DOM-окне**, не абсолютный (1С виртуализирует длинные списки). Для произвольной строки в длинном списке — `row: { col: val }` + `scroll: true`.
|
||||
- `scroll: true` идёт только **вниз** (PageDown). Для вверх — `page.keyboard.press('Home')` через `getPage()` или сначала `filterList`.
|
||||
- На дубликаты при фильтре — первая подходящая строка. Уточняйте фильтр для disambiguation.
|
||||
|
||||
### Действия
|
||||
|
||||
Все action-функции возвращают **плоский form state** (как `getFormState()`) с action-specific extras (`clicked`, `focused`, `selected`, `filled`, `notFilled`, `closed`, `opened`, `navigated`, `deleted`, `filtered`, `unfiltered`). Errors всегда на верхнем уровне `.errors` — exec-wrapper автоматически throw'ает на soft validation errors (`modal`/`balloon`).
|
||||
|
||||
| Функция | Описание | Возвращает |
|
||||
|---------|----------|------------|
|
||||
| `clickElement(text, {dblclick?, modifier?, table?, scroll?})` | Клик по кнопке/ссылке/строке. `{dblclick: true}` для открытия, `{modifier: 'ctrl'\|'shift'}` для мультиселекции. Первый аргумент может быть `{row, column}` для клика по ячейке spreadsheet или грида формы (`table` форсит грид; `scroll: true \| number` включает reveal-loop через PageDown — см. выше). Если `text` не совпал ни с одним контролом и `table` не задан — как последний fallback фокусирует одноимённое поле ввода (без изменения значения), см. раздел про клавиши | form state (`clicked` / `focused` / `submenu`) |
|
||||
| `fillFields({name: value})` | Заполнить поля (текст, чекбокс, радио, ссылки, DCS-фильтры). Пустое значение (`''`/`null`) = очистка | form state с `filled` |
|
||||
| `selectValue(field, search, opts?)` | Выбрать из справочника. search: текст, `{поле: значение}` или `''`/`null` для очистки. `{ type }` для составного типа | form state с `selected` |
|
||||
| `fillTableRow(fields, {tab?, add?, row?})` | Заполнить строку. Значение: строка, `{ value, type }` для составного типа, `''`/`null` для очистки | form state с `filled` (per-field ошибки как items `ok: false`, см. ниже) + `notFilled?` |
|
||||
| `deleteTableRow(row, {tab?})` | Удалить строку по индексу | form state |
|
||||
| `closeForm({save?})` | Закрыть форму. `save: false` = "Нет", `save: true` = "Да". Возвращает `closed: true/false` | form state с `closed` |
|
||||
| `filterList(text, {field?, exact?})` | Фильтр списка. Без field = все колонки, с field = расширенный поиск | form state |
|
||||
| `unfilterList({field?})` | Снять фильтры (все или конкретный) | form state |
|
||||
|
||||
#### fillFields — типы полей
|
||||
|
||||
| Значение | Тип поля | Метод |
|
||||
|----------|---------|--------|
|
||||
| `'Андромеда Плюс'` | Ссылочное | clipboard paste + typeahead |
|
||||
| `'5000'` | Текст | clipboard paste |
|
||||
| `'true'` / `'да'` | Чекбокс | toggle |
|
||||
| `'Оплата поставщику'` | Радио | fuzzy match по меткам |
|
||||
| `'Склад бытовой техники'` (DCS) | Фильтр отчёта | авто-включение чекбокса + заполнение |
|
||||
| `''` / `null` | Любое (кроме чекбокс/радио) | очистка через Shift+F4 |
|
||||
|
||||
### Утилиты
|
||||
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| `screenshot()` | Скриншот (PNG Buffer) |
|
||||
| `wait(seconds)` | Пауза, возвращает form state |
|
||||
| `getPage()` | Сырой Playwright Page для горячих клавиш и нестандартных операций |
|
||||
| `startRecording(path, opts?)` | Начать запись видео (CDP screencast → ffmpeg → MP4) |
|
||||
| `stopRecording()` | Остановить запись, вернуть `{ file, duration, size }` |
|
||||
| `showCaption(text, opts?)` | Текстовая подпись поверх страницы (`speech` — текст озвучки) |
|
||||
| `hideCaption()` | Убрать подпись |
|
||||
| `showTitleSlide(text, opts?)` | Полноэкранный титульный слайд (`subtitle`, `background`, `speech`) |
|
||||
| `hideTitleSlide()` | Убрать титульный слайд |
|
||||
| `showImage(path, opts?)` | Полноэкранное изображение (`style`: blur/dark/light/full, `speech`) |
|
||||
| `hideImage()` | Убрать изображение |
|
||||
| `addNarration(videoPath, opts?)` | Озвучка видео по субтитрам (Edge TTS / ElevenLabs / OpenAI) |
|
||||
| `getCaptions()` | Субтитры из текущей/последней записи |
|
||||
| `isRecording()` | Идёт ли запись (boolean) |
|
||||
| `setHighlight(on)` | Включить/выключить авто-выделение элементов при действиях |
|
||||
| `isHighlightMode()` | Активен ли режим авто-выделения (boolean) |
|
||||
| `highlight(text)` | Ручное выделение элемента (по имени, fuzzy match) |
|
||||
| `unhighlight()` | Снять выделение |
|
||||
|
||||
## Клавиатурные сочетания
|
||||
|
||||
Чтобы клавиша применилась к нужному полю, его сперва надо сфокусировать. `clickElement('ИмяПоля')` (без `table`) ставит фокус, ничего не меняя, и возвращает `focused: { field, id, ok }` — после этого жмём клавишу через `getPage()`:
|
||||
|
||||
```js
|
||||
await clickElement('Контрагент'); // фокус на ссылочное поле (focused.ok)
|
||||
const page = await getPage();
|
||||
await page.keyboard.press('F4'); // открыть форму выбора
|
||||
```
|
||||
|
||||
| Клавиша | Контекст | Действие |
|
||||
|---------|----------|----------|
|
||||
| `F8` | Ссылочное поле | Создать новый элемент (может требовать прав/настройки в 1С) |
|
||||
| `Shift+F4` | Любое поле | Очистить значение (автоматизировано: `fillFields({ поле: '' })`) |
|
||||
| `F4` | Ссылочное поле | Форма выбора |
|
||||
| `Alt+F` | Список/таблица | Расширенный поиск |
|
||||
|
||||
## Типичные ошибки
|
||||
|
||||
Большинство функций бросают исключение при ошибке. Сценарий прерывается на проблемном шаге с информативным сообщением. В интерактиве — `try/catch` для обработки.
|
||||
|
||||
**Исключение — `fillTableRow`**: на per-field ошибках не throws, а возвращает их в `filled[]` как items с `ok: false` (`{ field, ok: false, error: 'code', message: '...' }`). Это позволяет частичное восстановление: например при `error: 'composite_type'` модель может retry'нуть конкретную ячейку с `{ value, type }` синтаксисом, не перезаполняя всю строку. Проверка — `r.filled.filter(f => !f.ok)`. Жёсткие ошибки (нет формы, table не найдена) и soft validation errors от 1С (balloon/modal) — всё равно throws.
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `no form found` — форма не открыта | Добавьте `await wait(2)` после навигации |
|
||||
| `not found. Available: ...` — элемент не найден | Проверьте имя через `getFormState()`, используйте вариант из Available |
|
||||
| `fillFields: N of M field(s) failed` | Текст ошибки содержит список проблемных полей и доступные варианты |
|
||||
| `fillTableRow` вернул item с `ok: false` | См. поле `error` — `composite_type` → retry с `{value, type}`; `column_not_found` → проверьте имя поля через `readTable`; `not_found` → уточните значение поиска |
|
||||
| Пустой `readSpreadsheet()` | Увеличьте `await wait(N)` перед чтением |
|
||||
|
||||
## Особенности
|
||||
|
||||
- **Headed mode** — 1С требует видимый браузер, headless не поддерживается
|
||||
- **Время запуска** — первое подключение к 1С занимает 30-60 секунд (ожидание встроено)
|
||||
- **Fuzzy matching** — все поиски: точное совпадение → начало строки → вхождение. Буквы ё и е считаются эквивалентными
|
||||
- **Clipboard paste** — поля заполняются через Ctrl+V (корректно триггерит события 1С)
|
||||
- **Неразрывные пробелы** — 1С использует `\u00a0`, внутри API нормализация автоматическая
|
||||
- **Ошибки** — все функции бросают исключение при ошибке (сценарий прерывается), `try/catch` для обработки
|
||||
- **Панель разделов** — `navigateSection()` работает при любом расположении панели (сбоку, сверху), но требует режим «Картинка и текст» или «Текст». Режим «Только картинки» не поддерживается — API не может прочитать имена разделов из иконок
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Запись видеоинструкций](web-test-recording-guide.md) — запись видео, субтитры, подсветка, TTS-озвучка
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`, `/web-unpublish`
|
||||
- [Базы данных](db-guide.md) — `/db-load-xml`, `/db-update`, `/db-run`
|
||||
- [Расширения](cfe-guide.md) — `/cfe-init`, `/cfe-borrow`, `/cfe-patch-method`
|
||||
|
||||
+386
-386
@@ -1,386 +1,386 @@
|
||||
# Запись видеоинструкций
|
||||
|
||||
Навык `/web-test` умеет записывать видеоинструкции по работе в 1С: автоматические действия в браузере записываются в MP4 с субтитрами, подсветкой элементов и голосовой озвучкой. Результат — готовое обучающее видео.
|
||||
|
||||
```
|
||||
сценарий → запись экрана → субтитры → подсветка → озвучка голосом → MP4
|
||||
```
|
||||
|
||||
## Предусловия
|
||||
|
||||
Все пути и настройки хранятся в `.v8-project.json` — см. [справочник формата](v8-project-guide.md).
|
||||
|
||||
### ffmpeg (обязательно)
|
||||
|
||||
Выберите один из вариантов:
|
||||
|
||||
1. **В проект** (рекомендуется) — скачать essentials build с https://www.gyan.dev/ffmpeg/builds/, распаковать в `tools/ffmpeg/`. Код найдёт `tools/ffmpeg/bin/ffmpeg.exe` автоматически
|
||||
|
||||
2. **Глобально** — скачать, распаковать в любой каталог, добавить `bin/` в системный PATH
|
||||
|
||||
3. **Через конфиг** — указать путь в `.v8-project.json`:
|
||||
```json
|
||||
{ "ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe" }
|
||||
```
|
||||
|
||||
### node-edge-tts (для озвучки)
|
||||
|
||||
```bash
|
||||
npm install --prefix tools/tts node-edge-tts
|
||||
```
|
||||
|
||||
Бесплатный, без API-ключа. Если не установлен — запись видео работает, только озвучка недоступна.
|
||||
|
||||
### Конфигурация голоса в `.v8-project.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"ffmpegPath": "tools/ffmpeg/bin/ffmpeg.exe",
|
||||
"tts": {
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
Минимальный сценарий — запись 3 шагов с озвучкой:
|
||||
|
||||
```js
|
||||
// Начинаем запись
|
||||
await startRecording('recordings/demo.mp4');
|
||||
|
||||
// Субтитры + действия
|
||||
await showCaption('Переходим в раздел «Продажи»');
|
||||
await wait(1.5);
|
||||
await navigateSection('Продажи');
|
||||
|
||||
await showCaption('Открываем заказы клиентов');
|
||||
await wait(1.5);
|
||||
await openCommand('Заказы клиентов');
|
||||
|
||||
await showCaption('Создаём новый заказ');
|
||||
await wait(1.5);
|
||||
await clickElement('Создать');
|
||||
await wait(2);
|
||||
|
||||
// Завершаем запись
|
||||
await hideCaption();
|
||||
const video = await stopRecording();
|
||||
console.log(`Записано: ${video.duration.toFixed(1)}s`);
|
||||
|
||||
// Озвучка
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-DmitryNeural',
|
||||
});
|
||||
console.log(`Озвучено: ${narrated.file}`);
|
||||
```
|
||||
|
||||
Результат: `recordings/demo-narrated.mp4` — видео с голосовым сопровождением.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Запись без озвучки
|
||||
|
||||
Простейший вариант — субтитры на экране, без голоса:
|
||||
|
||||
```
|
||||
> Запиши видеоинструкцию: открой раздел Продажи, создай заказ клиента,
|
||||
> заполни организацию и контрагента. Без озвучки
|
||||
```
|
||||
|
||||
Claude запишет видео с субтитрами и подсветкой элементов.
|
||||
|
||||
### Запись с озвучкой
|
||||
|
||||
Полный pipeline — голос озвучивает каждый шаг:
|
||||
|
||||
```
|
||||
> Запиши озвученную видеоинструкцию по созданию заказа клиента.
|
||||
> Голос — Светлана
|
||||
```
|
||||
|
||||
Claude запишет видео, затем наложит голосовую дорожку. Субтитры показываются на экране, параллельно звучит голос.
|
||||
|
||||
### Переозвучка другим голосом
|
||||
|
||||
Видео уже записано — хотите другой голос? Не нужно перезаписывать:
|
||||
|
||||
```
|
||||
> Переозвучь recordings/demo.mp4 голосом Светланы
|
||||
```
|
||||
|
||||
Claude вызовет `addNarration` с другим голосом. Тексты берутся из файла `.captions.json`, который сохраняется рядом с видео при записи.
|
||||
|
||||
### Редактирование субтитров
|
||||
|
||||
После записи рядом с видео появляется файл `video.captions.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"videoTimestamps": true,
|
||||
"captions": [
|
||||
{ "text": "Переходим в раздел «Продажи»", "speech": "Переходим в раздел Продажи", "time": 3160 },
|
||||
{ "text": "Открываем заказы клиентов", "speech": "Открываем заказы клиентов", "time": 7040, "voice": "bqbHGIIO5oETYIqhWmfk" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Можно отредактировать `speech` (текст озвучки) или добавить `voice` (голос для конкретной реплики) и переозвучить:
|
||||
|
||||
```
|
||||
> Отредактируй субтитры в recordings/demo.captions.json — замени "Продажи" на
|
||||
> "раздел Продажи", потом переозвучь
|
||||
```
|
||||
|
||||
## Приёмы
|
||||
|
||||
### Титульный слайд
|
||||
|
||||
Полноэкранная заставка в начале видео. Поддерживает озвучку через `speech`:
|
||||
|
||||
```js
|
||||
await startRecording('recordings/demo.mp4');
|
||||
await showTitleSlide('Создание заказа клиента', {
|
||||
subtitle: '1С:Бухгалтерия в примерах',
|
||||
speech: 'Создание заказа клиента. Бухгалтерия в примерах.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
// ... далее контент
|
||||
```
|
||||
|
||||
### Слайды из презентации
|
||||
|
||||
Показать изображение (скриншот слайда, схему и т.д.) как полноэкранный оверлей с озвучкой:
|
||||
|
||||
```js
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'На этом слайде показана общая схема процесса'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
```
|
||||
|
||||
Стили оформления (`style`):
|
||||
- `'blur'` (по умолчанию) — размытый фон из картинки + тень. Лучший для презентаций
|
||||
- `'dark'` — тёмный фон + тень
|
||||
- `'light'` — белый фон + тень
|
||||
- `'full'` — на весь экран без отступов
|
||||
|
||||
```js
|
||||
await showImage('slides/diagram.png', { style: 'dark', speech: 'Диаграмма процесса' });
|
||||
```
|
||||
|
||||
### Подсветка элементов
|
||||
|
||||
Полупрозрачная рамка на элементе, который сейчас используется. Два режима:
|
||||
|
||||
- **Авторежим** — `setHighlight(true)` перед началом действий. Каждая функция (`navigateSection`, `clickElement`, `fillFields` и т.д.) автоматически подсвечивает элемент перед действием
|
||||
- **Ручная** — `highlight('Провести')` для произвольной подсветки конкретного элемента
|
||||
|
||||
```js
|
||||
setHighlight(true); // включить авто
|
||||
// ... все действия подсвечиваются автоматически
|
||||
setHighlight(false); // выключить перед stopRecording
|
||||
```
|
||||
|
||||
### Паузы и ритм
|
||||
|
||||
Ритм «субтитр → пауза → действие» даёт зрителю время прочитать, что произойдёт:
|
||||
|
||||
```js
|
||||
await showCaption('Проводим документ'); // зритель читает
|
||||
await wait(1.5); // пауза 1.5 сек
|
||||
await clickElement('Провести'); // действие
|
||||
```
|
||||
|
||||
Пауза после действия нужна только когда загружается следующая форма:
|
||||
|
||||
```js
|
||||
await clickElement('Создать');
|
||||
await wait(2); // форма загружается
|
||||
```
|
||||
|
||||
### Два голоса (подкаст / диалог)
|
||||
|
||||
Параметр `voice` в `showCaption` задаёт голос для конкретной реплики. `addNarration` автоматически использует его вместо глобального:
|
||||
|
||||
```js
|
||||
const MALE = 'bqbHGIIO5oETYIqhWmfk'; // Alexander
|
||||
const FEMALE = '0ArNnoIAWKlT4WweaVMY'; // Elena Gromova
|
||||
|
||||
// speechRate: 85 — ElevenLabs медленнее Edge TTS, нужен запас
|
||||
await startRecording('podcast.mp4', { speechRate: 85 });
|
||||
|
||||
await showImage('slides/slide-01.png', { style: 'full', speech: false });
|
||||
await showCaption('', { speech: 'Привет! Сегодня поговорим...', voice: MALE });
|
||||
await wait(0.8);
|
||||
await showCaption('', { speech: 'А я буду задавать вопросы...', voice: FEMALE });
|
||||
await wait(0.8);
|
||||
|
||||
const video = await stopRecording();
|
||||
const result = await addNarration(video.file, {
|
||||
provider: 'elevenlabs',
|
||||
apiKey: 'sk_...',
|
||||
// глобальный voice не нужен — каждый caption несёт свой
|
||||
});
|
||||
```
|
||||
|
||||
Приёмы:
|
||||
- `showCaption('', { speech, voice })` — пустой текст (без субтитра на экране), но speech записывается для озвучки
|
||||
- `showImage` со `speech: false` — слайд без озвучки, реплики идут через `showCaption`
|
||||
- `speechRate: 85` — для ElevenLabs увеличиваем множитель (по умолчанию 70мс/символ), чтобы фразы не наезжали друг на друга
|
||||
|
||||
### Разделение текста и озвучки
|
||||
|
||||
Параметр `speech` в `showCaption` позволяет показывать одно, а озвучивать другое:
|
||||
|
||||
```js
|
||||
// Субтитр технический, озвучка человечная
|
||||
await showCaption('Дт 60.02 — Кт 51', {
|
||||
speech: 'Дебет шестьдесят ноль два — кредит пятьдесят один'
|
||||
});
|
||||
|
||||
// Показать субтитр, но НЕ озвучивать
|
||||
await showCaption('Технические детали', { speech: false });
|
||||
```
|
||||
|
||||
Это полезно для:
|
||||
- **Бухгалтерских проводок** — на экране формула, голосом — словами
|
||||
- **Технических данных** — показать, но не зачитывать
|
||||
- **Информационных плашек** — немой субтитр на несколько секунд
|
||||
|
||||
## Доступные голоса и провайдеры
|
||||
|
||||
### Какой провайдер выбрать?
|
||||
|
||||
| Провайдер | Тембр | Произношение русского | Цена |
|
||||
|-----------|-------|----------------------|------|
|
||||
| **Edge TTS** | Синтетичнее | Корректные ударения, правильная артикуляция | Бесплатно |
|
||||
| **ElevenLabs** | Живее, естественнее | Возможны ошибки в ударениях и артикуляции (напр. «докумЭнт», «крЕдит» вместо «кредИт») | Платно (starter+) |
|
||||
| **OpenAI** | Зависит от голоса | Зависит от сервиса | Платно |
|
||||
|
||||
**Для русскоязычных видеоинструкций рекомендуется Edge TTS** — он бесплатный и даёт надёжное качество русской речи. Голоса DmitryNeural и SvetlanaNeural специально обучены для русского языка: правильно расставляют ударения, корректно артикулируют и делают паузы в нужных местах.
|
||||
|
||||
**ElevenLabs** даёт более живой, «человечный» тембр — голос звучит менее синтетически. Однако мультиязычная модель иногда ошибается в произношении русских слов (особенно профессиональная терминология). Если выбираете ElevenLabs для русского контента — берите **professional-голоса** с образовательным или деловым профилем (например, Olga Orlova, Artem), они дают лучший результат, чем англоязычные premade-голоса через мультиязычную модель. Управлять ударениями через API нельзя — фонемные теги (SSML) поддерживаются только для английских моделей.
|
||||
|
||||
### Edge TTS (бесплатный) — рекомендуется для русского
|
||||
|
||||
| Голос | Описание |
|
||||
|-------|----------|
|
||||
| `ru-RU-DmitryNeural` | Мужской, русский — спокойный, деловой |
|
||||
| `ru-RU-SvetlanaNeural` | Женский, русский — чёткий, уверенный |
|
||||
|
||||
Полный список: `en-US-AriaNeural`, `en-US-GuyNeural`, `de-DE-ConradNeural` и другие. Edge TTS поддерживает десятки языков.
|
||||
|
||||
Конфигурация не нужна — Edge TTS используется по умолчанию. Для смены голоса:
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"voice": "ru-RU-SvetlanaNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ElevenLabs (платный) — живой тембр
|
||||
|
||||
Модель `eleven_multilingual_v2` поддерживает русский. Тембр заметно живее, чем у Edge TTS, но возможны артикуляционные ошибки на русской терминологии.
|
||||
|
||||
Для русского контента выбирайте **professional-голоса** с образовательным/деловым профилем из Voice Library:
|
||||
|
||||
| Голос | ID | Профиль |
|
||||
|-------|----|---------|
|
||||
| Olga Orlova | `d60rsXo2p0OwikDR5bS7` | Clear and Engaging |
|
||||
| Artem | `WTn2eCRCpoFAC50VD351` | Friendly & Professional |
|
||||
| Denis | `0BcDz9UPwL3MpsnTeUlO` | Pleasant, Engaging and Friendly |
|
||||
| Alexander | `bqbHGIIO5oETYIqhWmfk` | Pleasant, Warm and Natural |
|
||||
| Elena Gromova | `0ArNnoIAWKlT4WweaVMY` | Podcasts & Conversation |
|
||||
| Victor | `9fjVd0EYNNXHllJquVdT` | Moscow accent |
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "elevenlabs",
|
||||
"apiKey": "sk_...",
|
||||
"voice": "d60rsXo2p0OwikDR5bS7"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`voice` — ID голоса (не имя). Professional-голоса добавляются в аккаунт через Voice Library в личном кабинете. Требуется платный тариф (starter и выше).
|
||||
|
||||
Особенности: лимит на параллельные запросы (2–3 одновременно), система автоматически ограничивает размер пакета.
|
||||
|
||||
### OpenAI-compatible (платный)
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "openai",
|
||||
"apiKey": "sk-...",
|
||||
"voice": "alloy"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Голоса: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
||||
|
||||
Поле `apiUrl` позволяет подключить любой OpenAI-совместимый сервис (например, локальный TTS-прокси).
|
||||
|
||||
## Полный пример
|
||||
|
||||
Типовая структура озвученного сценария:
|
||||
|
||||
```js
|
||||
await startRecording('output.mp4');
|
||||
|
||||
// Титульный слайд с озвучкой
|
||||
await showTitleSlide('Заголовок', {
|
||||
subtitle: 'Подзаголовок',
|
||||
speech: 'Заголовок. Подзаголовок.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
|
||||
// Слайд из презентации (опционально)
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'Описание слайда для озвучки'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
|
||||
setHighlight(true);
|
||||
|
||||
// ... шаги с showCaption + действия ...
|
||||
|
||||
await hideCaption();
|
||||
setHighlight(false);
|
||||
const video = await stopRecording();
|
||||
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-SvetlanaNeural',
|
||||
});
|
||||
```
|
||||
|
||||
## Типичные проблемы
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `ffmpeg not found` | Установите ffmpeg (см. Предусловия) |
|
||||
| Файл записи 0 байт | Проверьте права на запись в выходной каталог |
|
||||
| Видео дёргается | Добавьте `wait()` между шагами |
|
||||
| `Already recording` | Вызовите `stopRecording()` перед новой записью |
|
||||
| `No captions available` | Используйте `showCaption()` во время записи |
|
||||
| TTS timeout | Проверьте интернет-соединение (Edge TTS требует сеть) |
|
||||
| Озвучка обрезается | Увеличьте паузы `wait()` между субтитрами |
|
||||
| Фразы наезжают друг на друга | Увеличьте `speechRate` в `startRecording` (85 для ElevenLabs) |
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Тестирование через веб-клиент](web-test-guide.md) — навигация, формы, таблицы, отчёты
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`
|
||||
# Запись видеоинструкций
|
||||
|
||||
Навык `/web-test` умеет записывать видеоинструкции по работе в 1С: автоматические действия в браузере записываются в MP4 с субтитрами, подсветкой элементов и голосовой озвучкой. Результат — готовое обучающее видео.
|
||||
|
||||
```
|
||||
сценарий → запись экрана → субтитры → подсветка → озвучка голосом → MP4
|
||||
```
|
||||
|
||||
## Предусловия
|
||||
|
||||
Все пути и настройки хранятся в `.v8-project.json` — см. [справочник формата](v8-project-guide.md).
|
||||
|
||||
### ffmpeg (обязательно)
|
||||
|
||||
Выберите один из вариантов:
|
||||
|
||||
1. **В проект** (рекомендуется) — скачать essentials build с https://www.gyan.dev/ffmpeg/builds/, распаковать в `tools/ffmpeg/`. Код найдёт `tools/ffmpeg/bin/ffmpeg.exe` автоматически
|
||||
|
||||
2. **Глобально** — скачать, распаковать в любой каталог, добавить `bin/` в системный PATH
|
||||
|
||||
3. **Через конфиг** — указать путь в `.v8-project.json`:
|
||||
```json
|
||||
{ "ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe" }
|
||||
```
|
||||
|
||||
### node-edge-tts (для озвучки)
|
||||
|
||||
```bash
|
||||
npm install --prefix tools/tts node-edge-tts
|
||||
```
|
||||
|
||||
Бесплатный, без API-ключа. Если не установлен — запись видео работает, только озвучка недоступна.
|
||||
|
||||
### Конфигурация голоса в `.v8-project.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"ffmpegPath": "tools/ffmpeg/bin/ffmpeg.exe",
|
||||
"tts": {
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
Минимальный сценарий — запись 3 шагов с озвучкой:
|
||||
|
||||
```js
|
||||
// Начинаем запись
|
||||
await startRecording('recordings/demo.mp4');
|
||||
|
||||
// Субтитры + действия
|
||||
await showCaption('Переходим в раздел «Продажи»');
|
||||
await wait(1.5);
|
||||
await navigateSection('Продажи');
|
||||
|
||||
await showCaption('Открываем заказы клиентов');
|
||||
await wait(1.5);
|
||||
await openCommand('Заказы клиентов');
|
||||
|
||||
await showCaption('Создаём новый заказ');
|
||||
await wait(1.5);
|
||||
await clickElement('Создать');
|
||||
await wait(2);
|
||||
|
||||
// Завершаем запись
|
||||
await hideCaption();
|
||||
const video = await stopRecording();
|
||||
console.log(`Записано: ${video.duration.toFixed(1)}s`);
|
||||
|
||||
// Озвучка
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-DmitryNeural',
|
||||
});
|
||||
console.log(`Озвучено: ${narrated.file}`);
|
||||
```
|
||||
|
||||
Результат: `recordings/demo-narrated.mp4` — видео с голосовым сопровождением.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Запись без озвучки
|
||||
|
||||
Простейший вариант — субтитры на экране, без голоса:
|
||||
|
||||
```
|
||||
> Запиши видеоинструкцию: открой раздел Продажи, создай заказ клиента,
|
||||
> заполни организацию и контрагента. Без озвучки
|
||||
```
|
||||
|
||||
Claude запишет видео с субтитрами и подсветкой элементов.
|
||||
|
||||
### Запись с озвучкой
|
||||
|
||||
Полный pipeline — голос озвучивает каждый шаг:
|
||||
|
||||
```
|
||||
> Запиши озвученную видеоинструкцию по созданию заказа клиента.
|
||||
> Голос — Светлана
|
||||
```
|
||||
|
||||
Claude запишет видео, затем наложит голосовую дорожку. Субтитры показываются на экране, параллельно звучит голос.
|
||||
|
||||
### Переозвучка другим голосом
|
||||
|
||||
Видео уже записано — хотите другой голос? Не нужно перезаписывать:
|
||||
|
||||
```
|
||||
> Переозвучь recordings/demo.mp4 голосом Светланы
|
||||
```
|
||||
|
||||
Claude вызовет `addNarration` с другим голосом. Тексты берутся из файла `.captions.json`, который сохраняется рядом с видео при записи.
|
||||
|
||||
### Редактирование субтитров
|
||||
|
||||
После записи рядом с видео появляется файл `video.captions.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"videoTimestamps": true,
|
||||
"captions": [
|
||||
{ "text": "Переходим в раздел «Продажи»", "speech": "Переходим в раздел Продажи", "time": 3160 },
|
||||
{ "text": "Открываем заказы клиентов", "speech": "Открываем заказы клиентов", "time": 7040, "voice": "bqbHGIIO5oETYIqhWmfk" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Можно отредактировать `speech` (текст озвучки) или добавить `voice` (голос для конкретной реплики) и переозвучить:
|
||||
|
||||
```
|
||||
> Отредактируй субтитры в recordings/demo.captions.json — замени "Продажи" на
|
||||
> "раздел Продажи", потом переозвучь
|
||||
```
|
||||
|
||||
## Приёмы
|
||||
|
||||
### Титульный слайд
|
||||
|
||||
Полноэкранная заставка в начале видео. Поддерживает озвучку через `speech`:
|
||||
|
||||
```js
|
||||
await startRecording('recordings/demo.mp4');
|
||||
await showTitleSlide('Создание заказа клиента', {
|
||||
subtitle: '1С:Бухгалтерия в примерах',
|
||||
speech: 'Создание заказа клиента. Бухгалтерия в примерах.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
// ... далее контент
|
||||
```
|
||||
|
||||
### Слайды из презентации
|
||||
|
||||
Показать изображение (скриншот слайда, схему и т.д.) как полноэкранный оверлей с озвучкой:
|
||||
|
||||
```js
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'На этом слайде показана общая схема процесса'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
```
|
||||
|
||||
Стили оформления (`style`):
|
||||
- `'blur'` (по умолчанию) — размытый фон из картинки + тень. Лучший для презентаций
|
||||
- `'dark'` — тёмный фон + тень
|
||||
- `'light'` — белый фон + тень
|
||||
- `'full'` — на весь экран без отступов
|
||||
|
||||
```js
|
||||
await showImage('slides/diagram.png', { style: 'dark', speech: 'Диаграмма процесса' });
|
||||
```
|
||||
|
||||
### Подсветка элементов
|
||||
|
||||
Полупрозрачная рамка на элементе, который сейчас используется. Два режима:
|
||||
|
||||
- **Авторежим** — `setHighlight(true)` перед началом действий. Каждая функция (`navigateSection`, `clickElement`, `fillFields` и т.д.) автоматически подсвечивает элемент перед действием
|
||||
- **Ручная** — `highlight('Провести')` для произвольной подсветки конкретного элемента
|
||||
|
||||
```js
|
||||
setHighlight(true); // включить авто
|
||||
// ... все действия подсвечиваются автоматически
|
||||
setHighlight(false); // выключить перед stopRecording
|
||||
```
|
||||
|
||||
### Паузы и ритм
|
||||
|
||||
Ритм «субтитр → пауза → действие» даёт зрителю время прочитать, что произойдёт:
|
||||
|
||||
```js
|
||||
await showCaption('Проводим документ'); // зритель читает
|
||||
await wait(1.5); // пауза 1.5 сек
|
||||
await clickElement('Провести'); // действие
|
||||
```
|
||||
|
||||
Пауза после действия нужна только когда загружается следующая форма:
|
||||
|
||||
```js
|
||||
await clickElement('Создать');
|
||||
await wait(2); // форма загружается
|
||||
```
|
||||
|
||||
### Два голоса (подкаст / диалог)
|
||||
|
||||
Параметр `voice` в `showCaption` задаёт голос для конкретной реплики. `addNarration` автоматически использует его вместо глобального:
|
||||
|
||||
```js
|
||||
const MALE = 'bqbHGIIO5oETYIqhWmfk'; // Alexander
|
||||
const FEMALE = '0ArNnoIAWKlT4WweaVMY'; // Elena Gromova
|
||||
|
||||
// speechRate: 85 — ElevenLabs медленнее Edge TTS, нужен запас
|
||||
await startRecording('podcast.mp4', { speechRate: 85 });
|
||||
|
||||
await showImage('slides/slide-01.png', { style: 'full', speech: false });
|
||||
await showCaption('', { speech: 'Привет! Сегодня поговорим...', voice: MALE });
|
||||
await wait(0.8);
|
||||
await showCaption('', { speech: 'А я буду задавать вопросы...', voice: FEMALE });
|
||||
await wait(0.8);
|
||||
|
||||
const video = await stopRecording();
|
||||
const result = await addNarration(video.file, {
|
||||
provider: 'elevenlabs',
|
||||
apiKey: 'sk_...',
|
||||
// глобальный voice не нужен — каждый caption несёт свой
|
||||
});
|
||||
```
|
||||
|
||||
Приёмы:
|
||||
- `showCaption('', { speech, voice })` — пустой текст (без субтитра на экране), но speech записывается для озвучки
|
||||
- `showImage` со `speech: false` — слайд без озвучки, реплики идут через `showCaption`
|
||||
- `speechRate: 85` — для ElevenLabs увеличиваем множитель (по умолчанию 70мс/символ), чтобы фразы не наезжали друг на друга
|
||||
|
||||
### Разделение текста и озвучки
|
||||
|
||||
Параметр `speech` в `showCaption` позволяет показывать одно, а озвучивать другое:
|
||||
|
||||
```js
|
||||
// Субтитр технический, озвучка человечная
|
||||
await showCaption('Дт 60.02 — Кт 51', {
|
||||
speech: 'Дебет шестьдесят ноль два — кредит пятьдесят один'
|
||||
});
|
||||
|
||||
// Показать субтитр, но НЕ озвучивать
|
||||
await showCaption('Технические детали', { speech: false });
|
||||
```
|
||||
|
||||
Это полезно для:
|
||||
- **Бухгалтерских проводок** — на экране формула, голосом — словами
|
||||
- **Технических данных** — показать, но не зачитывать
|
||||
- **Информационных плашек** — немой субтитр на несколько секунд
|
||||
|
||||
## Доступные голоса и провайдеры
|
||||
|
||||
### Какой провайдер выбрать?
|
||||
|
||||
| Провайдер | Тембр | Произношение русского | Цена |
|
||||
|-----------|-------|----------------------|------|
|
||||
| **Edge TTS** | Синтетичнее | Корректные ударения, правильная артикуляция | Бесплатно |
|
||||
| **ElevenLabs** | Живее, естественнее | Возможны ошибки в ударениях и артикуляции (напр. «докумЭнт», «крЕдит» вместо «кредИт») | Платно (starter+) |
|
||||
| **OpenAI** | Зависит от голоса | Зависит от сервиса | Платно |
|
||||
|
||||
**Для русскоязычных видеоинструкций рекомендуется Edge TTS** — он бесплатный и даёт надёжное качество русской речи. Голоса DmitryNeural и SvetlanaNeural специально обучены для русского языка: правильно расставляют ударения, корректно артикулируют и делают паузы в нужных местах.
|
||||
|
||||
**ElevenLabs** даёт более живой, «человечный» тембр — голос звучит менее синтетически. Однако мультиязычная модель иногда ошибается в произношении русских слов (особенно профессиональная терминология). Если выбираете ElevenLabs для русского контента — берите **professional-голоса** с образовательным или деловым профилем (например, Olga Orlova, Artem), они дают лучший результат, чем англоязычные premade-голоса через мультиязычную модель. Управлять ударениями через API нельзя — фонемные теги (SSML) поддерживаются только для английских моделей.
|
||||
|
||||
### Edge TTS (бесплатный) — рекомендуется для русского
|
||||
|
||||
| Голос | Описание |
|
||||
|-------|----------|
|
||||
| `ru-RU-DmitryNeural` | Мужской, русский — спокойный, деловой |
|
||||
| `ru-RU-SvetlanaNeural` | Женский, русский — чёткий, уверенный |
|
||||
|
||||
Полный список: `en-US-AriaNeural`, `en-US-GuyNeural`, `de-DE-ConradNeural` и другие. Edge TTS поддерживает десятки языков.
|
||||
|
||||
Конфигурация не нужна — Edge TTS используется по умолчанию. Для смены голоса:
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"voice": "ru-RU-SvetlanaNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ElevenLabs (платный) — живой тембр
|
||||
|
||||
Модель `eleven_multilingual_v2` поддерживает русский. Тембр заметно живее, чем у Edge TTS, но возможны артикуляционные ошибки на русской терминологии.
|
||||
|
||||
Для русского контента выбирайте **professional-голоса** с образовательным/деловым профилем из Voice Library:
|
||||
|
||||
| Голос | ID | Профиль |
|
||||
|-------|----|---------|
|
||||
| Olga Orlova | `d60rsXo2p0OwikDR5bS7` | Clear and Engaging |
|
||||
| Artem | `WTn2eCRCpoFAC50VD351` | Friendly & Professional |
|
||||
| Denis | `0BcDz9UPwL3MpsnTeUlO` | Pleasant, Engaging and Friendly |
|
||||
| Alexander | `bqbHGIIO5oETYIqhWmfk` | Pleasant, Warm and Natural |
|
||||
| Elena Gromova | `0ArNnoIAWKlT4WweaVMY` | Podcasts & Conversation |
|
||||
| Victor | `9fjVd0EYNNXHllJquVdT` | Moscow accent |
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "elevenlabs",
|
||||
"apiKey": "sk_...",
|
||||
"voice": "d60rsXo2p0OwikDR5bS7"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`voice` — ID голоса (не имя). Professional-голоса добавляются в аккаунт через Voice Library в личном кабинете. Требуется платный тариф (starter и выше).
|
||||
|
||||
Особенности: лимит на параллельные запросы (2–3 одновременно), система автоматически ограничивает размер пакета.
|
||||
|
||||
### OpenAI-compatible (платный)
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "openai",
|
||||
"apiKey": "sk-...",
|
||||
"voice": "alloy"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Голоса: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
||||
|
||||
Поле `apiUrl` позволяет подключить любой OpenAI-совместимый сервис (например, локальный TTS-прокси).
|
||||
|
||||
## Полный пример
|
||||
|
||||
Типовая структура озвученного сценария:
|
||||
|
||||
```js
|
||||
await startRecording('output.mp4');
|
||||
|
||||
// Титульный слайд с озвучкой
|
||||
await showTitleSlide('Заголовок', {
|
||||
subtitle: 'Подзаголовок',
|
||||
speech: 'Заголовок. Подзаголовок.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
|
||||
// Слайд из презентации (опционально)
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'Описание слайда для озвучки'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
|
||||
setHighlight(true);
|
||||
|
||||
// ... шаги с showCaption + действия ...
|
||||
|
||||
await hideCaption();
|
||||
setHighlight(false);
|
||||
const video = await stopRecording();
|
||||
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-SvetlanaNeural',
|
||||
});
|
||||
```
|
||||
|
||||
## Типичные проблемы
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `ffmpeg not found` | Установите ffmpeg (см. Предусловия) |
|
||||
| Файл записи 0 байт | Проверьте права на запись в выходной каталог |
|
||||
| Видео дёргается | Добавьте `wait()` между шагами |
|
||||
| `Already recording` | Вызовите `stopRecording()` перед новой записью |
|
||||
| `No captions available` | Используйте `showCaption()` во время записи |
|
||||
| TTS timeout | Проверьте интернет-соединение (Edge TTS требует сеть) |
|
||||
| Озвучка обрезается | Увеличьте паузы `wait()` между субтитрами |
|
||||
| Фразы наезжают друг на друга | Увеличьте `speechRate` в `startRecording` (85 для ElevenLabs) |
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Тестирование через веб-клиент](web-test-guide.md) — навигация, формы, таблицы, отчёты
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`
|
||||
|
||||
Reference in New Issue
Block a user