fix(form-validate): версия формата — общим helper-ом, с учётом внешних обработок

Проверка версии читала Configuration.xml собственной регуляркой. Отсюда два
пробела: форма автономной внешней обработки не проверялась вовсе (своего
Configuration.xml у неё нет, версию несёт корень обработки), а разбор
дублировал уже существующий эталон.

Теперь используются копии общих эталонов — detect_format_version (авторитет
form-compile) и support-guard: is_external_root (авторитет cf-edit), оба
навыка добавлены в реестр check-inline-drift.

Попутно вскрылось следствие для соседней проверки: обработка, чьи исходники
лежат внутри дерева с Configuration.xml (обычная раскладка src/cf рядом с
src/epf), считалась «конфигурационным контекстом», и Check 12 ругался на её
собственные External*-типы. Теперь климб останавливается на ближайшем
якоре — том же правиле границы автономного объекта, что в support-guard.

Плюс паритет: PS отчитывался «Data bindings: none», PY эту ветку не имел.

Кейс на EPF-контекст добавлен. Регресс 16/16 на обоих рантаймах, корпус
21 097 форм без новых срабатываний, гарды зелёные.
This commit is contained in:
Nick Shirokov
2026-08-12 19:28:11 +03:00
parent 7dc2e6e443
commit 71f047291c
12 changed files with 534 additions and 31 deletions
@@ -60,6 +60,19 @@ $nsMgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")
$root = $xmlDoc.DocumentElement
# Корень автономной внешней обработки/отчёта. Копия общего эталона (семья
# support-guard: is_external_root, авторитет — cf-edit).
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
# --- Detect context: config vs EPF/ERF ---
# Walk up from FormPath looking for Configuration.xml → config context
# No Configuration.xml → external data processor / report (EPF/ERF)
@@ -67,14 +80,56 @@ $script:isConfigContext = $false
$walkDir = Split-Path (Resolve-Path $FormPath) -Parent
for ($i = 0; $i -lt 15; $i++) {
if (-not $walkDir -or $walkDir -eq (Split-Path $walkDir)) { break }
# Порядок проверок тот же, что у Detect-FormatVersion: сначала корень автономной обработки,
# потом Configuration.xml — иначе форма внутри EPF, лежащей в дереве конфигурации, взяла бы
# версию конфигурации.
$extRoot = "$walkDir.xml"
if (-not $script:versionAnchor) {
if (Test-ExternalObjectRoot $extRoot) {
# Ближайший якорь побеждает: автономная обработка остаётся автономной, даже если её
# исходники лежат внутри дерева с Configuration.xml (типовая раскладка проекта:
# src/cf рядом с src/epf). Иначе её собственные External*-типы считались бы ошибкой.
$script:versionAnchor = $extRoot
break
}
}
if (Test-Path (Join-Path $walkDir "Configuration.xml")) {
$script:isConfigContext = $true
$script:configXmlPath = Join-Path $walkDir "Configuration.xml"
if (-not $script:versionAnchor) { $script:versionAnchor = $script:configXmlPath }
break
}
$walkDir = Split-Path $walkDir
}
# Версия формата выгрузки. Копия общего эталона (семья detect_format_version, авторитет —
# form-compile): та же ветка для автономной EPF/ERF, где версию несёт корень обработки.
function Detect-FormatVersion([string]$dir) {
$d = $dir
while ($d) {
# Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт
# корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17.
$extPath = "$d.xml"
if (Test-Path $extPath) {
$extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8)
$extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length))
if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
}
$cfgPath = Join-Path $d "Configuration.xml"
if (Test-Path $cfgPath) {
$cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8)
# Длину среза берём по СТРОКЕ, а не по размеру файла: размер в БАЙТАХ, Substring считает
# СИМВОЛЫ, и на кириллице байт больше — короткий Configuration.xml ронял навык исключением.
$head = $cfgText.Substring(0, [Math]::Min(2000, $cfgText.Length))
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
}
$parent = Split-Path $d -Parent
if ($parent -eq $d) { break }
$d = $parent
}
return "2.17"
}
# --- Counters ---
$errors = 0
@@ -927,26 +982,22 @@ if (-not $stopped) {
}
}
# --- Check 14: версия формата формы совпадает с версией конфигурации ---
# --- Check 14: версия формата формы совпадает с версией выгрузки ---
# Версию задаёт платформа, которой выгружали, и в пределах одной выгрузки она едина. Форма из
# другой версии — «Неизвестная версия формата N загружаемого файла»: платформа не читает файл,
# который новее её самой. Типичный след ручной сборки: форму скопировали из свежей конфигурации.
# который новее её самой. Источник версии ищем общим helper-ом: он же покрывает автономную
# внешнюю обработку/отчёт, где Configuration.xml нет и версию несёт корень самой обработки.
if (-not $stopped -and $script:configXmlPath) {
if (-not $stopped -and $script:versionAnchor) {
$formVer = $root.GetAttribute("version")
$cfgVer = ""
try {
$cfgHead = [System.IO.File]::ReadAllText($script:configXmlPath, [System.Text.Encoding]::UTF8)
$vm = [regex]::Match($cfgHead.Substring(0, [Math]::Min(4000, $cfgHead.Length)), '<MetaDataObject[^>]*\bversion="([^"]+)"')
if ($vm.Success) { $cfgVer = $vm.Groups[1].Value }
} catch { }
$dumpVer = Detect-FormatVersion (Split-Path (Resolve-Path $FormPath) -Parent)
if (-not $cfgVer -or -not $formVer) {
if (-not $formVer) {
Report-OK "14. Format version: not comparable"
} elseif ($formVer -ne $cfgVer) {
Report-Error "14. Format version $formVer differs from configuration ($cfgVer) — a dump carries one version, the platform refuses a file it cannot read"
} elseif ($formVer -ne $dumpVer) {
Report-Error "14. Format version $formVer differs from the dump ($dumpVer) — a dump carries one version, the platform refuses a file it cannot read"
} else {
Report-OK "14. Format version: $formVer, matches configuration"
Report-OK "14. Format version: $formVer, matches the dump"
}
}
@@ -71,6 +71,49 @@ VALID_CFG_PREFIXES = {
}
# Корень автономной внешней обработки/отчёта. Копия общего эталона (семья
# support-guard: is_external_root, авторитет — cf-edit).
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
# Версия формата выгрузки. Копия общего эталона (семья detect_format_version, авторитет —
# form-compile): та же ветка для автономной EPF/ERF, где версию несёт корень обработки.
def detect_format_version(d):
while d:
# Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт
# корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17.
ext_path = d + ".xml"
if os.path.isfile(ext_path):
with open(ext_path, "r", encoding="utf-8-sig") as f:
ext_head = f.read(2000)
if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head):
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', ext_head)
if m:
return m.group(1)
cfg_path = os.path.join(d, "Configuration.xml")
if os.path.isfile(cfg_path):
with open(cfg_path, "r", encoding="utf-8-sig") as f:
head = f.read(2000)
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
if m:
return m.group(1)
parent = os.path.dirname(d)
if parent == d:
break
d = parent
return "2.17"
def localname(el):
return etree.QName(el.tag).localname
@@ -129,14 +172,28 @@ def main():
# Detect context: config vs EPF/ERF
is_config_context = False
config_xml_path = ''
version_anchor = ''
walk_dir = os.path.dirname(os.path.abspath(form_path))
for _ in range(15):
parent = os.path.dirname(walk_dir)
if parent == walk_dir:
break
# Порядок проверок тот же, что у detect_format_version: сначала корень автономной обработки,
# потом Configuration.xml — иначе форма внутри EPF, лежащей в дереве конфигурации, взяла бы
# версию конфигурации.
ext_root = walk_dir + '.xml'
if not version_anchor:
if _sg_is_external_root(ext_root):
# Ближайший якорь побеждает: автономная обработка остаётся автономной, даже если её
# исходники лежат внутри дерева с Configuration.xml (типовая раскладка проекта:
# src/cf рядом с src/epf). Иначе её собственные External*-типы считались бы ошибкой.
version_anchor = ext_root
break
if os.path.isfile(os.path.join(walk_dir, 'Configuration.xml')):
is_config_context = True
config_xml_path = os.path.join(walk_dir, 'Configuration.xml')
if not version_anchor:
version_anchor = config_xml_path
break
walk_dir = parent
@@ -489,6 +546,8 @@ def main():
path_msg = f"{path_msg}, {skip_note}" if path_msg else skip_note
if path_errors == 0 and path_msg:
report_ok(f"Data bindings: {path_msg}")
elif path_errors == 0:
report_ok("Data bindings: none")
# --- Check 6: Button command references ---
if not stopped:
@@ -849,29 +908,22 @@ def main():
elif prefix_errors == 0:
report_ok(f'13. Namespace prefixes: {prefix_checked} values, all declared')
# --- Check 14: версия формата формы совпадает с версией конфигурации ---
# --- Check 14: версия формата формы совпадает с версией выгрузки ---
# Версию задаёт платформа, которой выгружали, и в пределах одной выгрузки она едина. Форма из
# другой версии — «Неизвестная версия формата N загружаемого файла»: платформа не читает файл,
# который новее её самой. Типичный след ручной сборки: форму скопировали из свежей конфигурации.
if not stopped and config_xml_path:
# который новее её самой. Источник версии ищем общим helper-ом: он же покрывает автономную
# внешнюю обработку/отчёт, где Configuration.xml нет и версию несёт корень самой обработки.
if not stopped and version_anchor:
form_ver = root.get('version', '')
cfg_ver = ''
try:
with open(config_xml_path, 'r', encoding='utf-8-sig', errors='ignore') as fh:
head = fh.read(4000)
vm = re.search(r'<MetaDataObject[^>]*[ \t]version="([^"]+)"', head)
if vm:
cfg_ver = vm.group(1)
except OSError:
pass
dump_ver = detect_format_version(os.path.dirname(os.path.abspath(form_path)))
if not cfg_ver or not form_ver:
if not form_ver:
report_ok('14. Format version: not comparable')
elif form_ver != cfg_ver:
report_error(f'14. Format version {form_ver} differs from configuration ({cfg_ver}) '
elif form_ver != dump_ver:
report_error(f'14. Format version {form_ver} differs from the dump ({dump_ver}) '
'— a dump carries one version, the platform refuses a file it cannot read')
else:
report_ok(f'14. Format version: {form_ver}, matches configuration')
report_ok(f'14. Format version: {form_ver}, matches the dump')
# --- Finalize ---
checks = ok_count + errors + warnings
@@ -0,0 +1,16 @@
{
"name": "Внешняя обработка: версия формы сверяется с корнем обработки, а не с конфигурацией",
"preRun": [
{
"script": "epf-init/scripts/init",
"args": { "-Name": "ТестВерсия", "-SrcDir": "{workDir}", "-FormatVersion": "2.20" }
},
{
"script": "form-add/scripts/form-add",
"args": { "-ObjectPath": "{workDir}/ТестВерсия.xml", "-FormName": "Форма" }
}
],
"params": { "formPath": "ТестВерсия/Forms/Форма" },
"expect": { "stdoutContains": "Validation OK" },
"skipPlatformVerify": "автономная внешняя обработка: верификатор грузит каталог как конфигурацию, EPF так не проверить"
}
@@ -0,0 +1,251 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
<Configuration uuid="UUID-001">
<InternalInfo>
<xr:ContainedObject>
<xr:ClassId>UUID-002</xr:ClassId>
<xr:ObjectId>UUID-003</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-004</xr:ClassId>
<xr:ObjectId>UUID-005</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-006</xr:ClassId>
<xr:ObjectId>UUID-007</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-008</xr:ClassId>
<xr:ObjectId>UUID-009</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-010</xr:ClassId>
<xr:ObjectId>UUID-011</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-012</xr:ClassId>
<xr:ObjectId>UUID-013</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-014</xr:ClassId>
<xr:ObjectId>UUID-015</xr:ObjectId>
</xr:ContainedObject>
</InternalInfo>
<Properties>
<Name>TestConfig</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>TestConfig</v8:content>
</v8:item>
</Synonym>
<Comment/>
<NamePrefix/>
<ConfigurationExtensionCompatibilityMode>Version8_3_24</ConfigurationExtensionCompatibilityMode>
<DefaultRunMode>ManagedApplication</DefaultRunMode>
<UsePurposes>
<v8:Value xsi:type="app:ApplicationUsePurpose">PlatformApplication</v8:Value>
</UsePurposes>
<ScriptVariant>Russian</ScriptVariant>
<DefaultRoles/>
<Vendor/>
<Version/>
<UpdateCatalogAddress/>
<IncludeHelpInContents>false</IncludeHelpInContents>
<UseManagedFormInOrdinaryApplication>false</UseManagedFormInOrdinaryApplication>
<UseOrdinaryFormInManagedApplication>false</UseOrdinaryFormInManagedApplication>
<AdditionalFullTextSearchDictionaries/>
<CommonSettingsStorage/>
<ReportsUserSettingsStorage/>
<ReportsVariantsStorage/>
<FormDataSettingsStorage/>
<DynamicListsUserSettingsStorage/>
<URLExternalDataStorage/>
<Content/>
<DefaultReportForm/>
<DefaultReportVariantForm/>
<DefaultReportSettingsForm/>
<DefaultReportAppearanceTemplate/>
<DefaultDynamicListSettingsForm/>
<DefaultSearchForm/>
<DefaultDataHistoryChangeHistoryForm/>
<DefaultDataHistoryVersionDataForm/>
<DefaultDataHistoryVersionDifferencesForm/>
<DefaultCollaborationSystemUsersChoiceForm/>
<RequiredMobileApplicationPermissions/>
<UsedMobileApplicationFunctionalities>
<app:functionality>
<app:functionality>Biometrics</app:functionality>
<app:use>true</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Location</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BackgroundLocation</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BluetoothPrinters</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>WiFiPrinters</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Contacts</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Calendars</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>PushNotifications</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>LocalNotifications</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>InAppPurchases</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>PersonalComputerFileExchange</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Ads</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>NumberDialing</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>CallProcessing</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>CallLog</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AutoSendSMS</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>ReceiveSMS</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>SMSLog</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Camera</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Microphone</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>MusicLibrary</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>PictureAndVideoLibraries</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AudioPlaybackAndVibration</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BackgroundAudioPlaybackAndVibration</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>InstallPackages</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>OSBackup</app:functionality>
<app:use>true</app:use>
</app:functionality>
<app:functionality>
<app:functionality>ApplicationUsageStatistics</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BarcodeScanning</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BackgroundAudioRecording</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AllFilesAccess</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Videoconferences</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>NFC</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>DocumentScanning</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>SpeechToText</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Geofences</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>IncomingShareRequests</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AllIncomingShareRequestsTypesProcessing</app:functionality>
<app:use>false</app:use>
</app:functionality>
</UsedMobileApplicationFunctionalities>
<StandaloneConfigurationRestrictionRoles/>
<MobileApplicationURLs/>
<AllowedIncomingShareRequestTypes/>
<MainClientApplicationWindowMode>Normal</MainClientApplicationWindowMode>
<DefaultInterface/>
<DefaultStyle/>
<DefaultLanguage>Language.Русский</DefaultLanguage>
<BriefInformation/>
<DetailedInformation/>
<Copyright/>
<VendorInformationAddress/>
<ConfigurationInformationAddress/>
<DataLockControlMode>Managed</DataLockControlMode>
<ObjectAutonumerationMode>NotAutoFree</ObjectAutonumerationMode>
<ModalityUseMode>DontUse</ModalityUseMode>
<SynchronousPlatformExtensionAndAddInCallUseMode>DontUse</SynchronousPlatformExtensionAndAddInCallUseMode>
<InterfaceCompatibilityMode>TaxiEnableVersion8_2</InterfaceCompatibilityMode>
<DatabaseTablespacesUseMode>DontUse</DatabaseTablespacesUseMode>
<CompatibilityMode>Version8_3_24</CompatibilityMode>
<DefaultConstantsForm/>
</Properties>
<ChildObjects>
<Language>Русский</Language>
</ChildObjects>
</Configuration>
</MetaDataObject>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<ClientApplicationInterface xmlns="http://v8.1c.ru/8.2/managed-application/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="InterfaceLayouter">
<top>
<panel id="UUID-001">
<uuid>UUID-002</uuid>
</panel>
</top>
<left>
<panel id="UUID-003">
<uuid>UUID-004</uuid>
</panel>
</left>
<panelDef id="UUID-004"/>
<panelDef id="UUID-005"/>
<panelDef id="UUID-006"/>
<panelDef id="UUID-002"/>
<panelDef id="UUID-007"/>
</ClientApplicationInterface>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
<Language uuid="UUID-001">
<Properties>
<Name>Русский</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Русский</v8:content>
</v8:item>
</Synonym>
<Comment/>
<LanguageCode>ru</LanguageCode>
</Properties>
</Language>
</MetaDataObject>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.20">
<ExternalDataProcessor uuid="UUID-001">
<InternalInfo>
<xr:ContainedObject>
<xr:ClassId>UUID-002</xr:ClassId>
<xr:ObjectId>UUID-003</xr:ObjectId>
</xr:ContainedObject>
<xr:GeneratedType name="ExternalDataProcessorObject.ТестВерсия" category="Object">
<xr:TypeId>UUID-004</xr:TypeId>
<xr:ValueId>UUID-005</xr:ValueId>
</xr:GeneratedType>
</InternalInfo>
<Properties>
<Name>ТестВерсия</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>ТестВерсия</v8:content>
</v8:item>
</Synonym>
<Comment/>
<DefaultForm>ExternalDataProcessor.ТестВерсия.Form.Форма</DefaultForm>
<AuxiliaryForm/>
</Properties>
<ChildObjects>
<Form>Форма</Form>
</ChildObjects>
</ExternalDataProcessor>
</MetaDataObject>
@@ -0,0 +1,11 @@
#Область ОписаниеПеременных
#КонецОбласти
#Область ПрограммныйИнтерфейс
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#КонецОбласти
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.20">
<Form uuid="UUID-001">
<Properties>
<Name>Форма</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Форма</v8:content>
</v8:item>
</Synonym>
<Comment/>
<FormType>Managed</FormType>
<IncludeHelpInContents>false</IncludeHelpInContents>
<UsePurposes>
<v8:Value xsi:type="app:ApplicationUsePurpose">PlatformApplication</v8:Value>
<v8:Value xsi:type="app:ApplicationUsePurpose">MobilePlatformApplication</v8:Value>
</UsePurposes>
<ExtendedPresentation/>
</Properties>
</Form>
</MetaDataObject>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://v8.1c.ru/8.3/xcf/logform" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.20">
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
<Autofill>true</Autofill>
</AutoCommandBar>
<ChildItems/>
<Attributes>
<Attribute name="Объект" id="1">
<Type>
<v8:Type>cfg:ExternalDataProcessorObject.ТестВерсия</v8:Type>
</Type>
<MainAttribute>true</MainAttribute>
</Attribute>
</Attributes>
</Form>
@@ -0,0 +1,19 @@
#Область ОбработчикиСобытийФормы
#КонецОбласти
#Область ОбработчикиСобытийЭлементовФормы
#КонецОбласти
#Область ОбработчикиКомандФормы
#КонецОбласти
#Область ОбработчикиОповещений
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#КонецОбласти
+4 -2
View File
@@ -59,7 +59,9 @@ const FAMILIES = [
'subsystem-compile', 'subsystem-edit', 'template-add', 'xdto-compile', 'xdto-edit',
// *-info навыки читают тем же хелпером СОСТОЯНИЕ поддержки для вывода, а не запрещают
// правку. Тело то же, поэтому семья общая.
'form-info', 'meta-info', 'mxl-info', 'role-info', 'skd-info', 'subsystem-info'] },
'form-info', 'meta-info', 'mxl-info', 'role-info', 'skd-info', 'subsystem-info',
// form-validate отличает автономную обработку от конфигурации: границей служит тот же корень
'form-validate'] },
],
},
{
@@ -92,7 +94,7 @@ const FAMILIES = [
// если <каталог>.xml — корень ExternalDataProcessor/ExternalReport, чего в дереве
// конфигурации не бывает. Поэтому вариант один на всех, переключателя не нужно.
{ id: 'base', authority: 'form-compile',
consumers: ['cfe-borrow', 'form-add', 'help-add', 'interface-edit', 'meta-compile',
consumers: ['cfe-borrow', 'form-add', 'form-validate', 'help-add', 'interface-edit', 'meta-compile',
'mxl-compile', 'role-compile', 'subsystem-compile', 'template-add', 'xdto-compile'] },
],
},