mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-15 10:24:57 +03:00
feat(form-decompile,form-compile): оператор фильтра Like (подобно) + рус. синоним в shorthand
Раундтрип ломал отбор с comparisonType=Like: декомпилятор выдавал сырой токен Like в
short-form ("Поле Like %x%"), а парсер компилятора его не знал → весь текст уходил в поле,
op сбрасывался в Equal, значение терялось (напр. РегламентированноеУведомление.../ФормаСвДобытВалют:
"КодВалют Like %/ %" → поле="КодВалют Like %/ %", потеря Like + %/ %).
Корпус (acc+erp 8.3.24): из 15 comparisonType недоставал только Like (8 шт.) — добавлен Like/NotLike.
По просьбе — рус. синоним оператора: подобно/неподобно (forgiving-ввод, как ПОДОБНО в конфигураторе).
decompile (filterOpMap): Like→like, NotLike→notLike (каноничный токен short-form).
compile (ps1+py): comparisonTypes + Parse-FilterShorthand opPatterns += like/notLike + подобно/неподобно.
PY доведён до регистронезависимости PS (re.IGNORECASE на op-парсинге + CI-лукап comparisonType),
чтобы Like/LIKE/ПОДОБНО резолвились одинаково в обоих портах.
Верификация: таргет-раундтрип 4 форм с Like → match (было 10→0); регресс form-compile 43/43
(ps1+py); 1С-cert dynamic-list-form (фильтры like и подобно → <comparisonType>Like, грузятся). spec.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.132 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.133 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -1627,6 +1627,8 @@ $script:comparisonTypes = @{
|
||||
"inHierarchy" = "InHierarchy"; "inListByHierarchy" = "InListByHierarchy"
|
||||
"contains" = "Contains"; "notContains" = "NotContains"
|
||||
"beginsWith" = "BeginsWith"; "notBeginsWith" = "NotBeginsWith"
|
||||
"like" = "Like"; "notLike" = "NotLike"
|
||||
"подобно" = "Like"; "неподобно" = "NotLike" # рус. синоним (хэш регистронезависим: ПОДОБНО=подобно)
|
||||
"filled" = "Filled"; "notFilled" = "NotFilled"
|
||||
}
|
||||
|
||||
@@ -1642,6 +1644,7 @@ function Parse-FilterShorthand {
|
||||
$opPatterns = @('<>', '>=', '<=', '=', '>', '<',
|
||||
'notIn\b', 'in\b', 'inHierarchy\b', 'inListByHierarchy\b',
|
||||
'notContains\b', 'contains\b', 'notBeginsWith\b', 'beginsWith\b',
|
||||
'notLike\b', 'like\b', 'неподобно\b', 'подобно\b',
|
||||
'notFilled\b', 'filled\b')
|
||||
$opJoined = $opPatterns -join '|'
|
||||
if ($s -match "^(.+?)\s+($opJoined)\s*(.*)?$") {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.132 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.133 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -1333,8 +1333,12 @@ COMPARISON_TYPES = {
|
||||
'inHierarchy': 'InHierarchy', 'inListByHierarchy': 'InListByHierarchy',
|
||||
'contains': 'Contains', 'notContains': 'NotContains',
|
||||
'beginsWith': 'BeginsWith', 'notBeginsWith': 'NotBeginsWith',
|
||||
'like': 'Like', 'notLike': 'NotLike',
|
||||
'подобно': 'Like', 'неподобно': 'NotLike', # рус. синоним
|
||||
'filled': 'Filled', 'notFilled': 'NotFilled',
|
||||
}
|
||||
# Регистронезависимый лукап (зеркало PS-хэша): Like/LIKE/ПОДОБНО → канон
|
||||
_COMPARISON_TYPES_CI = {k.lower(): v for k, v in COMPARISON_TYPES.items()}
|
||||
|
||||
_REF_TYPE_RE = re.compile(
|
||||
r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета|'
|
||||
@@ -1365,9 +1369,10 @@ def parse_filter_shorthand(s):
|
||||
op_patterns = ['<>', '>=', '<=', '=', '>', '<',
|
||||
r'notIn\b', r'in\b', r'inHierarchy\b', r'inListByHierarchy\b',
|
||||
r'notContains\b', r'contains\b', r'notBeginsWith\b', r'beginsWith\b',
|
||||
r'notLike\b', r'like\b', r'неподобно\b', r'подобно\b',
|
||||
r'notFilled\b', r'filled\b']
|
||||
op_joined = '|'.join(op_patterns)
|
||||
m = re.match(r'^(.+?)\s+(' + op_joined + r')\s*(.*)?$', s)
|
||||
m = re.match(r'^(.+?)\s+(' + op_joined + r')\s*(.*)?$', s, re.IGNORECASE)
|
||||
if m:
|
||||
result['field'] = m.group(1).strip()
|
||||
result['op'] = m.group(2).strip()
|
||||
@@ -1449,7 +1454,8 @@ def emit_filter_item(lines, item, indent):
|
||||
if item.get('use') is False:
|
||||
lines.append(f'{indent}\t<dcsset:use>false</dcsset:use>')
|
||||
lines.append(f'{indent}\t<dcsset:left xsi:type="dcscor:Field">{esc_xml(str(item.get("field", "")))}</dcsset:left>')
|
||||
comp_type = COMPARISON_TYPES.get(str(item.get('op')))
|
||||
# Регистронезависимый лукап (зеркало PS): Like/LIKE/ПОДОБНО → канон; иначе — как есть
|
||||
comp_type = _COMPARISON_TYPES_CI.get(str(item.get('op')).lower())
|
||||
if not comp_type:
|
||||
comp_type = str(item.get('op'))
|
||||
lines.append(f'{indent}\t<dcsset:comparisonType>{esc_xml(comp_type)}</dcsset:comparisonType>')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.106 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.107 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -458,6 +458,7 @@ $script:filterOpMap = @{
|
||||
'InHierarchy'='inHierarchy'; 'InListByHierarchy'='inListByHierarchy';
|
||||
'Contains'='contains'; 'NotContains'='notContains';
|
||||
'BeginsWith'='beginsWith'; 'NotBeginsWith'='notBeginsWith';
|
||||
'Like'='like'; 'NotLike'='notLike';
|
||||
'Filled'='filled'; 'NotFilled'='notFilled'
|
||||
}
|
||||
|
||||
|
||||
@@ -990,6 +990,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и
|
||||
|
||||
- **order** — строка `"Поле"` (asc) / `"Поле desc"` (синонимы `убыв`/`desc`, `возр`/`asc`) / `"Auto"`, либо объект `{ field, direction?, use?, viewMode? }`.
|
||||
- **filter** — shorthand `"Поле оператор значение @флаги"` (`@off`, `@user`, `@quickAccess`, `@normal`, `@inaccessible`; `_` = пусто) или объект `{ field, op, value?, use?, userSettingID? }` или группа `{ group: "And"|"Or"|"Not", items: [...] }`.
|
||||
- **Операторы:** `=` `<>` `>` `>=` `<` `<=`, `in`/`notIn`, `inHierarchy`/`inListByHierarchy`, `contains`/`notContains`, `beginsWith`/`notBeginsWith`, `like`/`notLike` (подобно; `%`-шаблон в значении, напр. `"КодВалют like %/ %"`), `filled`/`notFilled`. Регистр оператора не важен; у `like`/`notLike` есть рус. синоним `подобно`/`неподобно`.
|
||||
- **Дата в фильтре = `StandardBeginningDate`** (так платформа хранит дату-значение почти всегда — корпус 268 vs 2 `xs:dateTime`). Формы значения (от компактной к полной):
|
||||
- **голая ISO-дата** `"2020-01-01T00:00:00"` (без `valueType`) → `Custom` + эта дата. Работает и в shorthand: `"ДатаЗаказа > 2020-01-01T00:00:00"`. Это дефолт даты в фильтре.
|
||||
- **строка-вариант** `"BeginningOfThisDay"` + `valueType: "v8:StandardBeginningDate"` — именованный вариант без даты (`BeginningOfThisWeek`/`BeginningOfThisYear`/…; имя ≠ дата, нужен `valueType`).
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{ "name": "Список", "type": "DynamicList", "useAlways": ["~Артикул", "Список.Code", "Description"], "settings": {
|
||||
"mainTable": "Catalog.Товары", "dynamicDataRead": true, "autoSaveUserSettings": false,
|
||||
"order": [ "Description", "Code desc" ],
|
||||
"filter": [ "Артикул = _ @off @user" ],
|
||||
"filter": [ "Артикул = _ @off @user", "Артикул like %тест%", "Description подобно %abc%" ],
|
||||
"conditionalAppearance": [ { "filter": ["Артикул = _"], "appearance": { "ЦветТекста": "web:Red" } } ]
|
||||
} }
|
||||
],
|
||||
|
||||
+10
@@ -110,6 +110,16 @@
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Артикул</dcsset:left>
|
||||
<dcsset:comparisonType>Like</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:string">%тест%</dcsset:right>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Description</dcsset:left>
|
||||
<dcsset:comparisonType>Like</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:string">%abc%</dcsset:right>
|
||||
</dcsset:item>
|
||||
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||
</dcsset:filter>
|
||||
|
||||
Reference in New Issue
Block a user