mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-13 17:34:57 +03:00
Initial commit: EPF skills for Claude Code
7 skills for working with 1C external data processor XML sources: - epf-init: scaffold a new processor (root XML + ObjectModule.bsl) - epf-add-form: add a managed form with BSL module - epf-add-template: add a template (HTML/Text/SpreadsheetDocument/BinaryData) - epf-remove-form: remove a form and update root XML - epf-remove-template: remove a template and update root XML - epf-build: build EPF from XML (documentation only) - epf-dump: dump EPF to XML (documentation only) Includes XML format spec and build/dump command reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
---
|
||||
name: epf-add-form
|
||||
description: Добавить управляемую форму к внешней обработке 1С
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-add-form — Добавление формы
|
||||
|
||||
Создаёт управляемую форму и регистрирует её в корневом XML обработки.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-add-form <ProcessorName> <FormName> [Synonym] [--main]
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|---------------|:------------:|--------------|-------------------------------------------|
|
||||
| ProcessorName | да | — | Имя обработки (должна существовать) |
|
||||
| FormName | да | — | Имя формы |
|
||||
| Synonym | нет | = FormName | Синоним формы |
|
||||
| --main | нет | false | Установить как форму по умолчанию |
|
||||
| SrcDir | нет | `src` | Каталог исходников |
|
||||
|
||||
## Команда
|
||||
|
||||
```powershell
|
||||
pwsh -NoProfile -File .claude/skills/epf-add-form/scripts/add-form.ps1 -ProcessorName "<ProcessorName>" -FormName "<FormName>" [-Synonym "<Synonym>"] [-Main] [-SrcDir "<SrcDir>"]
|
||||
```
|
||||
|
||||
## Что создаётся
|
||||
|
||||
```
|
||||
<SrcDir>/<ProcessorName>/Forms/
|
||||
├── <FormName>.xml # Метаданные формы (1 UUID)
|
||||
└── <FormName>/
|
||||
└── Ext/
|
||||
├── Form.xml # Описание формы (logform namespace)
|
||||
└── Form/
|
||||
└── Module.bsl # BSL-модуль с 4 регионами
|
||||
```
|
||||
|
||||
## Что модифицируется
|
||||
|
||||
- `<SrcDir>/<ProcessorName>.xml` — добавляется `<Form>` в `ChildObjects`, при `--main` обновляется `DefaultForm`
|
||||
|
||||
## Детали
|
||||
|
||||
- FormType: Managed
|
||||
- UsePurposes: PlatformApplication, MobilePlatformApplication
|
||||
- AutoCommandBar с id=-1
|
||||
- Реквизит "Объект" с MainAttribute=true
|
||||
- BSL-модуль содержит 5 регионов: ОбработчикиСобытийФормы, ОбработчикиСобытийЭлементовФормы, ОбработчикиКомандФормы, ОбработчикиОповещений, СлужебныеПроцедурыИФункции
|
||||
|
||||
## Спецификация
|
||||
|
||||
Подробности формата: `docs/1c-xml-format-spec.md`
|
||||
@@ -0,0 +1,202 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$ProcessorName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$FormName,
|
||||
|
||||
[string]$Synonym = $FormName,
|
||||
|
||||
[switch]$Main,
|
||||
|
||||
[string]$SrcDir = "src"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Проверки ---
|
||||
|
||||
$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml"
|
||||
if (-not (Test-Path $rootXmlPath)) {
|
||||
Write-Error "Корневой файл обработки не найден: $rootXmlPath. Сначала выполните epf-init."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$processorDir = Join-Path $SrcDir $ProcessorName
|
||||
$formsDir = Join-Path $processorDir "Forms"
|
||||
$formMetaPath = Join-Path $formsDir "$FormName.xml"
|
||||
|
||||
if (Test-Path $formMetaPath) {
|
||||
Write-Error "Форма уже существует: $formMetaPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Создание каталогов ---
|
||||
|
||||
$formDir = Join-Path $formsDir $FormName
|
||||
$formExtDir = Join-Path $formDir "Ext"
|
||||
$formModuleDir = Join-Path $formExtDir "Form"
|
||||
|
||||
New-Item -ItemType Directory -Path $formModuleDir -Force | Out-Null
|
||||
|
||||
# --- Кодировка ---
|
||||
|
||||
$encBom = New-Object System.Text.UTF8Encoding($true)
|
||||
$encNoBom = New-Object System.Text.UTF8Encoding($false)
|
||||
|
||||
# --- 1. Метаданные формы (Forms/<FormName>.xml) ---
|
||||
|
||||
$formUuid = [guid]::NewGuid().ToString()
|
||||
|
||||
$formMetaXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||
<Form uuid="$formUuid">
|
||||
<Properties>
|
||||
<Name>$FormName</Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>$Synonym</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<FormType>Managed</FormType>
|
||||
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||
<UsePurposes>
|
||||
<v8:Value xsi:type="app:ApplicationUsePurpose">PlatformApplication</v8:Value>
|
||||
<v8:Value xsi:type="app:ApplicationUsePurpose">MobilePlatformApplication</v8:Value>
|
||||
</UsePurposes>
|
||||
<ExtendedPresentation/>
|
||||
</Properties>
|
||||
</Form>
|
||||
</MetaDataObject>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($formMetaPath, $formMetaXml, $encBom)
|
||||
|
||||
# --- 2. Описание формы (Forms/<FormName>/Ext/Form.xml) ---
|
||||
|
||||
$formXmlPath = Join-Path $formExtDir "Form.xml"
|
||||
|
||||
$formXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Form xmlns="http://v8.1c.ru/8.3/xcf/logform" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
</AutoCommandBar>
|
||||
<ChildItems/>
|
||||
<Attributes>
|
||||
<Attribute name="Объект" id="1">
|
||||
<Type>
|
||||
<v8:Type>cfg:ExternalDataProcessorObject.$ProcessorName</v8:Type>
|
||||
</Type>
|
||||
<MainAttribute>true</MainAttribute>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Form>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($formXmlPath, $formXml, $encBom)
|
||||
|
||||
# --- 3. BSL-модуль (Forms/<FormName>/Ext/Form/Module.bsl) ---
|
||||
|
||||
$modulePath = Join-Path $formModuleDir "Module.bsl"
|
||||
|
||||
$moduleBsl = @"
|
||||
#Область ОбработчикиСобытийФормы
|
||||
|
||||
#КонецОбласти
|
||||
|
||||
#Область ОбработчикиСобытийЭлементовФормы
|
||||
|
||||
#КонецОбласти
|
||||
|
||||
#Область ОбработчикиКомандФормы
|
||||
|
||||
#КонецОбласти
|
||||
|
||||
#Область ОбработчикиОповещений
|
||||
|
||||
#КонецОбласти
|
||||
|
||||
#Область СлужебныеПроцедурыИФункции
|
||||
|
||||
#КонецОбласти
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($modulePath, $moduleBsl, $encBom)
|
||||
|
||||
# --- 4. Модификация корневого XML ---
|
||||
|
||||
$rootXmlFull = Resolve-Path $rootXmlPath
|
||||
$xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$xmlDoc.PreserveWhitespace = $true
|
||||
$xmlDoc.Load($rootXmlFull.Path)
|
||||
|
||||
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
|
||||
$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses")
|
||||
|
||||
$childObjects = $xmlDoc.SelectSingleNode("//md:ChildObjects", $nsMgr)
|
||||
if (-not $childObjects) {
|
||||
Write-Error "Не найден элемент ChildObjects в $rootXmlPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Добавить <Form> перед первым <Template>, или в конец
|
||||
$formElem = $xmlDoc.CreateElement("Form", "http://v8.1c.ru/8.3/MDClasses")
|
||||
$formElem.InnerText = $FormName
|
||||
|
||||
$firstTemplate = $childObjects.SelectSingleNode("md:Template", $nsMgr)
|
||||
if ($firstTemplate) {
|
||||
# Вставить перед Template, добавив перенос строки + табуляцию
|
||||
$whitespace = $xmlDoc.CreateWhitespace("`n`t`t`t")
|
||||
$childObjects.InsertBefore($whitespace, $firstTemplate) | Out-Null
|
||||
$childObjects.InsertBefore($formElem, $whitespace) | Out-Null
|
||||
} else {
|
||||
# Добавить в конец ChildObjects
|
||||
# Если ChildObjects пустой (самозакрывающийся), нужно добавить форматирование
|
||||
if ($childObjects.ChildNodes.Count -eq 0) {
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t`t")) | Out-Null
|
||||
$childObjects.AppendChild($formElem) | Out-Null
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t")) | Out-Null
|
||||
} else {
|
||||
$lastChild = $childObjects.LastChild
|
||||
# Вставить перед закрывающим whitespace (если есть), или в конец
|
||||
if ($lastChild.NodeType -eq [System.Xml.XmlNodeType]::Whitespace) {
|
||||
$childObjects.InsertBefore($xmlDoc.CreateWhitespace("`n`t`t`t"), $lastChild) | Out-Null
|
||||
$childObjects.InsertBefore($formElem, $lastChild) | Out-Null
|
||||
} else {
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t`t")) | Out-Null
|
||||
$childObjects.AppendChild($formElem) | Out-Null
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t")) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# При -Main обновить DefaultForm
|
||||
if ($Main) {
|
||||
$defaultForm = $xmlDoc.SelectSingleNode("//md:DefaultForm", $nsMgr)
|
||||
if ($defaultForm) {
|
||||
$defaultForm.InnerText = "ExternalDataProcessor.$ProcessorName.Form.$FormName"
|
||||
}
|
||||
}
|
||||
|
||||
# Сохранить с BOM
|
||||
$settings = New-Object System.Xml.XmlWriterSettings
|
||||
$settings.Encoding = $encBom
|
||||
$settings.Indent = $false # Preserve original whitespace
|
||||
|
||||
$stream = New-Object System.IO.FileStream($rootXmlFull.Path, [System.IO.FileMode]::Create)
|
||||
$writer = [System.Xml.XmlWriter]::Create($stream, $settings)
|
||||
$xmlDoc.Save($writer)
|
||||
$writer.Close()
|
||||
$stream.Close()
|
||||
|
||||
Write-Host "[OK] Создана форма: $FormName"
|
||||
Write-Host " Метаданные: $formMetaPath"
|
||||
Write-Host " Описание: $formXmlPath"
|
||||
Write-Host " Модуль: $modulePath"
|
||||
if ($Main) {
|
||||
Write-Host " DefaultForm обновлён"
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
name: epf-add-template
|
||||
description: Добавить макет к внешней обработке 1С
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-add-template — Добавление макета
|
||||
|
||||
Создаёт макет указанного типа и регистрирует его в корневом XML обработки.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-add-template <ProcessorName> <TemplateName> <TemplateType>
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|---------------|:------------:|-----------------|--------------------------------------------------|
|
||||
| ProcessorName | да | — | Имя обработки |
|
||||
| TemplateName | да | — | Имя макета |
|
||||
| TemplateType | да | — | Тип: HTML, Text, SpreadsheetDocument, BinaryData |
|
||||
| Synonym | нет | = TemplateName | Синоним макета |
|
||||
| SrcDir | нет | `src` | Каталог исходников |
|
||||
|
||||
## Команда
|
||||
|
||||
```powershell
|
||||
pwsh -NoProfile -File .claude/skills/epf-add-template/scripts/add-template.ps1 -ProcessorName "<ProcessorName>" -TemplateName "<TemplateName>" -TemplateType "<TemplateType>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"]
|
||||
```
|
||||
|
||||
## Маппинг типов
|
||||
|
||||
| Type | TemplateType | Расширение | Содержимое |
|
||||
|---------------------|----------------------|------------|-----------------------|
|
||||
| HTML | HTMLDocument | `.html` | Пустой HTML-документ |
|
||||
| Text | TextDocument | `.txt` | Пустой файл |
|
||||
| SpreadsheetDocument | SpreadsheetDocument | `.xml` | Минимальный spreadsheet |
|
||||
| BinaryData | BinaryData | `.bin` | Пустой файл |
|
||||
|
||||
## Что создаётся
|
||||
|
||||
```
|
||||
<SrcDir>/<ProcessorName>/Templates/
|
||||
├── <TemplateName>.xml # Метаданные макета (1 UUID)
|
||||
└── <TemplateName>/
|
||||
└── Ext/
|
||||
└── Template.<ext> # Содержимое макета
|
||||
```
|
||||
|
||||
## Что модифицируется
|
||||
|
||||
- `<SrcDir>/<ProcessorName>.xml` — добавляется `<Template>` в конец `ChildObjects`
|
||||
|
||||
## Спецификация
|
||||
|
||||
Подробности формата: `docs/1c-xml-format-spec.md`
|
||||
@@ -0,0 +1,166 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$ProcessorName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$TemplateName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateSet("HTML", "Text", "SpreadsheetDocument", "BinaryData")]
|
||||
[string]$TemplateType,
|
||||
|
||||
[string]$Synonym = $TemplateName,
|
||||
|
||||
[string]$SrcDir = "src"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Маппинг типов ---
|
||||
|
||||
$typeMap = @{
|
||||
"HTML" = @{ TemplateType = "HTMLDocument"; Ext = ".html" }
|
||||
"Text" = @{ TemplateType = "TextDocument"; Ext = ".txt" }
|
||||
"SpreadsheetDocument" = @{ TemplateType = "SpreadsheetDocument"; Ext = ".xml" }
|
||||
"BinaryData" = @{ TemplateType = "BinaryData"; Ext = ".bin" }
|
||||
}
|
||||
|
||||
$tmpl = $typeMap[$TemplateType]
|
||||
|
||||
# --- Проверки ---
|
||||
|
||||
$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml"
|
||||
if (-not (Test-Path $rootXmlPath)) {
|
||||
Write-Error "Корневой файл обработки не найден: $rootXmlPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$processorDir = Join-Path $SrcDir $ProcessorName
|
||||
$templatesDir = Join-Path $processorDir "Templates"
|
||||
$templateMetaPath = Join-Path $templatesDir "$TemplateName.xml"
|
||||
|
||||
if (Test-Path $templateMetaPath) {
|
||||
Write-Error "Макет уже существует: $templateMetaPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Создание каталогов ---
|
||||
|
||||
$templateExtDir = Join-Path (Join-Path $templatesDir $TemplateName) "Ext"
|
||||
New-Item -ItemType Directory -Path $templateExtDir -Force | Out-Null
|
||||
|
||||
# --- Кодировка ---
|
||||
|
||||
$encBom = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
# --- 1. Метаданные макета (Templates/<TemplateName>.xml) ---
|
||||
|
||||
$templateUuid = [guid]::NewGuid().ToString()
|
||||
|
||||
$templateMetaXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||
<Template uuid="$templateUuid">
|
||||
<Properties>
|
||||
<Name>$TemplateName</Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>$Synonym</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<TemplateType>$($tmpl.TemplateType)</TemplateType>
|
||||
</Properties>
|
||||
</Template>
|
||||
</MetaDataObject>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($templateMetaPath, $templateMetaXml, $encBom)
|
||||
|
||||
# --- 2. Содержимое макета (Templates/<TemplateName>/Ext/Template.<ext>) ---
|
||||
|
||||
$templateFilePath = Join-Path $templateExtDir "Template$($tmpl.Ext)"
|
||||
|
||||
switch ($TemplateType) {
|
||||
"HTML" {
|
||||
$content = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
[System.IO.File]::WriteAllText($templateFilePath, $content, $encBom)
|
||||
}
|
||||
"Text" {
|
||||
[System.IO.File]::WriteAllText($templateFilePath, "", $encBom)
|
||||
}
|
||||
"SpreadsheetDocument" {
|
||||
$content = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SpreadsheetDocument xmlns="http://v8.1c.ru/spreadsheet/document" xmlns:ss="http://v8.1c.ru/spreadsheet/document" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
</SpreadsheetDocument>
|
||||
"@
|
||||
[System.IO.File]::WriteAllText($templateFilePath, $content, $encBom)
|
||||
}
|
||||
"BinaryData" {
|
||||
[System.IO.File]::WriteAllBytes($templateFilePath, @())
|
||||
}
|
||||
}
|
||||
|
||||
# --- 3. Модификация корневого XML ---
|
||||
|
||||
$rootXmlFull = Resolve-Path $rootXmlPath
|
||||
$xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$xmlDoc.PreserveWhitespace = $true
|
||||
$xmlDoc.Load($rootXmlFull.Path)
|
||||
|
||||
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
|
||||
$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses")
|
||||
|
||||
$childObjects = $xmlDoc.SelectSingleNode("//md:ChildObjects", $nsMgr)
|
||||
if (-not $childObjects) {
|
||||
Write-Error "Не найден элемент ChildObjects в $rootXmlPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Добавить <Template> в конец ChildObjects
|
||||
$templateElem = $xmlDoc.CreateElement("Template", "http://v8.1c.ru/8.3/MDClasses")
|
||||
$templateElem.InnerText = $TemplateName
|
||||
|
||||
if ($childObjects.ChildNodes.Count -eq 0) {
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t`t")) | Out-Null
|
||||
$childObjects.AppendChild($templateElem) | Out-Null
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t")) | Out-Null
|
||||
} else {
|
||||
$lastChild = $childObjects.LastChild
|
||||
# Вставить перед закрывающим whitespace (если есть), или в конец
|
||||
if ($lastChild.NodeType -eq [System.Xml.XmlNodeType]::Whitespace) {
|
||||
$childObjects.InsertBefore($xmlDoc.CreateWhitespace("`n`t`t`t"), $lastChild) | Out-Null
|
||||
$childObjects.InsertBefore($templateElem, $lastChild) | Out-Null
|
||||
} else {
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t`t")) | Out-Null
|
||||
$childObjects.AppendChild($templateElem) | Out-Null
|
||||
$childObjects.AppendChild($xmlDoc.CreateWhitespace("`n`t`t")) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
# Сохранить с BOM
|
||||
$settings = New-Object System.Xml.XmlWriterSettings
|
||||
$settings.Encoding = $encBom
|
||||
$settings.Indent = $false
|
||||
|
||||
$stream = New-Object System.IO.FileStream($rootXmlFull.Path, [System.IO.FileMode]::Create)
|
||||
$writer = [System.Xml.XmlWriter]::Create($stream, $settings)
|
||||
$xmlDoc.Save($writer)
|
||||
$writer.Close()
|
||||
$stream.Close()
|
||||
|
||||
Write-Host "[OK] Создан макет: $TemplateName ($TemplateType)"
|
||||
Write-Host " Метаданные: $templateMetaPath"
|
||||
Write-Host " Содержимое: $templateFilePath"
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: epf-build
|
||||
description: Собрать внешнюю обработку 1С (EPF) из XML-исходников
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-build — Сборка обработки
|
||||
|
||||
Собирает EPF-файл из XML-исходников с помощью платформы 1С.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-build <ProcessorName> [SrcDir] [OutDir]
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|---------------|:------------:|--------------|--------------------------------------|
|
||||
| ProcessorName | да | — | Имя обработки (имя корневого XML) |
|
||||
| SrcDir | нет | `src` | Каталог исходников |
|
||||
| OutDir | нет | `build` | Каталог для результата |
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
| Переменная | Описание | Пример |
|
||||
|------------|---------------------------------------|-----------------------------------------------|
|
||||
| V8_PATH | Каталог bin платформы 1С | `C:\Program Files\1cv8\8.3.25.1257\bin` |
|
||||
| V8_BASE | Путь к пустой файловой ИБ | `.\base` |
|
||||
|
||||
## Команды
|
||||
|
||||
### 1. Создать пустую ИБ (если нет)
|
||||
|
||||
```cmd
|
||||
"%V8_PATH%\1cv8.exe" CREATEINFOBASE File="%V8_BASE%"
|
||||
```
|
||||
|
||||
### 2. Сборка EPF из XML
|
||||
|
||||
```cmd
|
||||
"%V8_PATH%\1cv8.exe" DESIGNER /F "%V8_BASE%" /DisableStartupDialogs /LoadExternalDataProcessorOrReportFromFiles "<SrcDir>\<ProcessorName>.xml" "<OutDir>\<ProcessorName>.epf" /Out "<OutDir>\build.log"
|
||||
```
|
||||
|
||||
## Коды возврата
|
||||
|
||||
| Код | Описание |
|
||||
|-----|-----------------------------|
|
||||
| 0 | Успешная сборка |
|
||||
| 1 | Ошибка (см. лог) |
|
||||
|
||||
## Автоопределение платформы (Windows)
|
||||
|
||||
Если `V8_PATH` не задан, можно найти автоматически:
|
||||
|
||||
```powershell
|
||||
$v8 = Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort-Object -Descending | Select-Object -First 1
|
||||
```
|
||||
|
||||
## Пример полного цикла
|
||||
|
||||
```powershell
|
||||
$env:V8_PATH = "C:\Program Files\1cv8\8.3.25.1257\bin"
|
||||
$env:V8_BASE = ".\base"
|
||||
|
||||
# Создать ИБ
|
||||
& "$env:V8_PATH\1cv8.exe" CREATEINFOBASE "File=$env:V8_BASE"
|
||||
|
||||
# Собрать
|
||||
& "$env:V8_PATH\1cv8.exe" DESIGNER /F $env:V8_BASE /DisableStartupDialogs /LoadExternalDataProcessorOrReportFromFiles "src\МояОбработка.xml" "build\МояОбработка.epf" /Out "build\build.log"
|
||||
```
|
||||
|
||||
## Спецификация
|
||||
|
||||
Подробности: `docs/build-spec.md`
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
name: epf-dump
|
||||
description: Разобрать EPF-файл обработки 1С в XML-исходники
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-dump — Разборка обработки
|
||||
|
||||
Разбирает EPF-файл во XML-исходники с помощью платформы 1С (иерархический формат).
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-dump <EpfFile> [OutDir]
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|----------|:------------:|--------------|-------------------------------------|
|
||||
| EpfFile | да | — | Путь к EPF-файлу |
|
||||
| OutDir | нет | `src` | Каталог для выгрузки исходников |
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
| Переменная | Описание | Пример |
|
||||
|------------|---------------------------------------|-----------------------------------------------|
|
||||
| V8_PATH | Каталог bin платформы 1С | `C:\Program Files\1cv8\8.3.25.1257\bin` |
|
||||
| V8_BASE | Путь к пустой файловой ИБ | `.\base` |
|
||||
|
||||
## Команды
|
||||
|
||||
### 1. Создать пустую ИБ (если нет)
|
||||
|
||||
```cmd
|
||||
"%V8_PATH%\1cv8.exe" CREATEINFOBASE File="%V8_BASE%"
|
||||
```
|
||||
|
||||
### 2. Разборка EPF в XML
|
||||
|
||||
```cmd
|
||||
"%V8_PATH%\1cv8.exe" DESIGNER /F "%V8_BASE%" /DisableStartupDialogs /DumpExternalDataProcessorOrReportToFiles "<OutDir>" "<EpfFile>" -Format Hierarchical /Out "<OutDir>\dump.log"
|
||||
```
|
||||
|
||||
## Коды возврата
|
||||
|
||||
| Код | Описание |
|
||||
|-----|-----------------------------|
|
||||
| 0 | Успешная разборка |
|
||||
| 1 | Ошибка (см. лог) |
|
||||
|
||||
## Формат `-Format Hierarchical`
|
||||
|
||||
Ключ `-Format Hierarchical` создаёт структуру каталогов:
|
||||
|
||||
```
|
||||
<OutDir>/
|
||||
├── <Name>.xml # Корневой файл
|
||||
└── <Name>/
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl # Модуль объекта (если есть)
|
||||
├── Forms/
|
||||
│ ├── <FormName>.xml
|
||||
│ └── <FormName>/
|
||||
│ └── Ext/
|
||||
│ ├── Form.xml
|
||||
│ └── Form/
|
||||
│ └── Module.bsl
|
||||
└── Templates/
|
||||
├── <TemplateName>.xml
|
||||
└── <TemplateName>/
|
||||
└── Ext/
|
||||
└── Template.<ext>
|
||||
```
|
||||
|
||||
## Пример полного цикла
|
||||
|
||||
```powershell
|
||||
$env:V8_PATH = "C:\Program Files\1cv8\8.3.25.1257\bin"
|
||||
$env:V8_BASE = ".\base"
|
||||
|
||||
# Создать ИБ
|
||||
& "$env:V8_PATH\1cv8.exe" CREATEINFOBASE "File=$env:V8_BASE"
|
||||
|
||||
# Разобрать
|
||||
& "$env:V8_PATH\1cv8.exe" DESIGNER /F $env:V8_BASE /DisableStartupDialogs /DumpExternalDataProcessorOrReportToFiles "src" "build\МояОбработка.epf" -Format Hierarchical /Out "build\dump.log"
|
||||
```
|
||||
|
||||
## Спецификация
|
||||
|
||||
Подробности: `docs/build-spec.md`
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: epf-init
|
||||
description: Создать пустую внешнюю обработку 1С (scaffold XML-исходников)
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-init — Создание новой обработки
|
||||
|
||||
Генерирует минимальный набор XML-исходников для внешней обработки 1С: корневой файл метаданных и каталог обработки.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-init <Name> [Synonym] [SrcDir]
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|-----------|:------------:|--------------|-------------------------------------|
|
||||
| Name | да | — | Имя обработки (латиница/кириллица) |
|
||||
| Synonym | нет | = Name | Синоним (отображаемое имя) |
|
||||
| SrcDir | нет | `src` | Каталог исходников относительно CWD |
|
||||
|
||||
## Команда
|
||||
|
||||
```powershell
|
||||
pwsh -NoProfile -File .claude/skills/epf-init/scripts/init.ps1 -Name "<Name>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"]
|
||||
```
|
||||
|
||||
## Что создаётся
|
||||
|
||||
```
|
||||
<SrcDir>/
|
||||
├── <Name>.xml # Корневой файл метаданных (4 UUID)
|
||||
└── <Name>/
|
||||
└── Ext/
|
||||
└── ObjectModule.bsl # Модуль объекта с 3 регионами
|
||||
```
|
||||
|
||||
- Корневой XML содержит `MetaDataObject/ExternalDataProcessor` с пустыми `DefaultForm` и `ChildObjects`
|
||||
- ClassId фиксирован: `c3831ec8-d8d5-4f93-8a22-f9bfae07327f`
|
||||
- Файл создаётся в UTF-8 с BOM
|
||||
|
||||
## Дальнейшие шаги
|
||||
|
||||
- Добавить форму: `/epf-add-form`
|
||||
- Добавить макет: `/epf-add-template`
|
||||
- Собрать EPF: `/epf-build`
|
||||
- Спецификация формата: `docs/1c-xml-format-spec.md`
|
||||
@@ -0,0 +1,86 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Name,
|
||||
|
||||
[string]$Synonym = $Name,
|
||||
|
||||
[string]$SrcDir = "src"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$uuid1 = [guid]::NewGuid().ToString()
|
||||
$uuid2 = [guid]::NewGuid().ToString()
|
||||
$uuid3 = [guid]::NewGuid().ToString()
|
||||
$uuid4 = [guid]::NewGuid().ToString()
|
||||
|
||||
$xml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||
<ExternalDataProcessor uuid="$uuid1">
|
||||
<InternalInfo>
|
||||
<xr:ContainedObject>
|
||||
<xr:ClassId>c3831ec8-d8d5-4f93-8a22-f9bfae07327f</xr:ClassId>
|
||||
<xr:ObjectId>$uuid2</xr:ObjectId>
|
||||
</xr:ContainedObject>
|
||||
<xr:GeneratedType name="ExternalDataProcessorObject.$Name" category="Object">
|
||||
<xr:TypeId>$uuid3</xr:TypeId>
|
||||
<xr:ValueId>$uuid4</xr:ValueId>
|
||||
</xr:GeneratedType>
|
||||
</InternalInfo>
|
||||
<Properties>
|
||||
<Name>$Name</Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>$Synonym</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<DefaultForm/>
|
||||
<AuxiliaryForm/>
|
||||
</Properties>
|
||||
<ChildObjects/>
|
||||
</ExternalDataProcessor>
|
||||
</MetaDataObject>
|
||||
"@
|
||||
|
||||
$rootFile = Join-Path $SrcDir "$Name.xml"
|
||||
$processorDir = Join-Path $SrcDir $Name
|
||||
|
||||
if (Test-Path $rootFile) {
|
||||
Write-Error "Файл уже существует: $rootFile"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (-not (Test-Path $SrcDir)) {
|
||||
New-Item -ItemType Directory -Path $SrcDir -Force | Out-Null
|
||||
}
|
||||
$extDir = Join-Path $processorDir "Ext"
|
||||
New-Item -ItemType Directory -Path $extDir -Force | Out-Null
|
||||
|
||||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||||
[System.IO.File]::WriteAllText((Resolve-Path $SrcDir | Join-Path -ChildPath "$Name.xml"), $xml, $enc)
|
||||
|
||||
# --- Модуль объекта ---
|
||||
|
||||
$moduleBsl = @"
|
||||
#Область ОписаниеПеременных
|
||||
|
||||
#КонецОбласти
|
||||
|
||||
#Область ПрограммныйИнтерфейс
|
||||
|
||||
#КонецОбласти
|
||||
|
||||
#Область СлужебныеПроцедурыИФункции
|
||||
|
||||
#КонецОбласти
|
||||
"@
|
||||
|
||||
$modulePath = Join-Path $extDir "ObjectModule.bsl"
|
||||
[System.IO.File]::WriteAllText($modulePath, $moduleBsl, $enc)
|
||||
|
||||
Write-Host "[OK] Создана обработка: $rootFile"
|
||||
Write-Host " Каталог: $processorDir"
|
||||
Write-Host " Модуль: $modulePath"
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
name: epf-remove-form
|
||||
description: Удалить форму из внешней обработки 1С
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-remove-form — Удаление формы
|
||||
|
||||
Удаляет форму и убирает её регистрацию из корневого XML обработки.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-remove-form <ProcessorName> <FormName>
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|---------------|:------------:|--------------|-------------------------------------|
|
||||
| ProcessorName | да | — | Имя обработки |
|
||||
| FormName | да | — | Имя формы для удаления |
|
||||
| SrcDir | нет | `src` | Каталог исходников |
|
||||
|
||||
## Команда
|
||||
|
||||
```powershell
|
||||
pwsh -NoProfile -File .claude/skills/epf-remove-form/scripts/remove-form.ps1 -ProcessorName "<ProcessorName>" -FormName "<FormName>" [-SrcDir "<SrcDir>"]
|
||||
```
|
||||
|
||||
## Что удаляется
|
||||
|
||||
```
|
||||
<SrcDir>/<ProcessorName>/Forms/<FormName>.xml # Метаданные формы
|
||||
<SrcDir>/<ProcessorName>/Forms/<FormName>/ # Каталог формы (рекурсивно)
|
||||
```
|
||||
|
||||
## Что модифицируется
|
||||
|
||||
- `<SrcDir>/<ProcessorName>.xml` — убирается `<Form>` из `ChildObjects`
|
||||
- Если удаляемая форма была DefaultForm — очищается значение DefaultForm
|
||||
|
||||
## Спецификация
|
||||
|
||||
Подробности формата: `docs/1c-xml-format-spec.md`
|
||||
@@ -0,0 +1,84 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$ProcessorName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$FormName,
|
||||
|
||||
[string]$SrcDir = "src"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Проверки ---
|
||||
|
||||
$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml"
|
||||
if (-not (Test-Path $rootXmlPath)) {
|
||||
Write-Error "Корневой файл обработки не найден: $rootXmlPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$processorDir = Join-Path $SrcDir $ProcessorName
|
||||
$formsDir = Join-Path $processorDir "Forms"
|
||||
$formMetaPath = Join-Path $formsDir "$FormName.xml"
|
||||
$formDir = Join-Path $formsDir $FormName
|
||||
|
||||
if (-not (Test-Path $formMetaPath)) {
|
||||
Write-Error "Метаданные формы не найдены: $formMetaPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Удаление файлов ---
|
||||
|
||||
if (Test-Path $formDir) {
|
||||
Remove-Item -Path $formDir -Recurse -Force
|
||||
Write-Host "[OK] Удалён каталог: $formDir"
|
||||
}
|
||||
|
||||
Remove-Item -Path $formMetaPath -Force
|
||||
Write-Host "[OK] Удалён файл: $formMetaPath"
|
||||
|
||||
# --- Модификация корневого XML ---
|
||||
|
||||
$rootXmlFull = Resolve-Path $rootXmlPath
|
||||
$xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$xmlDoc.PreserveWhitespace = $true
|
||||
$xmlDoc.Load($rootXmlFull.Path)
|
||||
|
||||
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
|
||||
$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses")
|
||||
|
||||
# Удалить <Form>FormName</Form> из ChildObjects
|
||||
$formNodes = $xmlDoc.SelectNodes("//md:ChildObjects/md:Form", $nsMgr)
|
||||
foreach ($node in $formNodes) {
|
||||
if ($node.InnerText -eq $FormName) {
|
||||
$parent = $node.ParentNode
|
||||
# Удалить предшествующий whitespace
|
||||
$prev = $node.PreviousSibling
|
||||
if ($prev -and $prev.NodeType -eq [System.Xml.XmlNodeType]::Whitespace) {
|
||||
$parent.RemoveChild($prev) | Out-Null
|
||||
}
|
||||
$parent.RemoveChild($node) | Out-Null
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# Очистить DefaultForm если указывала на эту форму
|
||||
$defaultForm = $xmlDoc.SelectSingleNode("//md:DefaultForm", $nsMgr)
|
||||
if ($defaultForm -and $defaultForm.InnerText -match "Form\.$FormName$") {
|
||||
$defaultForm.InnerText = ""
|
||||
}
|
||||
|
||||
# Сохранить с BOM
|
||||
$encBom = New-Object System.Text.UTF8Encoding($true)
|
||||
$settings = New-Object System.Xml.XmlWriterSettings
|
||||
$settings.Encoding = $encBom
|
||||
$settings.Indent = $false
|
||||
|
||||
$stream = New-Object System.IO.FileStream($rootXmlFull.Path, [System.IO.FileMode]::Create)
|
||||
$writer = [System.Xml.XmlWriter]::Create($stream, $settings)
|
||||
$xmlDoc.Save($writer)
|
||||
$writer.Close()
|
||||
$stream.Close()
|
||||
|
||||
Write-Host "[OK] Форма $FormName удалена из $rootXmlPath"
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: epf-remove-template
|
||||
description: Удалить макет из внешней обработки 1С
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# /epf-remove-template — Удаление макета
|
||||
|
||||
Удаляет макет и убирает его регистрацию из корневого XML обработки.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/epf-remove-template <ProcessorName> <TemplateName>
|
||||
```
|
||||
|
||||
| Параметр | Обязательный | По умолчанию | Описание |
|
||||
|---------------|:------------:|--------------|-------------------------------------|
|
||||
| ProcessorName | да | — | Имя обработки |
|
||||
| TemplateName | да | — | Имя макета для удаления |
|
||||
| SrcDir | нет | `src` | Каталог исходников |
|
||||
|
||||
## Команда
|
||||
|
||||
```powershell
|
||||
pwsh -NoProfile -File .claude/skills/epf-remove-template/scripts/remove-template.ps1 -ProcessorName "<ProcessorName>" -TemplateName "<TemplateName>" [-SrcDir "<SrcDir>"]
|
||||
```
|
||||
|
||||
## Что удаляется
|
||||
|
||||
```
|
||||
<SrcDir>/<ProcessorName>/Templates/<TemplateName>.xml # Метаданные макета
|
||||
<SrcDir>/<ProcessorName>/Templates/<TemplateName>/ # Каталог макета (рекурсивно)
|
||||
```
|
||||
|
||||
## Что модифицируется
|
||||
|
||||
- `<SrcDir>/<ProcessorName>.xml` — убирается `<Template>` из `ChildObjects`
|
||||
|
||||
## Спецификация
|
||||
|
||||
Подробности формата: `docs/1c-xml-format-spec.md`
|
||||
@@ -0,0 +1,78 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$ProcessorName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$TemplateName,
|
||||
|
||||
[string]$SrcDir = "src"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Проверки ---
|
||||
|
||||
$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml"
|
||||
if (-not (Test-Path $rootXmlPath)) {
|
||||
Write-Error "Корневой файл обработки не найден: $rootXmlPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$processorDir = Join-Path $SrcDir $ProcessorName
|
||||
$templatesDir = Join-Path $processorDir "Templates"
|
||||
$templateMetaPath = Join-Path $templatesDir "$TemplateName.xml"
|
||||
$templateDir = Join-Path $templatesDir $TemplateName
|
||||
|
||||
if (-not (Test-Path $templateMetaPath)) {
|
||||
Write-Error "Метаданные макета не найдены: $templateMetaPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Удаление файлов ---
|
||||
|
||||
if (Test-Path $templateDir) {
|
||||
Remove-Item -Path $templateDir -Recurse -Force
|
||||
Write-Host "[OK] Удалён каталог: $templateDir"
|
||||
}
|
||||
|
||||
Remove-Item -Path $templateMetaPath -Force
|
||||
Write-Host "[OK] Удалён файл: $templateMetaPath"
|
||||
|
||||
# --- Модификация корневого XML ---
|
||||
|
||||
$rootXmlFull = Resolve-Path $rootXmlPath
|
||||
$xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$xmlDoc.PreserveWhitespace = $true
|
||||
$xmlDoc.Load($rootXmlFull.Path)
|
||||
|
||||
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
|
||||
$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses")
|
||||
|
||||
# Удалить <Template>TemplateName</Template> из ChildObjects
|
||||
$templateNodes = $xmlDoc.SelectNodes("//md:ChildObjects/md:Template", $nsMgr)
|
||||
foreach ($node in $templateNodes) {
|
||||
if ($node.InnerText -eq $TemplateName) {
|
||||
$parent = $node.ParentNode
|
||||
# Удалить предшествующий whitespace
|
||||
$prev = $node.PreviousSibling
|
||||
if ($prev -and $prev.NodeType -eq [System.Xml.XmlNodeType]::Whitespace) {
|
||||
$parent.RemoveChild($prev) | Out-Null
|
||||
}
|
||||
$parent.RemoveChild($node) | Out-Null
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# Сохранить с BOM
|
||||
$encBom = New-Object System.Text.UTF8Encoding($true)
|
||||
$settings = New-Object System.Xml.XmlWriterSettings
|
||||
$settings.Encoding = $encBom
|
||||
$settings.Indent = $false
|
||||
|
||||
$stream = New-Object System.IO.FileStream($rootXmlFull.Path, [System.IO.FileMode]::Create)
|
||||
$writer = [System.Xml.XmlWriter]::Create($stream, $settings)
|
||||
$xmlDoc.Save($writer)
|
||||
$writer.Close()
|
||||
$stream.Close()
|
||||
|
||||
Write-Host "[OK] Макет $TemplateName удалён из $rootXmlPath"
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Реальные выгрузки обработок (примеры, не для версионирования)
|
||||
upload/
|
||||
|
||||
# Результаты сборки
|
||||
build/
|
||||
base/
|
||||
*.epf
|
||||
*.log
|
||||
|
||||
# Временные файлы тестов
|
||||
test-tmp/
|
||||
@@ -0,0 +1,90 @@
|
||||
# 1C EPF Skills for Claude Code
|
||||
|
||||
Набор [Claude Code Skills](https://docs.anthropic.com/en/docs/claude-code/skills) для работы с исходниками внешних обработок 1С:Предприятия 8.3. Позволяет создавать, модифицировать и собирать обработки (`.epf`) из XML-исходников, не запоминая детали формата.
|
||||
|
||||
## Навыки
|
||||
|
||||
| Навык | Описание |
|
||||
|-------|----------|
|
||||
| `/epf-init` | Создать новую обработку (корневой XML + модуль объекта) |
|
||||
| `/epf-add-form` | Добавить управляемую форму |
|
||||
| `/epf-add-template` | Добавить макет (HTML, Text, SpreadsheetDocument, BinaryData) |
|
||||
| `/epf-remove-form` | Удалить форму |
|
||||
| `/epf-remove-template` | Удалить макет |
|
||||
| `/epf-build` | Собрать EPF из XML (документация команды 1cv8.exe) |
|
||||
| `/epf-dump` | Разобрать EPF в XML (документация команды 1cv8.exe) |
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
```
|
||||
> /epf-init МояОбработка "Моя обработка"
|
||||
> /epf-add-form МояОбработка Форма --main
|
||||
> /epf-add-template МояОбработка Макет HTML
|
||||
> /epf-build МояОбработка
|
||||
```
|
||||
|
||||
После `/epf-init` создаётся структура:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МояОбработка.xml # Корневой файл метаданных
|
||||
└── МояОбработка/
|
||||
└── Ext/
|
||||
└── ObjectModule.bsl # Модуль объекта
|
||||
```
|
||||
|
||||
После `/epf-add-form` и `/epf-add-template`:
|
||||
|
||||
```
|
||||
src/
|
||||
├── МояОбработка.xml
|
||||
└── МояОбработка/
|
||||
├── Ext/
|
||||
│ └── ObjectModule.bsl
|
||||
├── Forms/
|
||||
│ ├── Форма.xml # Метаданные формы
|
||||
│ └── Форма/
|
||||
│ └── Ext/
|
||||
│ ├── Form.xml # Описание формы
|
||||
│ └── Form/
|
||||
│ └── Module.bsl # Модуль формы
|
||||
└── Templates/
|
||||
├── Макет.xml # Метаданные макета
|
||||
└── Макет/
|
||||
└── Ext/
|
||||
└── Template.html # Содержимое макета
|
||||
```
|
||||
|
||||
## Требования
|
||||
|
||||
- **Windows** с PowerShell 5.1+ (входит в Windows)
|
||||
- **1С:Предприятие 8.3** — для сборки/разборки EPF (навыки генерации XML работают без платформы)
|
||||
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
.claude/skills/ # Навыки Claude Code
|
||||
├── epf-init/ # SKILL.md + scripts/init.ps1
|
||||
├── epf-add-form/ # SKILL.md + scripts/add-form.ps1
|
||||
├── epf-add-template/ # SKILL.md + scripts/add-template.ps1
|
||||
├── epf-remove-form/ # SKILL.md + scripts/remove-form.ps1
|
||||
├── epf-remove-template/ # SKILL.md + scripts/remove-template.ps1
|
||||
├── epf-build/ # SKILL.md (только документация)
|
||||
└── epf-dump/ # SKILL.md (только документация)
|
||||
docs/
|
||||
├── 1c-xml-format-spec.md # Спецификация XML-формата выгрузки
|
||||
└── build-spec.md # Спецификация команд сборки/разборки
|
||||
```
|
||||
|
||||
## Спецификации
|
||||
|
||||
- [XML-формат выгрузки обработок](docs/1c-xml-format-spec.md) — полное описание структуры XML-файлов, namespace'ов, элементов форм
|
||||
- [Сборка и разборка EPF](docs/build-spec.md) — команды `1cv8.exe`, параметры, коды возврата
|
||||
|
||||
## Технические детали
|
||||
|
||||
- Все XML-файлы создаются в **UTF-8 с BOM** (как в реальных выгрузках 1С)
|
||||
- PowerShell-скрипты используют `System.Xml.XmlDocument` для модификации корневого XML
|
||||
- UUID генерируются через `[guid]::NewGuid()`
|
||||
- ClassId обработки фиксирован: `c3831ec8-d8d5-4f93-8a22-f9bfae07327f`
|
||||
- Порядок элементов в `ChildObjects`: TabularSections → Forms → Templates
|
||||
@@ -0,0 +1,655 @@
|
||||
# Спецификация XML-формата выгрузки внешней обработки 1С
|
||||
|
||||
Формат: XML-выгрузка внешней обработки (ExternalDataProcessor) из конфигуратора 1С:Предприятие 8.3.
|
||||
Версия формата: `2.17`.
|
||||
|
||||
## 1. Структура каталогов
|
||||
|
||||
```
|
||||
<ИмяОбработки>.xml # Корневой файл метаданных
|
||||
<ИмяОбработки>/
|
||||
Ext/
|
||||
ObjectModule.bsl # Модуль объекта (опционально)
|
||||
Forms/
|
||||
<ИмяФормы>.xml # Метаданные формы
|
||||
<ИмяФормы>/
|
||||
Ext/
|
||||
Form.xml # Описание формы (элементы, реквизиты, команды)
|
||||
Form/
|
||||
Module.bsl # Модуль формы
|
||||
Templates/
|
||||
<ИмяМакета>.xml # Метаданные макета
|
||||
<ИмяМакета>/
|
||||
Ext/
|
||||
Template.<расш> # Тело макета: .html, .xml (mxl) и др.
|
||||
```
|
||||
|
||||
Обработка может содержать:
|
||||
- 0..N форм (каталог `Forms/`)
|
||||
- 0..N макетов (каталог `Templates/`)
|
||||
- 0..1 модуль объекта (`Ext/ObjectModule.bsl`)
|
||||
- 0..N табличных частей (описаны в корневом XML)
|
||||
|
||||
## 2. Пространства имён XML
|
||||
|
||||
### 2.1. Файлы метаданных (корневой XML, формы, макеты)
|
||||
|
||||
Корневой элемент — `<MetaDataObject>`, пространство имён:
|
||||
|
||||
```
|
||||
xmlns="http://v8.1c.ru/8.3/MDClasses"
|
||||
```
|
||||
|
||||
Полный набор деклараций (можно копировать как есть):
|
||||
|
||||
```xml
|
||||
<MetaDataObject
|
||||
xmlns="http://v8.1c.ru/8.3/MDClasses"
|
||||
xmlns:app="http://v8.1c.ru/8.2/managed-application/core"
|
||||
xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config"
|
||||
xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi"
|
||||
xmlns:ent="http://v8.1c.ru/8.1/data/enterprise"
|
||||
xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform"
|
||||
xmlns:style="http://v8.1c.ru/8.1/data/ui/style"
|
||||
xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system"
|
||||
xmlns:v8="http://v8.1c.ru/8.1/data/core"
|
||||
xmlns:v8ui="http://v8.1c.ru/8.1/data/ui"
|
||||
xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web"
|
||||
xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows"
|
||||
xmlns:xen="http://v8.1c.ru/8.3/xcf/enums"
|
||||
xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef"
|
||||
xmlns:xr="http://v8.1c.ru/8.3/xcf/readable"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
version="2.17">
|
||||
```
|
||||
|
||||
### 2.2. Описание формы (Form.xml)
|
||||
|
||||
Корневой элемент — `<Form>`, пространство имён:
|
||||
|
||||
```
|
||||
xmlns="http://v8.1c.ru/8.3/xcf/logform"
|
||||
```
|
||||
|
||||
Полный набор деклараций:
|
||||
|
||||
```xml
|
||||
<Form
|
||||
xmlns="http://v8.1c.ru/8.3/xcf/logform"
|
||||
xmlns:app="http://v8.1c.ru/8.2/managed-application/core"
|
||||
xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config"
|
||||
xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core"
|
||||
xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings"
|
||||
xmlns:ent="http://v8.1c.ru/8.1/data/enterprise"
|
||||
xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform"
|
||||
xmlns:style="http://v8.1c.ru/8.1/data/ui/style"
|
||||
xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system"
|
||||
xmlns:v8="http://v8.1c.ru/8.1/data/core"
|
||||
xmlns:v8ui="http://v8.1c.ru/8.1/data/ui"
|
||||
xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web"
|
||||
xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows"
|
||||
xmlns:xr="http://v8.1c.ru/8.3/xcf/readable"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
version="2.17">
|
||||
```
|
||||
|
||||
**Ключевое отличие**: файлы метаданных используют `http://v8.1c.ru/8.3/MDClasses`, описание формы — `http://v8.1c.ru/8.3/xcf/logform`.
|
||||
|
||||
## 3. Корневой файл обработки (`<Имя>.xml`)
|
||||
|
||||
Определяет имя обработки, синоним, форму по умолчанию и список дочерних объектов.
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="..." version="2.17">
|
||||
<ExternalDataProcessor uuid="<UUID>">
|
||||
<InternalInfo>
|
||||
<xr:ContainedObject>
|
||||
<xr:ClassId>c3831ec8-d8d5-4f93-8a22-f9bfae07327f</xr:ClassId>
|
||||
<xr:ObjectId><UUID></xr:ObjectId>
|
||||
</xr:ContainedObject>
|
||||
<xr:GeneratedType name="ExternalDataProcessorObject.<Имя>" category="Object">
|
||||
<xr:TypeId><UUID></xr:TypeId>
|
||||
<xr:ValueId><UUID></xr:ValueId>
|
||||
</xr:GeneratedType>
|
||||
</InternalInfo>
|
||||
<Properties>
|
||||
<Name><Имя></Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content><Представление></v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<DefaultForm>ExternalDataProcessor.<Имя>.Form.<ИмяФормы></DefaultForm>
|
||||
<AuxiliaryForm/>
|
||||
</Properties>
|
||||
<ChildObjects>
|
||||
<!-- Табличные части (опционально) -->
|
||||
<TabularSection uuid="<UUID>">...</TabularSection>
|
||||
<!-- Формы -->
|
||||
<Form><ИмяФормы></Form>
|
||||
<!-- Макеты -->
|
||||
<Template><ИмяМакета></Template>
|
||||
</ChildObjects>
|
||||
</ExternalDataProcessor>
|
||||
</MetaDataObject>
|
||||
```
|
||||
|
||||
### Правила
|
||||
|
||||
| Элемент | Описание |
|
||||
|---------|----------|
|
||||
| `ClassId` | Всегда `c3831ec8-d8d5-4f93-8a22-f9bfae07327f` (идентификатор класса ExternalDataProcessor) |
|
||||
| `ObjectId`, `TypeId`, `ValueId` | Уникальные UUID, генерируются при создании |
|
||||
| `DefaultForm` | Полный путь: `ExternalDataProcessor.<Имя>.Form.<ИмяФормы>` |
|
||||
| `<Form>`, `<Template>` | Только имена (без путей), соответствуют именам подкаталогов в `Forms/` и `Templates/` |
|
||||
| `<TabularSection>` | Полное описание табличных частей объекта (включая реквизиты ТЧ с типами) |
|
||||
|
||||
### Табличные части объекта
|
||||
|
||||
Если обработка имеет табличные части, они описываются в `<ChildObjects>` корневого файла:
|
||||
|
||||
```xml
|
||||
<TabularSection uuid="<UUID>">
|
||||
<InternalInfo>
|
||||
<xr:GeneratedType name="DataProcessorTabularSection.<ИмяОбработки>.<ИмяТЧ>" category="TabularSection">
|
||||
<xr:TypeId><UUID></xr:TypeId>
|
||||
<xr:ValueId><UUID></xr:ValueId>
|
||||
</xr:GeneratedType>
|
||||
<xr:GeneratedType name="DataProcessorTabularSectionRow.<ИмяОбработки>.<ИмяТЧ>" category="TabularSectionRow">
|
||||
<xr:TypeId><UUID></xr:TypeId>
|
||||
<xr:ValueId><UUID></xr:ValueId>
|
||||
</xr:GeneratedType>
|
||||
</InternalInfo>
|
||||
<Properties>
|
||||
<Name><ИмяТЧ></Name>
|
||||
<Synonym>...</Synonym>
|
||||
<Comment/>
|
||||
<ToolTip/>
|
||||
<FillChecking>DontCheck</FillChecking>
|
||||
<StandardAttributes>
|
||||
<xr:StandardAttribute name="LineNumber">
|
||||
<!-- Стандартные свойства реквизита -->
|
||||
</xr:StandardAttribute>
|
||||
</StandardAttributes>
|
||||
</Properties>
|
||||
<ChildObjects>
|
||||
<Attribute uuid="<UUID>">
|
||||
<Properties>
|
||||
<Name><ИмяРеквизита></Name>
|
||||
<Type>...</Type>
|
||||
<!-- Остальные свойства -->
|
||||
</Properties>
|
||||
</Attribute>
|
||||
</ChildObjects>
|
||||
</TabularSection>
|
||||
```
|
||||
|
||||
## 4. Метаданные формы (`Forms/<Имя>.xml`)
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="..." version="2.17">
|
||||
<Form uuid="<UUID>">
|
||||
<Properties>
|
||||
<Name><ИмяФормы></Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content><Представление></v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<FormType>Managed</FormType>
|
||||
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||
<UsePurposes>
|
||||
<v8:Value xsi:type="app:ApplicationUsePurpose">PlatformApplication</v8:Value>
|
||||
</UsePurposes>
|
||||
<ExtendedPresentation/>
|
||||
</Properties>
|
||||
</Form>
|
||||
</MetaDataObject>
|
||||
```
|
||||
|
||||
`FormType` — всегда `Managed` для управляемых форм.
|
||||
|
||||
## 5. Метаданные макета (`Templates/<Имя>.xml`)
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="..." version="2.17">
|
||||
<Template uuid="<UUID>">
|
||||
<Properties>
|
||||
<Name><ИмяМакета></Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content><Представление></v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<TemplateType><ТипМакета></TemplateType>
|
||||
</Properties>
|
||||
</Template>
|
||||
</MetaDataObject>
|
||||
```
|
||||
|
||||
### Типы макетов
|
||||
|
||||
| Значение `TemplateType` | Расширение файла тела | Описание |
|
||||
|---|---|---|
|
||||
| `SpreadsheetDocument` | `.xml` | Табличный документ (MXL в XML) |
|
||||
| `HTMLDocument` | `.html` | HTML-документ |
|
||||
| `TextDocument` | `.txt` | Текстовый документ |
|
||||
| `BinaryData` | `.bin` | Двоичные данные |
|
||||
| `ActiveDocument` | `.xml` | Активный документ |
|
||||
|
||||
## 6. Описание формы (`Form.xml`)
|
||||
|
||||
Самый сложный файл. Содержит три корневых секции:
|
||||
- `<ChildItems>` — дерево элементов формы (визуальная структура)
|
||||
- `<Attributes>` — реквизиты формы (данные)
|
||||
- `<Commands>` — команды формы
|
||||
|
||||
### 6.1. Общая структура
|
||||
|
||||
```xml
|
||||
<Form xmlns="http://v8.1c.ru/8.3/xcf/logform" ... version="2.17">
|
||||
<Title>...</Title>
|
||||
<AutoTitle>false</AutoTitle>
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>false</Autofill>
|
||||
</AutoCommandBar>
|
||||
<Events>
|
||||
<Event name="OnCreateAtServer">ПриСозданииНаСервере</Event>
|
||||
</Events>
|
||||
<ChildItems>
|
||||
<!-- Элементы формы -->
|
||||
</ChildItems>
|
||||
<Attributes>
|
||||
<!-- Реквизиты формы -->
|
||||
</Attributes>
|
||||
<Commands>
|
||||
<!-- Команды формы -->
|
||||
</Commands>
|
||||
</Form>
|
||||
```
|
||||
|
||||
### 6.2. Идентификаторы (id)
|
||||
|
||||
- Каждый элемент, реквизит и команда имеет уникальный `id` (целое число).
|
||||
- `id` уникален в пределах своей секции: элементы, реквизиты и команды нумеруются независимо.
|
||||
- `id="-1"` зарезервирован для `AutoCommandBar` формы.
|
||||
- `id` колонок (`Column`) — уникальны в пределах своего реквизита.
|
||||
|
||||
### 6.3. Элементы формы (`<ChildItems>`)
|
||||
|
||||
#### Типы элементов
|
||||
|
||||
| XML-тег | Описание | Ключевые свойства |
|
||||
|---------|----------|-------------------|
|
||||
| `UsualGroup` | Обычная группа | `Group` (Vertical/Horizontal), `Representation`, `ShowTitle` |
|
||||
| `Button` | Кнопка | `Type` (UsualButton/CommandBarButton), `CommandName` |
|
||||
| `InputField` | Поле ввода | `DataPath`, `MinValue`, `MaxValue` |
|
||||
| `CheckBoxField` | Флажок | `DataPath`, `CheckBoxType`, `ThreeState`, `ReadOnly` |
|
||||
| `LabelField` | Поле надписи | `DataPath` (только отображение) |
|
||||
| `LabelDecoration` | Декорация-надпись | `Title` (статический текст) |
|
||||
| `FormTree` | Дерево формы | `DataPath`, `Header`, `RowPictureDataPath` |
|
||||
| `Table` | Таблица формы | `DataPath`, `Representation` (List/Tree), `ChangeRowSet` |
|
||||
| `HTMLDocumentField` | Поле HTML-документа | `DataPath` |
|
||||
| `CommandBar` | Командная панель (внутри элемента) | `Autofill` |
|
||||
| `Popup` | Подменю на командной панели | `Title`, `Picture` |
|
||||
|
||||
#### Правила DataPath
|
||||
|
||||
- Простые реквизиты: `DataPath` = имя реквизита формы. Пример: `<DataPath>СтрокаПоиска</DataPath>`
|
||||
- Колонки таблицы/дерева (реквизит формы): `<ИмяРеквизита>.<ИмяКолонки>`. Пример: `<DataPath>ТаблицаРеквизитов.Пометка</DataPath>`
|
||||
- Табличные части объекта: `Объект.<ИмяТЧ>.<ИмяРеквизита>`. Пример: `<DataPath>Объект.ТЧМетаданные.Флаг</DataPath>`
|
||||
|
||||
#### ExtendedTooltip
|
||||
|
||||
Каждый элемент формы **должен** иметь дочерний `<ExtendedTooltip>`. Минимальная форма:
|
||||
|
||||
```xml
|
||||
<ExtendedTooltip name="<ИмяЭлемента>ExtendedTooltip" id="<ID>"/>
|
||||
```
|
||||
|
||||
Имя: `<ИмяРодительскогоЭлемента>ExtendedTooltip`. Может содержать `<Title>` с текстом подсказки.
|
||||
|
||||
#### ContextMenu
|
||||
|
||||
Элементы, поддерживающие контекстное меню (`InputField`, `CheckBoxField`, `LabelField`, `FormTree`, `Table`, `HTMLDocumentField`), **должны** иметь:
|
||||
|
||||
```xml
|
||||
<ContextMenu name="<ИмяЭлемента>КонтекстноеМеню" id="<ID>"/>
|
||||
```
|
||||
|
||||
#### Пример: группа с кнопками
|
||||
|
||||
```xml
|
||||
<UsualGroup name="ГруппаКоманд" id="1">
|
||||
<Title><v8:item><v8:lang>ru</v8:lang><v8:content>Команды</v8:content></v8:item></Title>
|
||||
<Representation>None</Representation>
|
||||
<ShowTitle>false</ShowTitle>
|
||||
<ExtendedTooltip name="ГруппаКомандExtendedTooltip" id="100"/>
|
||||
<ChildItems>
|
||||
<Button name="КнопкаПостроить" id="2">
|
||||
<Type>UsualButton</Type>
|
||||
<Title>...</Title>
|
||||
<CommandName>Form.Command.Построить</CommandName>
|
||||
<ExtendedTooltip name="КнопкаПостроитьExtendedTooltip" id="101"/>
|
||||
</Button>
|
||||
</ChildItems>
|
||||
</UsualGroup>
|
||||
```
|
||||
|
||||
#### Пример: FormTree (дерево)
|
||||
|
||||
```xml
|
||||
<FormTree name="ДеревоМетаданных" id="11">
|
||||
<DataPath>ДеревоМетаданных</DataPath>
|
||||
<TitleLocation>None</TitleLocation>
|
||||
<ContextMenu name="ДеревоМетаданныхКонтекстноеМеню" id="12"/>
|
||||
<ExtendedTooltip name="ДеревоМетаданныхExtendedTooltip" id="108"/>
|
||||
<CommandBar name="ДеревоМетаданныхКоманднаяПанель" id="13">
|
||||
<Autofill>false</Autofill>
|
||||
<ExtendedTooltip name="ДеревоМетаданныхКоманднаяПанельExtendedTooltip" id="109"/>
|
||||
</CommandBar>
|
||||
<Header>false</Header>
|
||||
<RowPictureDataPath>ДеревоМетаданных.ИндексКартинки</RowPictureDataPath>
|
||||
<Events>
|
||||
<Event name="OnActivateRow">ДеревоМетаданныхПриАктивизацииСтроки</Event>
|
||||
</Events>
|
||||
<ChildItems>
|
||||
<!-- Колонки как дочерние элементы -->
|
||||
<CheckBoxField name="ДеревоМетаданныхПометка" id="14">
|
||||
<DataPath>ДеревоМетаданных.Пометка</DataPath>
|
||||
...
|
||||
</CheckBoxField>
|
||||
</ChildItems>
|
||||
</FormTree>
|
||||
```
|
||||
|
||||
#### Пример: Table (таблица, привязанная к реквизиту формы типа ValueTable)
|
||||
|
||||
```xml
|
||||
<Table name="ТаблицаРеквизитов" id="26">
|
||||
<DataPath>ТаблицаРеквизитов</DataPath>
|
||||
<TitleLocation>None</TitleLocation>
|
||||
<ContextMenu name="ТаблицаРеквизитовКонтекстноеМеню" id="27"/>
|
||||
<ExtendedTooltip name="ТаблицаРеквизитовExtendedTooltip" id="119"/>
|
||||
<CommandBar name="ТаблицаРеквизитовКоманднаяПанель" id="28">
|
||||
<Autofill>false</Autofill>
|
||||
<ExtendedTooltip name="ТаблицаРеквизитовКоманднаяПанельExtendedTooltip" id="120"/>
|
||||
</CommandBar>
|
||||
<ChangeRowSet>false</ChangeRowSet>
|
||||
<ChangeRowOrder>false</ChangeRowOrder>
|
||||
<ChildItems>
|
||||
<CheckBoxField name="ТаблицаРеквизитовПометка" id="29">
|
||||
<DataPath>ТаблицаРеквизитов.Пометка</DataPath>
|
||||
...
|
||||
</CheckBoxField>
|
||||
</ChildItems>
|
||||
</Table>
|
||||
```
|
||||
|
||||
#### Table: режим дерева
|
||||
|
||||
Элемент `Table` может отображать данные как дерево через `<Representation>Tree</Representation>`. В этом случае реквизит формы должен иметь тип `v8:ValueTree`.
|
||||
|
||||
```xml
|
||||
<Table name="ДеревоМетаданных" id="238">
|
||||
<Representation>Tree</Representation>
|
||||
<DataPath>ДеревоМетаданных</DataPath>
|
||||
...
|
||||
</Table>
|
||||
```
|
||||
|
||||
> **Примечание**: Элемент `FormTree` — альтернативный способ отобразить дерево. `FormTree` не требует явного указания `<Representation>`, дерево подразумевается. `Table` с `<Representation>Tree</Representation>` — более полный элемент с дополнительными возможностями (SearchStringAddition, ViewStatusAddition и др.).
|
||||
|
||||
#### Table: привязка к ТЧ объекта vs реквизит формы
|
||||
|
||||
| Источник данных | DataPath таблицы | DataPath колонки | Тип реквизита |
|
||||
|---|---|---|---|
|
||||
| Табличная часть объекта | `Объект.<ИмяТЧ>` | `Объект.<ИмяТЧ>.<ИмяРеквизита>` | (определён в корневом XML) |
|
||||
| Реквизит формы (ValueTable) | `<ИмяРеквизита>` | `<ИмяРеквизита>.<ИмяКолонки>` | `v8:ValueTable` |
|
||||
| Реквизит формы (ValueTree) | `<ИмяРеквизита>` | `<ИмяРеквизита>.<ИмяКолонки>` | `v8:ValueTree` |
|
||||
|
||||
### 6.4. Реквизиты формы (`<Attributes>`)
|
||||
|
||||
#### Примитивные типы
|
||||
|
||||
```xml
|
||||
<Attribute name="СтрокаПоиска" id="18">
|
||||
<Title><v8:item><v8:lang>ru</v8:lang><v8:content>Строка поиска</v8:content></v8:item></Title>
|
||||
<Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>200</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
#### Таблица типов
|
||||
|
||||
| v8:Type | Описание | Квалификаторы |
|
||||
|---------|----------|---------------|
|
||||
| `xs:string` | Строка | `v8:StringQualifiers`: `Length` (0 = неограниченная), `AllowedLength` (Variable/Fixed) |
|
||||
| `xs:boolean` | Булево | — |
|
||||
| `xs:decimal` | Число | `v8:NumberQualifiers`: `Digits`, `FractionDigits`, `AllowedSign` (Any/Nonnegative) |
|
||||
| `xs:dateTime` | Дата | `v8:DateQualifiers`: `DateFractions` (Date/Time/DateTime) |
|
||||
| `v8:ValueTable` | Таблица значений | Должен содержать `<Columns>` |
|
||||
| `v8:ValueTree` | Дерево значений | Должен содержать `<Columns>` |
|
||||
| `v8:UUID` | Уникальный идентификатор | — |
|
||||
| `cfg:ExternalDataProcessorObject.<Имя>` | Объект обработки (основной реквизит) | `<MainAttribute>true</MainAttribute>` |
|
||||
| `cfg:CatalogRef.<Имя>` | Ссылка на справочник | — |
|
||||
| `xmlns:mxl="http://v8.1c.ru/8.2/data/spreadsheet"` `mxl:SpreadsheetDocument` | Табличный документ | Требует дополнительное объявление namespace `mxl` |
|
||||
|
||||
> **ВАЖНО**: Для коллекций (ValueTable, ValueTree) тип **обязателен**. Пустой `<Type/>` приведёт к ошибке «Неверный путь к данным» при обращении к колонкам через DataPath.
|
||||
|
||||
#### Коллекции: ValueTable и ValueTree
|
||||
|
||||
```xml
|
||||
<Attribute name="ТаблицаРеквизитов" id="8">
|
||||
<Title>...</Title>
|
||||
<Type>
|
||||
<v8:Type>v8:ValueTable</v8:Type>
|
||||
</Type>
|
||||
<Columns>
|
||||
<Column name="Пометка" id="1">
|
||||
<Title>...</Title>
|
||||
<Type>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</Type>
|
||||
</Column>
|
||||
<Column name="ИмяРеквизита" id="2">
|
||||
<Title>...</Title>
|
||||
<Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>150</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Column>
|
||||
</Columns>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
Для дерева — `v8:ValueTree`, структура аналогична.
|
||||
|
||||
#### Основной реквизит (Объект)
|
||||
|
||||
Связывает форму с объектом обработки. Обязателен для доступа к табличным частям и модулю объекта.
|
||||
|
||||
```xml
|
||||
<Attribute name="Объект" id="20">
|
||||
<Type>
|
||||
<v8:Type>cfg:ExternalDataProcessorObject.<ИмяОбработки></v8:Type>
|
||||
</Type>
|
||||
<MainAttribute>true</MainAttribute>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
### 6.5. Команды формы (`<Commands>`)
|
||||
|
||||
```xml
|
||||
<Command name="Построить" id="1">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Построить</v8:content>
|
||||
</v8:item>
|
||||
</Title>
|
||||
<ToolTip>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Построить ER-диаграмму</v8:content>
|
||||
</v8:item>
|
||||
</ToolTip>
|
||||
<Action>КомандаПостроить</Action>
|
||||
<CurrentRowUse>DontUse</CurrentRowUse>
|
||||
</Command>
|
||||
```
|
||||
|
||||
Команда привязывается к кнопке через `CommandName`:
|
||||
```xml
|
||||
<Button ...>
|
||||
<CommandName>Form.Command.Построить</CommandName>
|
||||
</Button>
|
||||
```
|
||||
|
||||
### 6.6. События формы и элементов
|
||||
|
||||
#### События формы
|
||||
|
||||
```xml
|
||||
<Events>
|
||||
<Event name="OnCreateAtServer">ПриСозданииНаСервере</Event>
|
||||
<Event name="OnOpen">ПриОткрытии</Event>
|
||||
</Events>
|
||||
```
|
||||
|
||||
#### События элементов (внутри элемента)
|
||||
|
||||
```xml
|
||||
<Events>
|
||||
<Event name="OnChange">ДеревоМетаданныхПометкаПриИзменении</Event>
|
||||
<Event name="OnActivateRow">ДеревоМетаданныхПриАктивизацииСтроки</Event>
|
||||
</Events>
|
||||
```
|
||||
|
||||
| Имя события | Описание |
|
||||
|-------------|----------|
|
||||
| `OnCreateAtServer` | При создании на сервере (форма) |
|
||||
| `OnOpen` | При открытии (форма) |
|
||||
| `OnChange` | При изменении (элементы ввода, флажки) |
|
||||
| `OnActivateRow` | При активизации строки (дерево, таблица) |
|
||||
| `OnEditEnd` | При окончании редактирования (таблица) |
|
||||
|
||||
## 7. Модули BSL
|
||||
|
||||
### 7.1. Модуль объекта (`ObjectModule.bsl`)
|
||||
|
||||
Серверная логика без контекста формы. Доступен через `РеквизитФормыВЗначение("Объект")`.
|
||||
|
||||
```bsl
|
||||
// Экспортные функции — API объекта
|
||||
Функция ПолучитьДанные() Экспорт
|
||||
// ...
|
||||
КонецФункции
|
||||
```
|
||||
|
||||
### 7.2. Модуль формы (`Module.bsl`)
|
||||
|
||||
Обработчики событий формы, элементов и команд.
|
||||
|
||||
Директивы компиляции:
|
||||
- `&НаСервере` — выполняется на сервере, есть доступ к реквизитам формы
|
||||
- `&НаКлиенте` — выполняется на клиенте
|
||||
- `&НаСервереБезКонтекста` — на сервере без контекста формы
|
||||
|
||||
```bsl
|
||||
#Область ОбработчикиСобытийФормы
|
||||
|
||||
&НаСервере
|
||||
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
|
||||
ОбъектОбработки = РеквизитФормыВЗначение("Объект");
|
||||
// ... вызовы функций модуля объекта
|
||||
КонецПроцедуры
|
||||
|
||||
#КонецОбласти
|
||||
```
|
||||
|
||||
## 8. Генерация UUID
|
||||
|
||||
Все UUID в XML-файлах должны быть валидными UUID v4. Формат: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`.
|
||||
|
||||
При генерации нового проекта каждый UUID должен быть уникальным. UUID используются для:
|
||||
- Идентификации объекта обработки (`ExternalDataProcessor uuid`)
|
||||
- Внутренних типов (`ContainedObject`, `GeneratedType`)
|
||||
- Форм (`Form uuid`)
|
||||
- Макетов (`Template uuid`)
|
||||
- Табличных частей и их реквизитов
|
||||
|
||||
## 9. Известные ошибки и подводные камни
|
||||
|
||||
### «Неверный путь к данным» для колонок таблицы
|
||||
|
||||
**Проблема**: При загрузке формы конфигуратор выдаёт ошибку «Неверный путь к данным: <Реквизит>.<Колонка>» для всех колонок таблицы.
|
||||
|
||||
**Причина**: Реквизит формы с колонками (`<Columns>`) не имеет правильного типа. Для коллекций тип обязателен:
|
||||
- `v8:ValueTable` для таблиц
|
||||
- `v8:ValueTree` для деревьев
|
||||
|
||||
**Неправильно**:
|
||||
```xml
|
||||
<Attribute name="МояТаблица" id="1">
|
||||
<Type/> <!-- ОШИБКА: тип пустой -->
|
||||
<Columns>...</Columns>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
**Правильно**:
|
||||
```xml
|
||||
<Attribute name="МояТаблица" id="1">
|
||||
<Type>
|
||||
<v8:Type>v8:ValueTable</v8:Type> <!-- Тип обязателен -->
|
||||
</Type>
|
||||
<Columns>...</Columns>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
### BOM в файлах метаданных
|
||||
|
||||
Файлы метаданных (корневой XML, формы, макеты), выгруженные конфигуратором, содержат BOM (Byte Order Mark, `\xEF\xBB\xBF`) в начале. Файл `Form.xml` (описание формы) и `.bsl`-модули — **без BOM**. При ручном создании файлов рекомендуется следовать этому же правилу, хотя конфигуратор принимает файлы и без BOM.
|
||||
|
||||
### Кодировка
|
||||
|
||||
Все файлы — UTF-8. XML-файлы имеют заголовок `<?xml version="1.0" encoding="UTF-8"?>`.
|
||||
|
||||
## 10. Чеклист для создания новой обработки
|
||||
|
||||
1. Сгенерировать UUID для каждого объекта (обработка, формы, макеты, ТЧ)
|
||||
2. Создать структуру каталогов (раздел 1)
|
||||
3. Создать корневой XML (раздел 3) с правильными ChildObjects
|
||||
4. Для каждой формы:
|
||||
- Создать `<Имя>.xml` (раздел 4)
|
||||
- Создать `Form.xml` (раздел 6) — проверить пространство имён!
|
||||
- Создать `Module.bsl` (раздел 7.2)
|
||||
5. Для каждого макета:
|
||||
- Создать `<Имя>.xml` (раздел 5) с правильным TemplateType
|
||||
- Создать тело макета (`Template.<расш>`)
|
||||
6. При необходимости создать `ObjectModule.bsl` (раздел 7.1)
|
||||
7. Проверить:
|
||||
- Все `<Type>` для коллекций содержат `v8:ValueTable` / `v8:ValueTree`
|
||||
- Все `DataPath` корректны (особенно для колонок таблиц)
|
||||
- Все элементы имеют `ExtendedTooltip`
|
||||
- Все ID уникальны в пределах своих секций
|
||||
- `DefaultForm` в корневом файле соответствует реальному имени формы
|
||||
@@ -0,0 +1,74 @@
|
||||
# Сборка и разборка внешних обработок 1С (EPF/ERF)
|
||||
|
||||
## Общие сведения
|
||||
|
||||
Конфигуратор 1С:Предприятия 8.3 поддерживает пакетный режим для сборки `.epf`/`.erf` файлов из XML-исходников и обратной разборки. Это позволяет хранить исходники в Git и собирать бинарные файлы по необходимости.
|
||||
|
||||
**Требования**: для работы команд необходимо подключение к информационной базе (может быть пустой).
|
||||
|
||||
## Команды
|
||||
|
||||
### Сборка (XML → EPF)
|
||||
|
||||
```
|
||||
1cv8.exe DESIGNER /F <путь_к_базе> /DisableStartupDialogs /LoadExternalDataProcessorOrReportFromFiles <корневой_xml> <путь_к_epf> /Out <лог_файл>
|
||||
```
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `/F <путь>` | Путь к файловой информационной базе |
|
||||
| `/S <строка>` | Строка подключения к серверной базе (альтернатива `/F`) |
|
||||
| `/N <имя> /P <пароль>` | Аутентификация (если требуется) |
|
||||
| `/DisableStartupDialogs` | Подавляет GUI-диалоги (обязательно для пакетного режима) |
|
||||
| `<корневой_xml>` | Путь к корневому XML-файлу обработки (например, `src\МояОбработка.xml`) |
|
||||
| `<путь_к_epf>` | Путь к выходному файлу `.epf` или `.erf` |
|
||||
| `/Out <лог>` | Файл для записи лога операции |
|
||||
|
||||
> **Важно**: первый аргумент — путь к **корневому XML-файлу** (не к каталогу). Если указать каталог, конфигуратор вернёт ошибку.
|
||||
|
||||
### Разборка (EPF → XML)
|
||||
|
||||
```
|
||||
1cv8.exe DESIGNER /F <путь_к_базе> /DisableStartupDialogs /DumpExternalDataProcessorOrReportToFiles <каталог_выгрузки> <путь_к_epf> [-Format Hierarchical] /Out <лог_файл>
|
||||
```
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `<каталог_выгрузки>` | Каталог для XML-файлов |
|
||||
| `<путь_к_epf>` | Исходный файл `.epf` или `.erf` |
|
||||
| `-Format Hierarchical` | Иерархическая структура каталогов (по умолчанию) |
|
||||
| `-Format Plain` | Плоская структура |
|
||||
|
||||
### Коды возврата
|
||||
|
||||
| Код | Значение |
|
||||
|-----|----------|
|
||||
| `0` | Успешно |
|
||||
| `1` | Ошибка |
|
||||
| `101` | Ошибка данных |
|
||||
|
||||
### Создание пустой ИБ
|
||||
|
||||
```
|
||||
1cv8.exe CREATEINFOBASE File="<путь_к_каталогу_базы>"
|
||||
```
|
||||
|
||||
Создаёт файловую ИБ в указанном каталоге. Необходима для пакетного режима конфигуратора.
|
||||
|
||||
## Примечания
|
||||
|
||||
- Пустая ИБ достаточна для сборки, если обработка не ссылается на объекты конфигурации.
|
||||
- Если обработка использует ссылочные типы конфигурации (`СправочникСсылка.*` и т.п.), при выгрузке/загрузке нужна база с соответствующей конфигурацией — иначе типы сохраняются как UUID.
|
||||
- Путь к `1cv8.exe` зависит от установленной версии платформы (например, `C:\Program Files\1cv8\8.3.27.1859\bin\1cv8.exe`).
|
||||
- `/DisableStartupDialogs` — подавляет интерактивные диалоги (например, «ИБ не обнаружена»), без него конфигуратор может зависнуть в ожидании пользовательского ввода.
|
||||
- Первый аргумент `/LoadExternalDataProcessorOrReportFromFiles` — путь к корневому XML-файлу, а **не** к каталогу.
|
||||
|
||||
## Claude Code Skills
|
||||
|
||||
Сборка и разборка доступны как навыки Claude Code:
|
||||
- `/epf-build` — документация по сборке EPF из XML
|
||||
- `/epf-dump` — документация по разборке EPF в XML
|
||||
|
||||
Переменные окружения:
|
||||
- `V8_PATH` — каталог `bin` платформы 1С (например, `C:\Program Files\1cv8\8.3.27.1859\bin`)
|
||||
- `V8_BASE` — путь к пустой ИБ (создаётся автоматически при первом запуске)
|
||||
Reference in New Issue
Block a user