mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
Compare commits
16 Commits
358830c65b
...
d3520a8945
| Author | SHA1 | Date | |
|---|---|---|---|
| d3520a8945 | |||
| e731bde7f0 | |||
| 321e426f98 | |||
| 54c04cfe76 | |||
| 9727635e5d | |||
| 6404016afb | |||
| 17afd807d2 | |||
| 9bfc431a6a | |||
| d755c41233 | |||
| 87e636f644 | |||
| ae1dcaac07 | |||
| d155086444 | |||
| 940eafb8e4 | |||
| e4dcef8c90 | |||
| 08688f5cab | |||
| 1bc5e8f07a |
@@ -1,4 +1,4 @@
|
||||
# cfe-borrow v1.2 — Borrow objects from configuration into extension (CFE)
|
||||
# cfe-borrow v1.3 — Borrow objects from configuration into extension (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$ExtensionPath,
|
||||
@@ -316,6 +316,25 @@ function Expand-SelfClosingElement($container, $parentIndent) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- 7b. Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$script:formatVersion = Detect-FormatVersion $extDir
|
||||
|
||||
# --- 8. Namespaces declaration for object XML ---
|
||||
$script:xmlnsDecl = '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"'
|
||||
|
||||
@@ -466,7 +485,7 @@ function Borrow-Form {
|
||||
$newFormUuid = [guid]::NewGuid().ToString()
|
||||
$formMetaSb = New-Object System.Text.StringBuilder
|
||||
$formMetaSb.AppendLine("<?xml version=`"1.0`" encoding=`"UTF-8`"?>") | Out-Null
|
||||
$formMetaSb.AppendLine("<MetaDataObject $($script:xmlnsDecl) version=`"2.17`">") | Out-Null
|
||||
$formMetaSb.AppendLine("<MetaDataObject $($script:xmlnsDecl) version=`"$($script:formatVersion)`">") | Out-Null
|
||||
$formMetaSb.AppendLine("`t<Form uuid=`"${newFormUuid}`">") | Out-Null
|
||||
$formMetaSb.AppendLine("`t`t<InternalInfo/>") | Out-Null
|
||||
$formMetaSb.AppendLine("`t`t<Properties>") | Out-Null
|
||||
@@ -498,7 +517,7 @@ function Borrow-Form {
|
||||
$srcFormEl = $srcFormDoc.DocumentElement
|
||||
|
||||
$formVersion = $srcFormEl.GetAttribute("version")
|
||||
if (-not $formVersion) { $formVersion = "2.17" }
|
||||
if (-not $formVersion) { $formVersion = $script:formatVersion }
|
||||
|
||||
# Find direct children: form properties, AutoCommandBar, ChildItems
|
||||
$srcAutoCmd = $null
|
||||
@@ -1529,7 +1548,7 @@ function Build-BorrowedObjectXml {
|
||||
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
$sb.AppendLine("<?xml version=`"1.0`" encoding=`"UTF-8`"?>") | Out-Null
|
||||
$sb.AppendLine("<MetaDataObject $($script:xmlnsDecl) version=`"2.17`">") | Out-Null
|
||||
$sb.AppendLine("<MetaDataObject $($script:xmlnsDecl) version=`"$($script:formatVersion)`">") | Out-Null
|
||||
$sb.AppendLine("`t<${typeName} uuid=`"${newUuid}`">") | Out-Null
|
||||
|
||||
# InternalInfo
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cfe-borrow v1.2 — Borrow objects from configuration into extension (CFE)
|
||||
# cfe-borrow v1.3 — Borrow objects from configuration into extension (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -254,6 +254,22 @@ XMLNS_DECL = (
|
||||
)
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def get_child_indent(container):
|
||||
if container.text and "\n" in container.text:
|
||||
after_nl = container.text.rsplit("\n", 1)[-1]
|
||||
@@ -365,6 +381,8 @@ def main():
|
||||
cfg_resolved = os.path.abspath(cfg_path)
|
||||
cfg_dir = os.path.dirname(cfg_resolved)
|
||||
|
||||
format_version = detect_format_version(ext_dir)
|
||||
|
||||
# --- 2. Load extension Configuration.xml ---
|
||||
xml_parser = etree.XMLParser(remove_blank_text=False)
|
||||
tree = etree.parse(ext_resolved, xml_parser)
|
||||
@@ -501,7 +519,7 @@ def main():
|
||||
|
||||
lines = []
|
||||
lines.append('<?xml version="1.0" encoding="UTF-8"?>')
|
||||
lines.append(f'<MetaDataObject {XMLNS_DECL} version="2.17">')
|
||||
lines.append(f'<MetaDataObject {XMLNS_DECL} version="{format_version}">')
|
||||
lines.append(f'\t<{type_name} uuid="{new_uuid_val}">')
|
||||
lines.append(internal_info_xml)
|
||||
lines.append("\t\t<Properties>")
|
||||
@@ -1086,7 +1104,7 @@ def main():
|
||||
new_form_uuid = new_guid()
|
||||
form_meta_lines = [
|
||||
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||
f'<MetaDataObject {XMLNS_DECL} version="2.17">',
|
||||
f'<MetaDataObject {XMLNS_DECL} version="{format_version}">',
|
||||
f'\t<Form uuid="{new_form_uuid}">',
|
||||
'\t\t<InternalInfo/>',
|
||||
'\t\t<Properties>',
|
||||
@@ -1113,7 +1131,7 @@ def main():
|
||||
src_form_tree = etree.parse(src_form_xml_path, src_form_parser)
|
||||
src_form_el = src_form_tree.getroot()
|
||||
|
||||
form_version = src_form_el.get("version", "2.17")
|
||||
form_version = src_form_el.get("version", format_version)
|
||||
|
||||
src_auto_cmd = None
|
||||
form_props = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# epf-add-form v1.0 — Add managed form to 1C processor
|
||||
# epf-add-form v1.1 — Add managed form to 1C processor
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -16,6 +16,25 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$formatVersion = Detect-FormatVersion (Resolve-Path $SrcDir).Path
|
||||
|
||||
# --- Проверки ---
|
||||
|
||||
$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml"
|
||||
@@ -52,7 +71,7 @@ $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">
|
||||
<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="$formatVersion">
|
||||
<Form uuid="$formUuid">
|
||||
<Properties>
|
||||
<Name>$FormName</Name>
|
||||
@@ -83,7 +102,7 @@ $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">
|
||||
<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="$formatVersion">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
</AutoCommandBar>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
# add-form v1.0 — Add managed form to 1C external data processor
|
||||
# add-form v1.1 — Add managed form to 1C external data processor
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
@@ -12,6 +13,22 @@ from lxml import etree
|
||||
NSMAP = {"md": "http://v8.1c.ru/8.3/MDClasses"}
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def save_xml_with_bom(tree, path):
|
||||
"""Save XML tree to file with UTF-8 BOM."""
|
||||
xml_bytes = etree.tostring(tree, xml_declaration=True, encoding="UTF-8")
|
||||
@@ -46,6 +63,8 @@ def main():
|
||||
is_main = args.Main
|
||||
src_dir = args.SrcDir
|
||||
|
||||
format_version = detect_format_version(os.path.abspath(src_dir))
|
||||
|
||||
# --- Checks ---
|
||||
|
||||
root_xml_path = os.path.join(src_dir, f"{processor_name}.xml")
|
||||
@@ -92,7 +111,7 @@ def main():
|
||||
' 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">\n'
|
||||
f' version="{format_version}">\n'
|
||||
f'\t<Form uuid="{form_uuid}">\n'
|
||||
'\t\t<Properties>\n'
|
||||
f'\t\t\t<Name>{form_name}</Name>\n'
|
||||
@@ -139,7 +158,7 @@ def main():
|
||||
' 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">\n'
|
||||
f' version="{format_version}">\n'
|
||||
'\t<AutoCommandBar name="\u0424\u043e\u0440\u043c\u0430\u041a\u043e\u043c\u0430\u043d\u0434\u043d\u0430\u044f\u041f\u0430\u043d\u0435\u043b\u044c" id="-1">\n'
|
||||
'\t\t<Autofill>true</Autofill>\n'
|
||||
'\t</AutoCommandBar>\n'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-add v1.2 — Add managed form to 1C config object
|
||||
# form-add v1.3 — Add managed form to 1C config object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -16,6 +16,23 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Detect XML format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
# --- Фаза 1: Определение типа объекта ---
|
||||
|
||||
# Resolve ObjectPath (directory → .xml)
|
||||
@@ -36,6 +53,8 @@ if (-not (Test-Path $ObjectPath)) {
|
||||
}
|
||||
|
||||
$objectXmlFull = Resolve-Path $ObjectPath
|
||||
$script:formatVersion = Detect-FormatVersion (Split-Path $objectXmlFull.Path -Parent)
|
||||
|
||||
$xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$xmlDoc.PreserveWhitespace = $true
|
||||
$xmlDoc.Load($objectXmlFull.Path)
|
||||
@@ -159,7 +178,7 @@ if ($objectType -in $processorLikeTypes) {
|
||||
|
||||
$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">
|
||||
<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="$($script:formatVersion)">
|
||||
<Form uuid="$formUuid">
|
||||
<Properties>
|
||||
<Name>$FormName</Name>
|
||||
@@ -196,7 +215,7 @@ if ($Purpose -eq "List" -or $Purpose -eq "Choice") {
|
||||
|
||||
$formXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Form $formNsDecl version="2.17">
|
||||
<Form $formNsDecl version="$($script:formatVersion)">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
</AutoCommandBar>
|
||||
@@ -224,7 +243,7 @@ if ($Purpose -eq "List" -or $Purpose -eq "Choice") {
|
||||
|
||||
$formXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Form $formNsDecl version="2.17">
|
||||
<Form $formNsDecl version="$($script:formatVersion)">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
</AutoCommandBar>
|
||||
@@ -267,7 +286,7 @@ if ($Purpose -eq "List" -or $Purpose -eq "Choice") {
|
||||
|
||||
$formXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Form $formNsDecl version="2.17">
|
||||
<Form $formNsDecl version="$($script:formatVersion)">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
</AutoCommandBar>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-add v1.2 — Add managed form to 1C config object
|
||||
# form-add v1.3 — Add managed form to 1C config object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
@@ -15,6 +16,22 @@ NSMAP = {
|
||||
}
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def save_xml_with_bom(tree, path):
|
||||
"""Save XML tree to file with UTF-8 BOM."""
|
||||
xml_bytes = etree.tostring(tree, xml_declaration=True, encoding="UTF-8")
|
||||
@@ -67,6 +84,8 @@ def main():
|
||||
sys.exit(1)
|
||||
|
||||
object_xml_full = os.path.abspath(object_path)
|
||||
format_version = detect_format_version(os.path.dirname(object_xml_full))
|
||||
|
||||
parser_xml = etree.XMLParser(remove_blank_text=False)
|
||||
tree = etree.parse(object_xml_full, parser_xml)
|
||||
root = tree.getroot()
|
||||
@@ -171,7 +190,7 @@ def main():
|
||||
' 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">\n'
|
||||
f' version="{format_version}">\n'
|
||||
f'\t<Form uuid="{form_uuid}">\n'
|
||||
'\t\t<Properties>\n'
|
||||
f'\t\t\t<Name>{form_name}</Name>\n'
|
||||
@@ -225,7 +244,7 @@ def main():
|
||||
|
||||
form_xml = (
|
||||
f'<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
f'<Form {form_ns_decl} version="2.17">\n'
|
||||
f'<Form {form_ns_decl} version="{format_version}">\n'
|
||||
'\t<AutoCommandBar name="\u0424\u043e\u0440\u043c\u0430\u041a\u043e\u043c\u0430\u043d\u0434\u043d\u0430\u044f\u041f\u0430\u043d\u0435\u043b\u044c" id="-1">\n'
|
||||
'\t\t<Autofill>true</Autofill>\n'
|
||||
'\t</AutoCommandBar>\n'
|
||||
@@ -254,7 +273,7 @@ def main():
|
||||
|
||||
form_xml = (
|
||||
f'<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
f'<Form {form_ns_decl} version="2.17">\n'
|
||||
f'<Form {form_ns_decl} version="{format_version}">\n'
|
||||
'\t<AutoCommandBar name="\u0424\u043e\u0440\u043c\u0430\u041a\u043e\u043c\u0430\u043d\u0434\u043d\u0430\u044f\u041f\u0430\u043d\u0435\u043b\u044c" id="-1">\n'
|
||||
'\t\t<Autofill>true</Autofill>\n'
|
||||
'\t</AutoCommandBar>\n'
|
||||
@@ -297,7 +316,7 @@ def main():
|
||||
|
||||
form_xml = (
|
||||
f'<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
f'<Form {form_ns_decl} version="2.17">\n'
|
||||
f'<Form {form_ns_decl} version="{format_version}">\n'
|
||||
'\t<AutoCommandBar name="\u0424\u043e\u0440\u043c\u0430\u041a\u043e\u043c\u0430\u043d\u0434\u043d\u0430\u044f\u041f\u0430\u043d\u0435\u043b\u044c" id="-1">\n'
|
||||
'\t\t<Autofill>true</Autofill>\n'
|
||||
'\t</AutoCommandBar>\n'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.1 — Compile 1C managed form from JSON
|
||||
# form-compile v1.2 — Compile 1C managed form from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -11,6 +11,26 @@ param(
|
||||
$ErrorActionPreference = "Stop"
|
||||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
|
||||
# --- Detect XML format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$script:outPathResolved = if ([System.IO.Path]::IsPathRooted($OutputPath)) { $OutputPath } else { Join-Path (Get-Location) $OutputPath }
|
||||
$script:formatVersion = Detect-FormatVersion ([System.IO.Path]::GetDirectoryName($script:outPathResolved))
|
||||
|
||||
# --- 1. Load and validate JSON ---
|
||||
|
||||
if (-not (Test-Path $JsonPath)) {
|
||||
@@ -1107,7 +1127,7 @@ if ($def.title) {
|
||||
|
||||
# Header
|
||||
X '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
X '<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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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">'
|
||||
X '<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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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="$($script:formatVersion)">'
|
||||
|
||||
# Oops — Title was emitted before header. Need to fix the order.
|
||||
# Actually, let me restructure: build the body into a separate buffer, then assemble
|
||||
@@ -1117,7 +1137,7 @@ $script:xml = New-Object System.Text.StringBuilder 8192
|
||||
$script:nextId = 1
|
||||
|
||||
X '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
X '<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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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">'
|
||||
X '<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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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="$($script:formatVersion)">'
|
||||
|
||||
# 12a. Title (from def.title or properties.title — must be multilingual XML)
|
||||
$formTitle = $def.title
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.1 — Compile 1C managed form from JSON
|
||||
# form-compile v1.2 — Compile 1C managed form from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -1002,6 +1002,22 @@ def emit_properties(lines, props, indent):
|
||||
lines.append(f'{indent}<{xml_name}>{val}</{xml_name}>')
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
@@ -1012,6 +1028,10 @@ def main():
|
||||
parser.add_argument('-OutputPath', type=str, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
# --- Detect XML format version ---
|
||||
out_path_resolved = args.OutputPath if os.path.isabs(args.OutputPath) else os.path.join(os.getcwd(), args.OutputPath)
|
||||
format_version = detect_format_version(os.path.dirname(out_path_resolved))
|
||||
|
||||
# --- 1. Load and validate JSON ---
|
||||
json_path = args.JsonPath
|
||||
if not os.path.exists(json_path):
|
||||
@@ -1026,7 +1046,7 @@ def main():
|
||||
lines = []
|
||||
|
||||
lines.append('<?xml version="1.0" encoding="UTF-8"?>')
|
||||
lines.append('<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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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">')
|
||||
lines.append(f'<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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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="{format_version}">')
|
||||
|
||||
# Title
|
||||
form_title = defn.get('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-validate v1.3 — Validate 1C managed form
|
||||
# form-validate v1.4 — Validate 1C managed form
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -126,10 +126,10 @@ if ($root.LocalName -ne "Form") {
|
||||
Report-Error "Root element is '$($root.LocalName)', expected 'Form'"
|
||||
} else {
|
||||
$version = $root.GetAttribute("version")
|
||||
if ($version -eq "2.17") {
|
||||
if ($version -eq "2.17" -or $version -eq "2.20") {
|
||||
Report-OK "Root element: Form version=$version"
|
||||
} elseif ($version) {
|
||||
Report-Warn "Form version='$version' (expected 2.17)"
|
||||
Report-Warn "Form version='$version' (expected 2.17 or 2.20)"
|
||||
} else {
|
||||
Report-Warn "Form version attribute missing"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-validate v1.3 — Validate 1C managed form
|
||||
# form-validate v1.4 — Validate 1C managed form
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -161,10 +161,10 @@ def main():
|
||||
report_error(f"Root element is '{localname(root)}', expected 'Form'")
|
||||
else:
|
||||
version = root.get("version", "")
|
||||
if version == "2.17":
|
||||
if version in ("2.17", "2.20"):
|
||||
report_ok(f"Root element: Form version={version}")
|
||||
elif version:
|
||||
report_warn(f"Form version='{version}' (expected 2.17)")
|
||||
report_warn(f"Form version='{version}' (expected 2.17 or 2.20)")
|
||||
else:
|
||||
report_warn("Form version attribute missing")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# help-add v1.2 — Add built-in help to 1C object
|
||||
# help-add v1.3 — Add built-in help to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -11,6 +11,25 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# --- Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$formatVersion = Detect-FormatVersion (Resolve-Path $SrcDir).Path
|
||||
|
||||
# --- Проверки ---
|
||||
|
||||
$objectDir = Join-Path $SrcDir $ObjectName
|
||||
@@ -35,7 +54,7 @@ $encBom = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
$helpXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Help xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||
<Help xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="$formatVersion">
|
||||
<Page>$Lang</Page>
|
||||
</Help>
|
||||
"@
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
# add-help v1.2 — Add built-in help to 1C object
|
||||
# add-help v1.3 — Add built-in help to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from lxml import etree
|
||||
@@ -11,6 +12,22 @@ from lxml import etree
|
||||
NSMAP = {"md": "http://v8.1c.ru/8.3/MDClasses"}
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def save_xml_with_bom(tree, path):
|
||||
"""Save XML tree to file with UTF-8 BOM."""
|
||||
xml_bytes = etree.tostring(tree, xml_declaration=True, encoding="UTF-8")
|
||||
@@ -41,6 +58,8 @@ def main():
|
||||
lang = args.Lang
|
||||
src_dir = args.SrcDir
|
||||
|
||||
format_version = detect_format_version(os.path.abspath(src_dir))
|
||||
|
||||
# --- Checks ---
|
||||
|
||||
object_dir = os.path.join(src_dir, object_name)
|
||||
@@ -62,7 +81,7 @@ def main():
|
||||
'<Help xmlns="http://v8.1c.ru/8.3/xcf/extrnprops"'
|
||||
' xmlns:xs="http://www.w3.org/2001/XMLSchema"'
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
' version="2.17">\n'
|
||||
f' version="{format_version}">\n'
|
||||
f'\t<Page>{lang}</Page>\n'
|
||||
'</Help>'
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# interface-edit v1.2 — Edit 1C CommandInterface.xml
|
||||
# interface-edit v1.3 — Edit 1C CommandInterface.xml
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$CIPath,
|
||||
@@ -23,6 +23,25 @@ if (-not [System.IO.Path]::IsPathRooted($CIPath)) {
|
||||
}
|
||||
$resolvedPath = $CIPath
|
||||
|
||||
# --- Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$formatVersion = Detect-FormatVersion ([System.IO.Path]::GetDirectoryName($CIPath))
|
||||
|
||||
# --- Namespaces ---
|
||||
$script:ciNs = "http://v8.1c.ru/8.3/xcf/extrnprops"
|
||||
$script:xrNs = "http://v8.1c.ru/8.3/xcf/readable"
|
||||
@@ -42,7 +61,7 @@ if (-not (Test-Path $CIPath)) {
|
||||
xmlns:xr="$($script:xrNs)"
|
||||
xmlns:xs="$($script:xsNs)"
|
||||
xmlns:xsi="$($script:xsiNs)"
|
||||
version="2.17">
|
||||
version="$formatVersion">
|
||||
</CommandInterface>
|
||||
"@
|
||||
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
@@ -1,14 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
# interface-edit v1.2 — Edit 1C CommandInterface.xml
|
||||
# interface-edit v1.3 — Edit 1C CommandInterface.xml
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from lxml import etree
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
CI_NS = "http://v8.1c.ru/8.3/xcf/extrnprops"
|
||||
XR_NS = "http://v8.1c.ru/8.3/xcf/readable"
|
||||
XSI_NS = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
@@ -181,6 +198,10 @@ def main():
|
||||
print("Either -DefinitionFile or -Operation is required", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# --- Detect format version ---
|
||||
ci_dir = os.path.dirname(os.path.abspath(args.CIPath))
|
||||
format_version = detect_format_version(ci_dir)
|
||||
|
||||
# --- Resolve path ---
|
||||
ci_path = args.CIPath
|
||||
if not os.path.isabs(ci_path):
|
||||
@@ -199,7 +220,7 @@ def main():
|
||||
f'\txmlns:xr="{XR_NS}"\n'
|
||||
f'\txmlns:xs="{XS_NS}"\n'
|
||||
f'\txmlns:xsi="{XSI_NS}"\n'
|
||||
f'\tversion="2.17">\n'
|
||||
f'\tversion="{format_version}">\n'
|
||||
f'</CommandInterface>'
|
||||
)
|
||||
with open(ci_path, "w", encoding="utf-8-sig") as fh:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.6 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.7 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -2540,13 +2540,32 @@ function Emit-AddressingAttribute {
|
||||
|
||||
$script:xmlnsDecl = '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"'
|
||||
|
||||
# --- 14a. Detect format version from existing Configuration.xml ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$script:formatVersion = Detect-FormatVersion $OutputDir
|
||||
|
||||
# --- 15. Main assembler ---
|
||||
|
||||
$uuid = New-Guid-String
|
||||
|
||||
# XML declaration
|
||||
X '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
X "<MetaDataObject $($script:xmlnsDecl) version=`"2.17`">"
|
||||
X "<MetaDataObject $($script:xmlnsDecl) version=`"$($script:formatVersion)`">"
|
||||
X "`t<$objType uuid=`"$uuid`">"
|
||||
|
||||
# InternalInfo
|
||||
@@ -2908,7 +2927,7 @@ if ($objType -eq "ExchangePlan") {
|
||||
$contentPath = Join-Path $extDir "Content.xml"
|
||||
if (-not (Test-Path $contentPath)) {
|
||||
Ensure-ExtDir
|
||||
$contentXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<ExchangePlanContent xmlns=`"http://v8.1c.ru/8.3/xcf/extrnprops`" xmlns:xr=`"http://v8.1c.ru/8.3/xcf/readable`" version=`"2.17`"/>`r`n"
|
||||
$contentXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<ExchangePlanContent xmlns=`"http://v8.1c.ru/8.3/xcf/extrnprops`" xmlns:xr=`"http://v8.1c.ru/8.3/xcf/readable`" version=`"$($script:formatVersion)`"/>`r`n"
|
||||
[System.IO.File]::WriteAllText($contentPath, $contentXml, $enc)
|
||||
$modulesCreated += $contentPath
|
||||
}
|
||||
@@ -2917,7 +2936,7 @@ if ($objType -eq "BusinessProcess") {
|
||||
$flowchartPath = Join-Path $extDir "Flowchart.xml"
|
||||
if (-not (Test-Path $flowchartPath)) {
|
||||
Ensure-ExtDir
|
||||
$flowchartXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<Flowchart xmlns=`"http://v8.1c.ru/8.3/MDClasses`" version=`"2.17`"/>`r`n"
|
||||
$flowchartXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<Flowchart xmlns=`"http://v8.1c.ru/8.3/MDClasses`" version=`"$($script:formatVersion)`"/>`r`n"
|
||||
[System.IO.File]::WriteAllText($flowchartPath, $flowchartXml, $enc)
|
||||
$modulesCreated += $flowchartPath
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.6 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.7 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -2202,6 +2202,27 @@ def emit_addressing_attribute(indent, addr_def):
|
||||
|
||||
xmlns_decl = '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"'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 14a. Detect format version from existing Configuration.xml
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
format_version = detect_format_version(output_dir)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 15. Main assembler
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -2209,7 +2230,7 @@ xmlns_decl = 'xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8
|
||||
obj_uuid = new_uuid()
|
||||
|
||||
X('<?xml version="1.0" encoding="UTF-8"?>')
|
||||
X(f'<MetaDataObject {xmlns_decl} version="2.17">')
|
||||
X(f'<MetaDataObject {xmlns_decl} version="{format_version}">')
|
||||
X(f'\t<{obj_type} uuid="{obj_uuid}">')
|
||||
|
||||
# InternalInfo
|
||||
@@ -2529,7 +2550,7 @@ if obj_type == 'ExchangePlan':
|
||||
content_path = os.path.join(ext_dir, 'Content.xml')
|
||||
if not os.path.isfile(content_path):
|
||||
ensure_ext_dir()
|
||||
content_xml = '<?xml version="1.0" encoding="UTF-8"?>\r\n<ExchangePlanContent xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" version="2.17"/>\r\n'
|
||||
content_xml = f'<?xml version="1.0" encoding="UTF-8"?>\r\n<ExchangePlanContent xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" version="{format_version}"/>\r\n'
|
||||
write_utf8_bom(content_path, content_xml)
|
||||
modules_created.append(content_path)
|
||||
|
||||
@@ -2537,7 +2558,7 @@ if obj_type == 'BusinessProcess':
|
||||
flowchart_path = os.path.join(ext_dir, 'Flowchart.xml')
|
||||
if not os.path.isfile(flowchart_path):
|
||||
ensure_ext_dir()
|
||||
flowchart_xml = '<?xml version="1.0" encoding="UTF-8"?>\r\n<Flowchart xmlns="http://v8.1c.ru/8.3/MDClasses" version="2.17"/>\r\n'
|
||||
flowchart_xml = f'<?xml version="1.0" encoding="UTF-8"?>\r\n<Flowchart xmlns="http://v8.1c.ru/8.3/MDClasses" version="{format_version}"/>\r\n'
|
||||
write_utf8_bom(flowchart_path, flowchart_xml)
|
||||
modules_created.append(flowchart_path)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# role-compile v1.3 — Compile 1C role from JSON
|
||||
# role-compile v1.4 — Compile 1C role from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -505,6 +505,26 @@ if ($def.objects) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$resolvedOutputDir = if ([System.IO.Path]::IsPathRooted($OutputDir)) { $OutputDir } else { Join-Path (Get-Location) $OutputDir }
|
||||
$formatVersion = Detect-FormatVersion $resolvedOutputDir
|
||||
|
||||
# --- 8. Generate UUID ---
|
||||
|
||||
$uuid = [guid]::NewGuid().ToString()
|
||||
@@ -531,7 +551,7 @@ X ' xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef"'
|
||||
X ' xmlns:xr="http://v8.1c.ru/8.3/xcf/readable"'
|
||||
X ' xmlns:xs="http://www.w3.org/2001/XMLSchema"'
|
||||
X ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
X ' version="2.17">'
|
||||
X ' version="$formatVersion">'
|
||||
X " <Role uuid=`"$uuid`">"
|
||||
X ' <Properties>'
|
||||
X " <Name>$roleName</Name>"
|
||||
@@ -560,7 +580,7 @@ X '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
X '<Rights xmlns="http://v8.1c.ru/8.2/roles"'
|
||||
X ' xmlns:xs="http://www.w3.org/2001/XMLSchema"'
|
||||
X ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
X ' xsi:type="Rights" version="2.17">'
|
||||
X " xsi:type=`"Rights`" version=`"$formatVersion`">"
|
||||
|
||||
# Global flags (defaults match typical 1C roles)
|
||||
$sfno = if ($null -ne $def.setForNewObjects) { "$($def.setForNewObjects)".ToLower() } else { "false" }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# role-compile v1.3 — Compile 1C role from JSON
|
||||
# role-compile v1.4 — Compile 1C role from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -9,6 +9,22 @@ import sys
|
||||
import uuid
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def esc_xml(s):
|
||||
return s.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
|
||||
|
||||
@@ -459,6 +475,9 @@ def main():
|
||||
if not defn.get('objects') and defn.get('rights'):
|
||||
defn['objects'] = defn['rights']
|
||||
|
||||
out_dir_resolved = args.OutputDir if os.path.isabs(args.OutputDir) else os.path.join(os.getcwd(), args.OutputDir)
|
||||
format_version = detect_format_version(out_dir_resolved)
|
||||
|
||||
# --- 2. Parse all object entries ---
|
||||
parsed_objects = []
|
||||
if defn.get('objects'):
|
||||
@@ -490,7 +509,7 @@ def main():
|
||||
lines.append(' xmlns:xr="http://v8.1c.ru/8.3/xcf/readable"')
|
||||
lines.append(' xmlns:xs="http://www.w3.org/2001/XMLSchema"')
|
||||
lines.append(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
|
||||
lines.append(' version="2.17">')
|
||||
lines.append(f' version="{format_version}">')
|
||||
lines.append(f' <Role uuid="{uid}">')
|
||||
lines.append(' <Properties>')
|
||||
lines.append(f' <Name>{role_name}</Name>')
|
||||
@@ -516,7 +535,7 @@ def main():
|
||||
lines.append('<Rights xmlns="http://v8.1c.ru/8.2/roles"')
|
||||
lines.append(' xmlns:xs="http://www.w3.org/2001/XMLSchema"')
|
||||
lines.append(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
|
||||
lines.append(' xsi:type="Rights" version="2.17">')
|
||||
lines.append(f' xsi:type="Rights" version="{format_version}">')
|
||||
|
||||
# Global flags
|
||||
sfno = str(defn['setForNewObjects']).lower() if defn.get('setForNewObjects') is not None else 'false'
|
||||
|
||||
@@ -97,7 +97,31 @@ powershell.exe -NoProfile -File .claude/skills/skd-compile/scripts/skd-compile.p
|
||||
]
|
||||
```
|
||||
|
||||
`@autoDates` — автоматически генерирует параметры `ДатаНачала` и `ДатаОкончания` с выражениями `&Период.ДатаНачала` / `&Период.ДатаОкончания` и `availableAsField=false`. Заменяет 5 строк на 1.
|
||||
Флаги shorthand:
|
||||
- `@autoDates` — автоматически генерирует параметры `ДатаНачала` и `ДатаОкончания` с выражениями `&Период.ДатаНачала` / `&Период.ДатаОкончания` и `availableAsField=false`
|
||||
- `@valueList` — `<valueListAllowed>true</valueListAllowed>` — разрешает передавать список значений
|
||||
- `@hidden` — скрытый параметр: `availableAsField=false` + исключается из `"dataParameters": "auto"`
|
||||
|
||||
Объектная форма: `hidden: true`, `valueListAllowed: true`, `availableAsField: false`, `denyIncompleteValues: true`, `use: "Always"`.
|
||||
|
||||
Список допустимых значений (availableValues):
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "ПорядокОкругления",
|
||||
"type": "EnumRef.Округления",
|
||||
"value": "Перечисление.Округления.Окр1_00",
|
||||
"use": "Always",
|
||||
"denyIncompleteValues": true,
|
||||
"availableValues": [
|
||||
{"value": "Перечисление.Округления.Окр1_00", "presentation": "руб. коп"},
|
||||
{"value": "Перечисление.Округления.Окр1", "presentation": "руб."},
|
||||
{"value": "Перечисление.Округления.Окр1000", "presentation": "тыс. руб"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
В варианте настроек `"dataParameters": "auto"` автоматически генерирует записи для всех не-hidden параметров с `userSettingID`.
|
||||
|
||||
### Фильтры — shorthand
|
||||
|
||||
@@ -187,7 +211,13 @@ powershell.exe -NoProfile -File .claude/skills/skd-compile/scripts/skd-compile.p
|
||||
]
|
||||
```
|
||||
|
||||
Типы значений appearance: `style:XXX`/`web:XXX`/`win:XXX` → Color, `true`/`false` → Boolean, параметр `Текст` → LocalStringType, прочее → String.
|
||||
Типы значений appearance: `style:XXX`/`web:XXX`/`win:XXX` → Color, `true`/`false` → Boolean, параметр `Формат`/`Текст`/`Заголовок` → LocalStringType, прочее → String.
|
||||
|
||||
Типы значений фильтра: `Перечисление.*`/`Справочник.*`/`ПланСчетов.*`/`Документ.*` → DesignTimeValue (автодетект).
|
||||
|
||||
OrGroup в фильтре: `{"group": "Or", "items": ["условие1", "условие2"]}`.
|
||||
|
||||
Folder в selection: `{"folder": "Поступление", "items": ["ПолеА", "ПолеБ"]}` → SelectedItemFolder с lwsTitle и placement=Auto.
|
||||
|
||||
### Итоги с привязкой к группировкам
|
||||
|
||||
@@ -227,7 +257,16 @@ powershell.exe -NoProfile -File .claude/skills/skd-compile/scripts/skd-compile.p
|
||||
]
|
||||
```
|
||||
|
||||
Синтаксис ячеек: `"текст"` — статика, `"{Имя}"` — параметр, `"|"` — объединение с ячейкой выше, `null` — пустая.
|
||||
Синтаксис ячеек: `"текст"` — статика, `"{Имя}"` — параметр, `"|"` — объединение с ячейкой выше, `">"` — объединение с ячейкой слева, `null` — пустая.
|
||||
|
||||
Двухуровневая шапка с горизонтальным объединением:
|
||||
```json
|
||||
"rows": [
|
||||
["Вид актива", "Остаток начало", "Поступление", ">", ">", ">", "Выбытие", ">", ">", "Остаток конец"],
|
||||
["|", "|", "из произв.", "из п/ф", "со сч.40", "прочее", "Реализ.", "отгруж.", "прочее", "|"],
|
||||
["К1", "К2", "К3", "К4", "К5", "К6", "К7", "К8", "К9", "К10"]
|
||||
]
|
||||
```
|
||||
|
||||
Встроенные стили: `header` (фон, центр, перенос), `data` (фон группы), `subheader` (без фона, центр), `total` (без фона). Все — Arial 10, рамки Solid 1px, цвета через стили платформы.
|
||||
|
||||
@@ -235,15 +274,32 @@ powershell.exe -NoProfile -File .claude/skills/skd-compile/scripts/skd-compile.p
|
||||
|
||||
Raw XML (`"template": "<...>"`) остаётся как fallback. Детект: если есть `rows` — DSL, иначе — raw.
|
||||
|
||||
### Расшифровка (drilldown) в параметрах шаблона
|
||||
|
||||
Ключ `drilldown` в параметре шаблона автоматически генерирует `DetailsAreaTemplateParameter` и привязку `Расшифровка` в appearance ячеек:
|
||||
|
||||
```json
|
||||
"parameters": [
|
||||
{ "name": "Сырье", "expression": "ПоступлениеСырья", "drilldown": "ПоступлениеСырья" }
|
||||
]
|
||||
```
|
||||
|
||||
Генерирует: `ExpressionAreaTemplateParameter` (обычный) + `DetailsAreaTemplateParameter` с именем `Расшифровка_ПоступлениеСырья`, `fieldExpression` по полю `ИмяРесурса`, `mainAction=DrillDown`. Ячейки `{Сырье}` автоматически получают appearance `Расшифровка = Расшифровка_ПоступлениеСырья`.
|
||||
|
||||
### Привязки макетов к группировкам
|
||||
|
||||
```json
|
||||
"groupTemplates": [
|
||||
{ "groupField": "Счет", "templateType": "GroupHeader", "template": "Макет1" },
|
||||
{ "groupField": "Счет", "templateType": "Header", "template": "Макет2" }
|
||||
{ "groupName": "ДанныеОтчета", "templateType": "GroupHeader", "template": "Макет1" },
|
||||
{ "groupField": "Счет", "templateType": "Header", "template": "Макет2" },
|
||||
{ "groupField": "Счет", "templateType": "OverallHeader", "template": "Макет3" }
|
||||
]
|
||||
```
|
||||
|
||||
`groupField` — привязка к полю группировки, `groupName` — к именованной группировке в структуре варианта.
|
||||
|
||||
`templateType`: `Header` (строки данных) → `<groupTemplate>`, `OverallHeader` (итоги) → `<groupTemplate>`, `GroupHeader` (шапка) → `<groupHeaderTemplate>`.
|
||||
|
||||
## Примеры
|
||||
|
||||
### Минимальный
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-compile v1.3 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.7 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -322,6 +322,18 @@ function Parse-ParamShorthand {
|
||||
$s = $s -replace '\s*@autoDates', ''
|
||||
}
|
||||
|
||||
# Extract @valueList flag
|
||||
if ($s -match '@valueList') {
|
||||
$result.valueListAllowed = $true
|
||||
$s = $s -replace '\s*@valueList', ''
|
||||
}
|
||||
|
||||
# Extract @hidden flag
|
||||
if ($s -match '@hidden') {
|
||||
$result.hidden = $true
|
||||
$s = $s -replace '\s*@hidden', ''
|
||||
}
|
||||
|
||||
# Split "Name: Type = Value"
|
||||
if ($s -match '^([^:]+):\s*(\S+)(\s*=\s*(.+))?$') {
|
||||
$result.name = $Matches[1].Trim()
|
||||
@@ -469,6 +481,9 @@ function Parse-FilterShorthand {
|
||||
} elseif ($valPart -match '^\d+(\.\d+)?$') {
|
||||
$result.value = $valPart
|
||||
$result["valueType"] = "xs:decimal"
|
||||
} elseif ($valPart -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.') {
|
||||
$result.value = $valPart
|
||||
$result["valueType"] = "dcscor:DesignTimeValue"
|
||||
} else {
|
||||
$result.value = $valPart
|
||||
$result["valueType"] = "xs:string"
|
||||
@@ -746,8 +761,9 @@ function Emit-CalcFields {
|
||||
if ($cf -is [string]) {
|
||||
$parsed = Parse-CalcShorthand $cf
|
||||
} else {
|
||||
$dp = if ($cf.dataPath) { "$($cf.dataPath)" } else { "$($cf.field)" }
|
||||
$parsed = @{
|
||||
dataPath = "$($cf.dataPath)"
|
||||
dataPath = $dp
|
||||
expression = "$($cf.expression)"
|
||||
}
|
||||
}
|
||||
@@ -844,8 +860,14 @@ function Emit-SingleParam {
|
||||
# Value
|
||||
Emit-ParamValue -type $parsed.type -val $parsed.value -indent "`t`t"
|
||||
|
||||
# Hidden implies useRestriction=true + availableAsField=false
|
||||
if ($parsed.hidden -eq $true) {
|
||||
$parsed.availableAsField = $false
|
||||
$parsed.useRestriction = $true
|
||||
}
|
||||
|
||||
# UseRestriction
|
||||
if ($p -isnot [string] -and $p.useRestriction -eq $true) {
|
||||
if ($parsed.useRestriction -eq $true -or ($p -isnot [string] -and $p.useRestriction -eq $true)) {
|
||||
X "`t`t<useRestriction>true</useRestriction>"
|
||||
}
|
||||
|
||||
@@ -859,6 +881,38 @@ function Emit-SingleParam {
|
||||
X "`t`t<availableAsField>false</availableAsField>"
|
||||
}
|
||||
|
||||
# ValueListAllowed
|
||||
if ($parsed.valueListAllowed -eq $true) {
|
||||
X "`t`t<valueListAllowed>true</valueListAllowed>"
|
||||
}
|
||||
|
||||
# AvailableValues
|
||||
if ($p -isnot [string] -and $p.availableValues) {
|
||||
foreach ($av in $p.availableValues) {
|
||||
$avVal = "$($av.value)"
|
||||
$avType = "xs:string"
|
||||
if ($avVal -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.') {
|
||||
$avType = "dcscor:DesignTimeValue"
|
||||
}
|
||||
X "`t`t<availableValue>"
|
||||
X "`t`t`t<value xsi:type=`"$avType`">$(Esc-Xml $avVal)</value>"
|
||||
if ($av.presentation) {
|
||||
X "`t`t`t<presentation xsi:type=`"v8:LocalStringType`">"
|
||||
X "`t`t`t`t<v8:item>"
|
||||
X "`t`t`t`t`t<v8:lang>ru</v8:lang>"
|
||||
X "`t`t`t`t`t<v8:content>$(Esc-Xml "$($av.presentation)")</v8:content>"
|
||||
X "`t`t`t`t</v8:item>"
|
||||
X "`t`t`t</presentation>"
|
||||
}
|
||||
X "`t`t</availableValue>"
|
||||
}
|
||||
}
|
||||
|
||||
# DenyIncompleteValues
|
||||
if ($p -isnot [string] -and $p.denyIncompleteValues -eq $true) {
|
||||
X "`t`t<denyIncompleteValues>true</denyIncompleteValues>"
|
||||
}
|
||||
|
||||
# Use
|
||||
if ($p -isnot [string] -and $p.use) {
|
||||
X "`t`t<use>$(Esc-Xml "$($p.use)")</use>"
|
||||
@@ -867,6 +921,8 @@ function Emit-SingleParam {
|
||||
X "`t</parameter>"
|
||||
}
|
||||
|
||||
$script:allParams = @()
|
||||
|
||||
function Emit-Parameters {
|
||||
if (-not $def.parameters) { return }
|
||||
foreach ($p in $def.parameters) {
|
||||
@@ -881,11 +937,16 @@ function Emit-Parameters {
|
||||
}
|
||||
if ($p.expression) { $parsed.expression = "$($p.expression)" }
|
||||
if ($p.availableAsField -eq $false) { $parsed.availableAsField = $false }
|
||||
if ($p.valueListAllowed -eq $true) { $parsed.valueListAllowed = $true }
|
||||
if ($p.hidden -eq $true) { $parsed.hidden = $true }
|
||||
if ($p.autoDates -eq $true) { $parsed.autoDates = $true }
|
||||
}
|
||||
|
||||
Emit-SingleParam -p $p -parsed $parsed
|
||||
|
||||
# Track parameter for auto dataParameters
|
||||
$script:allParams += @{ name = $parsed.name; hidden = [bool]$parsed.hidden; type = "$($parsed.type)"; value = $parsed.value }
|
||||
|
||||
# @autoDates: auto-generate ДатаНачала and ДатаОкончания
|
||||
if ($parsed.autoDates) {
|
||||
$paramName = $parsed.name
|
||||
@@ -929,6 +990,8 @@ function Emit-ParamValue {
|
||||
X "$indent<value xsi:type=`"xs:dateTime`">$(Esc-Xml $valStr)</value>"
|
||||
} elseif ($valStr -eq "true" -or $valStr -eq "false") {
|
||||
X "$indent<value xsi:type=`"xs:boolean`">$(Esc-Xml $valStr)</value>"
|
||||
} elseif ($valStr -match '^(ПланСчетов|Справочник|Перечисление|Документ|ПланВидовХарактеристик|ПланВидовРасчета|БизнесПроцесс|Задача|РегистрСведений|ПланОбмена)\.' -or $valStr -match '^(ChartOfAccounts|Catalog|Enum|Document|ChartOfCharacteristicTypes|ChartOfCalculationTypes|BusinessProcess|Task|InformationRegister|ExchangePlan)\.') {
|
||||
X "$indent<value xsi:type=`"dcscor:DesignTimeValue`">$(Esc-Xml $valStr)</value>"
|
||||
} else {
|
||||
X "$indent<value xsi:type=`"xs:string`">$(Esc-Xml $valStr)</value>"
|
||||
}
|
||||
@@ -1005,7 +1068,7 @@ function Emit-ColorValue {
|
||||
}
|
||||
|
||||
function Emit-CellAppearance {
|
||||
param($style, [double]$width = 0, [bool]$vMerge = $false, [double]$minHeight = 0)
|
||||
param($style, [double]$width = 0, [bool]$vMerge = $false, [bool]$hMerge = $false, [double]$minHeight = 0, $extraItems = @())
|
||||
$ind = "`t`t`t`t`t"
|
||||
X "`t`t`t`t<dcsat:appearance>"
|
||||
# Background color
|
||||
@@ -1098,6 +1161,15 @@ function Emit-CellAppearance {
|
||||
X "$ind`t<dcscor:value xsi:type=`"xs:boolean`">true</dcscor:value>"
|
||||
X "$ind</dcscor:item>"
|
||||
}
|
||||
# Horizontal merge
|
||||
if ($hMerge) {
|
||||
X "$ind<dcscor:item>"
|
||||
X "$ind`t<dcscor:parameter>ОбъединятьПоГоризонтали</dcscor:parameter>"
|
||||
X "$ind`t<dcscor:value xsi:type=`"xs:boolean`">true</dcscor:value>"
|
||||
X "$ind</dcscor:item>"
|
||||
}
|
||||
# Extra appearance items (e.g. drilldown Расшифровка)
|
||||
foreach ($ei in $extraItems) { X $ei }
|
||||
X "`t`t`t`t</dcsat:appearance>"
|
||||
}
|
||||
|
||||
@@ -1115,7 +1187,7 @@ function Emit-AreaTemplateDSL {
|
||||
$minHeight = if ($t.minHeight) { [double]$t.minHeight } else { 0 }
|
||||
$colCount = if ($widths.Count -gt 0) { $widths.Count } else { $rows[0].Count }
|
||||
|
||||
# Build merge map: vMerge[row][col] = $true if cell is merged with above
|
||||
# Build vertical merge map: vMerge[row][col] = $true if cell is merged with above
|
||||
$vMerge = @{}
|
||||
for ($r = $rows.Count - 1; $r -ge 1; $r--) {
|
||||
$vMerge[$r] = @{}
|
||||
@@ -1128,6 +1200,26 @@ function Emit-AreaTemplateDSL {
|
||||
}
|
||||
if (-not $vMerge.ContainsKey(0)) { $vMerge[0] = @{} }
|
||||
|
||||
# Build horizontal merge map: hMerge[row][col] = $true if cell is merged with left
|
||||
$hMerge = @{}
|
||||
for ($r = 0; $r -lt $rows.Count; $r++) {
|
||||
$hMerge[$r] = @{}
|
||||
for ($c = 0; $c -lt $colCount; $c++) {
|
||||
$cellVal = $rows[$r][$c]
|
||||
if ($cellVal -is [string] -and $cellVal -eq '>') {
|
||||
$hMerge[$r][$c] = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Build drilldown map: param_name -> drilldown_value
|
||||
$drilldownMap = @{}
|
||||
if ($t.parameters) {
|
||||
foreach ($tp in $t.parameters) {
|
||||
if ($tp.drilldown) { $drilldownMap["$($tp.name)"] = "$($tp.drilldown)" }
|
||||
}
|
||||
}
|
||||
|
||||
X "`t<template>"
|
||||
X "`t`t<name>$(Esc-Xml "$($t.name)")</name>"
|
||||
X "`t`t<template xmlns:dcsat=`"http://v8.1c.ru/8.1/data-composition-system/area-template`" xsi:type=`"dcsat:AreaTemplate`">"
|
||||
@@ -1137,7 +1229,8 @@ function Emit-AreaTemplateDSL {
|
||||
for ($c = 0; $c -lt $colCount; $c++) {
|
||||
$cellVal = $rows[$r][$c]
|
||||
$w = if ($c -lt $widths.Count) { [double]$widths[$c] } else { 0 }
|
||||
$isMerged = $vMerge[$r][$c] -eq $true
|
||||
$isVMerged = $vMerge[$r][$c] -eq $true
|
||||
$isHMerged = $hMerge[$r][$c] -eq $true
|
||||
# Check if this cell starts a vertical merge (next row has "|" in same column)
|
||||
$startsVMerge = $false
|
||||
for ($nr = $r + 1; $nr -lt $rows.Count; $nr++) {
|
||||
@@ -1145,18 +1238,34 @@ function Emit-AreaTemplateDSL {
|
||||
}
|
||||
|
||||
X "`t`t`t`t<dcsat:tableCell>"
|
||||
if ($isMerged) {
|
||||
# Merged cell — only appearance with vMerge flag + width
|
||||
if ($isVMerged) {
|
||||
# Vertically merged cell — only appearance with vMerge flag + width
|
||||
Emit-CellAppearance $style $w $true
|
||||
} elseif ($isHMerged) {
|
||||
# Horizontally merged cell — only appearance with hMerge flag + width
|
||||
Emit-CellAppearance $style $w $false $true
|
||||
} else {
|
||||
# Cell value
|
||||
if ($null -ne $cellVal -and $cellVal -ne '') {
|
||||
$cellStr = "$cellVal"
|
||||
# Unescape \| and \>
|
||||
if ($cellStr -eq '\|') { $cellStr = '|' }
|
||||
elseif ($cellStr -eq '\>') { $cellStr = '>' }
|
||||
if ($cellStr -match '^\{(.+)\}$') {
|
||||
# Parameter reference
|
||||
$paramName = $Matches[1]
|
||||
X "`t`t`t`t`t<dcsat:item xsi:type=`"dcsat:Field`">"
|
||||
X "`t`t`t`t`t`t<dcsat:value xsi:type=`"dcscor:Parameter`">$(Esc-Xml $Matches[1])</dcsat:value>"
|
||||
X "`t`t`t`t`t`t<dcsat:value xsi:type=`"dcscor:Parameter`">$(Esc-Xml $paramName)</dcsat:value>"
|
||||
X "`t`t`t`t`t</dcsat:item>"
|
||||
# Build drilldown appearance extra items
|
||||
$cellExtraItems = @()
|
||||
if ($drilldownMap.ContainsKey($paramName)) {
|
||||
$ddVal = $drilldownMap[$paramName]
|
||||
$cellExtraItems += "`t`t`t`t`t<dcscor:item>"
|
||||
$cellExtraItems += "`t`t`t`t`t`t<dcscor:parameter>Расшифровка</dcscor:parameter>"
|
||||
$cellExtraItems += "`t`t`t`t`t`t<dcscor:value xsi:type=`"dcscor:Parameter`">Расшифровка_$ddVal</dcscor:value>"
|
||||
$cellExtraItems += "`t`t`t`t`t</dcscor:item>"
|
||||
}
|
||||
} else {
|
||||
# Static text
|
||||
X "`t`t`t`t`t<dcsat:item xsi:type=`"dcsat:Field`">"
|
||||
@@ -1171,7 +1280,9 @@ function Emit-AreaTemplateDSL {
|
||||
}
|
||||
# Appearance
|
||||
$h = if ($r -eq 0) { $minHeight } else { 0 }
|
||||
Emit-CellAppearance $style $w $startsVMerge $h
|
||||
if (-not $cellExtraItems) { $cellExtraItems = @() }
|
||||
Emit-CellAppearance $style $w $startsVMerge $false $h $cellExtraItems
|
||||
$cellExtraItems = @()
|
||||
}
|
||||
X "`t`t`t`t</dcsat:tableCell>"
|
||||
}
|
||||
@@ -1186,6 +1297,18 @@ function Emit-AreaTemplateDSL {
|
||||
X "`t`t`t<dcsat:name>$(Esc-Xml "$($tp.name)")</dcsat:name>"
|
||||
X "`t`t`t<dcsat:expression>$(Esc-Xml "$($tp.expression)")</dcsat:expression>"
|
||||
X "`t`t</parameter>"
|
||||
# Drilldown parameter
|
||||
if ($tp.drilldown) {
|
||||
$ddVal = "$($tp.drilldown)"
|
||||
X "`t`t<parameter xmlns:dcsat=`"http://v8.1c.ru/8.1/data-composition-system/area-template`" xsi:type=`"dcsat:DetailsAreaTemplateParameter`">"
|
||||
X "`t`t`t<dcsat:name>Расшифровка_$(Esc-Xml $ddVal)</dcsat:name>"
|
||||
X "`t`t`t<dcsat:fieldExpression>"
|
||||
X "`t`t`t`t<dcsat:field>ИмяРесурса</dcsat:field>"
|
||||
X "`t`t`t`t<dcsat:expression>`"$(Esc-Xml $ddVal)`"</dcsat:expression>"
|
||||
X "`t`t`t</dcsat:fieldExpression>"
|
||||
X "`t`t`t<dcsat:mainAction>DrillDown</dcsat:mainAction>"
|
||||
X "`t`t</parameter>"
|
||||
}
|
||||
}
|
||||
}
|
||||
X "`t</template>"
|
||||
@@ -1211,6 +1334,18 @@ function Emit-Templates {
|
||||
X "`t`t`t<dcsat:name>$(Esc-Xml "$($tp.name)")</dcsat:name>"
|
||||
X "`t`t`t<dcsat:expression>$(Esc-Xml "$($tp.expression)")</dcsat:expression>"
|
||||
X "`t`t</parameter>"
|
||||
# Drilldown parameter
|
||||
if ($tp.drilldown) {
|
||||
$ddVal = "$($tp.drilldown)"
|
||||
X "`t`t<parameter xmlns:dcsat=`"http://v8.1c.ru/8.1/data-composition-system/area-template`" xsi:type=`"dcsat:DetailsAreaTemplateParameter`">"
|
||||
X "`t`t`t<dcsat:name>Расшифровка_$(Esc-Xml $ddVal)</dcsat:name>"
|
||||
X "`t`t`t<dcsat:fieldExpression>"
|
||||
X "`t`t`t`t<dcsat:field>ИмяРесурса</dcsat:field>"
|
||||
X "`t`t`t`t<dcsat:expression>`"$(Esc-Xml $ddVal)`"</dcsat:expression>"
|
||||
X "`t`t`t</dcsat:fieldExpression>"
|
||||
X "`t`t`t<dcsat:mainAction>DrillDown</dcsat:mainAction>"
|
||||
X "`t`t</parameter>"
|
||||
}
|
||||
}
|
||||
}
|
||||
X "`t</template>"
|
||||
@@ -1222,11 +1357,20 @@ function Emit-Templates {
|
||||
function Emit-GroupTemplates {
|
||||
if (-not $def.groupTemplates) { return }
|
||||
foreach ($gt in $def.groupTemplates) {
|
||||
X "`t<groupTemplate>"
|
||||
X "`t`t<groupField>$(Esc-Xml "$($gt.groupField)")</groupField>"
|
||||
X "`t`t<templateType>$(Esc-Xml "$($gt.templateType)")</templateType>"
|
||||
$ttype = if ($gt.templateType) { "$($gt.templateType)" } else { "Header" }
|
||||
$isHeader = ($ttype -eq 'GroupHeader')
|
||||
$tag = if ($isHeader) { 'groupHeaderTemplate' } else { 'groupTemplate' }
|
||||
$xmlTType = if ($isHeader) { 'Header' } else { $ttype }
|
||||
|
||||
X "`t<$tag>"
|
||||
if ($gt.groupName) {
|
||||
X "`t`t<groupName>$(Esc-Xml "$($gt.groupName)")</groupName>"
|
||||
} elseif ($gt.groupField) {
|
||||
X "`t`t<groupField>$(Esc-Xml "$($gt.groupField)")</groupField>"
|
||||
}
|
||||
X "`t`t<templateType>$(Esc-Xml $xmlTType)</templateType>"
|
||||
X "`t`t<template>$(Esc-Xml "$($gt.template)")</template>"
|
||||
X "`t</groupTemplate>"
|
||||
X "`t</$tag>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1249,6 +1393,22 @@ function Emit-Selection {
|
||||
X "$indent`t`t<dcsset:field>$(Esc-Xml $item)</dcsset:field>"
|
||||
X "$indent`t</dcsset:item>"
|
||||
}
|
||||
} elseif ($item.folder) {
|
||||
X "$indent`t<dcsset:item xsi:type=`"dcsset:SelectedItemFolder`">"
|
||||
X "$indent`t`t<dcsset:lwsTitle>"
|
||||
X "$indent`t`t`t<v8:item>"
|
||||
X "$indent`t`t`t`t<v8:lang>ru</v8:lang>"
|
||||
X "$indent`t`t`t`t<v8:content>$(Esc-Xml "$($item.folder)")</v8:content>"
|
||||
X "$indent`t`t`t</v8:item>"
|
||||
X "$indent`t`t</dcsset:lwsTitle>"
|
||||
foreach ($sub in $item.items) {
|
||||
$subName = if ($sub -is [string]) { $sub } else { "$($sub.field)" }
|
||||
X "$indent`t`t<dcsset:item xsi:type=`"dcsset:SelectedItemField`">"
|
||||
X "$indent`t`t`t<dcsset:field>$(Esc-Xml $subName)</dcsset:field>"
|
||||
X "$indent`t`t</dcsset:item>"
|
||||
}
|
||||
X "$indent`t`t<dcsset:placement>Auto</dcsset:placement>"
|
||||
X "$indent`t</dcsset:item>"
|
||||
} else {
|
||||
X "$indent`t<dcsset:item xsi:type=`"dcsset:SelectedItemField`">"
|
||||
X "$indent`t`t<dcsset:field>$(Esc-Xml "$($item.field)")</dcsset:field>"
|
||||
@@ -1432,7 +1592,7 @@ function Emit-AppearanceValue {
|
||||
X "$indent`t<dcscor:value xsi:type=`"v8ui:Color`">$(Esc-Xml $actualVal)</dcscor:value>"
|
||||
} elseif ($actualVal -eq "true" -or $actualVal -eq "false") {
|
||||
X "$indent`t<dcscor:value xsi:type=`"xs:boolean`">$actualVal</dcscor:value>"
|
||||
} elseif ($key -eq "Текст" -or $key -eq "Заголовок") {
|
||||
} elseif ($key -eq "Текст" -or $key -eq "Заголовок" -or $key -eq "Формат") {
|
||||
X "$indent`t<dcscor:value xsi:type=`"v8:LocalStringType`">"
|
||||
X "$indent`t`t<v8:item>"
|
||||
X "$indent`t`t`t<v8:lang>ru</v8:lang>"
|
||||
@@ -1661,6 +1821,10 @@ function Parse-StructureShorthand {
|
||||
if ($seg -match '^(?i)(details|детали)$') {
|
||||
# Empty groupBy = detailed records
|
||||
$group | Add-Member -NotePropertyName "groupBy" -NotePropertyValue @()
|
||||
} elseif ($seg -match '^(.+)\[(.+)\]$') {
|
||||
# Named group: "ИмяГруппы[Поле]"
|
||||
$group | Add-Member -NotePropertyName "name" -NotePropertyValue $Matches[1].Trim()
|
||||
$group | Add-Member -NotePropertyName "groupBy" -NotePropertyValue @($Matches[2].Trim())
|
||||
} else {
|
||||
$group | Add-Member -NotePropertyName "groupBy" -NotePropertyValue @($seg)
|
||||
}
|
||||
@@ -1868,7 +2032,22 @@ function Emit-SettingsVariants {
|
||||
}
|
||||
|
||||
# DataParameters
|
||||
if ($s.dataParameters) {
|
||||
if ($s.dataParameters -eq 'auto') {
|
||||
# Auto-generate dataParameters for all non-hidden params
|
||||
$autoDP = @()
|
||||
foreach ($ap in $script:allParams) {
|
||||
if (-not $ap.hidden) {
|
||||
$dpItem = New-Object PSObject
|
||||
$dpItem | Add-Member -NotePropertyName "parameter" -NotePropertyValue $ap.name
|
||||
$dpItem | Add-Member -NotePropertyName "use" -NotePropertyValue $false
|
||||
$dpItem | Add-Member -NotePropertyName "userSettingID" -NotePropertyValue "auto"
|
||||
$autoDP += $dpItem
|
||||
}
|
||||
}
|
||||
if ($autoDP.Count -gt 0) {
|
||||
Emit-DataParameters -items $autoDP -indent "`t`t`t"
|
||||
}
|
||||
} elseif ($s.dataParameters) {
|
||||
Emit-DataParameters -items $s.dataParameters -indent "`t`t`t"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# skd-compile v1.3 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.7 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -12,6 +12,10 @@ import uuid
|
||||
def esc_xml(s):
|
||||
return s.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
|
||||
|
||||
def fmt_dec(v):
|
||||
"""Format decimal: 30.0 → '30', 16.625 → '16.625' (match PS1 output)."""
|
||||
return str(int(v)) if v == int(v) else str(v)
|
||||
|
||||
|
||||
def resolve_query_value(val, base_dir):
|
||||
if not val.startswith("@"):
|
||||
@@ -233,6 +237,16 @@ def parse_param_shorthand(s):
|
||||
result['autoDates'] = True
|
||||
s = re.sub(r'\s*@autoDates', '', s)
|
||||
|
||||
# Extract @valueList flag
|
||||
if '@valueList' in s:
|
||||
result['valueListAllowed'] = True
|
||||
s = re.sub(r'\s*@valueList', '', s)
|
||||
|
||||
# Extract @hidden flag
|
||||
if '@hidden' in s:
|
||||
result['hidden'] = True
|
||||
s = re.sub(r'\s*@hidden', '', s)
|
||||
|
||||
# Split "Name: Type = Value"
|
||||
m = re.match(r'^([^:]+):\s*(\S+)(\s*=\s*(.+))?$', s)
|
||||
if m:
|
||||
@@ -361,6 +375,9 @@ def parse_filter_shorthand(s):
|
||||
elif re.match(r'^\d+(\.\d+)?$', val_part):
|
||||
result['value'] = val_part
|
||||
result['valueType'] = 'xs:decimal'
|
||||
elif re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.', val_part):
|
||||
result['value'] = val_part
|
||||
result['valueType'] = 'dcscor:DesignTimeValue'
|
||||
else:
|
||||
result['value'] = val_part
|
||||
result['valueType'] = 'xs:string'
|
||||
@@ -598,7 +615,7 @@ def emit_calc_fields(lines, defn):
|
||||
is_obj = False
|
||||
else:
|
||||
parsed = {
|
||||
'dataPath': str(cf.get('dataPath', '')),
|
||||
'dataPath': str(cf.get('dataPath') or cf.get('field', '')),
|
||||
'expression': str(cf.get('expression', '')),
|
||||
}
|
||||
is_obj = True
|
||||
@@ -692,6 +709,8 @@ def emit_param_value(lines, type_str, val, indent):
|
||||
lines.append(f'{indent}<value xsi:type="xs:dateTime">{esc_xml(val_str)}</value>')
|
||||
elif val_str == 'true' or val_str == 'false':
|
||||
lines.append(f'{indent}<value xsi:type="xs:boolean">{esc_xml(val_str)}</value>')
|
||||
elif re.match(r'^(ПланСчетов|Справочник|Перечисление|Документ|ПланВидовХарактеристик|ПланВидовРасчета|БизнесПроцесс|Задача|РегистрСведений|ПланОбмена|ChartOfAccounts|Catalog|Enum|Document|ChartOfCharacteristicTypes|ChartOfCalculationTypes|BusinessProcess|Task|InformationRegister|ExchangePlan)\.', val_str):
|
||||
lines.append(f'{indent}<value xsi:type="dcscor:DesignTimeValue">{esc_xml(val_str)}</value>')
|
||||
else:
|
||||
lines.append(f'{indent}<value xsi:type="xs:string">{esc_xml(val_str)}</value>')
|
||||
|
||||
@@ -716,18 +735,51 @@ def emit_single_param(lines, p, parsed):
|
||||
# Value
|
||||
emit_param_value(lines, parsed.get('type', ''), parsed.get('value'), '\t\t')
|
||||
|
||||
# Hidden implies useRestriction=true + availableAsField=false
|
||||
if parsed.get('hidden') is True:
|
||||
parsed['availableAsField'] = False
|
||||
parsed['useRestriction'] = True
|
||||
|
||||
# UseRestriction
|
||||
if p is not None and not isinstance(p, str) and p.get('useRestriction') is True:
|
||||
if parsed.get('useRestriction') is True or (p is not None and not isinstance(p, str) and p.get('useRestriction') is True):
|
||||
lines.append('\t\t<useRestriction>true</useRestriction>')
|
||||
|
||||
# Expression
|
||||
if parsed.get('expression'):
|
||||
lines.append(f'\t\t<expression>{esc_xml(parsed["expression"])}</expression>')
|
||||
if parsed.get('hidden'):
|
||||
parsed['availableAsField'] = False
|
||||
|
||||
# AvailableAsField
|
||||
if parsed.get('availableAsField') is False:
|
||||
lines.append('\t\t<availableAsField>false</availableAsField>')
|
||||
|
||||
# ValueListAllowed
|
||||
if parsed.get('valueListAllowed'):
|
||||
lines.append('\t\t<valueListAllowed>true</valueListAllowed>')
|
||||
|
||||
# AvailableValues
|
||||
if p is not None and not isinstance(p, str) and p.get('availableValues'):
|
||||
for av in p['availableValues']:
|
||||
av_val = str(av.get('value', ''))
|
||||
av_type = 'xs:string'
|
||||
if re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.', av_val):
|
||||
av_type = 'dcscor:DesignTimeValue'
|
||||
lines.append('\t\t<availableValue>')
|
||||
lines.append(f'\t\t\t<value xsi:type="{av_type}">{esc_xml(av_val)}</value>')
|
||||
if av.get('presentation'):
|
||||
lines.append('\t\t\t<presentation xsi:type="v8:LocalStringType">')
|
||||
lines.append('\t\t\t\t<v8:item>')
|
||||
lines.append('\t\t\t\t\t<v8:lang>ru</v8:lang>')
|
||||
lines.append(f'\t\t\t\t\t<v8:content>{esc_xml(str(av["presentation"]))}</v8:content>')
|
||||
lines.append('\t\t\t\t</v8:item>')
|
||||
lines.append('\t\t\t</presentation>')
|
||||
lines.append('\t\t</availableValue>')
|
||||
|
||||
# DenyIncompleteValues
|
||||
if p is not None and not isinstance(p, str) and p.get('denyIncompleteValues') is True:
|
||||
lines.append('\t\t<denyIncompleteValues>true</denyIncompleteValues>')
|
||||
|
||||
# Use
|
||||
if p is not None and not isinstance(p, str) and p.get('use'):
|
||||
lines.append(f'\t\t<use>{esc_xml(str(p["use"]))}</use>')
|
||||
@@ -735,7 +787,12 @@ def emit_single_param(lines, p, parsed):
|
||||
lines.append('\t</parameter>')
|
||||
|
||||
|
||||
_all_params = []
|
||||
|
||||
|
||||
def emit_parameters(lines, defn):
|
||||
global _all_params
|
||||
_all_params = []
|
||||
if not defn.get('parameters'):
|
||||
return
|
||||
for p in defn['parameters']:
|
||||
@@ -752,11 +809,23 @@ def emit_parameters(lines, defn):
|
||||
parsed['expression'] = str(p['expression'])
|
||||
if p.get('availableAsField') is False:
|
||||
parsed['availableAsField'] = False
|
||||
if p.get('valueListAllowed') is True:
|
||||
parsed['valueListAllowed'] = True
|
||||
if p.get('hidden') is True:
|
||||
parsed['hidden'] = True
|
||||
if p.get('autoDates') is True:
|
||||
parsed['autoDates'] = True
|
||||
|
||||
emit_single_param(lines, p, parsed)
|
||||
|
||||
# Track parameter for auto dataParameters
|
||||
_all_params.append({
|
||||
'name': parsed['name'],
|
||||
'hidden': bool(parsed.get('hidden')),
|
||||
'type': parsed.get('type', ''),
|
||||
'value': parsed.get('value'),
|
||||
})
|
||||
|
||||
# @autoDates: auto-generate ДатаНачала and ДатаОкончания
|
||||
if parsed.get('autoDates'):
|
||||
param_name = parsed['name']
|
||||
@@ -827,7 +896,7 @@ def _emit_color_value(lines, color, indent):
|
||||
lines.append(f'{indent}<dcscor:value xsi:type="v8ui:Color">{esc_xml(color)}</dcscor:value>')
|
||||
|
||||
|
||||
def _emit_cell_appearance(lines, style, width=0, v_merge=False, min_height=0):
|
||||
def _emit_cell_appearance(lines, style, width=0, v_merge=False, h_merge=False, min_height=0, extra_items=None):
|
||||
ind = '\t\t\t\t\t'
|
||||
lines.append('\t\t\t\t<dcsat:appearance>')
|
||||
# Background color
|
||||
@@ -891,11 +960,11 @@ def _emit_cell_appearance(lines, style, width=0, v_merge=False, min_height=0):
|
||||
if width and width > 0:
|
||||
lines.append(f'{ind}<dcscor:item>')
|
||||
lines.append(f'{ind}\t<dcscor:parameter>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f\u0428\u0438\u0440\u0438\u043d\u0430</dcscor:parameter>')
|
||||
lines.append(f'{ind}\t<dcscor:value xsi:type="xs:decimal">{width}</dcscor:value>')
|
||||
lines.append(f'{ind}\t<dcscor:value xsi:type="xs:decimal">{fmt_dec(width)}</dcscor:value>')
|
||||
lines.append(f'{ind}</dcscor:item>')
|
||||
lines.append(f'{ind}<dcscor:item>')
|
||||
lines.append(f'{ind}\t<dcscor:parameter>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f\u0428\u0438\u0440\u0438\u043d\u0430</dcscor:parameter>')
|
||||
lines.append(f'{ind}\t<dcscor:value xsi:type="xs:decimal">{width}</dcscor:value>')
|
||||
lines.append(f'{ind}\t<dcscor:value xsi:type="xs:decimal">{fmt_dec(width)}</dcscor:value>')
|
||||
lines.append(f'{ind}</dcscor:item>')
|
||||
# Min height
|
||||
if min_height and min_height > 0:
|
||||
@@ -909,6 +978,16 @@ def _emit_cell_appearance(lines, style, width=0, v_merge=False, min_height=0):
|
||||
lines.append(f'{ind}\t<dcscor:parameter>\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u041f\u043e\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438</dcscor:parameter>')
|
||||
lines.append(f'{ind}\t<dcscor:value xsi:type="xs:boolean">true</dcscor:value>')
|
||||
lines.append(f'{ind}</dcscor:item>')
|
||||
# Horizontal merge
|
||||
if h_merge:
|
||||
lines.append(f'{ind}<dcscor:item>')
|
||||
lines.append(f'{ind}\t<dcscor:parameter>\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u041f\u043e\u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438</dcscor:parameter>')
|
||||
lines.append(f'{ind}\t<dcscor:value xsi:type="xs:boolean">true</dcscor:value>')
|
||||
lines.append(f'{ind}</dcscor:item>')
|
||||
# Extra appearance items (e.g. drilldown)
|
||||
if extra_items:
|
||||
for ei in extra_items:
|
||||
lines.append(ei)
|
||||
lines.append('\t\t\t\t</dcsat:appearance>')
|
||||
|
||||
|
||||
@@ -924,7 +1003,7 @@ def _emit_area_template_dsl(lines, t):
|
||||
min_height = float(t.get('minHeight', 0))
|
||||
col_count = len(widths) if widths else len(rows[0])
|
||||
|
||||
# Build merge map
|
||||
# Build vertical merge map
|
||||
v_merge = {}
|
||||
for r in range(len(rows) - 1, 0, -1):
|
||||
v_merge[r] = {}
|
||||
@@ -935,6 +1014,22 @@ def _emit_area_template_dsl(lines, t):
|
||||
if 0 not in v_merge:
|
||||
v_merge[0] = {}
|
||||
|
||||
# Build horizontal merge map
|
||||
h_merge = {}
|
||||
for r in range(len(rows)):
|
||||
h_merge[r] = {}
|
||||
for c in range(col_count):
|
||||
cell_val = rows[r][c] if c < len(rows[r]) else None
|
||||
if isinstance(cell_val, str) and cell_val == '>':
|
||||
h_merge[r][c] = True
|
||||
|
||||
# Build drilldown map: param_name -> drilldown_value
|
||||
drilldown_map = {}
|
||||
if t.get('parameters'):
|
||||
for tp in t['parameters']:
|
||||
if tp.get('drilldown'):
|
||||
drilldown_map[str(tp['name'])] = str(tp['drilldown'])
|
||||
|
||||
lines.append('\t<template>')
|
||||
lines.append(f'\t\t<name>{esc_xml(str(t["name"]))}</name>')
|
||||
lines.append('\t\t<template xmlns:dcsat="http://v8.1c.ru/8.1/data-composition-system/area-template" xsi:type="dcsat:AreaTemplate">')
|
||||
@@ -944,7 +1039,8 @@ def _emit_area_template_dsl(lines, t):
|
||||
for c in range(col_count):
|
||||
cell_val = rows[r][c] if c < len(rows[r]) else None
|
||||
w = float(widths[c]) if c < len(widths) else 0
|
||||
is_merged = v_merge.get(r, {}).get(c, False)
|
||||
is_v_merged = v_merge.get(r, {}).get(c, False)
|
||||
is_h_merged = h_merge.get(r, {}).get(c, False)
|
||||
# Check if this cell starts a vertical merge
|
||||
starts_v_merge = False
|
||||
for nr in range(r + 1, len(rows)):
|
||||
@@ -954,16 +1050,32 @@ def _emit_area_template_dsl(lines, t):
|
||||
break
|
||||
|
||||
lines.append('\t\t\t\t<dcsat:tableCell>')
|
||||
if is_merged:
|
||||
if is_v_merged:
|
||||
_emit_cell_appearance(lines, style, w, True)
|
||||
elif is_h_merged:
|
||||
_emit_cell_appearance(lines, style, w, h_merge=True)
|
||||
else:
|
||||
cell_extra_items = []
|
||||
if cell_val is not None and str(cell_val) != '':
|
||||
cell_str = str(cell_val)
|
||||
# Unescape \| and \>
|
||||
if cell_str == '\\|':
|
||||
cell_str = '|'
|
||||
elif cell_str == '\\>':
|
||||
cell_str = '>'
|
||||
m = re.match(r'^\{(.+)\}$', cell_str)
|
||||
if m:
|
||||
param_name = m.group(1)
|
||||
lines.append('\t\t\t\t\t<dcsat:item xsi:type="dcsat:Field">')
|
||||
lines.append(f'\t\t\t\t\t\t<dcsat:value xsi:type="dcscor:Parameter">{esc_xml(m.group(1))}</dcsat:value>')
|
||||
lines.append(f'\t\t\t\t\t\t<dcsat:value xsi:type="dcscor:Parameter">{esc_xml(param_name)}</dcsat:value>')
|
||||
lines.append('\t\t\t\t\t</dcsat:item>')
|
||||
# Build drilldown appearance extra items
|
||||
if param_name in drilldown_map:
|
||||
dd_val = drilldown_map[param_name]
|
||||
cell_extra_items.append('\t\t\t\t\t<dcscor:item>')
|
||||
cell_extra_items.append(f'\t\t\t\t\t\t<dcscor:parameter>\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430</dcscor:parameter>')
|
||||
cell_extra_items.append(f'\t\t\t\t\t\t<dcscor:value xsi:type="dcscor:Parameter">\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430_{dd_val}</dcscor:value>')
|
||||
cell_extra_items.append('\t\t\t\t\t</dcscor:item>')
|
||||
else:
|
||||
lines.append('\t\t\t\t\t<dcsat:item xsi:type="dcsat:Field">')
|
||||
lines.append('\t\t\t\t\t\t<dcsat:value xsi:type="v8:LocalStringType">')
|
||||
@@ -974,7 +1086,7 @@ def _emit_area_template_dsl(lines, t):
|
||||
lines.append('\t\t\t\t\t\t</dcsat:value>')
|
||||
lines.append('\t\t\t\t\t</dcsat:item>')
|
||||
h = min_height if r == 0 else 0
|
||||
_emit_cell_appearance(lines, style, w, starts_v_merge, h)
|
||||
_emit_cell_appearance(lines, style, w, starts_v_merge, False, h, cell_extra_items or None)
|
||||
lines.append('\t\t\t\t</dcsat:tableCell>')
|
||||
lines.append('\t\t\t</dcsat:item>')
|
||||
|
||||
@@ -985,6 +1097,17 @@ def _emit_area_template_dsl(lines, t):
|
||||
lines.append(f'\t\t\t<dcsat:name>{esc_xml(str(tp["name"]))}</dcsat:name>')
|
||||
lines.append(f'\t\t\t<dcsat:expression>{esc_xml(str(tp["expression"]))}</dcsat:expression>')
|
||||
lines.append('\t\t</parameter>')
|
||||
# Drilldown parameter
|
||||
if tp.get('drilldown'):
|
||||
dd_val = str(tp['drilldown'])
|
||||
lines.append('\t\t<parameter xmlns:dcsat="http://v8.1c.ru/8.1/data-composition-system/area-template" xsi:type="dcsat:DetailsAreaTemplateParameter">')
|
||||
lines.append(f'\t\t\t<dcsat:name>\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430_{esc_xml(dd_val)}</dcsat:name>')
|
||||
lines.append('\t\t\t<dcsat:fieldExpression>')
|
||||
lines.append('\t\t\t\t<dcsat:field>\u0418\u043c\u044f\u0420\u0435\u0441\u0443\u0440\u0441\u0430</dcsat:field>')
|
||||
lines.append(f'\t\t\t\t<dcsat:expression>"{esc_xml(dd_val)}"</dcsat:expression>')
|
||||
lines.append('\t\t\t</dcsat:fieldExpression>')
|
||||
lines.append('\t\t\t<dcsat:mainAction>DrillDown</dcsat:mainAction>')
|
||||
lines.append('\t\t</parameter>')
|
||||
lines.append('\t</template>')
|
||||
|
||||
|
||||
@@ -1007,6 +1130,17 @@ def emit_templates(lines, defn):
|
||||
lines.append(f'\t\t\t<dcsat:name>{esc_xml(str(tp["name"]))}</dcsat:name>')
|
||||
lines.append(f'\t\t\t<dcsat:expression>{esc_xml(str(tp["expression"]))}</dcsat:expression>')
|
||||
lines.append('\t\t</parameter>')
|
||||
# Drilldown parameter
|
||||
if tp.get('drilldown'):
|
||||
dd_val = str(tp['drilldown'])
|
||||
lines.append('\t\t<parameter xmlns:dcsat="http://v8.1c.ru/8.1/data-composition-system/area-template" xsi:type="dcsat:DetailsAreaTemplateParameter">')
|
||||
lines.append(f'\t\t\t<dcsat:name>\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430_{esc_xml(dd_val)}</dcsat:name>')
|
||||
lines.append('\t\t\t<dcsat:fieldExpression>')
|
||||
lines.append('\t\t\t\t<dcsat:field>\u0418\u043c\u044f\u0420\u0435\u0441\u0443\u0440\u0441\u0430</dcsat:field>')
|
||||
lines.append(f'\t\t\t\t<dcsat:expression>"{esc_xml(dd_val)}"</dcsat:expression>')
|
||||
lines.append('\t\t\t</dcsat:fieldExpression>')
|
||||
lines.append('\t\t\t<dcsat:mainAction>DrillDown</dcsat:mainAction>')
|
||||
lines.append('\t\t</parameter>')
|
||||
lines.append('\t</template>')
|
||||
|
||||
|
||||
@@ -1016,11 +1150,19 @@ def emit_group_templates(lines, defn):
|
||||
if not defn.get('groupTemplates'):
|
||||
return
|
||||
for gt in defn['groupTemplates']:
|
||||
lines.append('\t<groupTemplate>')
|
||||
lines.append(f'\t\t<groupField>{esc_xml(str(gt["groupField"]))}</groupField>')
|
||||
lines.append(f'\t\t<templateType>{esc_xml(str(gt["templateType"]))}</templateType>')
|
||||
ttype = str(gt.get('templateType', '')) or 'Header'
|
||||
is_header = (ttype == 'GroupHeader')
|
||||
tag = 'groupHeaderTemplate' if is_header else 'groupTemplate'
|
||||
xml_ttype = 'Header' if is_header else ttype
|
||||
|
||||
lines.append(f'\t<{tag}>')
|
||||
if gt.get('groupName'):
|
||||
lines.append(f'\t\t<groupName>{esc_xml(str(gt["groupName"]))}</groupName>')
|
||||
elif gt.get('groupField'):
|
||||
lines.append(f'\t\t<groupField>{esc_xml(str(gt["groupField"]))}</groupField>')
|
||||
lines.append(f'\t\t<templateType>{esc_xml(xml_ttype)}</templateType>')
|
||||
lines.append(f'\t\t<template>{esc_xml(str(gt["template"]))}</template>')
|
||||
lines.append('\t</groupTemplate>')
|
||||
lines.append(f'\t</{tag}>')
|
||||
|
||||
|
||||
# === Settings Variants ===
|
||||
@@ -1039,6 +1181,21 @@ def emit_selection(lines, items, indent, skip_auto=False):
|
||||
lines.append(f'{indent}\t<dcsset:item xsi:type="dcsset:SelectedItemField">')
|
||||
lines.append(f'{indent}\t\t<dcsset:field>{esc_xml(item)}</dcsset:field>')
|
||||
lines.append(f'{indent}\t</dcsset:item>')
|
||||
elif item.get('folder'):
|
||||
lines.append(f'{indent}\t<dcsset:item xsi:type="dcsset:SelectedItemFolder">')
|
||||
lines.append(f'{indent}\t\t<dcsset:lwsTitle>')
|
||||
lines.append(f'{indent}\t\t\t<v8:item>')
|
||||
lines.append(f'{indent}\t\t\t\t<v8:lang>ru</v8:lang>')
|
||||
lines.append(f'{indent}\t\t\t\t<v8:content>{esc_xml(str(item["folder"]))}</v8:content>')
|
||||
lines.append(f'{indent}\t\t\t</v8:item>')
|
||||
lines.append(f'{indent}\t\t</dcsset:lwsTitle>')
|
||||
for sub in (item.get('items') or []):
|
||||
sub_name = str(sub.get('field', sub)) if isinstance(sub, dict) else str(sub)
|
||||
lines.append(f'{indent}\t\t<dcsset:item xsi:type="dcsset:SelectedItemField">')
|
||||
lines.append(f'{indent}\t\t\t<dcsset:field>{esc_xml(sub_name)}</dcsset:field>')
|
||||
lines.append(f'{indent}\t\t</dcsset:item>')
|
||||
lines.append(f'{indent}\t\t<dcsset:placement>Auto</dcsset:placement>')
|
||||
lines.append(f'{indent}\t</dcsset:item>')
|
||||
else:
|
||||
lines.append(f'{indent}\t<dcsset:item xsi:type="dcsset:SelectedItemField">')
|
||||
lines.append(f'{indent}\t\t<dcsset:field>{esc_xml(str(item["field"]))}</dcsset:field>')
|
||||
@@ -1191,7 +1348,7 @@ def emit_appearance_value(lines, key, val, indent):
|
||||
lines.append(f'{indent}\t<dcscor:value xsi:type="v8ui:Color">{esc_xml(actual_val)}</dcscor:value>')
|
||||
elif actual_val == 'true' or actual_val == 'false':
|
||||
lines.append(f'{indent}\t<dcscor:value xsi:type="xs:boolean">{actual_val}</dcscor:value>')
|
||||
elif key == '\u0422\u0435\u043a\u0441\u0442' or key == '\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a':
|
||||
elif key in ('\u0422\u0435\u043a\u0441\u0442', '\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a', '\u0424\u043e\u0440\u043c\u0430\u0442'):
|
||||
lines.append(f'{indent}\t<dcscor:value xsi:type="v8:LocalStringType">')
|
||||
lines.append(f'{indent}\t\t<v8:item>')
|
||||
lines.append(f'{indent}\t\t\t<v8:lang>ru</v8:lang>')
|
||||
@@ -1376,7 +1533,13 @@ def parse_structure_shorthand(s):
|
||||
if re.match(r'(?i)^(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg):
|
||||
group['groupBy'] = []
|
||||
else:
|
||||
group['groupBy'] = [seg]
|
||||
# Named group: "ИмяГруппы[Поле]"
|
||||
m_named = re.match(r'^(.+)\[(.+)\]$', seg)
|
||||
if m_named:
|
||||
group['name'] = m_named.group(1).strip()
|
||||
group['groupBy'] = [m_named.group(2).strip()]
|
||||
else:
|
||||
group['groupBy'] = [seg]
|
||||
|
||||
if innermost is not None:
|
||||
group['children'] = [innermost]
|
||||
@@ -1540,7 +1703,19 @@ def emit_settings_variants(lines, defn):
|
||||
emit_output_parameters(lines, s['outputParameters'], '\t\t\t')
|
||||
|
||||
# DataParameters
|
||||
if s.get('dataParameters'):
|
||||
if s.get('dataParameters') == 'auto':
|
||||
# Auto-generate dataParameters for all non-hidden params
|
||||
auto_dp = []
|
||||
for ap in _all_params:
|
||||
if not ap['hidden']:
|
||||
auto_dp.append({
|
||||
'parameter': ap['name'],
|
||||
'use': False,
|
||||
'userSettingID': 'auto',
|
||||
})
|
||||
if auto_dp:
|
||||
emit_data_parameters(lines, auto_dp, '\t\t\t')
|
||||
elif s.get('dataParameters'):
|
||||
emit_data_parameters(lines, s['dataParameters'], '\t\t\t')
|
||||
|
||||
# Structure (supports string shorthand)
|
||||
@@ -1548,6 +1723,8 @@ def emit_settings_variants(lines, defn):
|
||||
struct_items = s['structure']
|
||||
if isinstance(struct_items, str):
|
||||
struct_items = parse_structure_shorthand(struct_items)
|
||||
elif isinstance(struct_items, dict):
|
||||
struct_items = [struct_items]
|
||||
for item in struct_items:
|
||||
emit_structure_item(lines, item, '\t\t\t')
|
||||
|
||||
|
||||
@@ -79,6 +79,18 @@ Shorthand: `"Имя [Заголовок]: тип = Выражение"`.
|
||||
|
||||
`@autoDates` генерирует `ДатаНачала` и `ДатаОкончания` автоматически.
|
||||
|
||||
### modify-parameter — изменить существующий параметр
|
||||
|
||||
Находит параметр по имени, добавляет/обновляет свойства.
|
||||
|
||||
```
|
||||
"ПорядокОкругления use=Always"
|
||||
"ПорядокОкругления denyIncompleteValues=true"
|
||||
"ПорядокОкругления availableValue=Перечисление.Округления.Окр1 presentation=руб."
|
||||
```
|
||||
|
||||
`availableValue=` добавляет один элемент списка допустимых значений (можно несколько через `;;`). Тип значения определяется автоматически (DesignTimeValue для ссылок).
|
||||
|
||||
### add-filter — добавить фильтр в вариант
|
||||
|
||||
Shorthand: `"Поле оператор значение @флаги"`. Флаги: `@off`, `@user`, `@quickAccess`, `@normal`, `@inaccessible`.
|
||||
@@ -112,6 +124,15 @@ Shorthand: `"Поле [desc]"`. По умолчанию asc. `Auto` — авто
|
||||
```
|
||||
"Номенклатура"
|
||||
"Auto"
|
||||
"Folder(Поступление: ПолеА, ПолеБ, ПолеВ)"
|
||||
```
|
||||
|
||||
`Folder(Название: поле1, поле2)` — группа полей (SelectedItemFolder) с заголовком и `placement=Auto`.
|
||||
|
||||
`@group=ИмяГруппировки` — добавить в selection именованной группировки (вместо уровня варианта):
|
||||
|
||||
```
|
||||
"Folder(Поступление: ПолеА, ПолеБ) @group=ДанныеОтчета"
|
||||
```
|
||||
|
||||
### add-dataSetLink — добавить связь наборов данных
|
||||
@@ -157,7 +178,17 @@ Shorthand: `"Параметр = значение [when условие] [for По
|
||||
"Формат = ЧДЦ=2 for Цена, Сумма"
|
||||
```
|
||||
|
||||
Типы значений (автодетект): `web:*`/`style:*`/`win:*` → цвет, `true`/`false` → boolean, иначе строка.
|
||||
Типы значений appearance (автодетект): `web:*`/`style:*`/`win:*` → Color, `true`/`false` → Boolean, параметр `Формат`/`Текст`/`Заголовок` → LocalStringType, иначе String.
|
||||
|
||||
Типы значений фильтра (автодетект): `Перечисление.*`/`Справочник.*`/`ПланСчетов.*`/`Документ.*` → DesignTimeValue, `true`/`false` → Boolean, дата → DateTime, числа → Decimal, иначе String.
|
||||
|
||||
OrGroup: несколько условий через ` or ` в `when` объединяются в FilterItemGroup/OrGroup:
|
||||
|
||||
```
|
||||
"Формат = ЧЦ=15; ЧДЦ=0 when ПараметрыДанных.Округление = Перечисление.Округления.Окр1 or ПараметрыДанных.Округление = Перечисление.Округления.Окр1000"
|
||||
```
|
||||
|
||||
**Важно**: для параметров данных используйте префикс `ПараметрыДанных.` в поле фильтра.
|
||||
|
||||
### set-query — заменить текст запроса
|
||||
|
||||
@@ -188,8 +219,11 @@ Shorthand: `"Поле1 > Поле2 > details"`. `details`/`детали` — д
|
||||
```
|
||||
"Организация > Номенклатура > details"
|
||||
"details"
|
||||
"СчетМеждународногоУчета @name=ДанныеОтчета"
|
||||
```
|
||||
|
||||
`@name=Имя` — присваивает имя группировке (`<dcsset:name>`). Используется для привязки шаблонов через `groupName`.
|
||||
|
||||
### modify-field — изменить существующее поле
|
||||
|
||||
Тот же shorthand что и `add-field`. Находит по dataPath, объединяет свойства (непустые переопределяют), сохраняет позицию.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-edit v1.3 — Atomic 1C DCS editor
|
||||
# skd-edit v1.6 — Atomic 1C DCS editor
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -10,7 +10,7 @@ param(
|
||||
"add-dataParameter","add-order","add-selection","add-dataSetLink",
|
||||
"add-dataSet","add-variant","add-conditionalAppearance",
|
||||
"set-query","patch-query","set-outputParameter","set-structure",
|
||||
"modify-field","modify-filter","modify-dataParameter",
|
||||
"modify-field","modify-filter","modify-dataParameter","modify-parameter",
|
||||
"clear-selection","clear-order","clear-filter",
|
||||
"remove-field","remove-total","remove-calculated-field","remove-parameter","remove-filter")]
|
||||
[string]$Operation,
|
||||
@@ -357,6 +357,9 @@ function Parse-FilterShorthand {
|
||||
} elseif ($valPart -match '^\d+(\.\d+)?$') {
|
||||
$result.value = $valPart
|
||||
$result["valueType"] = "xs:decimal"
|
||||
} elseif ($valPart -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.') {
|
||||
$result.value = $valPart
|
||||
$result["valueType"] = "dcscor:DesignTimeValue"
|
||||
} else {
|
||||
$result.value = $valPart
|
||||
$result["valueType"] = "xs:string"
|
||||
@@ -503,12 +506,17 @@ function Parse-ConditionalAppearanceShorthand {
|
||||
$result.fields = @($forPart -split '\s*,\s*' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
|
||||
}
|
||||
|
||||
# Parse "when" filter
|
||||
# Parse "when" filter (supports " or " for OrGroup)
|
||||
if ($whenIdx -ge 0) {
|
||||
$whenEnd = $s.Length
|
||||
if ($forIdx -gt $whenIdx) { $whenEnd = $forIdx }
|
||||
$whenPart = $s.Substring($whenIdx + 6, $whenEnd - $whenIdx - 6).Trim()
|
||||
$result.filter = Parse-FilterShorthand $whenPart
|
||||
$orParts = $whenPart -split '\s+or\s+'
|
||||
if ($orParts.Count -gt 1) {
|
||||
$result.filter = @($orParts | ForEach-Object { Parse-FilterShorthand $_.Trim() })
|
||||
} else {
|
||||
$result.filter = Parse-FilterShorthand $whenPart
|
||||
}
|
||||
}
|
||||
|
||||
# Parse main part: "Param = Value"
|
||||
@@ -535,6 +543,11 @@ function Parse-StructureShorthand {
|
||||
$seg = $segments[$i].Trim()
|
||||
$group = @{ type = "group" }
|
||||
|
||||
if ($seg -match '@name=(.+)') {
|
||||
$group["name"] = $Matches[1].Trim()
|
||||
$seg = ($seg -replace '\s*@name=.+', '').Trim()
|
||||
}
|
||||
|
||||
if ($seg -match '^(?i)(details|детали)$') {
|
||||
$group["groupBy"] = @()
|
||||
} else {
|
||||
@@ -853,6 +866,32 @@ function Build-SelectionItemFragment {
|
||||
$lines = @()
|
||||
if ($fieldName -eq "Auto") {
|
||||
$lines += "$i<dcsset:item xsi:type=`"dcsset:SelectedItemAuto`"/>"
|
||||
} elseif ($fieldName -match '^Folder\((.+)\)$') {
|
||||
$inner = $Matches[1]
|
||||
$colonIdx = $inner.IndexOf(':')
|
||||
if ($colonIdx -gt 0) {
|
||||
$title = $inner.Substring(0, $colonIdx).Trim()
|
||||
$items = $inner.Substring($colonIdx + 1) -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }
|
||||
} else {
|
||||
$title = ""
|
||||
$items = $inner -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }
|
||||
}
|
||||
$lines += "$i<dcsset:item xsi:type=`"dcsset:SelectedItemFolder`">"
|
||||
if ($title) {
|
||||
$lines += "$i`t<dcsset:lwsTitle>"
|
||||
$lines += "$i`t`t<v8:item>"
|
||||
$lines += "$i`t`t`t<v8:lang>ru</v8:lang>"
|
||||
$lines += "$i`t`t`t<v8:content>$(Esc-Xml $title)</v8:content>"
|
||||
$lines += "$i`t`t</v8:item>"
|
||||
$lines += "$i`t</dcsset:lwsTitle>"
|
||||
}
|
||||
foreach ($item in $items) {
|
||||
$lines += "$i`t<dcsset:item xsi:type=`"dcsset:SelectedItemField`">"
|
||||
$lines += "$i`t`t<dcsset:field>$(Esc-Xml $item)</dcsset:field>"
|
||||
$lines += "$i`t</dcsset:item>"
|
||||
}
|
||||
$lines += "$i`t<dcsset:placement>Auto</dcsset:placement>"
|
||||
$lines += "$i</dcsset:item>"
|
||||
} else {
|
||||
$lines += "$i<dcsset:item xsi:type=`"dcsset:SelectedItemField`">"
|
||||
$lines += "$i`t<dcsset:field>$(Esc-Xml $fieldName)</dcsset:field>"
|
||||
@@ -973,6 +1012,20 @@ function Build-VariantFragment {
|
||||
return $lines -join "`r`n"
|
||||
}
|
||||
|
||||
function Emit-FilterComparison {
|
||||
param($f, [string]$indent)
|
||||
$lines = @()
|
||||
$lines += "$indent<dcsset:item xsi:type=`"dcsset:FilterItemComparison`">"
|
||||
$lines += "$indent`t<dcsset:left xsi:type=`"dcscor:Field`">$(Esc-Xml $f.field)</dcsset:left>"
|
||||
$lines += "$indent`t<dcsset:comparisonType>$(Esc-Xml $f.op)</dcsset:comparisonType>"
|
||||
if ($null -ne $f.value) {
|
||||
$vt = if ($f["valueType"]) { $f["valueType"] } else { "xs:string" }
|
||||
$lines += "$indent`t<dcsset:right xsi:type=`"$vt`">$(Esc-Xml "$($f.value)")</dcsset:right>"
|
||||
}
|
||||
$lines += "$indent</dcsset:item>"
|
||||
return $lines
|
||||
}
|
||||
|
||||
function Build-ConditionalAppearanceItemFragment {
|
||||
param($parsed, [string]$indent)
|
||||
|
||||
@@ -996,15 +1049,17 @@ function Build-ConditionalAppearanceItemFragment {
|
||||
# filter
|
||||
if ($parsed.filter) {
|
||||
$lines += "$i`t<dcsset:filter>"
|
||||
$f = $parsed.filter
|
||||
$lines += "$i`t`t<dcsset:item xsi:type=`"dcsset:FilterItemComparison`">"
|
||||
$lines += "$i`t`t`t<dcsset:left xsi:type=`"dcscor:Field`">$(Esc-Xml $f.field)</dcsset:left>"
|
||||
$lines += "$i`t`t`t<dcsset:comparisonType>$(Esc-Xml $f.op)</dcsset:comparisonType>"
|
||||
if ($null -ne $f.value) {
|
||||
$vt = if ($f["valueType"]) { $f["valueType"] } else { "xs:string" }
|
||||
$lines += "$i`t`t`t<dcsset:right xsi:type=`"$vt`">$(Esc-Xml "$($f.value)")</dcsset:right>"
|
||||
if ($parsed.filter -is [array]) {
|
||||
# OrGroup
|
||||
$lines += "$i`t`t<dcsset:item xsi:type=`"dcsset:FilterItemGroup`">"
|
||||
$lines += "$i`t`t`t<dcsset:groupType>OrGroup</dcsset:groupType>"
|
||||
foreach ($f in $parsed.filter) {
|
||||
$lines += Emit-FilterComparison $f "$i`t`t`t"
|
||||
}
|
||||
$lines += "$i`t`t</dcsset:item>"
|
||||
} else {
|
||||
$lines += Emit-FilterComparison $parsed.filter "$i`t`t"
|
||||
}
|
||||
$lines += "$i`t`t</dcsset:item>"
|
||||
$lines += "$i`t</dcsset:filter>"
|
||||
} else {
|
||||
$lines += "$i`t<dcsset:filter/>"
|
||||
@@ -1013,18 +1068,25 @@ function Build-ConditionalAppearanceItemFragment {
|
||||
# appearance
|
||||
$lines += "$i`t<dcsset:appearance>"
|
||||
|
||||
# Auto-detect value type
|
||||
$val = $parsed.value
|
||||
$valType = "xs:string"
|
||||
if ($val -match '^(web|style|win):') {
|
||||
$valType = "v8ui:Color"
|
||||
} elseif ($val -eq "true" -or $val -eq "false") {
|
||||
$valType = "xs:boolean"
|
||||
}
|
||||
|
||||
$lines += "$i`t`t<dcscor:item xsi:type=`"dcsset:SettingsParameterValue`">"
|
||||
$lines += "$i`t`t`t<dcscor:parameter>$(Esc-Xml $parsed.param)</dcscor:parameter>"
|
||||
$lines += "$i`t`t`t<dcscor:value xsi:type=`"$valType`">$(Esc-Xml $val)</dcscor:value>"
|
||||
|
||||
if ($val -match '^(web|style|win):') {
|
||||
$lines += "$i`t`t`t<dcscor:value xsi:type=`"v8ui:Color`">$(Esc-Xml $val)</dcscor:value>"
|
||||
} elseif ($val -eq "true" -or $val -eq "false") {
|
||||
$lines += "$i`t`t`t<dcscor:value xsi:type=`"xs:boolean`">$(Esc-Xml $val)</dcscor:value>"
|
||||
} elseif ($parsed.param -eq "Формат" -or $parsed.param -eq "Текст" -or $parsed.param -eq "Заголовок") {
|
||||
$lines += "$i`t`t`t<dcscor:value xsi:type=`"v8:LocalStringType`">"
|
||||
$lines += "$i`t`t`t`t<v8:item>"
|
||||
$lines += "$i`t`t`t`t`t<v8:lang>ru</v8:lang>"
|
||||
$lines += "$i`t`t`t`t`t<v8:content>$(Esc-Xml $val)</v8:content>"
|
||||
$lines += "$i`t`t`t`t</v8:item>"
|
||||
$lines += "$i`t`t`t</dcscor:value>"
|
||||
} else {
|
||||
$lines += "$i`t`t`t<dcscor:value xsi:type=`"xs:string`">$(Esc-Xml $val)</dcscor:value>"
|
||||
}
|
||||
|
||||
$lines += "$i`t`t</dcscor:item>"
|
||||
$lines += "$i`t</dcsset:appearance>"
|
||||
|
||||
@@ -1039,6 +1101,11 @@ function Build-StructureItemFragment {
|
||||
$lines = @()
|
||||
$lines += "$i<dcsset:item xsi:type=`"dcsset:StructureItemGroup`">"
|
||||
|
||||
# name
|
||||
if ($item["name"]) {
|
||||
$lines += "$i`t<dcsset:name>$(Esc-Xml $item["name"])</dcsset:name>"
|
||||
}
|
||||
|
||||
# groupItems
|
||||
$groupBy = $item["groupBy"]
|
||||
if (-not $groupBy -or $groupBy.Count -eq 0) {
|
||||
@@ -1445,6 +1512,8 @@ $corNs = "http://v8.1c.ru/8.1/data-composition-system/core"
|
||||
|
||||
if ($Operation -eq "set-query" -or $Operation -eq "set-structure" -or $Operation -eq "add-dataSet") {
|
||||
$values = @($Value)
|
||||
} elseif ($Operation -eq "patch-query") {
|
||||
$values = @($Value -split ';;' | Where-Object { $_.Trim() })
|
||||
} else {
|
||||
$values = @($Value -split ';;' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
|
||||
}
|
||||
@@ -1622,6 +1691,106 @@ switch ($Operation) {
|
||||
}
|
||||
}
|
||||
|
||||
"modify-parameter" {
|
||||
foreach ($val in $values) {
|
||||
# Parse: "ParamName key=value key=value"
|
||||
$parts = $val -split '\s+', 2
|
||||
$paramName = $parts[0].Trim()
|
||||
$rest = if ($parts.Count -gt 1) { $parts[1].Trim() } else { "" }
|
||||
|
||||
# Find parameter element
|
||||
$paramEl = Find-ElementByChildValue $xmlDoc.DocumentElement "parameter" "name" $paramName $schNs
|
||||
if (-not $paramEl) {
|
||||
Write-Host "[WARN] Parameter `"$paramName`" not found — skipped"
|
||||
continue
|
||||
}
|
||||
|
||||
$childIndent = Get-ChildIndent $paramEl
|
||||
|
||||
# Separate availableValue=... from simple kv pairs
|
||||
$simpleRest = $rest
|
||||
$avPart = $null
|
||||
$avIdx = $rest.IndexOf('availableValue=')
|
||||
if ($avIdx -ge 0) {
|
||||
$simpleRest = $rest.Substring(0, $avIdx).Trim()
|
||||
$avPart = $rest.Substring($avIdx)
|
||||
}
|
||||
|
||||
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
|
||||
if ($simpleRest) {
|
||||
$kvPairs = [regex]::Matches($simpleRest, '(\w+)=(\S+)')
|
||||
foreach ($kv in $kvPairs) {
|
||||
$key = $kv.Groups[1].Value
|
||||
$value = $kv.Groups[2].Value
|
||||
|
||||
$existing = $paramEl.SelectSingleNode($key)
|
||||
if ($existing) {
|
||||
$existing.InnerText = $value
|
||||
Write-Host "[OK] Parameter `"$paramName`": $key updated to $value"
|
||||
} else {
|
||||
# Schema order: ...value, useRestriction, availableValue*, denyIncompleteValues, use
|
||||
$refNode = $null
|
||||
if ($key -eq "denyIncompleteValues") {
|
||||
foreach ($child in $paramEl.ChildNodes) {
|
||||
if ($child.NodeType -eq 'Element' -and $child.LocalName -eq 'use') {
|
||||
$refNode = $child; break
|
||||
}
|
||||
}
|
||||
}
|
||||
$fragXml = "$childIndent<$key>$(Esc-Xml $value)</$key>"
|
||||
$nodes = Import-Fragment $xmlDoc $fragXml
|
||||
foreach ($node in $nodes) {
|
||||
Insert-BeforeElement $paramEl $node $refNode $childIndent
|
||||
}
|
||||
Write-Host "[OK] Parameter `"$paramName`": $key=$value added"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Process availableValue
|
||||
if ($avPart) {
|
||||
$avRest = $avPart -replace '^availableValue=', ''
|
||||
# Parse: "Перечисление...X presentation=текст с пробелами"
|
||||
$avParts = $avRest -split '\s+presentation=', 2
|
||||
$avValue = $avParts[0].Trim()
|
||||
$avPresentation = if ($avParts.Count -gt 1) { $avParts[1].Trim() } else { "" }
|
||||
|
||||
# Detect value type
|
||||
$avType = "xs:string"
|
||||
if ($avValue -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.') {
|
||||
$avType = "dcscor:DesignTimeValue"
|
||||
}
|
||||
|
||||
$avLines = @()
|
||||
$avLines += "$childIndent<availableValue>"
|
||||
$avLines += "$childIndent`t<value xsi:type=`"$avType`">$(Esc-Xml $avValue)</value>"
|
||||
if ($avPresentation) {
|
||||
$avLines += "$childIndent`t<presentation xsi:type=`"v8:LocalStringType`">"
|
||||
$avLines += "$childIndent`t`t<v8:item>"
|
||||
$avLines += "$childIndent`t`t`t<v8:lang>ru</v8:lang>"
|
||||
$avLines += "$childIndent`t`t`t<v8:content>$(Esc-Xml $avPresentation)</v8:content>"
|
||||
$avLines += "$childIndent`t`t</v8:item>"
|
||||
$avLines += "$childIndent`t</presentation>"
|
||||
}
|
||||
$avLines += "$childIndent</availableValue>"
|
||||
$fragXml = $avLines -join "`r`n"
|
||||
|
||||
# Insert before first of (denyIncompleteValues, use) in document order
|
||||
$refNode = $null
|
||||
foreach ($child in $paramEl.ChildNodes) {
|
||||
if ($child.NodeType -eq 'Element' -and ($child.LocalName -eq 'denyIncompleteValues' -or $child.LocalName -eq 'use')) {
|
||||
$refNode = $child; break
|
||||
}
|
||||
}
|
||||
$nodes = Import-Fragment $xmlDoc $fragXml
|
||||
foreach ($node in $nodes) {
|
||||
Insert-BeforeElement $paramEl $node $refNode $childIndent
|
||||
}
|
||||
Write-Host "[OK] Parameter `"$paramName`": availableValue added"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"add-filter" {
|
||||
$settings = Resolve-VariantSettings
|
||||
$varName = Get-VariantName
|
||||
@@ -1710,8 +1879,33 @@ switch ($Operation) {
|
||||
|
||||
foreach ($val in $values) {
|
||||
$fieldName = $val.Trim()
|
||||
$groupName = $null
|
||||
|
||||
$selection = Ensure-SettingsChild $settings "selection" @()
|
||||
# Extract @group=Name
|
||||
if ($fieldName -match '\s*@group=(\S+)') {
|
||||
$groupName = $Matches[1]
|
||||
$fieldName = ($fieldName -replace '\s*@group=\S+', '').Trim()
|
||||
}
|
||||
|
||||
if ($groupName) {
|
||||
# Find named StructureItemGroup
|
||||
$dcssetNs = "http://v8.1c.ru/8.1/data-composition-system/settings"
|
||||
$xsiNs = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
|
||||
$nsMgr.AddNamespace("dcsset", $dcssetNs)
|
||||
$nsMgr.AddNamespace("xsi", $xsiNs)
|
||||
$groupEl = $settings.SelectSingleNode(".//dcsset:item[@xsi:type='dcsset:StructureItemGroup'][dcsset:name='$groupName']", $nsMgr)
|
||||
if (-not $groupEl) {
|
||||
Write-Host "[WARN] StructureItemGroup `"$groupName`" not found — adding to variant level"
|
||||
$targetEl = $settings
|
||||
} else {
|
||||
$targetEl = $groupEl
|
||||
}
|
||||
} else {
|
||||
$targetEl = $settings
|
||||
}
|
||||
|
||||
$selection = Ensure-SettingsChild $targetEl "selection" @()
|
||||
$selIndent = Get-ContainerChildIndent $selection
|
||||
|
||||
$selXml = Build-SelectionItemFragment -fieldName $fieldName -indent $selIndent
|
||||
@@ -1720,7 +1914,8 @@ switch ($Operation) {
|
||||
Insert-BeforeElement $selection $node $null $selIndent
|
||||
}
|
||||
|
||||
Write-Host "[OK] Selection `"$fieldName`" added to variant `"$varName`""
|
||||
$target = if ($groupName) { "group `"$groupName`"" } else { "variant `"$varName`"" }
|
||||
Write-Host "[OK] Selection `"$fieldName`" added to $target"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-edit v1.3 — Atomic 1C DCS editor (Python port)
|
||||
# skd-edit v1.6 — Atomic 1C DCS editor (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import os
|
||||
@@ -18,7 +18,7 @@ VALID_OPS = [
|
||||
"add-dataParameter", "add-order", "add-selection", "add-dataSetLink",
|
||||
"add-dataSet", "add-variant", "add-conditionalAppearance",
|
||||
"set-query", "patch-query", "set-outputParameter", "set-structure",
|
||||
"modify-field", "modify-filter", "modify-dataParameter",
|
||||
"modify-field", "modify-filter", "modify-dataParameter", "modify-parameter",
|
||||
"clear-selection", "clear-order", "clear-filter",
|
||||
"remove-field", "remove-total", "remove-calculated-field", "remove-parameter", "remove-filter",
|
||||
]
|
||||
@@ -350,6 +350,9 @@ def parse_filter_shorthand(s):
|
||||
elif re.match(r'^\d+(\.\d+)?$', val_part):
|
||||
result["value"] = val_part
|
||||
result["valueType"] = "xs:decimal"
|
||||
elif re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.', val_part):
|
||||
result["value"] = val_part
|
||||
result["valueType"] = "dcscor:DesignTimeValue"
|
||||
else:
|
||||
result["value"] = val_part
|
||||
result["valueType"] = "xs:string"
|
||||
@@ -408,7 +411,7 @@ def parse_order_shorthand(s):
|
||||
parts = s.split(None, 1)
|
||||
field = parts[0]
|
||||
direction = "Asc"
|
||||
if len(parts) > 1 and re.match(r'(?i)^desc$', parts[1]):
|
||||
if len(parts) > 1 and re.match(r'^desc$', parts[1], re.IGNORECASE):
|
||||
direction = "Desc"
|
||||
return {"field": field, "direction": direction}
|
||||
|
||||
@@ -480,7 +483,11 @@ def parse_conditional_appearance_shorthand(s):
|
||||
if for_idx > when_idx:
|
||||
when_end = for_idx
|
||||
when_part = s[when_idx + 6:when_end].strip()
|
||||
result["filter"] = parse_filter_shorthand(when_part)
|
||||
or_parts = re.split(r'\s+or\s+', when_part)
|
||||
if len(or_parts) > 1:
|
||||
result["filter"] = [parse_filter_shorthand(p.strip()) for p in or_parts]
|
||||
else:
|
||||
result["filter"] = parse_filter_shorthand(when_part)
|
||||
|
||||
main_part = s[:main_end].strip()
|
||||
eq_idx = main_part.find("=")
|
||||
@@ -502,7 +509,12 @@ def parse_structure_shorthand(s):
|
||||
seg = segments[i].strip()
|
||||
group = {"type": "group"}
|
||||
|
||||
if re.match(r'^(?i)(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg):
|
||||
name_m = re.search(r'\s*@name=(.+)', seg)
|
||||
if name_m:
|
||||
group["name"] = name_m.group(1).strip()
|
||||
seg = re.sub(r'\s*@name=.+', '', seg).strip()
|
||||
|
||||
if re.match(r'^(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg, re.IGNORECASE):
|
||||
group["groupBy"] = []
|
||||
else:
|
||||
group["groupBy"] = [seg]
|
||||
@@ -760,6 +772,31 @@ def build_selection_item_fragment(field_name, indent):
|
||||
i = indent
|
||||
if field_name == "Auto":
|
||||
return f'{i}<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>'
|
||||
m = re.match(r'^Folder\((.+)\)$', field_name)
|
||||
if m:
|
||||
inner = m.group(1)
|
||||
colon_idx = inner.find(':')
|
||||
if colon_idx > 0:
|
||||
title = inner[:colon_idx].strip()
|
||||
items = [x.strip() for x in inner[colon_idx + 1:].split(',') if x.strip()]
|
||||
else:
|
||||
title = ""
|
||||
items = [x.strip() for x in inner.split(',') if x.strip()]
|
||||
lines = [f'{i}<dcsset:item xsi:type="dcsset:SelectedItemFolder">']
|
||||
if title:
|
||||
lines.append(f"{i}\t<dcsset:lwsTitle>")
|
||||
lines.append(f"{i}\t\t<v8:item>")
|
||||
lines.append(f"{i}\t\t\t<v8:lang>ru</v8:lang>")
|
||||
lines.append(f"{i}\t\t\t<v8:content>{esc_xml(title)}</v8:content>")
|
||||
lines.append(f"{i}\t\t</v8:item>")
|
||||
lines.append(f"{i}\t</dcsset:lwsTitle>")
|
||||
for item in items:
|
||||
lines.append(f'{i}\t<dcsset:item xsi:type="dcsset:SelectedItemField">')
|
||||
lines.append(f"{i}\t\t<dcsset:field>{esc_xml(item)}</dcsset:field>")
|
||||
lines.append(f"{i}\t</dcsset:item>")
|
||||
lines.append(f"{i}\t<dcsset:placement>Auto</dcsset:placement>")
|
||||
lines.append(f"{i}</dcsset:item>")
|
||||
return "\r\n".join(lines)
|
||||
lines = [
|
||||
f'{i}<dcsset:item xsi:type="dcsset:SelectedItemField">',
|
||||
f"{i}\t<dcsset:field>{esc_xml(field_name)}</dcsset:field>",
|
||||
@@ -866,6 +903,16 @@ def build_variant_fragment(parsed, indent):
|
||||
return "\r\n".join(lines)
|
||||
|
||||
|
||||
def _emit_filter_comparison(lines, f, indent):
|
||||
lines.append(f'{indent}<dcsset:item xsi:type="dcsset:FilterItemComparison">')
|
||||
lines.append(f'{indent}\t<dcsset:left xsi:type="dcscor:Field">{esc_xml(f["field"])}</dcsset:left>')
|
||||
lines.append(f"{indent}\t<dcsset:comparisonType>{esc_xml(f['op'])}</dcsset:comparisonType>")
|
||||
if f.get("value") is not None:
|
||||
vt = f.get("valueType", "xs:string")
|
||||
lines.append(f'{indent}\t<dcsset:right xsi:type="{vt}">{esc_xml(str(f["value"]))}</dcsset:right>')
|
||||
lines.append(f"{indent}</dcsset:item>")
|
||||
|
||||
|
||||
def build_conditional_appearance_item_fragment(parsed, indent):
|
||||
i = indent
|
||||
lines = [f"{i}<dcsset:item>"]
|
||||
@@ -881,15 +928,17 @@ def build_conditional_appearance_item_fragment(parsed, indent):
|
||||
lines.append(f"{i}\t<dcsset:selection/>")
|
||||
|
||||
if parsed.get("filter"):
|
||||
f = parsed["filter"]
|
||||
flt = parsed["filter"]
|
||||
lines.append(f"{i}\t<dcsset:filter>")
|
||||
lines.append(f'{i}\t\t<dcsset:item xsi:type="dcsset:FilterItemComparison">')
|
||||
lines.append(f'{i}\t\t\t<dcsset:left xsi:type="dcscor:Field">{esc_xml(f["field"])}</dcsset:left>')
|
||||
lines.append(f"{i}\t\t\t<dcsset:comparisonType>{esc_xml(f['op'])}</dcsset:comparisonType>")
|
||||
if f.get("value") is not None:
|
||||
vt = f.get("valueType", "xs:string")
|
||||
lines.append(f'{i}\t\t\t<dcsset:right xsi:type="{vt}">{esc_xml(str(f["value"]))}</dcsset:right>')
|
||||
lines.append(f"{i}\t\t</dcsset:item>")
|
||||
if isinstance(flt, list):
|
||||
# OrGroup
|
||||
lines.append(f'{i}\t\t<dcsset:item xsi:type="dcsset:FilterItemGroup">')
|
||||
lines.append(f"{i}\t\t\t<dcsset:groupType>OrGroup</dcsset:groupType>")
|
||||
for f in flt:
|
||||
_emit_filter_comparison(lines, f, f"{i}\t\t\t")
|
||||
lines.append(f"{i}\t\t</dcsset:item>")
|
||||
else:
|
||||
_emit_filter_comparison(lines, flt, f"{i}\t\t")
|
||||
lines.append(f"{i}\t</dcsset:filter>")
|
||||
else:
|
||||
lines.append(f"{i}\t<dcsset:filter/>")
|
||||
@@ -897,15 +946,23 @@ def build_conditional_appearance_item_fragment(parsed, indent):
|
||||
# appearance
|
||||
lines.append(f"{i}\t<dcsset:appearance>")
|
||||
val = parsed["value"]
|
||||
val_type = "xs:string"
|
||||
if re.match(r'^(web|style|win):', val):
|
||||
val_type = "v8ui:Color"
|
||||
elif val in ("true", "false"):
|
||||
val_type = "xs:boolean"
|
||||
|
||||
lines.append(f'{i}\t\t<dcscor:item xsi:type="dcsset:SettingsParameterValue">')
|
||||
lines.append(f"{i}\t\t\t<dcscor:parameter>{esc_xml(parsed['param'])}</dcscor:parameter>")
|
||||
lines.append(f'{i}\t\t\t<dcscor:value xsi:type="{val_type}">{esc_xml(val)}</dcscor:value>')
|
||||
|
||||
if re.match(r'^(web|style|win):', val):
|
||||
lines.append(f'{i}\t\t\t<dcscor:value xsi:type="v8ui:Color">{esc_xml(val)}</dcscor:value>')
|
||||
elif val in ("true", "false"):
|
||||
lines.append(f'{i}\t\t\t<dcscor:value xsi:type="xs:boolean">{esc_xml(val)}</dcscor:value>')
|
||||
elif parsed["param"] in ("Формат", "Текст", "Заголовок"):
|
||||
lines.append(f'{i}\t\t\t<dcscor:value xsi:type="v8:LocalStringType">')
|
||||
lines.append(f"{i}\t\t\t\t<v8:item>")
|
||||
lines.append(f"{i}\t\t\t\t\t<v8:lang>ru</v8:lang>")
|
||||
lines.append(f"{i}\t\t\t\t\t<v8:content>{esc_xml(val)}</v8:content>")
|
||||
lines.append(f"{i}\t\t\t\t</v8:item>")
|
||||
lines.append(f"{i}\t\t\t</dcscor:value>")
|
||||
else:
|
||||
lines.append(f'{i}\t\t\t<dcscor:value xsi:type="xs:string">{esc_xml(val)}</dcscor:value>')
|
||||
|
||||
lines.append(f"{i}\t\t</dcscor:item>")
|
||||
lines.append(f"{i}\t</dcsset:appearance>")
|
||||
|
||||
@@ -917,6 +974,9 @@ def build_structure_item_fragment(item, indent):
|
||||
i = indent
|
||||
lines = [f'{i}<dcsset:item xsi:type="dcsset:StructureItemGroup">']
|
||||
|
||||
if item.get("name"):
|
||||
lines.append(f"{i}\t<dcsset:name>{esc_xml(item['name'])}</dcsset:name>")
|
||||
|
||||
group_by = item.get("groupBy", [])
|
||||
if not group_by:
|
||||
lines.append(f"{i}\t<dcsset:groupItems/>")
|
||||
@@ -1165,7 +1225,7 @@ def resolve_variant_settings():
|
||||
break
|
||||
if sv:
|
||||
break
|
||||
if not sv:
|
||||
if sv is None:
|
||||
print(f"Variant '{variant_arg}' not found", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
else:
|
||||
@@ -1173,7 +1233,7 @@ def resolve_variant_settings():
|
||||
if isinstance(child.tag, str) and local_name(child) == "settingsVariant" and etree.QName(child.tag).namespace == SCH_NS:
|
||||
sv = child
|
||||
break
|
||||
if not sv:
|
||||
if sv is None:
|
||||
print("No settingsVariant found in DCS", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -1252,6 +1312,8 @@ xml_doc = tree.getroot()
|
||||
|
||||
if operation in ("set-query", "set-structure", "add-dataSet"):
|
||||
values = [value_arg]
|
||||
elif operation == "patch-query":
|
||||
values = [v for v in value_arg.split(";;") if v.strip()]
|
||||
else:
|
||||
values = [v.strip() for v in value_arg.split(";;") if v.strip()]
|
||||
|
||||
@@ -1406,6 +1468,81 @@ elif operation == "add-parameter":
|
||||
if parsed.get("autoDates"):
|
||||
print('[OK] Auto-parameters "\u0414\u0430\u0442\u0430\u041d\u0430\u0447\u0430\u043b\u0430", "\u0414\u0430\u0442\u0430\u041e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f" added')
|
||||
|
||||
elif operation == "modify-parameter":
|
||||
for val in values:
|
||||
parts = val.split(None, 1)
|
||||
param_name = parts[0].strip()
|
||||
rest = parts[1].strip() if len(parts) > 1 else ""
|
||||
|
||||
param_el = find_element_by_child_value(xml_doc, "parameter", "name", param_name, SCH_NS)
|
||||
if param_el is None:
|
||||
print(f'[WARN] Parameter "{param_name}" not found -- skipped')
|
||||
continue
|
||||
|
||||
child_indent = get_child_indent(param_el)
|
||||
|
||||
# Separate availableValue=... from simple kv pairs
|
||||
simple_rest = rest
|
||||
av_part = None
|
||||
av_idx = rest.find("availableValue=")
|
||||
if av_idx >= 0:
|
||||
simple_rest = rest[:av_idx].strip()
|
||||
av_part = rest[av_idx:]
|
||||
|
||||
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
|
||||
if simple_rest:
|
||||
for m in re.finditer(r'(\w+)=(\S+)', simple_rest):
|
||||
key, value = m.group(1), m.group(2)
|
||||
existing = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == key), None)
|
||||
if existing is not None:
|
||||
existing.text = value
|
||||
print(f'[OK] Parameter "{param_name}": {key} updated to {value}')
|
||||
else:
|
||||
# Schema order: ...value, useRestriction, availableValue*, denyIncompleteValues, use
|
||||
ref_node = None
|
||||
if key == "denyIncompleteValues":
|
||||
ref_node = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "use"), None)
|
||||
frag_xml = f"{child_indent}<{key}>{esc_xml(value)}</{key}>"
|
||||
nodes = import_fragment(xml_doc, frag_xml)
|
||||
for node in nodes:
|
||||
insert_before_element(param_el, node, ref_node, child_indent)
|
||||
print(f'[OK] Parameter "{param_name}": {key}={value} added')
|
||||
|
||||
# Process availableValue
|
||||
if av_part:
|
||||
av_rest = av_part[len("availableValue="):]
|
||||
# Parse: "Перечисление...X presentation=текст с пробелами"
|
||||
av_parts = re.split(r'\s+presentation=', av_rest, 1)
|
||||
av_value = av_parts[0].strip()
|
||||
av_presentation = av_parts[1].strip() if len(av_parts) > 1 else ""
|
||||
|
||||
av_type = "xs:string"
|
||||
if re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.', av_value):
|
||||
av_type = "dcscor:DesignTimeValue"
|
||||
|
||||
av_lines = [f"{child_indent}<availableValue>"]
|
||||
av_lines.append(f'{child_indent}\t<value xsi:type="{av_type}">{esc_xml(av_value)}</value>')
|
||||
if av_presentation:
|
||||
av_lines.append(f'{child_indent}\t<presentation xsi:type="v8:LocalStringType">')
|
||||
av_lines.append(f"{child_indent}\t\t<v8:item>")
|
||||
av_lines.append(f"{child_indent}\t\t\t<v8:lang>ru</v8:lang>")
|
||||
av_lines.append(f"{child_indent}\t\t\t<v8:content>{esc_xml(av_presentation)}</v8:content>")
|
||||
av_lines.append(f"{child_indent}\t\t</v8:item>")
|
||||
av_lines.append(f"{child_indent}\t</presentation>")
|
||||
av_lines.append(f"{child_indent}</availableValue>")
|
||||
frag_xml = "\r\n".join(av_lines)
|
||||
|
||||
# Insert before first of (denyIncompleteValues, use) in document order
|
||||
ref_node = None
|
||||
for child in param_el:
|
||||
if isinstance(child.tag, str) and local_name(child) in ("denyIncompleteValues", "use"):
|
||||
ref_node = child
|
||||
break
|
||||
nodes = import_fragment(xml_doc, frag_xml)
|
||||
for node in nodes:
|
||||
insert_before_element(param_el, node, ref_node, child_indent)
|
||||
print(f'[OK] Parameter "{param_name}": availableValue added')
|
||||
|
||||
elif operation == "add-filter":
|
||||
settings = resolve_variant_settings()
|
||||
var_name = get_variant_name()
|
||||
@@ -1470,13 +1607,38 @@ elif operation == "add-selection":
|
||||
var_name = get_variant_name()
|
||||
for val in values:
|
||||
field_name = val.strip()
|
||||
selection = ensure_settings_child(settings, "selection", [])
|
||||
group_name = None
|
||||
|
||||
# Extract @group=Name
|
||||
gm = re.search(r'\s*@group=(\S+)', field_name)
|
||||
if gm:
|
||||
group_name = gm.group(1)
|
||||
field_name = re.sub(r'\s*@group=\S+', '', field_name).strip()
|
||||
|
||||
if group_name:
|
||||
# Find named StructureItemGroup
|
||||
target_el = None
|
||||
for item in settings.iter(f"{{{SET_NS}}}item"):
|
||||
xsi_type = item.get(f"{{{XSI_NS}}}type", "")
|
||||
if "StructureItemGroup" in xsi_type:
|
||||
name_el = item.find(f"{{{SET_NS}}}name")
|
||||
if name_el is not None and name_el.text == group_name:
|
||||
target_el = item
|
||||
break
|
||||
if target_el is None:
|
||||
print(f'[WARN] StructureItemGroup "{group_name}" not found -- adding to variant level')
|
||||
target_el = settings
|
||||
else:
|
||||
target_el = settings
|
||||
|
||||
selection = ensure_settings_child(target_el, "selection", [])
|
||||
sel_indent = get_container_child_indent(selection)
|
||||
sel_xml = build_selection_item_fragment(field_name, sel_indent)
|
||||
sel_nodes = import_fragment(xml_doc, sel_xml)
|
||||
for node in sel_nodes:
|
||||
insert_before_element(selection, node, None, sel_indent)
|
||||
print(f'[OK] Selection "{field_name}" added to variant "{var_name}"')
|
||||
target = f'group "{group_name}"' if group_name else f'variant "{var_name}"'
|
||||
print(f'[OK] Selection "{field_name}" added to {target}')
|
||||
|
||||
elif operation == "set-query":
|
||||
ds_node = resolve_data_set()
|
||||
@@ -1674,7 +1836,11 @@ elif operation == "add-conditionalAppearance":
|
||||
|
||||
desc = f"{parsed['param']} = {parsed['value']}"
|
||||
if parsed.get("filter"):
|
||||
desc += f" when {parsed['filter']['field']} {parsed['filter']['op']}"
|
||||
flt = parsed["filter"]
|
||||
if isinstance(flt, list):
|
||||
desc += f" when OrGroup({len(flt)} conditions)"
|
||||
else:
|
||||
desc += f" when {flt['field']} {flt['op']}"
|
||||
if parsed.get("fields"):
|
||||
desc += f" for {', '.join(parsed['fields'])}"
|
||||
print(f'[OK] ConditionalAppearance "{desc}" added to variant "{var_name}"')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# subsystem-compile v1.2 — Create 1C subsystem from JSON definition
|
||||
# subsystem-compile v1.3 — Create 1C subsystem from JSON definition
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -267,12 +267,31 @@ if ($def.children) {
|
||||
foreach ($ch in $def.children) { $children += "$ch" }
|
||||
}
|
||||
|
||||
# --- Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$formatVersion = Detect-FormatVersion $OutputDir
|
||||
|
||||
# --- 4. Build XML ---
|
||||
$uuid = New-Guid-String
|
||||
$indent = "`t`t`t"
|
||||
|
||||
X '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
X '<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">'
|
||||
X '<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="$formatVersion">'
|
||||
X "`t<Subsystem uuid=`"$uuid`">"
|
||||
X "`t`t<Properties>"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# subsystem-compile v1.2 — Create 1C subsystem from JSON definition
|
||||
# subsystem-compile v1.3 — Create 1C subsystem from JSON definition
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -10,6 +10,22 @@ import uuid
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def esc_xml(s):
|
||||
return s.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
|
||||
|
||||
@@ -169,6 +185,8 @@ def main():
|
||||
type_part = CONTENT_TYPE_MAP[type_part]
|
||||
return f'{type_part}.{name_part}'
|
||||
|
||||
format_version = detect_format_version(output_dir)
|
||||
|
||||
# --- 3. Resolve defaults ---
|
||||
synonym = str(defn['synonym']) if defn.get('synonym') else split_camel_case(obj_name)
|
||||
comment = str(defn['comment']) if defn.get('comment') else ''
|
||||
@@ -205,7 +223,7 @@ def main():
|
||||
lines = []
|
||||
|
||||
lines.append('<?xml version="1.0" encoding="UTF-8"?>')
|
||||
lines.append('<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">')
|
||||
lines.append(f'<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="{format_version}">')
|
||||
lines.append(f'\t<Subsystem uuid="{uid}">')
|
||||
lines.append('\t\t<Properties>')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# template-add v1.1 — Add template to 1C object
|
||||
# template-add v1.3 — Add template to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -37,7 +37,7 @@ $tmpl = $typeMap[$TemplateType]
|
||||
|
||||
$rootXmlPath = Join-Path $SrcDir "$ObjectName.xml"
|
||||
if (-not (Test-Path $rootXmlPath)) {
|
||||
Write-Error "Корневой файл обработки не найден: $rootXmlPath"
|
||||
Write-Error "Корневой файл объекта не найден: $rootXmlPath`nОжидается: <SrcDir>/<ObjectName>/<ObjectName>.xml`nПодсказка: SrcDir должен указывать на папку типа объектов (например Reports), а не на корень конфигурации"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -59,13 +59,32 @@ New-Item -ItemType Directory -Path $templateExtDir -Force | Out-Null
|
||||
|
||||
$encBom = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
# --- Detect format version ---
|
||||
|
||||
function Detect-FormatVersion([string]$dir) {
|
||||
$d = $dir
|
||||
while ($d) {
|
||||
$cfgPath = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfgPath) {
|
||||
$head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length))
|
||||
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
|
||||
}
|
||||
$parent = Split-Path $d -Parent
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$formatVersion = Detect-FormatVersion (Resolve-Path $SrcDir).Path
|
||||
|
||||
# --- 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">
|
||||
<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=`"$formatVersion`">
|
||||
<Template uuid="$templateUuid">
|
||||
<Properties>
|
||||
<Name>$TemplateName</Name>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
# add-template v1.0 — Add template to 1C object
|
||||
# add-template v1.3 — Add template to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
@@ -37,6 +38,22 @@ def write_text_with_bom(path, text):
|
||||
f.write(text)
|
||||
|
||||
|
||||
def detect_format_version(d):
|
||||
while d:
|
||||
cfg_path = os.path.join(d, "Configuration.xml")
|
||||
if os.path.isfile(cfg_path):
|
||||
with open(cfg_path, "r", encoding="utf-8-sig") as f:
|
||||
head = f.read(2000)
|
||||
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
|
||||
if m:
|
||||
return m.group(1)
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
@@ -59,11 +76,15 @@ def main():
|
||||
|
||||
tmpl = TYPE_MAP[template_type]
|
||||
|
||||
format_version = detect_format_version(os.path.abspath(src_dir))
|
||||
|
||||
# --- Checks ---
|
||||
|
||||
root_xml_path = os.path.join(src_dir, f"{object_name}.xml")
|
||||
if not os.path.exists(root_xml_path):
|
||||
print(f"Корневой файл обработки не найден: {root_xml_path}", file=sys.stderr)
|
||||
print(f"Корневой файл объекта не найден: {root_xml_path}", file=sys.stderr)
|
||||
print(f"Ожидается: <SrcDir>/<ObjectName>/<ObjectName>.xml", file=sys.stderr)
|
||||
print(f"Подсказка: SrcDir должен указывать на папку типа объектов (например Reports), а не на корень конфигурации", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
processor_dir = os.path.join(src_dir, object_name)
|
||||
@@ -102,7 +123,7 @@ def main():
|
||||
' 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">\n'
|
||||
f' version="{format_version}">\n'
|
||||
f'\t<Template uuid="{template_uuid}">\n'
|
||||
'\t\t<Properties>\n'
|
||||
f'\t\t\t<Name>{template_name}</Name>\n'
|
||||
|
||||
@@ -155,6 +155,8 @@ const form = await getFormState();
|
||||
|
||||
**confirmation** — if present, a Yes/No dialog is shown. Call `clickElement('Да')` or `clickElement('Нет')`.
|
||||
|
||||
**errors.stateText** — array of SpreadsheetDocument state messages (e.g. `"Не установлено значение параметра \"X\""`, `"Отчет не сформирован..."`, `"Изменились настройки..."`). Present when the report area shows an info bar instead of data.
|
||||
|
||||
### Reading data
|
||||
|
||||
#### `readTable({ maxRows?, offset?, table? })` → `{ columns, rows, total, shown, offset }`
|
||||
|
||||
@@ -1366,7 +1366,12 @@ export async function readSpreadsheet() {
|
||||
|
||||
const { allCells } = await scanSpreadsheetCells(formNum);
|
||||
|
||||
if (allCells.size === 0) throw new Error('readSpreadsheet: no SpreadsheetDocument found. Report may not be generated yet.');
|
||||
if (allCells.size === 0) {
|
||||
// Check for state window messages (info bar) that explain why the report is empty
|
||||
const err = await checkForErrors();
|
||||
const hint = err?.stateText?.length ? err.stateText.join('; ') : '';
|
||||
throw new Error('readSpreadsheet: no SpreadsheetDocument found.' + (hint ? ' State: ' + hint : ' Report may not be generated yet.'));
|
||||
}
|
||||
|
||||
const mapping = buildSpreadsheetMapping(allCells);
|
||||
if (!mapping) {
|
||||
|
||||
@@ -1176,7 +1176,15 @@ export function checkErrorsScript() {
|
||||
}
|
||||
}
|
||||
|
||||
return (result.balloon || result.messages || result.modal || result.confirmation) ? result : null;
|
||||
// 5. SpreadsheetDocument state window (info bar inside moxelContainer)
|
||||
// Shows messages like "Не установлено значение параметра X" or "Отчет не сформирован"
|
||||
const stateWins = [...document.querySelectorAll('.stateWindowSupportSurface')].filter(el => el.offsetWidth > 0);
|
||||
if (stateWins.length) {
|
||||
const texts = stateWins.map(el => el.innerText?.trim()).filter(Boolean);
|
||||
if (texts.length) result.stateText = texts;
|
||||
}
|
||||
|
||||
return (result.balloon || result.messages || result.modal || result.confirmation || result.stateText) ? result : null;
|
||||
})()`;
|
||||
}
|
||||
|
||||
|
||||
+43
-7
@@ -515,6 +515,7 @@ DataCompositionSchema
|
||||
| `useRestriction` | нет | `true` — параметр скрыт от пользователя, `false` — доступен |
|
||||
| `expression` | нет | Выражение для автоматического вычисления (например, `&Период.ДатаНачала`) |
|
||||
| `availableAsField` | нет | `false` — параметр недоступен как поле в отчёте |
|
||||
| `valueListAllowed` | нет | `true` — разрешает передавать список значений в параметр |
|
||||
| `use` | нет | Режим: `Always` (всегда), `Auto` (автоматически) |
|
||||
|
||||
### Типы значений параметров
|
||||
@@ -562,26 +563,61 @@ DataCompositionSchema
|
||||
|---|---|
|
||||
| `name` | Имя макета (ссылаются groupTemplate) |
|
||||
| `template` (вложенный) | Описание строк/ячеек (`dcsat:AreaTemplate`) |
|
||||
| `parameter` | Параметры макета (`dcsat:ExpressionAreaTemplateParameter`) — выражения для подстановки |
|
||||
| `parameter` (Expression) | Параметры макета (`dcsat:ExpressionAreaTemplateParameter`) — выражения для подстановки |
|
||||
| `parameter` (Details) | Параметры расшифровки (`dcsat:DetailsAreaTemplateParameter`) — для drilldown |
|
||||
|
||||
#### DetailsAreaTemplateParameter
|
||||
|
||||
Параметр расшифровки — активирует drilldown при клике на ячейку:
|
||||
|
||||
```xml
|
||||
<parameter xmlns:dcsat="http://v8.1c.ru/8.1/data-composition-system/area-template"
|
||||
xsi:type="dcsat:DetailsAreaTemplateParameter">
|
||||
<dcsat:name>Расшифровка_ПоступлениеСырья</dcsat:name>
|
||||
<dcsat:fieldExpression>
|
||||
<dcsat:field>ИмяРесурса</dcsat:field>
|
||||
<dcsat:expression>"ПоступлениеСырья"</dcsat:expression>
|
||||
</dcsat:fieldExpression>
|
||||
<dcsat:mainAction>DrillDown</dcsat:mainAction>
|
||||
</parameter>
|
||||
```
|
||||
|
||||
Привязка к ячейке — через appearance `Расшифровка`:
|
||||
|
||||
```xml
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>Расшифровка</dcscor:parameter>
|
||||
<dcscor:value xsi:type="dcscor:Parameter">Расшифровка_ПоступлениеСырья</dcscor:value>
|
||||
</dcscor:item>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Привязки макетов группировок (groupTemplate)
|
||||
## 10. Привязки макетов группировок (groupTemplate, groupHeaderTemplate)
|
||||
|
||||
Связывают группировку с пользовательским макетом:
|
||||
Связывают группировку с пользовательским макетом. Два XML-элемента:
|
||||
|
||||
- `<groupTemplate>` — шаблон строки данных (`Header`) и итогов (`OverallHeader`)
|
||||
- `<groupHeaderTemplate>` — шаблон заголовка группировки (шапка таблицы)
|
||||
|
||||
```xml
|
||||
<groupTemplate>
|
||||
<groupField>ТипЦен</groupField>
|
||||
<groupHeaderTemplate>
|
||||
<groupName>ДанныеОтчета</groupName>
|
||||
<templateType>Header</templateType>
|
||||
<template>Макет1</template>
|
||||
</groupHeaderTemplate>
|
||||
<groupTemplate>
|
||||
<groupField>Счет</groupField>
|
||||
<templateType>Header</templateType>
|
||||
<template>Макет2</template>
|
||||
</groupTemplate>
|
||||
```
|
||||
|
||||
| Элемент | Описание |
|
||||
|---|---|
|
||||
| `groupField` | Имя поля группировки |
|
||||
| `templateType` | Тип: `Header` (заголовок), `Footer` (подвал), `Overall` (общий) |
|
||||
| `groupField` | Привязка к полю группировки |
|
||||
| `groupName` | Привязка к именованной группировке в структуре варианта |
|
||||
| `templateType` | `Header` (строки данных), `OverallHeader` (итоги) |
|
||||
| `template` | Ссылка на имя template из раздела 9 |
|
||||
|
||||
---
|
||||
|
||||
+91
-6
@@ -297,7 +297,7 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
### Shorthand
|
||||
|
||||
```
|
||||
"<name>: <type> [= <default>] [@autoDates]"
|
||||
"<name>: <type> [= <default>] [@autoDates] [@valueList] [@hidden]"
|
||||
```
|
||||
|
||||
Примеры:
|
||||
@@ -332,6 +332,25 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
"parameters": ["Период: StandardPeriod = LastMonth @autoDates"]
|
||||
```
|
||||
|
||||
### @valueList
|
||||
|
||||
Флаг `@valueList` генерирует `<valueListAllowed>true</valueListAllowed>` — разрешает передавать список значений в параметр:
|
||||
|
||||
```json
|
||||
"parameters": ["Организации: CatalogRef.Организации @valueList"]
|
||||
```
|
||||
|
||||
### @hidden
|
||||
|
||||
Флаг `@hidden` — скрытый параметр. Автоматически ставит `availableAsField=false` и исключает параметр из автогенерируемых `dataParameters` при `"dataParameters": "auto"`:
|
||||
|
||||
```json
|
||||
"parameters": [
|
||||
{ "name": "Счет43", "type": "ChartOfAccountsRef.Хозрасчетный", "value": "...", "hidden": true },
|
||||
"СкрытыйПараметр: string = test @hidden"
|
||||
]
|
||||
```
|
||||
|
||||
### Объектная форма
|
||||
|
||||
```json
|
||||
@@ -355,8 +374,31 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
| `value` | Значение по умолчанию |
|
||||
| `expression` | Выражение для вычисления |
|
||||
| `availableAsField` | `false` — скрыть из полей |
|
||||
| `valueListAllowed` | `true` — разрешить список значений |
|
||||
| `hidden` | `true` — скрытый параметр (авто `availableAsField=false`, исключение из `dataParameters: auto`) |
|
||||
| `useRestriction` | `true` — скрыть от пользователя |
|
||||
| `use` | `"Always"`, `"Auto"` |
|
||||
| `denyIncompleteValues` | `true` — запретить произвольные значения (только из availableValues) |
|
||||
| `availableValues` | Массив `[{value, presentation}]` — допустимые значения с представлениями |
|
||||
|
||||
### availableValues
|
||||
|
||||
Список допустимых значений параметра. Тип значения определяется автоматически (`Перечисление.*`, `Справочник.*` и др. → `dcscor:DesignTimeValue`):
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "ПорядокОкругления",
|
||||
"type": "EnumRef.Округления",
|
||||
"value": "Перечисление.Округления.Окр1_00",
|
||||
"use": "Always",
|
||||
"denyIncompleteValues": true,
|
||||
"availableValues": [
|
||||
{"value": "Перечисление.Округления.Окр1_00", "presentation": "руб. коп"},
|
||||
{"value": "Перечисление.Округления.Окр1", "presentation": "руб."},
|
||||
{"value": "Перечисление.Округления.Окр1000", "presentation": "тыс. руб"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Значения параметров по типу
|
||||
|
||||
@@ -399,6 +441,8 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
}
|
||||
```
|
||||
|
||||
Ключ `field` — алиас для `dataPath` (используется если `dataPath` не указан).
|
||||
|
||||
---
|
||||
|
||||
## 8. Связи наборов (dataSetLinks)
|
||||
@@ -458,6 +502,16 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
- Строка → `SelectedItemField`
|
||||
- `"Auto"` → `SelectedItemAuto` (только на уровне группировок; на верхнем уровне settings игнорируется)
|
||||
- Объект с `field`/`title` → `SelectedItemField` с `lwsTitle`
|
||||
- Объект с `folder`/`items` → `SelectedItemFolder` — группа полей с заголовком и `placement=Auto`:
|
||||
|
||||
```json
|
||||
"selection": [
|
||||
"Auto",
|
||||
"Счет",
|
||||
{"folder": "Поступление", "items": ["ПолеА", "ПолеБ", "ПолеВ"]},
|
||||
{"folder": "Выбытие", "items": ["ВыбытиеРеализовано", "ВыбытиеПрочее"]}
|
||||
]
|
||||
```
|
||||
|
||||
### filter
|
||||
|
||||
@@ -480,7 +534,8 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
- `@quickAccess` → `viewMode=QuickAccess`
|
||||
- `@normal` → `viewMode=Normal`
|
||||
- `@inaccessible` → `viewMode=Inaccessible`
|
||||
- Типы значений автоопределяются: `true`/`false` → boolean, `2024-01-01T00:00:00` → dateTime, числа → decimal, прочее → string
|
||||
- Типы значений автоопределяются: `true`/`false` → boolean, `2024-01-01T00:00:00` → dateTime, числа → decimal, `Перечисление.*`/`Справочник.*`/`ПланСчетов.*`/`Документ.*` → DesignTimeValue, прочее → string
|
||||
- OrGroup: `{"group": "Or", "items": ["условие1", "условие2"]}` — объединяет условия через ИЛИ
|
||||
|
||||
#### Объектная форма
|
||||
|
||||
@@ -574,7 +629,7 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
**Типы значений appearance** определяются автоматически:
|
||||
- `style:XXX`, `web:XXX`, `win:XXX` → `v8ui:Color`
|
||||
- `true`/`false` → `xs:boolean`
|
||||
- Параметр `Текст` или `Заголовок` → `v8:LocalStringType`
|
||||
- Параметр `Формат`, `Текст` или `Заголовок` → `v8:LocalStringType`
|
||||
- Прочее → `xs:string`
|
||||
|
||||
Поддержка `use=false` на уровне параметра:
|
||||
@@ -606,6 +661,14 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
|
||||
### dataParameters
|
||||
|
||||
#### Автогенерация
|
||||
|
||||
```json
|
||||
"dataParameters": "auto"
|
||||
```
|
||||
|
||||
Генерирует записи `dataParameters` для всех не-hidden параметров с `userSettingID`. Скрытые параметры (`hidden: true` / `@hidden`) исключаются.
|
||||
|
||||
#### Shorthand-строка
|
||||
|
||||
```json
|
||||
@@ -760,7 +823,7 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
| `style` | Именованный пресет оформления (по умолчанию `"data"`) |
|
||||
| `widths` | Массив ширин колонок (применяется ко всем строкам) |
|
||||
| `minHeight` | Минимальная высота первой строки (для шапок) |
|
||||
| `parameters` | Параметры макета — выражения для подстановки |
|
||||
| `parameters` | Параметры макета — выражения для подстановки (поддерживают `drilldown`) |
|
||||
|
||||
#### Синтаксис ячеек
|
||||
|
||||
@@ -768,7 +831,8 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
|----------|----------|
|
||||
| `"текст"` | Статический текст (`v8:LocalStringType`) |
|
||||
| `"{Имя}"` | Параметр шаблона (`dcscor:Parameter`), задаётся через `parameters` |
|
||||
| `"\|"` | Вертикальное объединение с ячейкой выше |
|
||||
| `"\|"` | Вертикальное объединение с ячейкой выше (`ОбъединятьПоВертикали`) |
|
||||
| `">"` | Горизонтальное объединение с ячейкой слева (`ОбъединятьПоГоризонтали`) |
|
||||
| `null` | Пустая ячейка (без содержимого) |
|
||||
|
||||
#### Встроенные пресеты стилей
|
||||
@@ -820,14 +884,35 @@ XML-маппинг — по `<group>` на каждый элемент:
|
||||
|
||||
Детект: если есть `rows` — используется компактный DSL, иначе — raw XML из `template`.
|
||||
|
||||
#### Расшифровка (drilldown) в параметрах шаблона
|
||||
|
||||
Ключ `drilldown` в параметре шаблона автоматически генерирует:
|
||||
1. `DetailsAreaTemplateParameter` с именем `Расшифровка_<значение>`, `fieldExpression` по полю `ИмяРесурса`, `mainAction=DrillDown`
|
||||
2. Привязку `Расшифровка` в appearance ячеек, ссылающихся на этот параметр через `{Имя}`
|
||||
|
||||
```json
|
||||
"parameters": [
|
||||
{ "name": "Сырье", "expression": "ПоступлениеСырья", "drilldown": "ПоступлениеСырья" }
|
||||
]
|
||||
```
|
||||
|
||||
### groupTemplates
|
||||
|
||||
```json
|
||||
"groupTemplates": [
|
||||
{ "groupField": "ТипЦен", "templateType": "Header", "template": "Макет1" }
|
||||
{ "groupName": "ДанныеОтчета", "templateType": "GroupHeader", "template": "Макет1" },
|
||||
{ "groupField": "Счет", "templateType": "Header", "template": "Макет2" },
|
||||
{ "groupField": "Счет", "templateType": "OverallHeader", "template": "Макет3" }
|
||||
]
|
||||
```
|
||||
|
||||
| Ключ | Описание |
|
||||
|------|----------|
|
||||
| `groupField` | Привязка к полю группировки → `<groupField>` |
|
||||
| `groupName` | Привязка к именованной группировке в структуре варианта → `<groupName>` |
|
||||
| `templateType` | `Header` / `OverallHeader` → `<groupTemplate>`, `GroupHeader` → `<groupHeaderTemplate>` |
|
||||
| `template` | Имя макета |
|
||||
|
||||
---
|
||||
|
||||
## 11. Полный пример — минимальный
|
||||
|
||||
+10
-4
@@ -71,7 +71,7 @@
|
||||
]
|
||||
```
|
||||
|
||||
`@autoDates` автоматически генерирует параметры `ДатаНачала`/`ДатаОкончания` (заменяет 5 строк на 1).
|
||||
Флаги: `@autoDates` (авто ДатаНачала/ДатаОкончания), `@valueList` (разрешить список значений), `@hidden` (скрыть параметр, исключить из `dataParameters: auto`).
|
||||
|
||||
### Вычисляемые поля — shorthand
|
||||
|
||||
@@ -96,9 +96,11 @@
|
||||
```
|
||||
|
||||
- **filter shorthand**: `"Поле оператор значение @флаги"` — флаги `@off`, `@user`, `@quickAccess`, `@normal`, `@inaccessible`
|
||||
- **dataParameters shorthand**: `"Имя = значение @флаги"`
|
||||
- **dataParameters shorthand**: `"Имя = значение @флаги"`, или `"auto"` — автогенерация для всех не-hidden параметров
|
||||
- **structure shorthand**: `"Поле1 > Поле2 > details"` — `>` разделяет уровни группировки
|
||||
- **conditionalAppearance**: условное оформление с автоопределением типов значений (Color, Boolean, LocalStringType)
|
||||
- **conditionalAppearance**: условное оформление с автоопределением типов (Color, Boolean, LocalStringType для Формат/Текст/Заголовок, DesignTimeValue для ссылок), OrGroup через `{"group": "Or", "items": [...]}`
|
||||
- **selection**: поддержка `{"folder": "Название", "items": [...]}` для группировки полей (SelectedItemFolder)
|
||||
- **parameters**: `availableValues`, `denyIncompleteValues`, `use: "Always"` в объектной форме
|
||||
|
||||
### Шаблоны вывода — компактный DSL
|
||||
|
||||
@@ -125,13 +127,17 @@
|
||||
}
|
||||
],
|
||||
"groupTemplates": [
|
||||
{ "groupField": "Счет", "templateType": "GroupHeader", "template": "Макет1" },
|
||||
{ "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` в директории проекта.
|
||||
|
||||
### Объектная форма
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "availableValues, denyIncompleteValues, Folder в selection",
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ Т.Счет, Т.Остаток, Т.Поступление1, Т.Поступление2, Т.Выбытие1, Т.Выбытие2 ИЗ Регистр КАК Т",
|
||||
"fields": ["Счет: string", "Остаток: decimal(15,2)", "Поступление1: decimal(15,2)", "Поступление2: decimal(15,2)", "Выбытие1: decimal(15,2)", "Выбытие2: decimal(15,2)"]
|
||||
}],
|
||||
"parameters": [{
|
||||
"name": "ПорядокОкругления",
|
||||
"type": "EnumRef.Округления",
|
||||
"value": "Перечисление.Округления.Окр1_00",
|
||||
"use": "Always",
|
||||
"denyIncompleteValues": true,
|
||||
"availableValues": [
|
||||
{"value": "Перечисление.Округления.Окр1_00", "presentation": "руб. коп"},
|
||||
{"value": "Перечисление.Округления.Окр1", "presentation": "руб."},
|
||||
{"value": "Перечисление.Округления.Окр1000", "presentation": "тыс. руб"}
|
||||
]
|
||||
}],
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": [
|
||||
"Auto",
|
||||
"Счет",
|
||||
"Остаток",
|
||||
{"folder": "Поступление", "items": ["Поступление1", "Поступление2"]},
|
||||
{"folder": "Выбытие", "items": ["Выбытие1", "Выбытие2"]}
|
||||
],
|
||||
"structure": {
|
||||
"type": "group",
|
||||
"name": "ДанныеОтчета",
|
||||
"groupBy": ["Счет"],
|
||||
"selection": [
|
||||
"Auto",
|
||||
{"folder": "Поступление", "items": ["Поступление1", "Поступление2"]}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
"validatePath": "Template.xml",
|
||||
"expect": {
|
||||
"files": ["Template.xml"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "Горизонтальное объединение ячеек (>) в шаблонах",
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ Т.Счет, Т.Остаток, Т.Пост1, Т.Пост2, Т.Пост3, Т.Выб1, Т.Выб2, Т.Итого ИЗ Регистр КАК Т",
|
||||
"fields": ["Счет: string", "Остаток: decimal(15,2)", "Пост1: decimal(15,2)", "Пост2: decimal(15,2)", "Пост3: decimal(15,2)", "Выб1: decimal(15,2)", "Выб2: decimal(15,2)", "Итого: decimal(15,2)"]
|
||||
}],
|
||||
"templates": [
|
||||
{
|
||||
"name": "Макет1",
|
||||
"style": "header",
|
||||
"widths": [30, 16, 16, 16, 16, 16, 16, 16],
|
||||
"minHeight": 24.75,
|
||||
"rows": [
|
||||
["Счет", "Остаток", "Поступление", ">", ">", "Выбытие", ">", "Итого"],
|
||||
["|", "|", "из произв.", "из п/ф", "прочее", "Реализ.", "прочее", "|"],
|
||||
["К1", "К2", "К3", "К4", "К5", "К6", "К7", "К8"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Макет2",
|
||||
"style": "data",
|
||||
"widths": [30, 16, 16, 16, 16, 16, 16, 16],
|
||||
"rows": [["{Счет}", "{Остаток}", "{Пост1}", "{Пост2}", "{Пост3}", "{Выб1}", "{Выб2}", "{Итого}"]]
|
||||
}
|
||||
],
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": ["Auto"],
|
||||
"structure": "details"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"validatePath": "Template.xml",
|
||||
"expect": {
|
||||
"files": ["Template.xml"],
|
||||
"contains": [
|
||||
"ОбъединятьПоГоризонтали",
|
||||
"ОбъединятьПоВертикали",
|
||||
"Поступление",
|
||||
"Выбытие"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema"
|
||||
xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common"
|
||||
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: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">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>Основной</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Счет</dataPath>
|
||||
<field>Счет</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Остаток</dataPath>
|
||||
<field>Остаток</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Поступление1</dataPath>
|
||||
<field>Поступление1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Поступление2</dataPath>
|
||||
<field>Поступление2</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Выбытие1</dataPath>
|
||||
<field>Выбытие1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Выбытие2</dataPath>
|
||||
<field>Выбытие2</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ Т.Счет, Т.Остаток, Т.Поступление1, Т.Поступление2, Т.Выбытие1, Т.Выбытие2 ИЗ Регистр КАК Т</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>ПорядокОкругления</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:EnumRef.Округления</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1_00</value>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1_00</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>руб. коп</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>руб.</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1000</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>тыс. руб</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<denyIncompleteValues>true</denyIncompleteValues>
|
||||
<use>Always</use>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Счет</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Остаток</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemFolder">
|
||||
<dcsset:lwsTitle>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Поступление</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:lwsTitle>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Поступление1</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Поступление2</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:placement>Auto</dcsset:placement>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemFolder">
|
||||
<dcsset:lwsTitle>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Выбытие</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:lwsTitle>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Выбытие1</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Выбытие2</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:placement>Auto</dcsset:placement>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:name>ДанныеОтчета</dcsset:name>
|
||||
<dcsset:groupItems>
|
||||
<dcsset:item xsi:type="dcsset:GroupItemField">
|
||||
<dcsset:field>Счет</dcsset:field>
|
||||
<dcsset:groupType>Items</dcsset:groupType>
|
||||
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
|
||||
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
|
||||
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
|
||||
</dcsset:item>
|
||||
</dcsset:groupItems>
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemFolder">
|
||||
<dcsset:lwsTitle>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Поступление</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:lwsTitle>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Поступление1</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Поступление2</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:placement>Auto</dcsset:placement>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "conditionalAppearance: DesignTimeValue, Format, OrGroup",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ Т.Сумма ИЗ Регистр КАК Т",
|
||||
"fields": ["Сумма: decimal(15,2)"]
|
||||
}],
|
||||
"parameters": ["ПорядокОкругления: string"]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "add-conditionalAppearance",
|
||||
"value": "Формат = ЧЦ=15; ЧДЦ=2 when ПараметрыДанных.ПорядокОкругления = Перечисление.Округления.Окр1_00 ;; Формат = ЧЦ=15; ЧДЦ=0 when ПараметрыДанных.ПорядокОкругления = Перечисление.Округления.Окр1 or ПараметрыДанных.ПорядокОкругления = Перечисление.Округления.Окр1000"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "modify-parameter: combined kv + availableValue in single entry",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ Т.Сумма ИЗ Регистр КАК Т",
|
||||
"fields": ["Сумма: decimal(15,2)"]
|
||||
}],
|
||||
"parameters": [{"name": "ПорядокОкругления", "type": "string", "value": "Окр1_00"}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "modify-parameter",
|
||||
"value": "ПорядокОкругления denyIncompleteValues=true use=Always availableValue=Перечисление.Округления.Окр1_00 presentation=руб. коп ;; ПорядокОкругления availableValue=Перечисление.Округления.Окр1 presentation=руб. ;; ПорядокОкругления availableValue=Перечисление.Округления.Окр1000 presentation=тыс. руб"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "modify-parameter: use, denyIncompleteValues, availableValue",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ Т.Сумма ИЗ Регистр КАК Т",
|
||||
"fields": ["Сумма: decimal(15,2)"]
|
||||
}],
|
||||
"parameters": [{"name": "ПорядокОкругления", "type": "string", "value": "Окр1_00"}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "modify-parameter",
|
||||
"value": "ПорядокОкругления use=Always ;; ПорядокОкругления denyIncompleteValues=true ;; ПорядокОкругления availableValue=Перечисление.Округления.Окр1_00 presentation=руб. коп ;; ПорядокОкругления availableValue=Перечисление.Округления.Окр1 presentation=руб."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "set-structure с @name= и Folder в selection + @group=",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ Т.Счет, Т.Поступление1, Т.Поступление2, Т.Выбытие1 ИЗ Регистр КАК Т",
|
||||
"fields": ["Счет: string", "Поступление1: decimal(15,2)", "Поступление2: decimal(15,2)", "Выбытие1: decimal(15,2)"]
|
||||
}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
},
|
||||
{
|
||||
"script": "skd-edit/scripts/skd-edit",
|
||||
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "set-structure", "-Value": "Счет @name=ДанныеОтчета" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "add-selection",
|
||||
"value": "Auto @group=ДанныеОтчета ;; Счет @group=ДанныеОтчета ;; Folder(Поступление: Поступление1, Поступление2) @group=ДанныеОтчета ;; Выбытие1 @group=ДанныеОтчета"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" 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: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">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>Основной</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ Т.Сумма ИЗ Регистр КАК Т</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>ПорядокОкругления</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
</dcsset:selection>
|
||||
<dcsset:conditionalAppearance>
|
||||
<dcsset:item>
|
||||
<dcsset:selection />
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">ПараметрыДанных.ПорядокОкругления</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1_00</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:appearance>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Формат</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>ЧЦ=15; ЧДЦ=2</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:appearance>
|
||||
</dcsset:item>
|
||||
<dcsset:item>
|
||||
<dcsset:selection />
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemGroup">
|
||||
<dcsset:groupType>OrGroup</dcsset:groupType>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">ПараметрыДанных.ПорядокОкругления</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1</dcsset:right>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">ПараметрыДанных.ПорядокОкругления</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1000</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:appearance>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Формат</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>ЧЦ=15; ЧДЦ=0</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:appearance>
|
||||
</dcsset:item>
|
||||
</dcsset:conditionalAppearance>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto" />
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" 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: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">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>Основной</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ Т.Сумма ИЗ Регистр КАК Т</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>ПорядокОкругления</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string">Окр1_00</value>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1_00</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>руб. коп</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>руб.</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1000</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>тыс. руб</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<denyIncompleteValues>true</denyIncompleteValues>
|
||||
<use>Always</use>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
</dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto" />
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" 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: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">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>Основной</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ Т.Сумма ИЗ Регистр КАК Т</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>ПорядокОкругления</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string">Окр1_00</value>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1_00</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>руб. коп</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<availableValue>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Перечисление.Округления.Окр1</value>
|
||||
<presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>руб.</v8:content>
|
||||
</v8:item>
|
||||
</presentation>
|
||||
</availableValue>
|
||||
<denyIncompleteValues>true</denyIncompleteValues>
|
||||
<use>Always</use>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
</dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto" />
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" 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: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">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>Основной</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Счет</dataPath>
|
||||
<field>Счет</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Поступление1</dataPath>
|
||||
<field>Поступление1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Поступление2</dataPath>
|
||||
<field>Поступление2</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Выбытие1</dataPath>
|
||||
<field>Выбытие1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ Т.Счет, Т.Поступление1, Т.Поступление2, Т.Выбытие1 ИЗ Регистр КАК Т</query>
|
||||
</dataSet>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:name>ДанныеОтчета</dcsset:name>
|
||||
<dcsset:groupItems>
|
||||
<dcsset:item xsi:type="dcsset:GroupItemField">
|
||||
<dcsset:field>Счет</dcsset:field>
|
||||
<dcsset:groupType>Items</dcsset:groupType>
|
||||
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
|
||||
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
|
||||
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
|
||||
</dcsset:item>
|
||||
</dcsset:groupItems>
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto" />
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Счет</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemFolder">
|
||||
<dcsset:lwsTitle>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Поступление</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:lwsTitle>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Поступление1</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Поступление2</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:placement>Auto</dcsset:placement>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Выбытие1</dcsset:field>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
<dcsset:selection>
|
||||
</dcsset:selection>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
Reference in New Issue
Block a user