mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-14 23:05:16 +03:00
Compare commits
7 Commits
3eaa7ffa3b
...
6e14f2502e
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e14f2502e | |||
| ff2d8513c4 | |||
| efdf56691c | |||
| 12745b14c3 | |||
| a5a1636918 | |||
| 05374100c1 | |||
| 449f814d16 |
@@ -88,7 +88,9 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-compile.ps1" -V
|
||||
|
||||
Многоязычный заголовок: `"title": { "ru": "...", "en": "..." }`. Применимо везде, где принимается title/presentation (поля, calculatedFields, parameters, settingsVariants, availableValues и пр.). Строка эквивалентна `{ "ru": "..." }`.
|
||||
|
||||
Типы: `string`, `string(N)`, `decimal(D,F)`, `boolean`, `date`, `dateTime`, `CatalogRef.X`, `DocumentRef.X`, `EnumRef.X`, `StandardPeriod`. Ссылочные типы эмитируются с inline namespace `d5p1:` (`http://v8.1c.ru/8.1/data/enterprise/current-config`). Сборка EPF со ссылочными типами требует базу с соответствующей конфигурацией.
|
||||
Типы: `string`, `string(N)`, `decimal`, `decimal(D)`, `decimal(D,F)`, `boolean`, `date`, `dateTime`, `CatalogRef.X`, `DocumentRef.X`, `EnumRef.X`, `StandardPeriod`. Ссылочные типы эмитируются с inline namespace `d5p1:` (`http://v8.1c.ru/8.1/data/enterprise/current-config`). Сборка EPF со ссылочными типами требует базу с соответствующей конфигурацией.
|
||||
|
||||
`decimal` без скобок = `10,2` (деньги по умолчанию), `decimal(N)` = `N,0` (целое); `,nonneg` в конце скобок → AllowedSign=Nonnegative.
|
||||
|
||||
Составной тип (несколько типов значений) — массив в объектной форме: `"type": ["CatalogRef.A", "CatalogRef.B"]`. Квалификаторы (`(N)`, `(D,F)`) применяются к каждому элементу.
|
||||
|
||||
@@ -147,6 +149,8 @@ Shorthand: `"Имя [Заголовок]: тип = значение @флаги"
|
||||
|
||||
Объектная форма: `title`, `hidden: true`, `valueListAllowed: true`, `availableAsField: false`, `denyIncompleteValues: true`, `use: "Always"`.
|
||||
|
||||
Если значения по умолчанию нет — пропусти `=` в shorthand или укажи `"value": null` в объектной форме.
|
||||
|
||||
Список допустимых значений (availableValues):
|
||||
|
||||
```json
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-compile v1.23 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.26 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -143,6 +143,7 @@ $script:typeSynonyms["строка"] = "string"
|
||||
$script:typeSynonyms["булево"] = "boolean"
|
||||
$script:typeSynonyms["дата"] = "date"
|
||||
$script:typeSynonyms["датавремя"] = "dateTime"
|
||||
$script:typeSynonyms["время"] = "time"
|
||||
$script:typeSynonyms["стандартныйпериод"] = "StandardPeriod"
|
||||
# English canonical (lowercase for lookup)
|
||||
$script:typeSynonyms["bool"] = "boolean"
|
||||
@@ -219,22 +220,32 @@ function Emit-SingleValueType {
|
||||
return
|
||||
}
|
||||
|
||||
# string or string(N)
|
||||
if ($typeStr -match '^string(\((\d+)\))?$') {
|
||||
# string, string(N), string(N,fix) — fix → AllowedLength=Fixed
|
||||
if ($typeStr -match '^string(\((\d+)(,(fix|fixed))?\))?$') {
|
||||
$len = if ($Matches[2]) { $Matches[2] } else { "0" }
|
||||
$al = if ($Matches[4]) { "Fixed" } else { "Variable" }
|
||||
X "$indent<v8:Type>xs:string</v8:Type>"
|
||||
X "$indent<v8:StringQualifiers>"
|
||||
X "$indent`t<v8:Length>$len</v8:Length>"
|
||||
X "$indent`t<v8:AllowedLength>Variable</v8:AllowedLength>"
|
||||
X "$indent`t<v8:AllowedLength>$al</v8:AllowedLength>"
|
||||
X "$indent</v8:StringQualifiers>"
|
||||
return
|
||||
}
|
||||
|
||||
# decimal(D,F) or decimal(D,F,nonneg)
|
||||
if ($typeStr -match '^decimal\((\d+),(\d+)(,nonneg)?\)$') {
|
||||
$digits = $Matches[1]
|
||||
$fraction = $Matches[2]
|
||||
$sign = if ($Matches[3]) { "Nonnegative" } else { "Any" }
|
||||
# decimal forms (defaults — bare decimal = money 10,2; decimal(N) = integer N,0):
|
||||
# decimal → 10,2,Any
|
||||
# decimal(N) → N,0,Any
|
||||
# decimal(N,nonneg) → N,0,Nonnegative
|
||||
# decimal(N,M) → N,M,Any
|
||||
# decimal(N,M,nonneg) → N,M,Nonnegative
|
||||
if ($typeStr -match '^decimal(\((\d+)(,(\d+))?(,nonneg)?\))?$') {
|
||||
if (-not $Matches[1]) {
|
||||
$digits = "10"; $fraction = "2"; $sign = "Any"
|
||||
} else {
|
||||
$digits = $Matches[2]
|
||||
$fraction = if ($Matches[4]) { $Matches[4] } else { "0" }
|
||||
$sign = if ($Matches[5]) { "Nonnegative" } else { "Any" }
|
||||
}
|
||||
X "$indent<v8:Type>xs:decimal</v8:Type>"
|
||||
X "$indent<v8:NumberQualifiers>"
|
||||
X "$indent`t<v8:Digits>$digits</v8:Digits>"
|
||||
@@ -244,11 +255,12 @@ function Emit-SingleValueType {
|
||||
return
|
||||
}
|
||||
|
||||
# date / dateTime
|
||||
if ($typeStr -match '^(date|dateTime)$') {
|
||||
# date / dateTime / time — all use xs:dateTime, differ only in DateFractions
|
||||
if ($typeStr -match '^(date|dateTime|time)$') {
|
||||
$fractions = switch ($typeStr) {
|
||||
"date" { "Date" }
|
||||
"dateTime" { "DateTime" }
|
||||
"time" { "Time" }
|
||||
}
|
||||
X "$indent<v8:Type>xs:dateTime</v8:Type>"
|
||||
X "$indent<v8:DateQualifiers>"
|
||||
@@ -375,8 +387,8 @@ function Parse-ParamShorthand {
|
||||
$s = ($s -replace '\s*\[[^\]]*\]\s*', ' ').Trim()
|
||||
}
|
||||
|
||||
# Split "Name: Type = Value"
|
||||
if ($s -match '^([^:]+):\s*(\S+)(\s*=\s*(.+))?$') {
|
||||
# Split "Name: Type = Value" — RHS may be empty (`= ` / `=`) → treated as empty value
|
||||
if ($s -match '^([^:]+):\s*(\S+)(\s*=\s*(.*))?$') {
|
||||
$result.name = $Matches[1].Trim()
|
||||
$result.type = Resolve-TypeStr ($Matches[2].Trim())
|
||||
if ($Matches[4]) {
|
||||
@@ -985,8 +997,17 @@ function Emit-SingleParam {
|
||||
X "`t`t</valueType>"
|
||||
}
|
||||
|
||||
# Value
|
||||
Emit-ParamValue -type $parsed.type -val $parsed.value -indent "`t`t"
|
||||
# Value — for valueListAllowed params Designer omits <value> when empty
|
||||
$vla = [bool]$parsed.valueListAllowed
|
||||
if ($parsed.type -is [array] -or $parsed.type -is [System.Collections.IList]) {
|
||||
# Composite type — Designer writes xsi:nil for any empty composite;
|
||||
# non-empty composite values are uncommon and would need per-type tagging.
|
||||
if (Test-EmptyValue $parsed.value) {
|
||||
if (-not $vla) { X "`t`t<value xsi:nil=`"true`"/>" }
|
||||
}
|
||||
} else {
|
||||
Emit-ParamValue -type $parsed.type -val $parsed.value -indent "`t`t" -valueListAllowed $vla
|
||||
}
|
||||
|
||||
# Hidden implies useRestriction=true + availableAsField=false
|
||||
if ($parsed.hidden -eq $true) {
|
||||
@@ -1017,13 +1038,17 @@ function Emit-SingleParam {
|
||||
# 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 (Test-EmptyValue $av.value) {
|
||||
Emit-EmptyValue -type $parsed.type -indent "`t`t`t" -tagPrefix "" -valueListAllowed $false
|
||||
} else {
|
||||
$avVal = "$($av.value)"
|
||||
$avType = "xs:string"
|
||||
if ($avVal -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.') {
|
||||
$avType = "dcscor:DesignTimeValue"
|
||||
}
|
||||
X "`t`t`t<value xsi:type=`"$avType`">$(Esc-Xml $avVal)</value>"
|
||||
}
|
||||
# `title` accepted as synonym of `presentation` — both map to the same UI label.
|
||||
$avPres = if ($av.presentation) { $av.presentation } elseif ($av.title) { $av.title } else { "" }
|
||||
if ($avPres) {
|
||||
@@ -1059,9 +1084,19 @@ function Emit-Parameters {
|
||||
if ($p -is [string]) {
|
||||
$parsed = Parse-ParamShorthand $p
|
||||
} else {
|
||||
# Composite type: ["string(10,fix)", "CatalogRef.X"] → array of resolved
|
||||
# strings; emit-valueType handles arrays, empty value falls through to nil.
|
||||
$resolvedType = ""
|
||||
if ($p.type) {
|
||||
if ($p.type -is [array] -or $p.type -is [System.Collections.IList]) {
|
||||
$resolvedType = @($p.type | ForEach-Object { Resolve-TypeStr "$_" })
|
||||
} else {
|
||||
$resolvedType = Resolve-TypeStr "$($p.type)"
|
||||
}
|
||||
}
|
||||
$parsed = @{
|
||||
name = "$($p.name)"
|
||||
type = if ($p.type) { Resolve-TypeStr "$($p.type)" } else { "" }
|
||||
type = $resolvedType
|
||||
value = $p.value
|
||||
autoDates = $false
|
||||
}
|
||||
@@ -1107,10 +1142,52 @@ function Emit-Parameters {
|
||||
}
|
||||
}
|
||||
|
||||
function Emit-ParamValue {
|
||||
param([string]$type, $val, [string]$indent)
|
||||
function Test-EmptyValue {
|
||||
param($v)
|
||||
if ($null -eq $v) { return $true }
|
||||
$s = "$v".Trim()
|
||||
if ($s -eq "") { return $true }
|
||||
if ($s -eq "_") { return $true }
|
||||
if ($s.ToLowerInvariant() -eq "null") { return $true }
|
||||
return $false
|
||||
}
|
||||
|
||||
if ($null -eq $val) { return }
|
||||
function Emit-EmptyValue {
|
||||
param([string]$type, [string]$indent, [string]$tagPrefix = "", [bool]$valueListAllowed = $false)
|
||||
|
||||
if ($valueListAllowed) { return }
|
||||
$t = if ($null -eq $type) { "" } else { "$type" }
|
||||
$pf = $tagPrefix
|
||||
|
||||
if ($t -eq "") {
|
||||
X "$indent<${pf}value xsi:nil=`"true`"/>"
|
||||
} elseif ($t -eq "StandardPeriod") {
|
||||
X "$indent<${pf}value xsi:type=`"v8:StandardPeriod`">"
|
||||
X "$indent`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">Custom</v8:variant>"
|
||||
X "$indent`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||
X "$indent`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||
X "$indent</${pf}value>"
|
||||
} elseif ($t -match '^string') {
|
||||
X "$indent<${pf}value xsi:type=`"xs:string`"/>"
|
||||
} elseif ($t -match '^(date|time)') {
|
||||
X "$indent<${pf}value xsi:type=`"xs:dateTime`">0001-01-01T00:00:00</${pf}value>"
|
||||
} elseif ($t -match '^decimal') {
|
||||
X "$indent<${pf}value xsi:type=`"xs:decimal`">0</${pf}value>"
|
||||
} elseif ($t -eq "boolean") {
|
||||
X "$indent<${pf}value xsi:type=`"xs:boolean`">false</${pf}value>"
|
||||
} else {
|
||||
# Ref types or unknown — safe nil
|
||||
X "$indent<${pf}value xsi:nil=`"true`"/>"
|
||||
}
|
||||
}
|
||||
|
||||
function Emit-ParamValue {
|
||||
param([string]$type, $val, [string]$indent, [bool]$valueListAllowed = $false)
|
||||
|
||||
if (Test-EmptyValue $val) {
|
||||
Emit-EmptyValue -type $type -indent $indent -tagPrefix "" -valueListAllowed $valueListAllowed
|
||||
return
|
||||
}
|
||||
|
||||
$valStr = "$val"
|
||||
|
||||
@@ -1868,6 +1945,8 @@ function Emit-DataParameters {
|
||||
# Value
|
||||
if ($dp.nilValue -eq $true) {
|
||||
X "$indent`t`t<dcscor:value xsi:nil=`"true`"/>"
|
||||
} elseif (Test-EmptyValue $dp.value) {
|
||||
Emit-EmptyValue -type "$($dp.valueType)" -indent "$indent`t`t" -tagPrefix "dcscor:" -valueListAllowed $false
|
||||
} elseif ($null -ne $dp.value) {
|
||||
$vtype = "$($dp.valueType)"
|
||||
if ($dp.value -is [PSCustomObject] -and $dp.value.variant) {
|
||||
@@ -2206,7 +2285,7 @@ function Emit-SettingsVariants {
|
||||
}
|
||||
$dpItem | Add-Member -NotePropertyName "value" -NotePropertyValue @{ variant = $variant }
|
||||
if ($variant -ne 'Custom') { $hasMeaningfulValue = $true }
|
||||
} elseif ($null -ne $ap.value -and "$($ap.value)" -ne '') {
|
||||
} elseif (-not (Test-EmptyValue $ap.value)) {
|
||||
$dpItem | Add-Member -NotePropertyName "value" -NotePropertyValue $ap.value
|
||||
$dpItem | Add-Member -NotePropertyName "valueType" -NotePropertyValue "$($ap.type)"
|
||||
$hasMeaningfulValue = $true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# skd-compile v1.23 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.26 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -74,6 +74,7 @@ TYPE_SYNONYMS = {
|
||||
"\u0431\u0443\u043b\u0435\u0432\u043e": "boolean",
|
||||
"\u0434\u0430\u0442\u0430": "date",
|
||||
"\u0434\u0430\u0442\u0430\u0432\u0440\u0435\u043c\u044f": "dateTime",
|
||||
"\u0432\u0440\u0435\u043c\u044f": "time",
|
||||
"\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439\u043f\u0435\u0440\u0438\u043e\u0434": "StandardPeriod",
|
||||
# English canonical (lowercase)
|
||||
"bool": "boolean",
|
||||
@@ -148,23 +149,32 @@ def emit_single_value_type(lines, type_str, indent):
|
||||
lines.append(f'{indent}<v8:Type>xs:boolean</v8:Type>')
|
||||
return
|
||||
|
||||
# string or string(N)
|
||||
m = re.match(r'^string(\((\d+)\))?$', type_str)
|
||||
# string, string(N), string(N,fix) — fix → AllowedLength=Fixed
|
||||
m = re.match(r'^string(\((\d+)(,(fix|fixed))?\))?$', type_str)
|
||||
if m:
|
||||
length = m.group(2) if m.group(2) else '0'
|
||||
al = 'Fixed' if m.group(4) else 'Variable'
|
||||
lines.append(f'{indent}<v8:Type>xs:string</v8:Type>')
|
||||
lines.append(f'{indent}<v8:StringQualifiers>')
|
||||
lines.append(f'{indent}\t<v8:Length>{length}</v8:Length>')
|
||||
lines.append(f'{indent}\t<v8:AllowedLength>Variable</v8:AllowedLength>')
|
||||
lines.append(f'{indent}\t<v8:AllowedLength>{al}</v8:AllowedLength>')
|
||||
lines.append(f'{indent}</v8:StringQualifiers>')
|
||||
return
|
||||
|
||||
# decimal(D,F) or decimal(D,F,nonneg)
|
||||
m = re.match(r'^decimal\((\d+),(\d+)(,nonneg)?\)$', type_str)
|
||||
# decimal forms (defaults — bare decimal = money 10,2; decimal(N) = integer N,0):
|
||||
# decimal → 10,2,Any
|
||||
# decimal(N) → N,0,Any
|
||||
# decimal(N,nonneg) → N,0,Nonnegative
|
||||
# decimal(N,M) → N,M,Any
|
||||
# decimal(N,M,nonneg) → N,M,Nonnegative
|
||||
m = re.match(r'^decimal(\((\d+)(,(\d+))?(,nonneg)?\))?$', type_str)
|
||||
if m:
|
||||
digits = m.group(1)
|
||||
fraction = m.group(2)
|
||||
sign = 'Nonnegative' if m.group(3) else 'Any'
|
||||
if not m.group(1):
|
||||
digits, fraction, sign = '10', '2', 'Any'
|
||||
else:
|
||||
digits = m.group(2)
|
||||
fraction = m.group(4) if m.group(4) else '0'
|
||||
sign = 'Nonnegative' if m.group(5) else 'Any'
|
||||
lines.append(f'{indent}<v8:Type>xs:decimal</v8:Type>')
|
||||
lines.append(f'{indent}<v8:NumberQualifiers>')
|
||||
lines.append(f'{indent}\t<v8:Digits>{digits}</v8:Digits>')
|
||||
@@ -173,10 +183,10 @@ def emit_single_value_type(lines, type_str, indent):
|
||||
lines.append(f'{indent}</v8:NumberQualifiers>')
|
||||
return
|
||||
|
||||
# date / dateTime
|
||||
m = re.match(r'^(date|dateTime)$', type_str)
|
||||
# date / dateTime / time — all use xs:dateTime, differ only in DateFractions
|
||||
m = re.match(r'^(date|dateTime|time)$', type_str)
|
||||
if m:
|
||||
fractions_map = {'date': 'Date', 'dateTime': 'DateTime'}
|
||||
fractions_map = {'date': 'Date', 'dateTime': 'DateTime', 'time': 'Time'}
|
||||
fractions = fractions_map[type_str]
|
||||
lines.append(f'{indent}<v8:Type>xs:dateTime</v8:Type>')
|
||||
lines.append(f'{indent}<v8:DateQualifiers>')
|
||||
@@ -282,8 +292,8 @@ def parse_param_shorthand(s):
|
||||
result['title'] = m.group(1).strip()
|
||||
s = re.sub(r'\s*\[[^\]]*\]\s*', ' ', s).strip()
|
||||
|
||||
# Split "Name: Type = Value"
|
||||
m = re.match(r'^([^:]+):\s*(\S+)(\s*=\s*(.+))?$', s)
|
||||
# Split "Name: Type = Value" — RHS may be empty (`= ` / `=`) → treated as empty value
|
||||
m = re.match(r'^([^:]+):\s*(\S+)(\s*=\s*(.*))?$', s)
|
||||
if m:
|
||||
result['name'] = m.group(1).strip()
|
||||
result['type'] = resolve_type_str(m.group(2).strip())
|
||||
@@ -790,8 +800,49 @@ def emit_total_fields(lines, defn):
|
||||
|
||||
# === Parameters ===
|
||||
|
||||
def emit_param_value(lines, type_str, val, indent):
|
||||
if val is None:
|
||||
def is_empty_value(v):
|
||||
if v is None:
|
||||
return True
|
||||
s = str(v).strip()
|
||||
if s == '':
|
||||
return True
|
||||
if s == '_':
|
||||
return True
|
||||
if s.lower() == 'null':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def emit_empty_value(lines, type_str, indent, tag_prefix='', value_list_allowed=False):
|
||||
if value_list_allowed:
|
||||
return
|
||||
t = type_str or ''
|
||||
pf = tag_prefix
|
||||
|
||||
if t == '':
|
||||
lines.append(f'{indent}<{pf}value xsi:nil="true"/>')
|
||||
elif t == 'StandardPeriod':
|
||||
lines.append(f'{indent}<{pf}value xsi:type="v8:StandardPeriod">')
|
||||
lines.append(f'{indent}\t<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>')
|
||||
lines.append(f'{indent}\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>')
|
||||
lines.append(f'{indent}\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>')
|
||||
lines.append(f'{indent}</{pf}value>')
|
||||
elif re.match(r'^string', t):
|
||||
lines.append(f'{indent}<{pf}value xsi:type="xs:string"/>')
|
||||
elif re.match(r'^(date|time)', t):
|
||||
lines.append(f'{indent}<{pf}value xsi:type="xs:dateTime">0001-01-01T00:00:00</{pf}value>')
|
||||
elif re.match(r'^decimal', t):
|
||||
lines.append(f'{indent}<{pf}value xsi:type="xs:decimal">0</{pf}value>')
|
||||
elif t == 'boolean':
|
||||
lines.append(f'{indent}<{pf}value xsi:type="xs:boolean">false</{pf}value>')
|
||||
else:
|
||||
# Ref types or unknown — safe nil
|
||||
lines.append(f'{indent}<{pf}value xsi:nil="true"/>')
|
||||
|
||||
|
||||
def emit_param_value(lines, type_str, val, indent, value_list_allowed=False):
|
||||
if is_empty_value(val):
|
||||
emit_empty_value(lines, type_str, indent, '', value_list_allowed)
|
||||
return
|
||||
|
||||
val_str = str(val)
|
||||
@@ -847,8 +898,17 @@ def emit_single_param(lines, p, parsed):
|
||||
emit_value_type(lines, parsed['type'], '\t\t\t')
|
||||
lines.append('\t\t</valueType>')
|
||||
|
||||
# Value
|
||||
emit_param_value(lines, parsed.get('type', ''), parsed.get('value'), '\t\t')
|
||||
# Value — for valueListAllowed params Designer omits <value> when empty
|
||||
vla = bool(parsed.get('valueListAllowed'))
|
||||
p_type = parsed.get('type', '')
|
||||
if isinstance(p_type, (list, tuple)):
|
||||
# Composite type — Designer writes xsi:nil for any empty composite;
|
||||
# non-empty composite values are uncommon and would need per-type tagging.
|
||||
if is_empty_value(parsed.get('value')):
|
||||
if not vla:
|
||||
lines.append('\t\t<value xsi:nil="true"/>')
|
||||
else:
|
||||
emit_param_value(lines, p_type, parsed.get('value'), '\t\t', vla)
|
||||
|
||||
# Hidden implies useRestriction=true + availableAsField=false
|
||||
if parsed.get('hidden') is True:
|
||||
@@ -876,12 +936,15 @@ def emit_single_param(lines, p, parsed):
|
||||
# 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 is_empty_value(av.get('value')):
|
||||
emit_empty_value(lines, parsed.get('type', ''), '\t\t\t', '', False)
|
||||
else:
|
||||
av_val = str(av.get('value', ''))
|
||||
av_type = 'xs:string'
|
||||
if re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.', av_val):
|
||||
av_type = 'dcscor:DesignTimeValue'
|
||||
lines.append(f'\t\t\t<value xsi:type="{av_type}">{esc_xml(av_val)}</value>')
|
||||
# `title` accepted as synonym of `presentation` — both map to the same UI label.
|
||||
av_pres = av.get('presentation') or av.get('title') or ''
|
||||
if av_pres:
|
||||
@@ -918,9 +981,18 @@ def emit_parameters(lines, defn):
|
||||
if isinstance(p, str):
|
||||
parsed = parse_param_shorthand(p)
|
||||
else:
|
||||
# Composite type: ["string(10,fix)", "CatalogRef.X"] → list of resolved
|
||||
# strings; emit_value_type handles lists, empty value falls through to nil.
|
||||
raw_type = p.get('type')
|
||||
if isinstance(raw_type, (list, tuple)):
|
||||
resolved_type = [resolve_type_str(str(t)) for t in raw_type]
|
||||
elif raw_type:
|
||||
resolved_type = resolve_type_str(str(raw_type))
|
||||
else:
|
||||
resolved_type = ''
|
||||
parsed = {
|
||||
'name': str(p.get('name', '')),
|
||||
'type': resolve_type_str(str(p['type'])) if p.get('type') else '',
|
||||
'type': resolved_type,
|
||||
'value': p.get('value'),
|
||||
'autoDates': False,
|
||||
}
|
||||
@@ -1585,6 +1657,8 @@ def emit_data_parameters(lines, items, indent):
|
||||
# Value
|
||||
if dp.get('nilValue') is True:
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:nil="true"/>')
|
||||
elif is_empty_value(dp.get('value')):
|
||||
emit_empty_value(lines, str(dp.get('valueType') or ''), f'{indent}\t\t', 'dcscor:', False)
|
||||
elif dp.get('value') is not None:
|
||||
val = dp['value']
|
||||
vtype = str(dp.get('valueType') or '')
|
||||
@@ -1853,7 +1927,7 @@ def emit_settings_variants(lines, defn):
|
||||
item['value'] = {'variant': variant}
|
||||
if variant != 'Custom':
|
||||
has_meaningful_value = True
|
||||
elif ap.get('value') is not None and str(ap.get('value')) != '':
|
||||
elif not is_empty_value(ap.get('value')):
|
||||
item['value'] = ap['value']
|
||||
item['valueType'] = str(ap.get('type') or '')
|
||||
has_meaningful_value = True
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-edit v1.22 — Atomic 1C DCS editor
|
||||
# skd-edit v1.23 — Atomic 1C DCS editor
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -337,7 +337,7 @@ function Parse-CalcShorthand {
|
||||
function Parse-ParamShorthand {
|
||||
param([string]$s)
|
||||
|
||||
$result = @{ name = ""; type = ""; value = $null; autoDates = $false; title = $null; hidden = $false; always = $false; availableValues = @() }
|
||||
$result = @{ name = ""; type = ""; value = $null; autoDates = $false; title = $null; hidden = $false; always = $false; availableValues = @(); valueListAllowed = $false }
|
||||
|
||||
# Extract availableValue=... (must be before main parse — captures to end of string)
|
||||
if ($s -match '\s*availableValue=(.+)$') {
|
||||
@@ -350,6 +350,11 @@ function Parse-ParamShorthand {
|
||||
$s = $s -replace '\s*@autoDates', ''
|
||||
}
|
||||
|
||||
if ($s -match '@valueList\b') {
|
||||
$result.valueListAllowed = $true
|
||||
$s = $s -replace '\s*@valueList\b', ''
|
||||
}
|
||||
|
||||
if ($s -match '@hidden\b') {
|
||||
$result.hidden = $true
|
||||
$s = $s -replace '\s*@hidden\b', ''
|
||||
@@ -366,11 +371,14 @@ function Parse-ParamShorthand {
|
||||
$s = ($s -replace '\s*\[[^\]]*\]\s*', ' ').Trim()
|
||||
}
|
||||
|
||||
if ($s -match '^([^:]+):\s*(\S+)(\s*=\s*(.+))?$') {
|
||||
# Split "Name: Type = Value" — RHS may be empty (`= ` / `=`) → treated as empty-value sentinel
|
||||
if ($s -match '^([^:]+):\s*(\S+)(\s*=\s*(.*))?$') {
|
||||
$result.name = $Matches[1].Trim()
|
||||
$result.type = Resolve-TypeStr ($Matches[2].Trim())
|
||||
if ($Matches[4]) {
|
||||
$result.value = $Matches[4].Trim()
|
||||
$hasEq = $null -ne $Matches[3]
|
||||
$rhs = $Matches[4]
|
||||
if ($hasEq) {
|
||||
$result.value = if ($rhs) { $rhs.Trim() } else { "" }
|
||||
}
|
||||
} else {
|
||||
$result.name = $s.Trim()
|
||||
@@ -490,17 +498,16 @@ function Parse-DataParamShorthand {
|
||||
|
||||
$s = $s.Trim()
|
||||
|
||||
if ($s -match '^([^=]+)=\s*(.+)$') {
|
||||
if ($s -match '^([^=]+)=\s*(.*)$') {
|
||||
$result.parameter = $Matches[1].Trim()
|
||||
$valStr = $Matches[2].Trim()
|
||||
|
||||
$periodVariants = @("Custom","Today","ThisWeek","ThisTenDays","ThisMonth","ThisQuarter","ThisHalfYear","ThisYear","FromBeginningOfThisWeek","FromBeginningOfThisTenDays","FromBeginningOfThisMonth","FromBeginningOfThisQuarter","FromBeginningOfThisHalfYear","FromBeginningOfThisYear","LastWeek","LastTenDays","LastMonth","LastQuarter","LastHalfYear","LastYear","NextDay","NextWeek","NextTenDays","NextMonth","NextQuarter","NextHalfYear","NextYear","TillEndOfThisWeek","TillEndOfThisTenDays","TillEndOfThisMonth","TillEndOfThisQuarter","TillEndOfThisHalfYear","TillEndOfThisYear")
|
||||
if ($periodVariants -contains $valStr) {
|
||||
# Empty / sentinel — record as "" so caller emits xsi:nil
|
||||
if ($valStr -eq "" -or $valStr -eq "_" -or $valStr.ToLowerInvariant() -eq "null") {
|
||||
$result.value = ""
|
||||
} elseif ($periodVariants -contains $valStr) {
|
||||
$result.value = @{ variant = $valStr }
|
||||
} elseif ($valStr -match '^\d{4}-\d{2}-\d{2}T') {
|
||||
$result.value = $valStr
|
||||
} elseif ($valStr -eq "true" -or $valStr -eq "false") {
|
||||
$result.value = $valStr
|
||||
} else {
|
||||
$result.value = $valStr
|
||||
}
|
||||
@@ -744,10 +751,21 @@ function Parse-AvailableValueList {
|
||||
# --- 4. Build-* functions (XML fragment generators) ---
|
||||
|
||||
function Build-ValueTypeXml {
|
||||
param([string]$typeStr, [string]$indent)
|
||||
param($typeStr, [string]$indent)
|
||||
|
||||
if (-not $typeStr) { return "" }
|
||||
$typeStr = Resolve-TypeStr $typeStr
|
||||
|
||||
# Composite: array of types — concatenate per-type fragments
|
||||
if ($typeStr -is [array] -or $typeStr -is [System.Collections.IList]) {
|
||||
$parts = @()
|
||||
foreach ($t in $typeStr) {
|
||||
$p = Build-ValueTypeXml -typeStr "$t" -indent $indent
|
||||
if ($p) { $parts += $p }
|
||||
}
|
||||
return $parts -join "`n"
|
||||
}
|
||||
|
||||
$typeStr = Resolve-TypeStr "$typeStr"
|
||||
$lines = @()
|
||||
|
||||
if ($typeStr -eq "boolean") {
|
||||
@@ -755,20 +773,27 @@ function Build-ValueTypeXml {
|
||||
return $lines -join "`n"
|
||||
}
|
||||
|
||||
if ($typeStr -match '^string(\((\d+)\))?$') {
|
||||
# string, string(N), string(N,fix) — fix → AllowedLength=Fixed
|
||||
if ($typeStr -match '^string(\((\d+)(,(fix|fixed))?\))?$') {
|
||||
$len = if ($Matches[2]) { $Matches[2] } else { "0" }
|
||||
$al = if ($Matches[4]) { "Fixed" } else { "Variable" }
|
||||
$lines += "$indent<v8:Type>xs:string</v8:Type>"
|
||||
$lines += "$indent<v8:StringQualifiers>"
|
||||
$lines += "$indent`t<v8:Length>$len</v8:Length>"
|
||||
$lines += "$indent`t<v8:AllowedLength>Variable</v8:AllowedLength>"
|
||||
$lines += "$indent`t<v8:AllowedLength>$al</v8:AllowedLength>"
|
||||
$lines += "$indent</v8:StringQualifiers>"
|
||||
return $lines -join "`n"
|
||||
}
|
||||
|
||||
if ($typeStr -match '^decimal\((\d+),(\d+)(,nonneg)?\)$') {
|
||||
$digits = $Matches[1]
|
||||
$fraction = $Matches[2]
|
||||
$sign = if ($Matches[3]) { "Nonnegative" } else { "Any" }
|
||||
# decimal forms — bare decimal = money 10,2; decimal(N) = integer N,0
|
||||
if ($typeStr -match '^decimal(\((\d+)(,(\d+))?(,nonneg)?\))?$') {
|
||||
if (-not $Matches[1]) {
|
||||
$digits = "10"; $fraction = "2"; $sign = "Any"
|
||||
} else {
|
||||
$digits = $Matches[2]
|
||||
$fraction = if ($Matches[4]) { $Matches[4] } else { "0" }
|
||||
$sign = if ($Matches[5]) { "Nonnegative" } else { "Any" }
|
||||
}
|
||||
$lines += "$indent<v8:Type>xs:decimal</v8:Type>"
|
||||
$lines += "$indent<v8:NumberQualifiers>"
|
||||
$lines += "$indent`t<v8:Digits>$digits</v8:Digits>"
|
||||
@@ -778,10 +803,12 @@ function Build-ValueTypeXml {
|
||||
return $lines -join "`n"
|
||||
}
|
||||
|
||||
if ($typeStr -match '^(date|dateTime)$') {
|
||||
# date / dateTime / time — all xs:dateTime, differ only in DateFractions
|
||||
if ($typeStr -match '^(date|dateTime|time)$') {
|
||||
$fractions = switch ($typeStr) {
|
||||
"date" { "Date" }
|
||||
"dateTime" { "DateTime" }
|
||||
"time" { "Time" }
|
||||
}
|
||||
$lines += "$indent<v8:Type>xs:dateTime</v8:Type>"
|
||||
$lines += "$indent<v8:DateQualifiers>"
|
||||
@@ -809,6 +836,52 @@ function Build-ValueTypeXml {
|
||||
return $lines -join "`n"
|
||||
}
|
||||
|
||||
# Sentinel-normalized empty check — null / "" / "_" / "null" (case-insensitive).
|
||||
function Test-EmptyValue {
|
||||
param($v)
|
||||
if ($null -eq $v) { return $true }
|
||||
$s = "$v".Trim()
|
||||
if ($s -eq "") { return $true }
|
||||
if ($s -eq "_") { return $true }
|
||||
if ($s.ToLowerInvariant() -eq "null") { return $true }
|
||||
return $false
|
||||
}
|
||||
|
||||
# Returns XML fragment string for a type-aware empty <value>.
|
||||
# Empty + valueListAllowed → omit entirely (returns $null).
|
||||
# tagPrefix used for dcscor: in data parameters.
|
||||
function Build-EmptyValueXml {
|
||||
param([string]$type, [string]$indent, [string]$tagPrefix = "", [string]$tagName = "value", [bool]$valueListAllowed = $false)
|
||||
if ($valueListAllowed) { return $null }
|
||||
$t = if ($null -eq $type) { "" } else { "$type" }
|
||||
# Strip well-known XML schema prefixes so callers can pass raw <v8:Type> text
|
||||
$t = $t -replace '^xs:', '' -replace '^v8:', '' -replace '^d\d+p\d+:', ''
|
||||
$pf = $tagPrefix
|
||||
$tn = $tagName
|
||||
$lines = @()
|
||||
if ($t -eq "") {
|
||||
$lines += "$indent<${pf}${tn} xsi:nil=`"true`"/>"
|
||||
} elseif ($t -eq "StandardPeriod") {
|
||||
$lines += "$indent<${pf}${tn} xsi:type=`"v8:StandardPeriod`">"
|
||||
$lines += "$indent`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">Custom</v8:variant>"
|
||||
$lines += "$indent`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||
$lines += "$indent`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||
$lines += "$indent</${pf}${tn}>"
|
||||
} elseif ($t -match '^string') {
|
||||
$lines += "$indent<${pf}${tn} xsi:type=`"xs:string`"/>"
|
||||
} elseif ($t -match '^(date|time)') {
|
||||
$lines += "$indent<${pf}${tn} xsi:type=`"xs:dateTime`">0001-01-01T00:00:00</${pf}${tn}>"
|
||||
} elseif ($t -match '^decimal') {
|
||||
$lines += "$indent<${pf}${tn} xsi:type=`"xs:decimal`">0</${pf}${tn}>"
|
||||
} elseif ($t -eq "boolean") {
|
||||
$lines += "$indent<${pf}${tn} xsi:type=`"xs:boolean`">false</${pf}${tn}>"
|
||||
} else {
|
||||
# Ref types or unknown — safe nil
|
||||
$lines += "$indent<${pf}${tn} xsi:nil=`"true`"/>"
|
||||
}
|
||||
return $lines -join "`n"
|
||||
}
|
||||
|
||||
function Build-MLTextXml {
|
||||
param([string]$tag, [string]$text, [string]$indent)
|
||||
$lines = @()
|
||||
@@ -1022,8 +1095,13 @@ function Build-AvailableValueFragment {
|
||||
|
||||
$lines = @()
|
||||
$lines += "$indent<availableValue>"
|
||||
$valueLines = Build-ParamValueXml -type $declaredType -value $item.value -indent "$indent`t"
|
||||
foreach ($vl in $valueLines) { $lines += $vl }
|
||||
if (Test-EmptyValue $item.value) {
|
||||
$emptyXml = Build-EmptyValueXml -type $declaredType -indent "$indent`t" -tagPrefix "" -tagName "value" -valueListAllowed $false
|
||||
if ($emptyXml) { $lines += $emptyXml }
|
||||
} else {
|
||||
$valueLines = Build-ParamValueXml -type $declaredType -value $item.value -indent "$indent`t"
|
||||
foreach ($vl in $valueLines) { $lines += $vl }
|
||||
}
|
||||
if ($item.presentation) {
|
||||
$lines += "$indent`t<presentation xsi:type=`"v8:LocalStringType`">"
|
||||
$lines += "$indent`t`t<v8:item>"
|
||||
@@ -1056,9 +1134,15 @@ function Build-ParamFragment {
|
||||
$lines += "$i`t</valueType>"
|
||||
}
|
||||
|
||||
$vla = [bool]$parsed.valueListAllowed
|
||||
if ($null -ne $parsed.value) {
|
||||
$valueLines = Build-ParamValueXml -type $parsed.type -value $parsed.value -indent "$i`t"
|
||||
foreach ($vl in $valueLines) { $lines += $vl }
|
||||
if (Test-EmptyValue $parsed.value) {
|
||||
$emptyXml = Build-EmptyValueXml -type $parsed.type -indent "$i`t" -tagPrefix "" -tagName "value" -valueListAllowed $vla
|
||||
if ($emptyXml) { $lines += $emptyXml }
|
||||
} else {
|
||||
$valueLines = Build-ParamValueXml -type $parsed.type -value $parsed.value -indent "$i`t"
|
||||
foreach ($vl in $valueLines) { $lines += $vl }
|
||||
}
|
||||
}
|
||||
|
||||
if ($parsed.hidden) {
|
||||
@@ -1066,6 +1150,10 @@ function Build-ParamFragment {
|
||||
$lines += "$i`t<availableAsField>false</availableAsField>"
|
||||
}
|
||||
|
||||
if ($vla) {
|
||||
$lines += "$i`t<valueListAllowed>true</valueListAllowed>"
|
||||
}
|
||||
|
||||
if ($parsed.availableValues -and $parsed.availableValues.Count -gt 0) {
|
||||
foreach ($av in $parsed.availableValues) {
|
||||
$avLines = Build-AvailableValueFragment -item $av -declaredType $parsed.type -indent "$i`t"
|
||||
@@ -1207,6 +1295,8 @@ function Build-DataParamFragment {
|
||||
$lines += "$i`t`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||
$lines += "$i`t`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||
$lines += "$i`t</dcscor:value>"
|
||||
} elseif (Test-EmptyValue $parsed.value) {
|
||||
$lines += "$i`t<dcscor:value xsi:nil=`"true`"/>"
|
||||
} elseif ("$($parsed.value)" -match '^\d{4}-\d{2}-\d{2}T') {
|
||||
$lines += "$i`t<dcscor:value xsi:type=`"xs:dateTime`">$(Esc-Xml "$($parsed.value)")</dcscor:value>"
|
||||
} elseif ("$($parsed.value)" -eq "true" -or "$($parsed.value)" -eq "false") {
|
||||
@@ -2107,8 +2197,20 @@ switch ($Operation) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$valueLines = Build-ParamValueXml -type $declaredType -value $value -indent $childIndent
|
||||
$fragXml = $valueLines -join "`n"
|
||||
# Detect valueListAllowed flag on the parameter — empty value should be omitted
|
||||
$vlaSet = $false
|
||||
foreach ($ch in $paramEl.ChildNodes) {
|
||||
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'valueListAllowed' -and $ch.NamespaceURI -eq $schNs) {
|
||||
if ($ch.InnerText.Trim() -eq 'true') { $vlaSet = $true }
|
||||
break
|
||||
}
|
||||
}
|
||||
if (Test-EmptyValue $value) {
|
||||
$fragXml = Build-EmptyValueXml -type $declaredType -indent $childIndent -tagPrefix "" -tagName "value" -valueListAllowed $vlaSet
|
||||
} else {
|
||||
$valueLines = Build-ParamValueXml -type $declaredType -value $value -indent $childIndent
|
||||
$fragXml = $valueLines -join "`n"
|
||||
}
|
||||
|
||||
$wasExisting = ($null -ne $existing)
|
||||
if ($existing) {
|
||||
@@ -2127,9 +2229,11 @@ switch ($Operation) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$nodes = Import-Fragment $xmlDoc $fragXml
|
||||
foreach ($node in $nodes) {
|
||||
Insert-BeforeElement $paramEl $node $refNode $childIndent
|
||||
if ($fragXml) {
|
||||
$nodes = Import-Fragment $xmlDoc $fragXml
|
||||
foreach ($node in $nodes) {
|
||||
Insert-BeforeElement $paramEl $node $refNode $childIndent
|
||||
}
|
||||
}
|
||||
$verb = if ($wasExisting) { "updated" } else { "added" }
|
||||
$script:Dirty = $true; Write-Host "[OK] Parameter `"$paramName`": value $verb to $value"
|
||||
@@ -3072,6 +3176,8 @@ switch ($Operation) {
|
||||
$valLines += "$itemIndent`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||
$valLines += "$itemIndent`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||
$valLines += "$itemIndent</dcscor:value>"
|
||||
} elseif (Test-EmptyValue $parsed.value) {
|
||||
$valLines += "$itemIndent<dcscor:value xsi:nil=`"true`"/>"
|
||||
} elseif ("$($parsed.value)" -match '^\d{4}-\d{2}-\d{2}T') {
|
||||
$valLines += "$itemIndent<dcscor:value xsi:type=`"xs:dateTime`">$(Esc-Xml "$($parsed.value)")</dcscor:value>"
|
||||
} elseif ("$($parsed.value)" -eq "true" -or "$($parsed.value)" -eq "false") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-edit v1.22 — Atomic 1C DCS editor (Python port)
|
||||
# skd-edit v1.23 — Atomic 1C DCS editor (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import os
|
||||
@@ -335,7 +335,7 @@ def parse_calc_shorthand(s):
|
||||
|
||||
|
||||
def parse_param_shorthand(s):
|
||||
result = {"name": "", "type": "", "value": None, "autoDates": False, "title": None, "hidden": False, "always": False, "availableValues": []}
|
||||
result = {"name": "", "type": "", "value": None, "autoDates": False, "title": None, "hidden": False, "always": False, "availableValues": [], "valueListAllowed": False}
|
||||
|
||||
# Extract availableValue=... (must be before main parse — captures to end of string)
|
||||
m_av = re.search(r'\s*availableValue=(.+)$', s)
|
||||
@@ -347,6 +347,10 @@ def parse_param_shorthand(s):
|
||||
result["autoDates"] = True
|
||||
s = re.sub(r'\s*@autoDates', '', s)
|
||||
|
||||
if re.search(r'@valueList\b', s):
|
||||
result["valueListAllowed"] = True
|
||||
s = re.sub(r'\s*@valueList\b', '', s)
|
||||
|
||||
if re.search(r'@hidden\b', s):
|
||||
result["hidden"] = True
|
||||
s = re.sub(r'\s*@hidden\b', '', s)
|
||||
@@ -361,12 +365,13 @@ def parse_param_shorthand(s):
|
||||
result["title"] = m.group(1).strip()
|
||||
s = re.sub(r'\s*\[[^\]]*\]\s*', ' ', s).strip()
|
||||
|
||||
m = re.match(r'^([^:]+):\s*(\S+)(\s*=\s*(.+))?$', s)
|
||||
# Allow empty RHS (`= ` / `=`) as empty-value sentinel
|
||||
m = re.match(r'^([^:]+):\s*(\S+)(\s*=\s*(.*))?$', s)
|
||||
if m:
|
||||
result["name"] = m.group(1).strip()
|
||||
result["type"] = resolve_type_str(m.group(2).strip())
|
||||
if m.group(4):
|
||||
result["value"] = m.group(4).strip()
|
||||
if m.group(3) is not None:
|
||||
result["value"] = m.group(4).strip() if m.group(4) else ""
|
||||
else:
|
||||
result["name"] = s.strip()
|
||||
|
||||
@@ -466,7 +471,7 @@ def parse_data_param_shorthand(s):
|
||||
|
||||
s = s.strip()
|
||||
|
||||
m = re.match(r'^([^=]+)=\s*(.+)$', s)
|
||||
m = re.match(r'^([^=]+)=\s*(.*)$', s)
|
||||
if m:
|
||||
result["parameter"] = m.group(1).strip()
|
||||
val_str = m.group(2).strip()
|
||||
@@ -480,7 +485,10 @@ def parse_data_param_shorthand(s):
|
||||
"TillEndOfThisWeek", "TillEndOfThisTenDays", "TillEndOfThisMonth",
|
||||
"TillEndOfThisQuarter", "TillEndOfThisHalfYear", "TillEndOfThisYear",
|
||||
]
|
||||
if val_str in period_variants:
|
||||
# Empty / sentinel — record as "" so caller emits xsi:nil
|
||||
if val_str == "" or val_str == "_" or val_str.lower() == "null":
|
||||
result["value"] = ""
|
||||
elif val_str in period_variants:
|
||||
result["value"] = {"variant": val_str}
|
||||
else:
|
||||
result["value"] = val_str
|
||||
@@ -684,8 +692,13 @@ def parse_available_value_list(s):
|
||||
def build_available_value_fragment(item, declared_type, indent):
|
||||
"""Return XML lines for a single <availableValue> block."""
|
||||
lines = [f"{indent}<availableValue>"]
|
||||
for vl in build_param_value_xml(declared_type, item["value"], f"{indent}\t"):
|
||||
lines.append(vl)
|
||||
if is_empty_value(item.get("value")):
|
||||
empty_xml = build_empty_value_xml(declared_type, f"{indent}\t", "", "value", False)
|
||||
if empty_xml:
|
||||
lines.append(empty_xml)
|
||||
else:
|
||||
for vl in build_param_value_xml(declared_type, item["value"], f"{indent}\t"):
|
||||
lines.append(vl)
|
||||
if item.get("presentation"):
|
||||
lines.append(f'{indent}\t<presentation xsi:type="v8:LocalStringType">')
|
||||
lines.append(f"{indent}\t\t<v8:item>")
|
||||
@@ -702,27 +715,44 @@ def build_available_value_fragment(item, declared_type, indent):
|
||||
def build_value_type_xml(type_str, indent):
|
||||
if not type_str:
|
||||
return ""
|
||||
type_str = resolve_type_str(type_str)
|
||||
|
||||
# Composite: list/tuple → concatenate per-type fragments
|
||||
if isinstance(type_str, (list, tuple)):
|
||||
parts = []
|
||||
for t in type_str:
|
||||
p = build_value_type_xml(str(t), indent)
|
||||
if p:
|
||||
parts.append(p)
|
||||
return "\n".join(parts)
|
||||
|
||||
type_str = resolve_type_str(str(type_str))
|
||||
lines = []
|
||||
|
||||
if type_str == "boolean":
|
||||
lines.append(f"{indent}<v8:Type>xs:boolean</v8:Type>")
|
||||
return "\n".join(lines)
|
||||
|
||||
m = re.match(r'^string(\((\d+)\))?$', type_str)
|
||||
# string, string(N), string(N,fix) — fix → AllowedLength=Fixed
|
||||
m = re.match(r'^string(\((\d+)(,(fix|fixed))?\))?$', type_str)
|
||||
if m:
|
||||
length = m.group(2) if m.group(2) else "0"
|
||||
al = "Fixed" if m.group(4) else "Variable"
|
||||
lines.append(f"{indent}<v8:Type>xs:string</v8:Type>")
|
||||
lines.append(f"{indent}<v8:StringQualifiers>")
|
||||
lines.append(f"{indent}\t<v8:Length>{length}</v8:Length>")
|
||||
lines.append(f"{indent}\t<v8:AllowedLength>Variable</v8:AllowedLength>")
|
||||
lines.append(f"{indent}\t<v8:AllowedLength>{al}</v8:AllowedLength>")
|
||||
lines.append(f"{indent}</v8:StringQualifiers>")
|
||||
return "\n".join(lines)
|
||||
|
||||
m = re.match(r'^decimal\((\d+),(\d+)(,nonneg)?\)$', type_str)
|
||||
# decimal — bare = 10,2; decimal(N) = N,0
|
||||
m = re.match(r'^decimal(\((\d+)(,(\d+))?(,nonneg)?\))?$', type_str)
|
||||
if m:
|
||||
digits, fraction = m.group(1), m.group(2)
|
||||
sign = "Nonnegative" if m.group(3) else "Any"
|
||||
if not m.group(1):
|
||||
digits, fraction, sign = "10", "2", "Any"
|
||||
else:
|
||||
digits = m.group(2)
|
||||
fraction = m.group(4) if m.group(4) else "0"
|
||||
sign = "Nonnegative" if m.group(5) else "Any"
|
||||
lines.append(f"{indent}<v8:Type>xs:decimal</v8:Type>")
|
||||
lines.append(f"{indent}<v8:NumberQualifiers>")
|
||||
lines.append(f"{indent}\t<v8:Digits>{digits}</v8:Digits>")
|
||||
@@ -731,9 +761,10 @@ def build_value_type_xml(type_str, indent):
|
||||
lines.append(f"{indent}</v8:NumberQualifiers>")
|
||||
return "\n".join(lines)
|
||||
|
||||
m = re.match(r'^(date|dateTime)$', type_str)
|
||||
# date / dateTime / time — all xs:dateTime
|
||||
m = re.match(r'^(date|dateTime|time)$', type_str)
|
||||
if m:
|
||||
fractions = "Date" if type_str == "date" else "DateTime"
|
||||
fractions = {"date": "Date", "dateTime": "DateTime", "time": "Time"}[type_str]
|
||||
lines.append(f"{indent}<v8:Type>xs:dateTime</v8:Type>")
|
||||
lines.append(f"{indent}<v8:DateQualifiers>")
|
||||
lines.append(f"{indent}\t<v8:DateFractions>{fractions}</v8:DateFractions>")
|
||||
@@ -756,6 +787,52 @@ def build_value_type_xml(type_str, indent):
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def is_empty_value(v):
|
||||
"""Empty sentinel — None / '' / '_' / 'null' (case-insensitive)."""
|
||||
if v is None:
|
||||
return True
|
||||
s = str(v).strip()
|
||||
if s == "":
|
||||
return True
|
||||
if s == "_":
|
||||
return True
|
||||
if s.lower() == "null":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def build_empty_value_xml(type_str, indent, tag_prefix="", tag_name="value", value_list_allowed=False):
|
||||
"""Type-aware empty <value> fragment. Returns None when valueListAllowed (omit)."""
|
||||
if value_list_allowed:
|
||||
return None
|
||||
t = "" if type_str is None else str(type_str)
|
||||
# Strip well-known XML schema prefixes so callers can pass raw <v8:Type> text
|
||||
t = re.sub(r'^xs:', '', t)
|
||||
t = re.sub(r'^v8:', '', t)
|
||||
t = re.sub(r'^d\d+p\d+:', '', t)
|
||||
pf, tn = tag_prefix, tag_name
|
||||
lines = []
|
||||
if t == "":
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:nil="true"/>')
|
||||
elif t == "StandardPeriod":
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:type="v8:StandardPeriod">')
|
||||
lines.append(f'{indent}\t<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>')
|
||||
lines.append(f'{indent}\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>')
|
||||
lines.append(f'{indent}\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>')
|
||||
lines.append(f'{indent}</{pf}{tn}>')
|
||||
elif re.match(r'^string', t):
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:type="xs:string"/>')
|
||||
elif re.match(r'^(date|time)', t):
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:type="xs:dateTime">0001-01-01T00:00:00</{pf}{tn}>')
|
||||
elif re.match(r'^decimal', t):
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:type="xs:decimal">0</{pf}{tn}>')
|
||||
elif t == "boolean":
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:type="xs:boolean">false</{pf}{tn}>')
|
||||
else:
|
||||
lines.append(f'{indent}<{pf}{tn} xsi:nil="true"/>')
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def build_mltext_xml(tag, text, indent):
|
||||
lines = [
|
||||
f'{indent}<{tag} xsi:type="v8:LocalStringType">',
|
||||
@@ -934,14 +1011,23 @@ def build_param_fragment(parsed, indent):
|
||||
lines.append(build_value_type_xml(parsed["type"], f"{i}\t\t"))
|
||||
lines.append(f"{i}\t</valueType>")
|
||||
|
||||
vla = bool(parsed.get("valueListAllowed"))
|
||||
if parsed["value"] is not None:
|
||||
for vl in build_param_value_xml(parsed.get("type", ""), parsed["value"], f"{i}\t"):
|
||||
lines.append(vl)
|
||||
if is_empty_value(parsed["value"]):
|
||||
empty_xml = build_empty_value_xml(parsed.get("type", ""), f"{i}\t", "", "value", vla)
|
||||
if empty_xml:
|
||||
lines.append(empty_xml)
|
||||
else:
|
||||
for vl in build_param_value_xml(parsed.get("type", ""), parsed["value"], f"{i}\t"):
|
||||
lines.append(vl)
|
||||
|
||||
if parsed.get("hidden"):
|
||||
lines.append(f"{i}\t<useRestriction>true</useRestriction>")
|
||||
lines.append(f"{i}\t<availableAsField>false</availableAsField>")
|
||||
|
||||
if vla:
|
||||
lines.append(f"{i}\t<valueListAllowed>true</valueListAllowed>")
|
||||
|
||||
for av in parsed.get("availableValues", []) or []:
|
||||
for l in build_available_value_fragment(av, parsed.get("type", ""), f"{i}\t"):
|
||||
lines.append(l)
|
||||
@@ -1065,6 +1151,8 @@ def build_data_param_fragment(parsed, indent):
|
||||
lines.append(f"{i}\t\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>")
|
||||
lines.append(f"{i}\t\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>")
|
||||
lines.append(f"{i}\t</dcscor:value>")
|
||||
elif is_empty_value(val):
|
||||
lines.append(f'{i}\t<dcscor:value xsi:nil="true"/>')
|
||||
elif re.match(r'^\d{4}-\d{2}-\d{2}T', str(val)):
|
||||
lines.append(f'{i}\t<dcscor:value xsi:type="xs:dateTime">{esc_xml(str(val))}</dcscor:value>')
|
||||
elif str(val) in ("true", "false"):
|
||||
@@ -1802,8 +1890,16 @@ elif operation == "modify-parameter":
|
||||
if isinstance(tnode.tag, str) and local_name(tnode) == "Type":
|
||||
declared_type = re.sub(r'^d\d+p\d+:', '', (tnode.text or "").strip())
|
||||
break
|
||||
value_lines = build_param_value_xml(declared_type, value, child_indent)
|
||||
frag_xml = "\n".join(value_lines)
|
||||
# Detect valueListAllowed — empty value should be omitted when set
|
||||
vla_set = False
|
||||
vla_el = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "valueListAllowed" and etree.QName(ch.tag).namespace == SCH_NS), None)
|
||||
if vla_el is not None and (vla_el.text or "").strip() == "true":
|
||||
vla_set = True
|
||||
if is_empty_value(value):
|
||||
frag_xml = build_empty_value_xml(declared_type, child_indent, "", "value", vla_set)
|
||||
else:
|
||||
value_lines = build_param_value_xml(declared_type, value, child_indent)
|
||||
frag_xml = "\n".join(value_lines)
|
||||
was_existing = existing is not None
|
||||
if existing is not None:
|
||||
# Find next-element sibling as ref before removing
|
||||
@@ -1812,9 +1908,10 @@ elif operation == "modify-parameter":
|
||||
remove_node_with_whitespace(existing)
|
||||
else:
|
||||
ref_node = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("useRestriction", "availableValue", "denyIncompleteValues", "use")), None)
|
||||
nodes = import_fragment(xml_doc, frag_xml)
|
||||
for node in nodes:
|
||||
insert_before_element(param_el, node, ref_node, child_indent)
|
||||
if frag_xml:
|
||||
nodes = import_fragment(xml_doc, frag_xml)
|
||||
for node in nodes:
|
||||
insert_before_element(param_el, node, ref_node, child_indent)
|
||||
verb = "updated" if was_existing else "added"
|
||||
dirty = True; print(f'[OK] Parameter "{param_name}": value {verb} to {value}')
|
||||
elif existing is not None:
|
||||
@@ -2543,6 +2640,8 @@ elif operation == "modify-dataParameter":
|
||||
val_lines.append(f"{item_indent}\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>")
|
||||
val_lines.append(f"{item_indent}\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>")
|
||||
val_lines.append(f"{item_indent}</dcscor:value>")
|
||||
elif is_empty_value(pv):
|
||||
val_lines.append(f'{item_indent}<dcscor:value xsi:nil="true"/>')
|
||||
elif re.match(r'^\d{4}-\d{2}-\d{2}T', str(pv)):
|
||||
val_lines.append(f'{item_indent}<dcscor:value xsi:type="xs:dateTime">{esc_xml(str(pv))}</dcscor:value>')
|
||||
elif str(pv) in ("true", "false"):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-validate v1.1 — Validate 1C DCS structure
|
||||
# skd-validate v1.2 — Validate 1C DCS structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -438,6 +438,17 @@ if ($script:stopped) { & $finalize; exit 1 }
|
||||
if ($calcFieldNodes.Count -gt 0) {
|
||||
$cfOk = $true
|
||||
$cfSeen = @{}
|
||||
# Collect totalField dataPaths — an empty calculatedField is legitimate if a
|
||||
# totalField with the same dataPath provides the expression (real-world
|
||||
# pattern in vendor ERP/БП reports for fields visible only in totals).
|
||||
$tfPaths = @{}
|
||||
foreach ($tf in $totalFieldNodes) {
|
||||
$tfDp = $tf.SelectSingleNode("s:dataPath", $ns)
|
||||
if ($tfDp -and $tfDp.InnerText) {
|
||||
$tfPaths[$tfDp.InnerText] = $true
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($cf in $calcFieldNodes) {
|
||||
$dp = $cf.SelectSingleNode("s:dataPath", $ns)
|
||||
$expr = $cf.SelectSingleNode("s:expression", $ns)
|
||||
@@ -457,8 +468,15 @@ if ($calcFieldNodes.Count -gt 0) {
|
||||
}
|
||||
|
||||
if (-not $expr -or -not $expr.InnerText.Trim()) {
|
||||
Report-Error "CalculatedField '$path' has empty expression"
|
||||
$cfOk = $false
|
||||
# Empty expression is legitimate in several vendor patterns:
|
||||
# - totalField with same dataPath provides the calculation
|
||||
# - groupTemplate uses the field as group name (declarative only)
|
||||
# - field is referenced only by settingsVariants for grouping
|
||||
# Surface as warning, not error, to avoid false positives on real
|
||||
# ERP/БП reports while still flagging the unusual shape.
|
||||
if (-not $tfPaths.ContainsKey($path)) {
|
||||
Report-Warn "CalculatedField '$path' has empty expression (declarative-only?)"
|
||||
}
|
||||
}
|
||||
|
||||
# Warn if collides with a dataset field
|
||||
@@ -542,14 +560,16 @@ if ($templateNodes.Count -gt 0) {
|
||||
}
|
||||
$tName = $nameNode.InnerText
|
||||
if ($tplSeen.ContainsKey($tName)) {
|
||||
Report-Error "Duplicate template name: $tName"
|
||||
$tplOk = $false
|
||||
# Vendor configs (ERP/БП) ship templates with repeating names — the
|
||||
# platform identifies them by position/context, not by <name>. Demote
|
||||
# to warning so the check still surfaces the collision without failing.
|
||||
Report-Warn "Duplicate template name: $tName (allowed by platform but ambiguous)"
|
||||
} else {
|
||||
$tplSeen[$tName] = $true
|
||||
}
|
||||
}
|
||||
if ($tplOk) {
|
||||
Report-OK "$($templateNodes.Count) template(s): names unique"
|
||||
Report-OK "$($templateNodes.Count) template(s) found"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +601,8 @@ if ($script:stopped) { & $finalize; exit 1 }
|
||||
|
||||
$validComparisonTypes = @(
|
||||
"Equal","NotEqual","Greater","GreaterOrEqual","Less","LessOrEqual",
|
||||
"InList","NotInList","InHierarchy","InListByHierarchy",
|
||||
"InList","NotInList","InHierarchy","NotInHierarchy",
|
||||
"InListByHierarchy","NotInListByHierarchy",
|
||||
"Contains","NotContains","BeginsWith","NotBeginsWith",
|
||||
"Filled","NotFilled"
|
||||
)
|
||||
@@ -734,6 +755,176 @@ if ($variantNodes.Count -eq 0) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- 16. valueType structural checks ---
|
||||
# Catches broken XDTO that XML/structural checks miss (decimal without xs:,
|
||||
# missing qualifiers, mismatched qualifier blocks, unknown sign/length tokens).
|
||||
|
||||
$validTypeQualifier = @{
|
||||
'xs:decimal' = 'v8:NumberQualifiers'
|
||||
'xs:string' = 'v8:StringQualifiers'
|
||||
'xs:dateTime' = 'v8:DateQualifiers'
|
||||
'xs:boolean' = ''
|
||||
'v8:StandardPeriod' = ''
|
||||
'v8:UUID' = ''
|
||||
'v8:Null' = ''
|
||||
'v8:Type' = ''
|
||||
'v8:ValueStorage' = ''
|
||||
}
|
||||
$validSign = @('Any', 'Nonnegative', 'Negative')
|
||||
$validLength = @('Variable', 'Fixed')
|
||||
$validFractions = @('Date', 'DateTime', 'Time')
|
||||
|
||||
# DCS supports composite types: multiple <v8:Type> blocks may share a single
|
||||
# trailing qualifier block (e.g. xs:string + CatalogRef.X + StringQualifiers).
|
||||
# So we collect all types and qualifiers per valueType, then check consistency.
|
||||
$qualifierProducers = @{
|
||||
'v8:NumberQualifiers' = 'xs:decimal'
|
||||
'v8:StringQualifiers' = 'xs:string'
|
||||
'v8:DateQualifiers' = 'xs:dateTime'
|
||||
}
|
||||
|
||||
$valueTypeNodes = $root.SelectNodes("//s:valueType", $ns)
|
||||
$vtChecked = 0
|
||||
$vtOk = $true
|
||||
foreach ($vt in $valueTypeNodes) {
|
||||
$vtChecked++
|
||||
$types = @() # list of short type strings; '' marks a ref type
|
||||
$qualifiers = @() # list of @{ name = 'v8:XQualifiers'; node = $child }
|
||||
|
||||
foreach ($child in $vt.ChildNodes) {
|
||||
if ($child.NodeType -ne 'Element') { continue }
|
||||
if ($child.NamespaceURI -ne 'http://v8.1c.ru/8.1/data/core') { continue }
|
||||
$localName = $child.LocalName
|
||||
|
||||
if ($localName -eq 'Type') {
|
||||
$t = "$($child.InnerText)".Trim()
|
||||
if (-not $t) {
|
||||
Report-Error "valueType: <v8:Type> is empty"
|
||||
$vtOk = $false
|
||||
continue
|
||||
}
|
||||
if ($t -match '^([A-Za-z][A-Za-z0-9]*):(.+)$') {
|
||||
$prefix = $Matches[1]
|
||||
$localT = $Matches[2]
|
||||
if ($prefix -eq 'xs' -or $prefix -eq 'v8') {
|
||||
if (-not $validTypeQualifier.ContainsKey($t)) {
|
||||
Report-Error "valueType: unknown type '$t' (allowed: xs:decimal/xs:string/xs:dateTime/xs:boolean/v8:StandardPeriod or <prefix>:*Ref.X)"
|
||||
$vtOk = $false
|
||||
} else {
|
||||
$types += $t
|
||||
}
|
||||
} else {
|
||||
$prefixNs = $child.GetNamespaceOfPrefix($prefix)
|
||||
if ($prefixNs -eq 'http://v8.1c.ru/8.1/data/enterprise/current-config') {
|
||||
if (-not ($localT -match '^[A-Za-z]+(Ref)?\.')) {
|
||||
Report-Error "valueType: ref type '$t' must look like '<prefix>:<Kind>.<Name>' (e.g. d5p1:CatalogRef.X)"
|
||||
$vtOk = $false
|
||||
} else {
|
||||
$types += '' # ref — no qualifier needed
|
||||
}
|
||||
} elseif ($prefixNs -eq 'http://v8.1c.ru/8.1/data/enterprise') {
|
||||
# System types: AccumulationRecordType etc. — no qualifiers
|
||||
if (-not ($localT -match '^[A-Za-z][A-Za-z0-9]*$')) {
|
||||
Report-Error "valueType: system type '$t' has unexpected local-name shape"
|
||||
$vtOk = $false
|
||||
} else {
|
||||
$types += ''
|
||||
}
|
||||
} else {
|
||||
Report-Error "valueType: type '$t' uses prefix '$prefix' bound to unexpected namespace '$prefixNs'"
|
||||
$vtOk = $false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Report-Error "valueType: type '$t' has no namespace prefix (expected xs:/v8:/d5p1: — e.g. xs:decimal not decimal)"
|
||||
$vtOk = $false
|
||||
}
|
||||
} elseif ($localName -match 'Qualifiers$') {
|
||||
$qName = "v8:$localName"
|
||||
$qualifiers += @{ name = $qName; node = $child }
|
||||
# Validate qualifier internals
|
||||
if ($qName -eq 'v8:NumberQualifiers') {
|
||||
$digits = $child.SelectSingleNode("v8:Digits", $ns)
|
||||
$frac = $child.SelectSingleNode("v8:FractionDigits", $ns)
|
||||
$sign = $child.SelectSingleNode("v8:AllowedSign", $ns)
|
||||
if (-not $digits -or -not ($digits.InnerText -match '^\d+$')) {
|
||||
Report-Error "v8:NumberQualifiers: <v8:Digits> missing or not a non-negative integer"
|
||||
$vtOk = $false
|
||||
}
|
||||
if (-not $frac -or -not ($frac.InnerText -match '^\d+$')) {
|
||||
Report-Error "v8:NumberQualifiers: <v8:FractionDigits> missing or not a non-negative integer"
|
||||
$vtOk = $false
|
||||
}
|
||||
if ($sign -and $sign.InnerText -and $sign.InnerText -notin $validSign) {
|
||||
Report-Error "v8:NumberQualifiers: <v8:AllowedSign>$($sign.InnerText)</v8:AllowedSign> — must be one of: $($validSign -join ', ')"
|
||||
$vtOk = $false
|
||||
}
|
||||
} elseif ($qName -eq 'v8:StringQualifiers') {
|
||||
$len = $child.SelectSingleNode("v8:Length", $ns)
|
||||
$al = $child.SelectSingleNode("v8:AllowedLength", $ns)
|
||||
if (-not $len -or -not ($len.InnerText -match '^\d+$')) {
|
||||
Report-Error "v8:StringQualifiers: <v8:Length> missing or not a non-negative integer"
|
||||
$vtOk = $false
|
||||
}
|
||||
if ($al -and $al.InnerText -and $al.InnerText -notin $validLength) {
|
||||
Report-Error "v8:StringQualifiers: <v8:AllowedLength>$($al.InnerText)</v8:AllowedLength> — must be one of: $($validLength -join ', ')"
|
||||
$vtOk = $false
|
||||
}
|
||||
} elseif ($qName -eq 'v8:DateQualifiers') {
|
||||
$df = $child.SelectSingleNode("v8:DateFractions", $ns)
|
||||
if ($df -and $df.InnerText -and $df.InnerText -notin $validFractions) {
|
||||
Report-Error "v8:DateQualifiers: <v8:DateFractions>$($df.InnerText)</v8:DateFractions> — must be one of: $($validFractions -join ', ')"
|
||||
$vtOk = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Cross-check: every qualifier must have a matching scalar type in this valueType
|
||||
foreach ($q in $qualifiers) {
|
||||
$producer = $qualifierProducers[$q.name]
|
||||
if (-not $producer) { continue }
|
||||
if ($types -notcontains $producer) {
|
||||
Report-Error "valueType: <$($q.name)> has no matching <v8:Type>$producer</v8:Type> in this valueType"
|
||||
$vtOk = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($vtChecked -gt 0 -and $vtOk) {
|
||||
Report-OK "$vtChecked valueType block(s): structure and qualifiers OK"
|
||||
}
|
||||
|
||||
if ($script:stopped) { & $finalize; exit 1 }
|
||||
|
||||
# --- 17. value content checks ---
|
||||
# Catches literal placeholders ("_") and empty strings in DesignTimeValue refs
|
||||
# that XDTO would reject at db-load-xml.
|
||||
|
||||
$valueNodes = @()
|
||||
$valueNodes += @($root.SelectNodes("//s:value[@xsi:type]", $ns))
|
||||
$valueNodes += @($root.SelectNodes("//dcscor:value[@xsi:type]", $ns))
|
||||
$vChecked = 0
|
||||
$vOk = $true
|
||||
foreach ($vn in $valueNodes) {
|
||||
if (-not $vn) { continue }
|
||||
$vChecked++
|
||||
$xsiType = $vn.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance")
|
||||
$text = $vn.InnerText
|
||||
if ($xsiType -eq 'dcscor:DesignTimeValue') {
|
||||
if (-not $text -or $text.Trim() -eq '' -or $text.Trim() -eq '_') {
|
||||
Report-Error "<value xsi:type=`"dcscor:DesignTimeValue`">$text</value> — DesignTimeValue must be a reference path (e.g. Перечисление.X.Y), not '$text'"
|
||||
$vOk = $false
|
||||
} elseif (-not ($text -match '^[A-Za-zА-Яа-яЁё]+\.[A-Za-zА-Яа-яЁё0-9_]+')) {
|
||||
Report-Warn "<value xsi:type=`"dcscor:DesignTimeValue`">$text</value> — doesn't look like a typical ref path"
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($vChecked -gt 0 -and $vOk) {
|
||||
Report-OK "$vChecked <value> element(s) with xsi:type: content OK"
|
||||
}
|
||||
|
||||
if ($script:stopped) { & $finalize; exit 1 }
|
||||
|
||||
# --- Final output ---
|
||||
|
||||
& $finalize
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-validate v1.1 — Validate 1C DCS structure (Python port)
|
||||
# skd-validate v1.2 — Validate 1C DCS structure (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import os
|
||||
@@ -434,6 +434,15 @@ if stopped:
|
||||
if len(calc_field_nodes) > 0:
|
||||
cf_ok = True
|
||||
cf_seen = {}
|
||||
# Collect totalField dataPaths — an empty calculatedField is legitimate if a
|
||||
# totalField with the same dataPath provides the expression (real-world
|
||||
# pattern in vendor ERP/БП reports for fields visible only in totals).
|
||||
tf_paths = set()
|
||||
for tf in total_field_nodes:
|
||||
tf_dp = find(tf, "s:dataPath")
|
||||
if tf_dp is not None and inner_text(tf_dp):
|
||||
tf_paths.add(inner_text(tf_dp))
|
||||
|
||||
for cf in calc_field_nodes:
|
||||
dp = find(cf, "s:dataPath")
|
||||
expr = find(cf, "s:expression")
|
||||
@@ -451,8 +460,14 @@ if len(calc_field_nodes) > 0:
|
||||
cf_seen[path] = True
|
||||
|
||||
if expr is None or not text_of(expr):
|
||||
report_error(f"CalculatedField '{path}' has empty expression")
|
||||
cf_ok = False
|
||||
# Empty expression is legitimate in several vendor patterns:
|
||||
# - totalField with same dataPath provides the calculation
|
||||
# - groupTemplate uses the field as group name (declarative only)
|
||||
# - field is referenced only by settingsVariants for grouping
|
||||
# Surface as warning, not error, to avoid false positives on real
|
||||
# ERP/БП reports while still flagging the unusual shape.
|
||||
if path not in tf_paths:
|
||||
report_warn(f"CalculatedField '{path}' has empty expression (declarative-only?)")
|
||||
|
||||
# Warn if collides with a dataset field
|
||||
if path in all_field_paths:
|
||||
@@ -526,12 +541,14 @@ if len(template_nodes) > 0:
|
||||
continue
|
||||
t_name = inner_text(name_node)
|
||||
if t_name in tpl_seen:
|
||||
report_error(f"Duplicate template name: {t_name}")
|
||||
tpl_ok = False
|
||||
# Vendor configs (ERP/БП) ship templates with repeating names — the
|
||||
# platform identifies them by position/context, not by <name>. Demote
|
||||
# to warning so the check still surfaces the collision without failing.
|
||||
report_warn(f"Duplicate template name: {t_name} (allowed by platform but ambiguous)")
|
||||
else:
|
||||
tpl_seen[t_name] = True
|
||||
if tpl_ok:
|
||||
report_ok(f"{len(template_nodes)} template(s): names unique")
|
||||
report_ok(f"{len(template_nodes)} template(s) found")
|
||||
|
||||
# ── 13. GroupTemplate checks ─────────────────────────────────
|
||||
|
||||
@@ -558,7 +575,8 @@ if stopped:
|
||||
|
||||
valid_comparison_types = (
|
||||
"Equal", "NotEqual", "Greater", "GreaterOrEqual", "Less", "LessOrEqual",
|
||||
"InList", "NotInList", "InHierarchy", "InListByHierarchy",
|
||||
"InList", "NotInList", "InHierarchy", "NotInHierarchy",
|
||||
"InListByHierarchy", "NotInListByHierarchy",
|
||||
"Contains", "NotContains", "BeginsWith", "NotBeginsWith",
|
||||
"Filled", "NotFilled",
|
||||
)
|
||||
@@ -685,6 +703,166 @@ else:
|
||||
if v_ok:
|
||||
report_ok(f"{len(variant_nodes)} settingsVariant(s) found")
|
||||
|
||||
# ── 16. valueType structural checks ───────────────────────────
|
||||
# Catches broken XDTO that XML/structural checks miss (decimal without xs:,
|
||||
# missing qualifiers, mismatched qualifier blocks, unknown sign/length tokens).
|
||||
|
||||
import re as _re_vt
|
||||
|
||||
_VALID_TYPE_QUALIFIER = {
|
||||
'xs:decimal': 'v8:NumberQualifiers',
|
||||
'xs:string': 'v8:StringQualifiers',
|
||||
'xs:dateTime': 'v8:DateQualifiers',
|
||||
'xs:boolean': '',
|
||||
'v8:StandardPeriod': '',
|
||||
'v8:UUID': '',
|
||||
'v8:Null': '',
|
||||
'v8:Type': '',
|
||||
'v8:ValueStorage': '',
|
||||
}
|
||||
_VALID_SIGN = ('Any', 'Nonnegative', 'Negative')
|
||||
_VALID_LENGTH = ('Variable', 'Fixed')
|
||||
_VALID_FRACTIONS = ('Date', 'DateTime', 'Time')
|
||||
_V8_NS_URI = 'http://v8.1c.ru/8.1/data/core'
|
||||
_CONFIG_NS_URI = 'http://v8.1c.ru/8.1/data/enterprise/current-config'
|
||||
|
||||
# DCS supports composite types: multiple <v8:Type> blocks may share a single
|
||||
# trailing qualifier block (e.g. xs:string + CatalogRef.X + StringQualifiers).
|
||||
# So we collect all types and qualifiers per valueType, then check consistency.
|
||||
_QUALIFIER_PRODUCERS = {
|
||||
'v8:NumberQualifiers': 'xs:decimal',
|
||||
'v8:StringQualifiers': 'xs:string',
|
||||
'v8:DateQualifiers': 'xs:dateTime',
|
||||
}
|
||||
|
||||
vt_nodes = find_all(root, "//s:valueType")
|
||||
vt_checked = 0
|
||||
vt_ok = True
|
||||
for vt in vt_nodes:
|
||||
vt_checked += 1
|
||||
types = [] # short type strings; '' marks a ref type
|
||||
qualifiers = [] # list of (qName, node)
|
||||
|
||||
for child in vt:
|
||||
if not isinstance(child.tag, str):
|
||||
continue
|
||||
qn = etree.QName(child.tag)
|
||||
if qn.namespace != _V8_NS_URI:
|
||||
continue
|
||||
local = qn.localname
|
||||
|
||||
if local == 'Type':
|
||||
t = (child.text or '').strip()
|
||||
if not t:
|
||||
report_error("valueType: <v8:Type> is empty")
|
||||
vt_ok = False
|
||||
continue
|
||||
m = _re_vt.match(r'^([A-Za-z][A-Za-z0-9]*):(.+)$', t)
|
||||
if not m:
|
||||
report_error(f"valueType: type '{t}' has no namespace prefix (expected xs:/v8:/d5p1: — e.g. xs:decimal not decimal)")
|
||||
vt_ok = False
|
||||
continue
|
||||
prefix, local_t = m.group(1), m.group(2)
|
||||
if prefix in ('xs', 'v8'):
|
||||
if t not in _VALID_TYPE_QUALIFIER:
|
||||
report_error(f"valueType: unknown type '{t}' (allowed: xs:decimal/xs:string/xs:dateTime/xs:boolean/v8:StandardPeriod or <prefix>:*Ref.X)")
|
||||
vt_ok = False
|
||||
else:
|
||||
types.append(t)
|
||||
else:
|
||||
prefix_ns = child.nsmap.get(prefix)
|
||||
if prefix_ns == _CONFIG_NS_URI:
|
||||
if not _re_vt.match(r'^[A-Za-z]+(Ref)?\.', local_t):
|
||||
report_error(f"valueType: ref type '{t}' must look like '<prefix>:<Kind>.<Name>' (e.g. d5p1:CatalogRef.X)")
|
||||
vt_ok = False
|
||||
else:
|
||||
types.append('') # ref — no qualifier needed
|
||||
elif prefix_ns == 'http://v8.1c.ru/8.1/data/enterprise':
|
||||
# System types: AccumulationRecordType etc. — no qualifiers
|
||||
if not _re_vt.match(r'^[A-Za-z][A-Za-z0-9]*$', local_t):
|
||||
report_error(f"valueType: system type '{t}' has unexpected local-name shape")
|
||||
vt_ok = False
|
||||
else:
|
||||
types.append('')
|
||||
else:
|
||||
report_error(f"valueType: type '{t}' uses prefix '{prefix}' bound to unexpected namespace '{prefix_ns}'")
|
||||
vt_ok = False
|
||||
|
||||
elif local.endswith('Qualifiers'):
|
||||
q_name = f"v8:{local}"
|
||||
qualifiers.append((q_name, child))
|
||||
if q_name == 'v8:NumberQualifiers':
|
||||
digits = find(child, "v8:Digits")
|
||||
frac = find(child, "v8:FractionDigits")
|
||||
sign = find(child, "v8:AllowedSign")
|
||||
if digits is None or not _re_vt.match(r'^\d+$', text_of(digits)):
|
||||
report_error("v8:NumberQualifiers: <v8:Digits> missing or not a non-negative integer")
|
||||
vt_ok = False
|
||||
if frac is None or not _re_vt.match(r'^\d+$', text_of(frac)):
|
||||
report_error("v8:NumberQualifiers: <v8:FractionDigits> missing or not a non-negative integer")
|
||||
vt_ok = False
|
||||
if sign is not None and text_of(sign) and text_of(sign) not in _VALID_SIGN:
|
||||
report_error(f"v8:NumberQualifiers: <v8:AllowedSign>{text_of(sign)}</v8:AllowedSign> — must be one of: {', '.join(_VALID_SIGN)}")
|
||||
vt_ok = False
|
||||
elif q_name == 'v8:StringQualifiers':
|
||||
length = find(child, "v8:Length")
|
||||
al = find(child, "v8:AllowedLength")
|
||||
if length is None or not _re_vt.match(r'^\d+$', text_of(length)):
|
||||
report_error("v8:StringQualifiers: <v8:Length> missing or not a non-negative integer")
|
||||
vt_ok = False
|
||||
if al is not None and text_of(al) and text_of(al) not in _VALID_LENGTH:
|
||||
report_error(f"v8:StringQualifiers: <v8:AllowedLength>{text_of(al)}</v8:AllowedLength> — must be one of: {', '.join(_VALID_LENGTH)}")
|
||||
vt_ok = False
|
||||
elif q_name == 'v8:DateQualifiers':
|
||||
df = find(child, "v8:DateFractions")
|
||||
if df is not None and text_of(df) and text_of(df) not in _VALID_FRACTIONS:
|
||||
report_error(f"v8:DateQualifiers: <v8:DateFractions>{text_of(df)}</v8:DateFractions> — must be one of: {', '.join(_VALID_FRACTIONS)}")
|
||||
vt_ok = False
|
||||
|
||||
# Cross-check: every qualifier must have a matching scalar type in this valueType
|
||||
for q_name, _ in qualifiers:
|
||||
producer = _QUALIFIER_PRODUCERS.get(q_name)
|
||||
if not producer:
|
||||
continue
|
||||
if producer not in types:
|
||||
report_error(f"valueType: <{q_name}> has no matching <v8:Type>{producer}</v8:Type> in this valueType")
|
||||
vt_ok = False
|
||||
|
||||
if vt_checked > 0 and vt_ok:
|
||||
report_ok(f"{vt_checked} valueType block(s): structure and qualifiers OK")
|
||||
|
||||
if stopped:
|
||||
finalize()
|
||||
sys.exit(1)
|
||||
|
||||
# ── 17. value content checks ──────────────────────────────────
|
||||
# Catches literal placeholders ('_') and empty strings in DesignTimeValue refs
|
||||
# that XDTO would reject at db-load-xml.
|
||||
|
||||
value_nodes = find_all(root, "//s:value[@xsi:type]") + find_all(root, "//dcscor:value[@xsi:type]")
|
||||
v_checked = 0
|
||||
v_ok = True
|
||||
for vn in value_nodes:
|
||||
if vn is None:
|
||||
continue
|
||||
v_checked += 1
|
||||
xsi_type = vn.get(XSI_TYPE) or ''
|
||||
text = vn.text or ''
|
||||
if xsi_type == 'dcscor:DesignTimeValue':
|
||||
stripped = text.strip()
|
||||
if not stripped or stripped == '_':
|
||||
report_error(f"<value xsi:type=\"dcscor:DesignTimeValue\">{text}</value> — DesignTimeValue must be a reference path (e.g. Перечисление.X.Y), not '{text}'")
|
||||
v_ok = False
|
||||
elif not _re_vt.match(r'^[A-Za-zА-Яа-яЁё]+\.[A-Za-zА-Яа-яЁё0-9_]+', stripped):
|
||||
report_warn(f"<value xsi:type=\"dcscor:DesignTimeValue\">{text}</value> — doesn't look like a typical ref path")
|
||||
|
||||
if v_checked > 0 and v_ok:
|
||||
report_ok(f"{v_checked} <value> element(s) with xsi:type: content OK")
|
||||
|
||||
if stopped:
|
||||
finalize()
|
||||
sys.exit(1)
|
||||
|
||||
# ── Final output ──────────────────────────────────────────────
|
||||
|
||||
finalize()
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "decimal — все формы квалификаторов (bare, (N), (N,M), nonneg, синонимы)",
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле1",
|
||||
"fields": [
|
||||
"ДеньгиПоУмолчанию: decimal",
|
||||
"ЦелоеОдинАргумент: decimal(10)",
|
||||
"ОбычныеДеньги: decimal(10,2)",
|
||||
"Положительные: decimal(10,2,nonneg)",
|
||||
"ЦелоеПоложительное: decimal(10,nonneg)",
|
||||
"ЧислоСинонимБезАргументов: число",
|
||||
"ЧислоСинонимЦелое: число(8)",
|
||||
"ЧислоСинонимКоличество: число(15,3)"
|
||||
]
|
||||
}],
|
||||
"parameters": [
|
||||
"ПараметрДеньги: decimal",
|
||||
"ПараметрЦелое: decimal(10)",
|
||||
"ПараметрКоличество: decimal(15,3,nonneg)"
|
||||
]
|
||||
},
|
||||
"validatePath": "Template.xml",
|
||||
"expect": {
|
||||
"files": ["Template.xml"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Параметры с пустыми значениями (все типы, разные sentinel-формы)",
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле1",
|
||||
"fields": ["Поле1: число(1,0)"]
|
||||
}],
|
||||
"parameters": [
|
||||
"Параметр1",
|
||||
"Параметр2: string =",
|
||||
"ПараметрСписок: EnumRef.СтатусТеста @valueList = _",
|
||||
"ПараметрСсылка: CatalogRef.ПлоскийПростой",
|
||||
"ПараметрДата: date = null",
|
||||
{ "name": "ПараметрЧисло", "type": "decimal", "value": null },
|
||||
"ПараметрБулево: boolean = ",
|
||||
"ПараметрСтандартныйПериод: StandardPeriod = _",
|
||||
{ "name": "ПараметрТипНеЗадан", "value": null },
|
||||
"ПараметрСписокСтрок: string @valueList",
|
||||
"ПараметрВремяСЗначением: time = 0001-01-01T12:30:00",
|
||||
"ПараметрВремяПусто: time",
|
||||
"ПараметрСтрокаФиксСЗначением: string(10,fix) = АБВ",
|
||||
"ПараметрСтрокаФиксПусто: string(10,fix)",
|
||||
{ "name": "СоставнойТип", "type": ["string(10,fix)", "CatalogRef.ПлоскийПростой"], "value": null }
|
||||
]
|
||||
},
|
||||
"validatePath": "Template.xml",
|
||||
"expect": {
|
||||
"files": ["Template.xml"]
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,12 @@
|
||||
<dataPath>Поле</dataPath>
|
||||
<field>Поле</field>
|
||||
<valueType>
|
||||
<v8:Type>decimal</v8:Type>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
@@ -77,6 +82,11 @@
|
||||
<valueType>
|
||||
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>
|
||||
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
|
||||
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
|
||||
</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Флаг</name>
|
||||
@@ -129,6 +139,7 @@
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Валюта</name>
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
<?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>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>ЦелоеОдинАргумент</dataPath>
|
||||
<field>ЦелоеОдинАргумент</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>ОбычныеДеньги</dataPath>
|
||||
<field>ОбычныеДеньги</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Положительные</dataPath>
|
||||
<field>Положительные</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Nonnegative</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>ЦелоеПоложительное</dataPath>
|
||||
<field>ЦелоеПоложительное</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Nonnegative</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>ЧислоСинонимБезАргументов</dataPath>
|
||||
<field>ЧислоСинонимБезАргументов</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>ЧислоСинонимЦелое</dataPath>
|
||||
<field>ЧислоСинонимЦелое</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>8</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</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>3</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Поле1</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>ПараметрДеньги</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрЦелое</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрКоличество</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>3</v8:FractionDigits>
|
||||
<v8:AllowedSign>Nonnegative</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</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,190 @@
|
||||
<?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>Поле1</dataPath>
|
||||
<field>Поле1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>1</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Поле1</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>Параметр1</name>
|
||||
<value xsi:nil="true"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Параметр2</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"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрСписок</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:EnumRef.СтатусТеста</v8:Type>
|
||||
</valueType>
|
||||
<valueListAllowed>true</valueListAllowed>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрСсылка</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.ПлоскийПростой</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:nil="true"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрДата</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Date</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрЧисло</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрБулево</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">false</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрСтандартныйПериод</name>
|
||||
<valueType>
|
||||
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>
|
||||
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
|
||||
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
|
||||
</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрТипНеЗадан</name>
|
||||
<value xsi:nil="true"/>
|
||||
</parameter>
|
||||
<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>
|
||||
<valueListAllowed>true</valueListAllowed>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрВремяСЗначением</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Time</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T12:30:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрВремяПусто</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Time</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрСтрокаФиксСЗначением</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>10</v8:Length>
|
||||
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string">АБВ</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПараметрСтрокаФиксПусто</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>10</v8:Length>
|
||||
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>СоставнойТип</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>10</v8:Length>
|
||||
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.ПлоскийПростой</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:nil="true"/>
|
||||
</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>
|
||||
@@ -71,6 +71,11 @@
|
||||
<valueType>
|
||||
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>
|
||||
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
|
||||
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
|
||||
</value>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
|
||||
@@ -17,14 +17,24 @@
|
||||
<dataPath>Поле1</dataPath>
|
||||
<field>Поле1</field>
|
||||
<valueType>
|
||||
<v8:Type>decimal</v8:Type>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</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>decimal</v8:Type>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Организации</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:nil="true"/>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "modify-dataParameter: пустые значения (sentinel-формы) → dcscor:value xsi:nil",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле1",
|
||||
"fields": ["Поле1: decimal(1,0)"]
|
||||
}],
|
||||
"parameters": [
|
||||
"Период: StandardPeriod = LastMonth",
|
||||
"Организация: string = Альфа"
|
||||
],
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
"settings": {
|
||||
"selection": ["Auto"],
|
||||
"dataParameters": ["Период = LastMonth", "Организация = Альфа"],
|
||||
"structure": "details"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
},
|
||||
{
|
||||
"script": "skd-edit/scripts/skd-edit",
|
||||
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-dataParameter", "-Value": "Период = _" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "modify-dataParameter",
|
||||
"value": "Организация = null"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "add-parameter: пустые значения и расширенные типы (decimal bare, time, string fix, sentinels)",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле1",
|
||||
"fields": ["Поле1: decimal(1,0)"]
|
||||
}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "add-parameter",
|
||||
"value": "ПарСтрока: string =;;ПарСтрокаНулл: string = null;;ПарСтрокаПодч: string = _;;ПарДата: date =;;ПарВремя: time =;;ПарВремяНепусто: time = 0001-01-01T12:30:00;;ПарДатаВремя: dateTime = _;;ПарЧислоБар: decimal =;;ПарЧислоН: decimal(8) =;;ПарБул: boolean =;;ПарПериод: StandardPeriod = _;;ПарСсылка: CatalogRef.Номенклатура = null;;ПарСтрокаФикс: string(10,fix) =;;ПарСписок: string @valueList = _"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "modify-parameter: установка пустого значения через sentinel-формы (value=_, value=null)",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле1",
|
||||
"fields": ["Поле1: decimal(1,0)"]
|
||||
}],
|
||||
"parameters": [
|
||||
"ПарСтрока: string = ABC",
|
||||
"ПарДата: date = 2025-01-15T00:00:00",
|
||||
"ПарЧисло: decimal = 42",
|
||||
"ПарСсылка: CatalogRef.Номенклатура = Справочник.Номенклатура.НашаОрганизация"
|
||||
]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
},
|
||||
{
|
||||
"script": "skd-edit/scripts/skd-edit",
|
||||
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-parameter", "-Value": "ПарСтрока value=_" }
|
||||
},
|
||||
{
|
||||
"script": "skd-edit/scripts/skd-edit",
|
||||
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-parameter", "-Value": "ПарДата value=null" }
|
||||
},
|
||||
{
|
||||
"script": "skd-edit/scripts/skd-edit",
|
||||
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-parameter", "-Value": "ПарЧисло value=_" }
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml",
|
||||
"operation": "modify-parameter",
|
||||
"value": "ПарСсылка value=null"
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
<?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>Поле1</dataPath>
|
||||
<field>Поле1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>1</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Поле1</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>Период</name>
|
||||
<valueType>
|
||||
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">LastMonth</v8:variant>
|
||||
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
|
||||
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
|
||||
</value>
|
||||
</parameter>
|
||||
<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">Альфа</value>
|
||||
</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:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Период</dcscor:parameter>
|
||||
<dcscor:value xsi:nil="true"/>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Организация</dcscor:parameter>
|
||||
<dcscor:value xsi:nil="true"/>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<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,196 @@
|
||||
<?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>Поле1</dataPath>
|
||||
<field>Поле1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>1</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Поле1</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"/>
|
||||
</parameter>
|
||||
<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"/>
|
||||
</parameter>
|
||||
<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"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарДата</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Date</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарВремя</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Time</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарВремяНепусто</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Time</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T12:30:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарДатаВремя</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарЧислоБар</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарЧислоН</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>8</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарБул</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">false</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарПериод</name>
|
||||
<valueType>
|
||||
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>
|
||||
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
|
||||
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
|
||||
</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарСсылка</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Номенклатура</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:nil="true"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарСтрокаФикс</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>10</v8:Length>
|
||||
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<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>
|
||||
<valueListAllowed>true</valueListAllowed>
|
||||
</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,92 @@
|
||||
<?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>Поле1</dataPath>
|
||||
<field>Поле1</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>1</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Поле1</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"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарДата</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>Date</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарЧисло</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПарСсылка</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Номенклатура</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:nil="true"/>
|
||||
</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>
|
||||
@@ -86,6 +86,7 @@
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
@@ -111,6 +112,7 @@
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:use>false</dcscor:use>
|
||||
<dcscor:parameter>Организация</dcscor:parameter>
|
||||
<dcscor:value xsi:nil="true"/>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПорядокОкругленияСумм</name>
|
||||
@@ -57,6 +58,7 @@
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Организация</name>
|
||||
@@ -67,12 +69,14 @@
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string"/>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПрекращаемаяДеятельность</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">false</value>
|
||||
</parameter>
|
||||
|
||||
<settingsVariant>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Ошибка: AllowedSign со значением вне Any/Nonnegative/Negative",
|
||||
"setup": "fixture:bad-allowed-sign",
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"expectError": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Ошибка: xs:decimal с неполными NumberQualifiers (нет Digits/FractionDigits)",
|
||||
"setup": "fixture:bad-decimal-no-qualifiers",
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"expectError": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Ошибка: <v8:Type>decimal</v8:Type> без префикса xs:",
|
||||
"setup": "fixture:bad-decimal-no-xs",
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"expectError": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Ошибка: xs:string с NumberQualifiers (несоответствие тип/qualifiers)",
|
||||
"setup": "fixture:bad-qualifier-mismatch",
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"expectError": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Ошибка: DesignTimeValue со значением '_' (BUG-2 от titan)",
|
||||
"setup": "fixture:bad-ref-literal",
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"expectError": true
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>SELECT 1</query>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Garbage</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
</dataSet>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:settings/>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>SELECT 1</query>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
</dataSet>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:settings/>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?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>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>SELECT 1</query>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>decimal</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
</dataSet>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:settings/>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>SELECT 1</query>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Текст</dataPath>
|
||||
<field>Текст</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
</dataSet>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:settings/>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>SELECT 1</query>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Поле1</dataPath>
|
||||
<field>Поле1</field>
|
||||
</field>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>Организация</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Организации</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="dcscor:DesignTimeValue">_</value>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:settings/>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
Reference in New Issue
Block a user