mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-18 07:35:52 +03:00
Compare commits
194
Commits
@@ -61,7 +61,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -
|
|||||||
|
|
||||||
| DSL ключ | XML элемент | Значение ключа |
|
| DSL ключ | XML элемент | Значение ключа |
|
||||||
|--------------|-------------------|---------------------------------------------------|
|
|--------------|-------------------|---------------------------------------------------|
|
||||||
| `"group"` | UsualGroup | `"horizontal"` / `"vertical"` / `"alwaysHorizontal"` / `"alwaysVertical"` / `"collapsible"` |
|
| `"group"` | UsualGroup | ориентация: `"vertical"` / `"horizontalIfPossible"` / `"alwaysHorizontal"` (поведение — отдельный ключ `behavior`) |
|
||||||
| `"columnGroup"` | ColumnGroup | `"horizontal"` / `"vertical"` / `"inCell"` — только внутри `columns` таблицы |
|
| `"columnGroup"` | ColumnGroup | `"horizontal"` / `"vertical"` / `"inCell"` — только внутри `columns` таблицы |
|
||||||
| `"input"` | InputField | имя элемента |
|
| `"input"` | InputField | имя элемента |
|
||||||
| `"check"` | CheckBoxField | имя |
|
| `"check"` | CheckBoxField | имя |
|
||||||
@@ -83,15 +83,15 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -
|
|||||||
|
|
||||||
| Ключ | Описание |
|
| Ключ | Описание |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| `name` | Переопределить имя (по умолчанию = значение ключа типа) |
|
| `name` | Переопределить имя (по умолчанию = значение ключа типа). Имена уникальны во всех коллекциях формы (элементы, реквизиты, команды, колонки) |
|
||||||
| `title` | Заголовок элемента |
|
| `title` | Заголовок элемента |
|
||||||
|
| `tooltip` | Всплывающая подсказка элемента (строка или `{ru,en}`) |
|
||||||
| `visible: false` | Скрыть (синоним: `hidden: true`) |
|
| `visible: false` | Скрыть (синоним: `hidden: true`) |
|
||||||
| `enabled: false` | Сделать недоступным (синоним: `disabled: true`) |
|
| `enabled: false` | Сделать недоступным (синоним: `disabled: true`) |
|
||||||
| `readOnly: true` | Только чтение |
|
| `readOnly: true` | Только чтение |
|
||||||
| `on: [...]` | События с автоименованием обработчиков |
|
| `events: {...}` | Обработчики событий: `{ "OnChange": "ИмяОбработчика" }`. Тот же формат, что у событий формы. Значение `null` → имя обработчика сгенерируется автоматически |
|
||||||
| `handlers: {...}` | Явное задание имён обработчиков: `{"OnChange": "МоёИмя"}` |
|
|
||||||
|
|
||||||
### Допустимые имена событий (`on`)
|
### Допустимые имена событий (`events`)
|
||||||
|
|
||||||
Компилятор предупреждает о неизвестных событиях. Имена регистрозависимы — используйте точно как указано.
|
Компилятор предупреждает о неизвестных событиях. Имена регистрозависимы — используйте точно как указано.
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -
|
|||||||
| Ключ | Описание | Пример |
|
| Ключ | Описание | Пример |
|
||||||
|------|----------|--------|
|
|------|----------|--------|
|
||||||
| `path` | DataPath — привязка к данным | `"Объект.Организация"` |
|
| `path` | DataPath — привязка к данным | `"Объект.Организация"` |
|
||||||
| `titleLocation` | Размещение заголовка | `"none"`, `"left"`, `"top"` |
|
| `titleLocation` | Размещение заголовка | `"none"`, `"left"`, `"right"`, `"top"`, `"bottom"`, `"auto"` |
|
||||||
| `multiLine: true` | Многострочное поле | текстовое поле, комментарий |
|
| `multiLine: true` | Многострочное поле | текстовое поле, комментарий |
|
||||||
| `passwordMode: true` | Режим пароля (звёздочки) | поле ввода пароля |
|
| `passwordMode: true` | Режим пароля (звёздочки) | поле ввода пароля |
|
||||||
| `choiceButton: true` | Кнопка выбора ("...") | ссылочное поле |
|
| `choiceButton: true` | Кнопка выбора ("...") | ссылочное поле |
|
||||||
@@ -179,13 +179,14 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -
|
|||||||
|
|
||||||
### Группа (group)
|
### Группа (group)
|
||||||
|
|
||||||
Значение ключа задаёт ориентацию: `"horizontal"`, `"vertical"`, `"alwaysHorizontal"`, `"alwaysVertical"`, `"collapsible"`.
|
Значение ключа задаёт **ориентацию**: `"vertical"`, `"horizontalIfPossible"`, `"alwaysHorizontal"`.
|
||||||
|
|
||||||
| Ключ | Описание |
|
| Ключ | Описание |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
|
| `behavior` | Поведение группы: `"collapsible"` (сворачиваемая) / `"popup"` (всплывающая). Опустить = обычная |
|
||||||
| `showTitle: true` | Показывать заголовок группы |
|
| `showTitle: true` | Показывать заголовок группы |
|
||||||
| `united: false` | Левый край полей ввода выравнивается только в пределах этой группы (по умолчанию `true` — сквозное выравнивание по самому длинному заголовку, в т.ч. с соседними группами) |
|
| `united: false` | Левый край полей ввода выравнивается только в пределах этой группы (по умолчанию `true` — сквозное выравнивание по самому длинному заголовку, в т.ч. с соседними группами) |
|
||||||
| `collapsed: true` | Только для `"group": "collapsible"` — группа создаётся свёрнутой |
|
| `collapsed: true` | Для `behavior: "collapsible"` / `"popup"` — группа создаётся свёрнутой |
|
||||||
| `representation` | `"none"`, `"normal"`, `"weak"`, `"strong"` |
|
| `representation` | `"none"`, `"normal"`, `"weak"`, `"strong"` |
|
||||||
| `children: [...]` | Вложенные элементы |
|
| `children: [...]` | Вложенные элементы |
|
||||||
|
|
||||||
@@ -202,8 +203,8 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -
|
|||||||
| `height` | Высота в строках таблицы |
|
| `height` | Высота в строках таблицы |
|
||||||
| `header: false` | Скрыть шапку |
|
| `header: false` | Скрыть шапку |
|
||||||
| `footer: true` | Показать подвал |
|
| `footer: true` | Показать подвал |
|
||||||
| `commandBarLocation` | `"None"`, `"Top"`, `"Auto"` |
|
| `commandBarLocation` | `"None"`, `"Top"`, `"Bottom"`, `"Auto"` |
|
||||||
| `searchStringLocation` | `"None"`, `"Top"`, `"Auto"` |
|
| `searchStringLocation` | `"None"`, `"Top"`, `"Bottom"`, `"CommandBar"`, `"PullFromTop"`, `"Auto"` |
|
||||||
| `choiceMode: true` | Режим выбора (для форм выбора) |
|
| `choiceMode: true` | Режим выбора (для форм выбора) |
|
||||||
| `initialTreeView` | `"ExpandTopLevel"` и др. (иерархические списки) |
|
| `initialTreeView` | `"ExpandTopLevel"` и др. (иерархические списки) |
|
||||||
| `enableDrag: true` | Разрешить перетаскивание |
|
| `enableDrag: true` | Разрешить перетаскивание |
|
||||||
@@ -440,7 +441,7 @@ PictureField, привязанный к булеву/числу, рисует и
|
|||||||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "group": "horizontal", "name": "ГруппаФайл", "children": [
|
{ "group": "horizontal", "name": "ГруппаФайл", "children": [
|
||||||
{ "input": "ИмяФайла", "path": "ИмяФайла", "title": "Файл", "inputHint": "Выберите файл...", "choiceButton": true, "on": ["StartChoice"] },
|
{ "input": "ИмяФайла", "path": "ИмяФайла", "title": "Файл", "inputHint": "Выберите файл...", "choiceButton": true, "events": { "StartChoice": "ИмяФайлаНачалоВыбора" } },
|
||||||
{ "check": "ПерваяСтрокаЗаголовок", "path": "ПерваяСтрокаЗаголовок" }
|
{ "check": "ПерваяСтрокаЗаголовок", "path": "ПерваяСтрокаЗаголовок" }
|
||||||
]},
|
]},
|
||||||
{ "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true, "title": "Лог" },
|
{ "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true, "title": "Лог" },
|
||||||
@@ -500,8 +501,8 @@ PictureField, привязанный к булеву/числу, рисует и
|
|||||||
"title": "Просмотр данных",
|
"title": "Просмотр данных",
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "group": "horizontal", "name": "Фильтр", "children": [
|
{ "group": "horizontal", "name": "Фильтр", "children": [
|
||||||
{ "input": "Период", "path": "Период", "on": ["OnChange"] },
|
{ "input": "Период", "path": "Период", "events": { "OnChange": "ПериодПриИзменении" } },
|
||||||
{ "input": "Организация", "path": "Организация", "on": ["OnChange"] }
|
{ "input": "Организация", "path": "Организация", "events": { "OnChange": "ОрганизацияПриИзменении" } }
|
||||||
]},
|
]},
|
||||||
{ "table": "Данные", "path": "Данные", "changeRowSet": true, "columns": [
|
{ "table": "Данные", "path": "Данные", "changeRowSet": true, "columns": [
|
||||||
{ "input": "Дата", "path": "Данные.Дата" },
|
{ "input": "Дата", "path": "Данные.Дата" },
|
||||||
@@ -522,10 +523,26 @@ PictureField, привязанный к булеву/числу, рисует и
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Продвинутые конструкции (по необходимости)
|
||||||
|
|
||||||
|
Описанного выше хватает для большинства форм. Под конкретную задачу подгрузите файл из `references/`:
|
||||||
|
|
||||||
|
- `dynamic-list.md` — форма списка: источник, отбор, сортировка, группировки, параметры запроса
|
||||||
|
- `appearance.md` — условное и статическое оформление элементов (цвета/шрифты/рамки)
|
||||||
|
- `choice-params.md` — параметры и связи выбора у полей ввода
|
||||||
|
- `command-interface.md` — командный интерфейс формы
|
||||||
|
- `roles-access.md` — пользовательская видимость и доступ по ролям
|
||||||
|
- `companion-panels.md` — контент расширенной подсказки и контекстного меню
|
||||||
|
- `special-fields.md` — поля документа/датчика (HTML, текст, индикатор, ползунок)
|
||||||
|
- `charts.md` — диаграммы и планировщик
|
||||||
|
- `report-form.md` — свойства формы отчёта
|
||||||
|
- `type-system-advanced.md` — наборы и составные типы
|
||||||
|
- `table-advanced.md` — расширенные свойства таблиц
|
||||||
|
- `layout-advanced.md` — тонкая компоновка и геометрия
|
||||||
|
|
||||||
## Автогенерация
|
## Автогенерация
|
||||||
|
|
||||||
- **Companion-элементы**: ContextMenu, ExtendedTooltip и др. создаются автоматически
|
- **Companion-элементы**: ContextMenu, ExtendedTooltip и др. создаются автоматически
|
||||||
- **Обработчики событий**: `"on": ["OnChange"]` → `ОрганизацияПриИзменении`
|
|
||||||
- **Namespace**: все 17 namespace-деклараций
|
- **Namespace**: все 17 namespace-деклараций
|
||||||
- **ID**: последовательная нумерация, AutoCommandBar = id="-1"
|
- **ID**: последовательная нумерация, AutoCommandBar = id="-1"
|
||||||
- **Unknown keys**: выводится предупреждение о нераспознанных ключах
|
- **Unknown keys**: выводится предупреждение о нераспознанных ключах
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
# Оформление
|
||||||
|
|
||||||
|
Два независимых механизма: **оформление элемента** (постоянные цвета/шрифт/граница на конкретном элементе) и **условное оформление формы** (`conditionalAppearance` — правила, применяемые при выполнении условия).
|
||||||
|
|
||||||
|
## Оформление элемента (цвета / шрифты / граница)
|
||||||
|
|
||||||
|
Свойства задаются прямо на элементе. Применимо к полям (`input`/`check`/`radio`/`labelField`/`picField`/`calendar`), декорациям (`label`/`picture`), кнопкам (`button`), группам (`group`/`columnGroup`), страницам (`page`/`pages`), попапам (`popup`) и таблицам (`table`). Каждое свойство необязательно.
|
||||||
|
|
||||||
|
| Ключ | Что задаёт |
|
||||||
|
|------|-----------|
|
||||||
|
| `textColor` | Цвет текста |
|
||||||
|
| `backColor` | Цвет фона |
|
||||||
|
| `borderColor` | Цвет рамки |
|
||||||
|
| `font` | Шрифт |
|
||||||
|
| `border` | Граница |
|
||||||
|
| `titleTextColor` / `titleBackColor` / `titleFont` | Цвет текста / цвет фона / шрифт заголовка колонки (`labelField`, колонки таблицы); у `page`/`pages`/`popup` — `titleTextColor`/`titleFont` заголовка страницы/попапа |
|
||||||
|
| `footerTextColor` / `footerBackColor` / `footerFont` | Цвет текста / цвет фона / шрифт подвала колонки |
|
||||||
|
|
||||||
|
Те же свойства доступны и через словарь `appearance` элемента — под русскими именами параметров платформы: `ЦветТекста`, `ЦветФона`, `ЦветРамки`, `Шрифт`, `Граница`, `ЦветТекстаЗаголовка`, `ЦветФонаЗаголовка`, `ШрифтЗаголовка`, `ЦветТекстаПодвала`, `ЦветФонаПодвала`, `ШрифтПодвала`. Это та же запись, что и в правилах условного оформления (ниже) и в `appearance` поля дин-списка.
|
||||||
|
|
||||||
|
### Цвет
|
||||||
|
|
||||||
|
Строка в одной из форм:
|
||||||
|
|
||||||
|
| Форма | Значение |
|
||||||
|
|-------|----------|
|
||||||
|
| `web:Имя` | Цвет из web-палитры, напр. `web:Red`, `web:FireBrick`, `web:HoneyDew` |
|
||||||
|
| `win:Имя` | Системный цвет Windows, напр. `win:MenuBar`, `win:ButtonText`, `win:DisabledText` |
|
||||||
|
| `style:ИмяСтиля` | Ссылка на элемент стиля конфигурации/платформы, напр. `style:FormBackColor`, `style:BorderColor` |
|
||||||
|
| `#RRGGBB` | RGB-hex, напр. `#FF0000` |
|
||||||
|
|
||||||
|
Имя должно существовать в своей палитре (несуществующий web-/win-цвет или ссылка на отсутствующий `style:`-элемент — ошибка загрузки формы).
|
||||||
|
|
||||||
|
### Шрифт (`font` / `titleFont` / `footerFont`)
|
||||||
|
|
||||||
|
- Строка `"style:ИмяСтиля"` — шрифт из элемента стиля. Минимальная форма.
|
||||||
|
- Объект — задаются только нужные атрибуты:
|
||||||
|
|
||||||
|
| Ключ | Назначение |
|
||||||
|
|------|-----------|
|
||||||
|
| `ref` | Ссылка на стиль (`"style:X"`) или системный шрифт (`"sys:…"`) |
|
||||||
|
| `faceName` | Имя гарнитуры (для собственного шрифта) |
|
||||||
|
| `height` | Размер |
|
||||||
|
| `bold` / `italic` / `underline` / `strikeout` | `true`/`false` — начертание |
|
||||||
|
| `scale` | Масштаб, % |
|
||||||
|
| `kind` | `Absolute` (собственный шрифт — с `faceName`+`height`) / `WindowsFont` (системный — с `ref:"sys:…"`) |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "label": "Внимание!", "textColor": "web:FireBrick",
|
||||||
|
"font": { "faceName": "Arial", "height": 12, "bold": true, "kind": "Absolute", "scale": 100 } }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Граница (`border`)
|
||||||
|
|
||||||
|
- Строка `"style:ИмяСтиля"` (или объект `{ "ref": "style:X" }`) — граница из стиля.
|
||||||
|
- Объект `{ "width": N, "style": "..." }` — собственная граница. `style` — один из: `Single`, `Double`, `Underline`, `DoubleUnderline`, `Overline`, `Embossed`, `Indented`, `WithoutBorder`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Цена", "path": "Объект.Цена", "textColor": "#FF0000",
|
||||||
|
"borderColor": "style:BorderColor", "border": { "width": 1, "style": "Single" } }
|
||||||
|
{ "labelField": "Код", "titleTextColor": "web:HoneyDew", "border": "style:ControlBorder" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Условное оформление формы (`conditionalAppearance`)
|
||||||
|
|
||||||
|
Форменный ключ верхнего уровня — массив правил. Каждое правило применяет оформление к перечисленным полям, когда выполняется его условие.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"conditionalAppearance": [
|
||||||
|
{ "selection": ["ОбычноеПоле"], "filter": ["ЧисловоеПоле > 100"],
|
||||||
|
"appearance": { "ЦветФона": "style:FormBackColor" },
|
||||||
|
"presentation": { "ru": "Подсветка", "en": "Highlight" } }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `selection` | array | Имена форматируемых полей формы |
|
||||||
|
| `filter` | array | Условие применения (грамматика — ниже) |
|
||||||
|
| `appearance` | object | Словарь «параметр платформы: значение» |
|
||||||
|
| `presentation` | string / object | Подпись правила в списке настроек |
|
||||||
|
| `use` | bool | `false` — правило отключено |
|
||||||
|
| `viewMode` | string | Режим отображения настройки |
|
||||||
|
| `userSettingID` | string | Идентификатор пользовательской настройки; `"auto"` — сгенерировать |
|
||||||
|
|
||||||
|
### filter
|
||||||
|
|
||||||
|
Та же грамматика, что в отборе списка — shorthand `"Поле оператор значение @флаги"` или объект:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"filter": [
|
||||||
|
"Статус = 3",
|
||||||
|
{ "field": "Сумма", "op": ">=", "value": 1000 },
|
||||||
|
{ "group": "Or", "items": [ "Просрочено = true", "Заблокирован = true" ] }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Операторы:** `=` `<>` `>` `>=` `<` `<=`, `in` / `notIn`, `inHierarchy`, `contains` / `notContains`, `beginsWith` / `notBeginsWith`, `like` / `notLike` (`%`-шаблон), `filled` / `notFilled`.
|
||||||
|
- **Флаги:** `@off` (отключён), `@user`, `@quickAccess`; `_` = пустое значение.
|
||||||
|
- **Группа:** `{ "group": "And"|"Or"|"Not", "items": [...], "use"? }`.
|
||||||
|
- **Дата-значение:** ISO-дата `"2024-01-01T00:00:00"` — фиксированная дата; именованный относительный период — строкой `"BeginningOfThisWeek"` с `"valueType": "v8:StandardBeginningDate"` (варианты `BeginningOfThisDay`/`BeginningOfThisWeek`/`BeginningOfThisMonth`/`BeginningOfThisYear`/…).
|
||||||
|
|
||||||
|
### appearance
|
||||||
|
|
||||||
|
Словарь «параметр платформы: значение». Имена параметров — русские: `ЦветТекста`, `ЦветФона`, `Шрифт`, `Граница`, `Текст`, `Заголовок`, `Формат`, `ВидимостьЭлемента`, `Доступность` и другие параметры оформления компоновки.
|
||||||
|
|
||||||
|
Значения:
|
||||||
|
- **Цвет** (`ЦветТекста`/`ЦветФона`/…) и **шрифт** (`Шрифт`) — те же формы, что в оформлении элемента выше (`web:`/`win:`/`style:`/`#RRGGBB`; шрифт — строка `"style:X"` или объект).
|
||||||
|
- **Текстовые параметры** (`Текст`/`Заголовок`/`Формат`) — по форме значения:
|
||||||
|
- голая строка → нелокализованный литерал (`""` → пустое значение);
|
||||||
|
- объект `{ "ru": "...", "en": "..." }` → локализуемая строка;
|
||||||
|
- объект `{ "field": "путь" }` → ссылка на поле компоновки.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"conditionalAppearance": [
|
||||||
|
{ "selection": ["Остаток"], "filter": ["Остаток < 0"],
|
||||||
|
"appearance": { "ЦветТекста": "web:Red", "Шрифт": { "bold": true } } },
|
||||||
|
{ "selection": ["Комментарий"], "filter": ["Комментарий notFilled"],
|
||||||
|
"appearance": { "Текст": { "ru": "— нет данных —" }, "ЦветТекста": "win:DisabledText" } }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
> Условное оформление **самого дин-списка** задаётся не здесь, а в `settings.conditionalAppearance` реквизита-списка — см. `references/dynamic-list.md`.
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
# Диаграммы, диаграмма Ганта, планировщик
|
||||||
|
|
||||||
|
Поле-диаграмма (`chart` / `ganttChart`), поле-планировщик (`planner`) и дендрограмма выводят значение из реквизита соответствующего типа. Конструкция всегда двойная:
|
||||||
|
|
||||||
|
1. **Реквизит** chart/planner-типа (несёт данные и, при необходимости, design-time конфиг).
|
||||||
|
2. **Элемент** формы, привязанный к реквизиту через `path`.
|
||||||
|
|
||||||
|
Минимум — реквизит нужного типа плюс элемент с тем же `path`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"attributes": [ { "name": "Диаграмма", "type": "d5p1:Chart" } ],
|
||||||
|
"items": [ { "chart": "ПолеДиаграммы", "path": "Диаграмма" } ]
|
||||||
|
```
|
||||||
|
|
||||||
|
Реквизит, заполняемый в коде (без встроенной настройки), достаточно объявить типом — элемент привязывается и работает.
|
||||||
|
|
||||||
|
## Типы реквизита и элемента
|
||||||
|
|
||||||
|
| Элемент | Ключ типа | Тип реквизита | Что несёт элемент дополнительно |
|
||||||
|
|---------|-----------|---------------|---------------------------------|
|
||||||
|
| Диаграмма | `chart` | `d5p1:Chart` | — |
|
||||||
|
| Диаграмма Ганта | `ganttChart` | `d5p1:GanttChart` | `ganttTable` — вложенная таблица (см. ниже) |
|
||||||
|
| Планировщик | `planner` | `pl:Planner` | — |
|
||||||
|
| График. схема | `graphicalSchema` | `d5p1:FlowchartContextType` | `edit`, `warningOnEditRepresentation` |
|
||||||
|
| Период | `periodField` | `v8:StandardPeriod` | — |
|
||||||
|
| Дендрограмма | `dendrogram` | — | — |
|
||||||
|
|
||||||
|
Имя элемента — значение ключа (`"chart": "ПолеДиаграммы"`); `path` — короткое имя реквизита.
|
||||||
|
|
||||||
|
### Элемент диаграммы Ганта (`ganttTable`)
|
||||||
|
|
||||||
|
У поля Ганта внутри лежит полноценная таблица — задаётся ключом `ganttTable` (та же грамматика, что у обычной `table`):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "ganttChart": "Ганта", "path": "Ганта",
|
||||||
|
"ganttTable": { "table": "ТаблицаГанта", "path": "Ганта", "height": 3 } }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Design-time конфиг диаграммы (`chart`)
|
||||||
|
|
||||||
|
Реквизит типа `d5p1:Chart` / `d5p1:GanttChart` может нести встроенную настройку диаграммы — объект `chart` на реквизите. Платформа всегда пишет полный набор свойств (~127: тип, серии, легенда, заголовок, шкалы, цвета, шрифты, оси), поэтому **авторинг с нуля непрактичен** — возьмите рабочую диаграмму за основу и правьте смысловое ядро.
|
||||||
|
|
||||||
|
Ключи `chart` = канонические имена свойств диаграммы; задавайте только те, что меняете:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Диаграмма", "type": "d5p1:Chart", "chart": {
|
||||||
|
"chartType": "Line",
|
||||||
|
"isSeriesDesign": true, "realSeriesCount": "2",
|
||||||
|
"realSeriesData": [
|
||||||
|
{ "id": "1", "color": "auto", "line": {"width":2,"gap":false,"style":"Solid"},
|
||||||
|
"marker": "Auto", "text": "Серия 1", "strIsChanged": false, "isExpand": false,
|
||||||
|
"isIndicator": false, "colorPriority": false }
|
||||||
|
],
|
||||||
|
"isShowTitle": true, "title": "Продажи",
|
||||||
|
"isShowLegend": true, "legendPlacement": "Bottom",
|
||||||
|
"paletteKind": "Auto"
|
||||||
|
} }
|
||||||
|
```
|
||||||
|
|
||||||
|
Смысловое ядро для правки:
|
||||||
|
|
||||||
|
| Ключ | Назначение |
|
||||||
|
|------|------------|
|
||||||
|
| `chartType` | Тип: `Line` / `Pie` / `Bar` / `Histogram` / `Column` / `Area` / … |
|
||||||
|
| `realSeriesData` | Массив серий — объекты `{ id, text, color, line, marker, … }` |
|
||||||
|
| `isShowTitle` + `title` | Показ и текст заголовка |
|
||||||
|
| `isShowLegend` + `legendPlacement` | Показ и расположение легенды (`Bottom` / `Right` / …) |
|
||||||
|
| `paletteKind` | Палитра (`Auto` / …) |
|
||||||
|
| `bkgColor` / `labelsColor` / … | Базовые цвета |
|
||||||
|
|
||||||
|
Формы значений внутри `chart`:
|
||||||
|
|
||||||
|
- **Цвета** — verbatim: `auto`, `style:ИмяСтиля`, `web:Red`, `#hex`.
|
||||||
|
- **`line`** — `{ width, gap, style }` (стиль линии: `Solid` / …).
|
||||||
|
- **`border`** — `{ width, style }`.
|
||||||
|
- **`font`** — `{ kind: "AutoFont" }` либо атрибуты шрифта.
|
||||||
|
- **Локализуемые строки** (`title`, `vsFormat`, `lbFormat`, `labelFormat`, серия `text`, …) — голая строка либо `{ "ru": "…", "en": "…" }`.
|
||||||
|
- **Области** (`elementsChart` / `elementsLegend` / `elementsTitle`) — `{ left, right, top, bottom }`.
|
||||||
|
- **Серии** (`realSeriesData` / `realExSeriesData`) — массивы объектов.
|
||||||
|
|
||||||
|
Любое из ~127 свойств переопределяется по каноническому имени; остальное оставляйте дефолтным (не указывайте — берётся из основы).
|
||||||
|
|
||||||
|
### Диаграмма Ганта (`d5p1:GanttChart`)
|
||||||
|
|
||||||
|
Реквизит типа `d5p1:GanttChart` использует **тот же** ключ `chart`. Внутри — вложенный полный `chart`-блок плюс гант-специфика (`points` / `series` / `timeScale` / `drawEmpty` / …). Так же берите рабочую диаграмму Ганта за основу.
|
||||||
|
|
||||||
|
> **Ограничение.** Диаграммы (Chart/Gantt) с заполненными **точками/осями** (`realPointData` / `realDataItems`, заполненные `valuesAxis` / `pointsAxis`) генерик-движком не поддержаны — это редкий вариант. Частые дашборд-диаграммы и диаграммы Ганта (серии / легенда / оформление / шкалы) поддержаны полностью.
|
||||||
|
|
||||||
|
## Design-time конфиг планировщика (`planner`)
|
||||||
|
|
||||||
|
Реквизит типа `pl:Planner` несёт встроенную настройку планировщика — объект `planner`. Компилятор подставляет умолчания для пропущенных ключей, поэтому авторинг может быть кратким:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Планировщик", "type": "pl:Planner", "planner": {
|
||||||
|
"items": [
|
||||||
|
{ "text": "Встреча", "begin": "2026-06-09T01:00:00", "end": "2026-06-09T04:00:00",
|
||||||
|
"borderColor": "auto", "backColor": "auto", "deleted": false, "editMode": "EnableEdit" }
|
||||||
|
],
|
||||||
|
"period": { "begin": "2026-06-09T00:00:00", "end": "2026-06-09T23:59:59" },
|
||||||
|
"displayCurrentDate": true, "itemsTimeRepresentation": "BeginTime",
|
||||||
|
"timeScale": { "placement": "Left", "levels": [ { "measure": "Hour", "interval": 1 } ] }
|
||||||
|
} }
|
||||||
|
```
|
||||||
|
|
||||||
|
Минимум — один `item`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"planner": { "items": [ { "text": "Встреча", "begin": "2026-06-09T01:00:00", "end": "2026-06-09T04:00:00" } ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ `planner` | Тип | Назначение |
|
||||||
|
|----------------|-----|------------|
|
||||||
|
| `items` | array | Элементы расписания. Поля элемента: `text`, `tooltip`, `begin`, `end`, `value`, `borderColor`, `backColor`, `textColor`, `font`, `border`, `replacementDate`, `deleted` (bool), `editMode` (`EnableEdit` / …), `id` (необязательно — авто-GUID), `textFormatted` |
|
||||||
|
| `dimensions` | array | Измерения (разрезы) планировщика. Поля: `value` (объект разреза — ссылка `Enum.X.EnumValue.Y` / `Справочник.X`; опустить → пусто), `text` (заголовок), `borderColor`, `backColor`, `textColor`, `font`, `textFormatted`, `elements`. `elements` — элементы измерения, рекурсивны (могут нести вложенные `elements`): `value`, `text`, цвета, `font`, `showOnlySubordinatesAreas` (bool), `textFormatted` |
|
||||||
|
| `period` | object | Отображаемый период `{ begin, end }` (необязательно) |
|
||||||
|
| `timeScale` | object | Шкала времени (см. ниже) |
|
||||||
|
| `borderColor` / `backColor` / `textColor` / `lineColor` | color | Цвета (умолч. `auto`) |
|
||||||
|
| `font` | font | Шрифт (умолч. `{ kind: "AutoFont" }`) |
|
||||||
|
| `border` | border | Рамка `{ width, style }` |
|
||||||
|
| `beginOfRepresentationPeriod` / `endOfRepresentationPeriod` | dateTime | Период представления |
|
||||||
|
| `displayCurrentDate` / `displayWrapHeaders` / `displayTimeScaleWrapHeaders` / `alignElementsOfTimeScale` | bool | Флаги отображения |
|
||||||
|
| `timeScaleWrapHeadersFormat` | ML | Формат перенесённых заголовков шкалы |
|
||||||
|
| `timeScaleWrapBeginIndent` / `timeScaleWrapEndIndent` | int | Отступы переноса шкалы |
|
||||||
|
| `periodicVariantUnit` / `periodicVariantRepetition` | value / int | Единица и кратность периодического варианта |
|
||||||
|
| `itemsTimeRepresentation` | value | Представление времени элементов (`BeginTime` / …) |
|
||||||
|
| `itemsBehaviorWhenSpaceInsufficient` / `newItemsTextType` / `fixDimensionsHeader` / `fixTimeScaleHeader` | value | Поведение элементов и заголовков |
|
||||||
|
| `autoMinColumnWidth` / `autoMinRowHeight` | bool | Авто-минимум размеров |
|
||||||
|
| `minColumnWidth` / `minRowHeight` | int | Минимальные размеры |
|
||||||
|
|
||||||
|
Шкала времени (`timeScale`):
|
||||||
|
|
||||||
|
```json
|
||||||
|
"timeScale": {
|
||||||
|
"placement": "Left",
|
||||||
|
"levels": [ { "measure": "Hour", "interval": 1 } ]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключи: `placement`, `levels` (массив уровней), `transparent`, `backColor`, `textColor`, `currentLevel`. Уровень: `measure` (`Hour` / `Day` / …), `interval`, `show`, `line` (`{ width, gap, style }`), `scaleColor`, `dayFormatRule`, `format` (ML), `labels` (`{ ticks }`), `backColor`, `textColor`, `showPereodicalLabels`.
|
||||||
|
|
||||||
|
Формы значений в `planner` те же, что у диаграммы: цвета verbatim (`auto` / `style:X` / `web:Red` / `#hex`); шрифт `{ kind: "AutoFont" }` либо ref-строка; граница `{ width, style }`; ML-форматы — строка или `{ "ru": …, "en": … }`.
|
||||||
|
|
||||||
|
> **Ограничение.** Привязка элемента расписания к элементам измерений (`item.dimensionValues`) пока всегда пустая. Сами измерения (`dimensions`) задавать можно.
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Параметры выбора и связь по типу
|
||||||
|
|
||||||
|
Свойства поля ввода (`input`), управляющие выбором значения: чем ограничен список выбора и каким будет тип значения. Имена параметров — строки 1С как есть (`"Отбор.Х"`).
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Контрагент", "path": "Объект.Контрагент",
|
||||||
|
"choiceParameters": [
|
||||||
|
{ "name": "Отбор.Активный", "value": true },
|
||||||
|
{ "name": "Отбор.ВидПродукции", "value": ["Enum.Виды.Агрохимикат", "Enum.Виды.Пестицид"] }
|
||||||
|
],
|
||||||
|
"choiceParameterLinks": [
|
||||||
|
{ "name": "Отбор.Организация", "dataPath": "Объект.Организация" },
|
||||||
|
{ "name": "Отбор.Тип", "dataPath": "Объект.Тип", "valueChange": "DontChange" }
|
||||||
|
],
|
||||||
|
"typeLink": { "dataPath": "Объект.ЗначениеДата", "linkItem": 0 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Параметры выбора (`choiceParameters`)
|
||||||
|
|
||||||
|
Фиксированные значения параметров выбора, отбирающие список значений независимо от данных формы. Массив объектов `{ name, value }`:
|
||||||
|
|
||||||
|
- `name` — имя параметра (`"Отбор.Активный"`).
|
||||||
|
- `value` — значение. Допустимы: bool, число, строка, ISO-дата (`"2020-01-01T00:00:00"`), ссылка-путь (`Enum.X.Y`, `Catalog.X`). **Массив** значений задаёт фиксированный массив.
|
||||||
|
|
||||||
|
Короткая форма — строки `"name=value"`; значение с запятыми становится массивом, `true`/`false` → bool, число → число, остальное → строка/ссылка:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"choiceParameters": [
|
||||||
|
"Отбор.Активный=true",
|
||||||
|
"Отбор.ВидПродукции=Enum.Виды.Агрохимикат, Enum.Виды.Пестицид"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Связи параметров выбора (`choiceParameterLinks`)
|
||||||
|
|
||||||
|
Параметры выбора, значение которых берётся из **другого поля формы** (а не задано фиксированно). Типовой случай — отбор списка договоров по выбранному контрагенту. Массив объектов `{ name, dataPath, valueChange? }`:
|
||||||
|
|
||||||
|
- `name` — имя параметра выбора.
|
||||||
|
- `dataPath` — путь к полю формы, чьё значение подставляется в параметр.
|
||||||
|
- `valueChange` — что делать с уже выбранным значением при смене источника: `Clear` (очистить, необязательно — поведение по умолчанию) / `DontChange` (не менять).
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Договор", "path": "Объект.Договор",
|
||||||
|
"choiceParameterLinks": [
|
||||||
|
{ "name": "Отбор.Владелец", "dataPath": "Объект.Контрагент" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Короткая форма — строки `"name=dataPath"`, опциональный хвост `:Clear` / `:DontChange`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"choiceParameterLinks": [ "Отбор.Организация=Объект.Организация", "Отбор.Тип=Объект.Тип:DontChange" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Связь по типу (`typeLink`)
|
||||||
|
|
||||||
|
Тип значения поля определяется другим полем формы (напр. поле «Значение» субконто, тип которого задаётся выбранным видом субконто). Объект `{ dataPath, linkItem }`:
|
||||||
|
|
||||||
|
- `dataPath` — путь к полю, задающему тип.
|
||||||
|
- `linkItem` — индекс элемента связи (необязательно, по умолчанию `0`).
|
||||||
|
|
||||||
|
```json
|
||||||
|
"typeLink": { "dataPath": "Объект.ВидСубконто", "linkItem": 0 }
|
||||||
|
```
|
||||||
|
|
||||||
|
Короткая форма — строка `"dataPath"` либо `"dataPath#linkItem"`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"typeLink": "Объект.ВидСубконто"
|
||||||
|
"typeLink": "Объект.ВидСубконто#1"
|
||||||
|
```
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# Командный интерфейс формы
|
||||||
|
|
||||||
|
Форменный ключ `commandInterface` управляет расстановкой команд по двум панелям формы:
|
||||||
|
|
||||||
|
- `commandBar` — командная панель формы;
|
||||||
|
- `navigationPanel` — панель навигации.
|
||||||
|
|
||||||
|
Указывать нужно **только команды, у которых меняется расстановка по умолчанию** (видимость, группа, порядок). Команды, которые платформа размещает автоматически и без изменений, в блок не включают.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"commandInterface": {
|
||||||
|
"commandBar": [
|
||||||
|
{ "command": "Form.Command.Печать", "defaultVisible": false, "group": "FormCommandBarImportant",
|
||||||
|
"visible": { "common": false, "roles": { "Бухгалтер": true } } },
|
||||||
|
"CommonCommand.История"
|
||||||
|
],
|
||||||
|
"navigationPanel": {
|
||||||
|
"important": [ { "command": "CommonCommand.СвязанныеДокументы", "defaultVisible": false, "visible": false } ],
|
||||||
|
"seeAlso": [ { "command": "CommonCommand.Заметки", "defaultVisible": false, "visible": false } ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Элемент-команда
|
||||||
|
|
||||||
|
Каждый элемент панели — объект, либо строка-shorthand (= голый `command` со всеми остальными свойствами по умолчанию):
|
||||||
|
|
||||||
|
```json
|
||||||
|
"CommonCommand.История"
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `command` | string | Ссылка на команду дословно: `CommonCommand.X`, `Document.X.StandardCommand.Y`, `Form.Command.X`, `Form.StandardCommand.OK`, `"0"` (пустой / разделитель) |
|
||||||
|
| `type` | string | `Auto` (по умолчанию, необязательно) или `Added` |
|
||||||
|
| `defaultVisible` | bool | Видимость по умолчанию. На практике задаётся только `false` — чтобы скрыть команду, которая иначе видна |
|
||||||
|
| `visible` | bool / object | Видимость с исключениями по ролям: `bool` либо `{ "common": bool, "roles": { "Имя": bool } }` |
|
||||||
|
| `group` | string | Группа размещения дословно: предопределённая (`FormCommandBarImportant`, `FormNavigationPanelGoTo`, …), именованная (`CommandGroup.X`) или GUID-группа расширения |
|
||||||
|
| `index` | int | Порядок команды внутри группы |
|
||||||
|
| `attribute` | string | Путь реквизита для элемента панели навигации |
|
||||||
|
|
||||||
|
## Две формы записи панели
|
||||||
|
|
||||||
|
Панель можно описать **плоским массивом** или **деревом по группам** — выбирайте любую.
|
||||||
|
|
||||||
|
**Плоский массив** — каждый элемент при необходимости несёт собственный `group`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"commandBar": [
|
||||||
|
{ "command": "Form.Command.Печать", "group": "FormCommandBarImportant", "defaultVisible": false },
|
||||||
|
{ "command": "CommonCommand.История", "group": "FormCommandBarImportant", "index": 1 }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Дерево** — объект `{ группа: [команды] }`; группа берётся из ключа, элементы её не повторяют:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"navigationPanel": {
|
||||||
|
"important": [ "CommonCommand.СвязанныеДокументы" ],
|
||||||
|
"goTo": [ { "command": "Document.Заказ.StandardCommand.Movements", "defaultVisible": false, "visible": false } ],
|
||||||
|
"seeAlso": [ "CommonCommand.Заметки" ]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключи-группы дерева зависят от панели:
|
||||||
|
|
||||||
|
- `navigationPanel`: `important`, `goTo`, `seeAlso` (можно по-русски — `важное`, `перейти`, `смТакже`);
|
||||||
|
- `commandBar`: `important`, `createBasedOn`;
|
||||||
|
- любой другой ключ (`CommandGroup.X` или GUID) подставляется в группу дословно.
|
||||||
|
|
||||||
|
## Скрыть видимую команду
|
||||||
|
|
||||||
|
Самый частый случай — убрать команду, которую платформа показывает по умолчанию:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"commandBar": [
|
||||||
|
{ "command": "Form.Command.Печать", "defaultVisible": false, "visible": false }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Показать команду только некоторым ролям:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "command": "Form.Command.Печать", "defaultVisible": false,
|
||||||
|
"visible": { "common": false, "roles": { "Бухгалтер": true } } }
|
||||||
|
```
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
# Companion-панели и расширенная подсказка элемента
|
||||||
|
|
||||||
|
Любой элемент формы может нести свой собственный контент в трёх companion-свойствах: расширенную подсказку (`extendedTooltip`), командную панель (`commandBar`) и контекстное меню (`contextMenu`). Все три задаются ключами прямо на объекте элемента.
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{ "table": "Список", "path": "Список",
|
||||||
|
"commandBar": { "children": [ … ] },
|
||||||
|
"contextMenu": { "children": [ … ] },
|
||||||
|
"extendedTooltip": "Двойной клик открывает карточку" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Расширенная подсказка (`extendedTooltip`)
|
||||||
|
|
||||||
|
Подсказка-надпись рядом с элементом. Две формы записи.
|
||||||
|
|
||||||
|
**Текст-форма** — просто текст подсказки:
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
"extendedTooltip": "Укажите ИНН контрагента"
|
||||||
|
"extendedTooltip": { "ru": "Сумма с НДС", "en": "Amount incl. VAT" }
|
||||||
|
"extendedTooltip": { "text": "Всего <b>с НДС</b>", "formatted": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
- строка — ru-текст;
|
||||||
|
- `{ "ru": …, "en": … }` — многоязычный (как `title`);
|
||||||
|
- `{ "text": …, "formatted": true }` — форматированный текст (inline-разметка 1С: `<b>…</>`, `<i>`, `<u>`, `<color web:Red>…</>`, `<bgColor …>`, `<font …>`, `<fontSize …>`, `<link URL>…</>`, `<img …>`; закрывающий тег — `</>`). `formatted` нужен только когда текст содержит такую разметку.
|
||||||
|
|
||||||
|
**Own-content форма** — объект с раскладкой/оформлением/флагами, когда подсказке нужны размеры, цвет, гиперссылка и т.п.:
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
"extendedTooltip": {
|
||||||
|
"text": "Перейти к инструкции",
|
||||||
|
"hyperlink": true,
|
||||||
|
"textColor": "web:Blue",
|
||||||
|
"events": { "URLProcessing": "ПодсказкаОбработкаНавигационнойСсылки" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключи own-content объекта (все необязательны):
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `text` | string/ML | Текст подсказки (с `formatted` — форматированный) |
|
||||||
|
| `formatted` | bool | Интерпретировать inline-разметку в `text` |
|
||||||
|
| `tooltip` | string/ML | Всплывающая подсказка самой расширенной подсказки (редко; ≠ обычному `tooltip` элемента) |
|
||||||
|
| `hyperlink` | bool | Сделать подсказку гиперссылкой |
|
||||||
|
| `visible` / `enabled` | bool | Видимость / доступность подсказки |
|
||||||
|
| `width` / `height` | number | Размеры |
|
||||||
|
| `maxWidth` / `autoMaxWidth` | number / bool | Максимальная ширина / авто-максимум |
|
||||||
|
| `titleHeight` | number | Высота заголовка |
|
||||||
|
| `horizontalStretch` | bool | Горизонтальное растяжение |
|
||||||
|
| `verticalAlign` | string | Вертикальное выравнивание |
|
||||||
|
| `textColor` / `font` | string/object | Цвет текста / шрифт (см. `references/appearance.md`) |
|
||||||
|
| `events` | object | Обработчики событий подсказки, напр. `{ "URLProcessing": "Имя" }` у гиперссылочной подсказки |
|
||||||
|
|
||||||
|
## Командная панель (`commandBar`)
|
||||||
|
|
||||||
|
Собственная командная панель элемента (обычно таблицы или группы).
|
||||||
|
|
||||||
|
**Значение** — массив или объект:
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
"commandBar": [ { "button": "Создать", "command": "СоздатьЭлемент" } ]
|
||||||
|
|
||||||
|
"commandBar": {
|
||||||
|
"autofill": false,
|
||||||
|
"horizontalAlign": "Right",
|
||||||
|
"children": [
|
||||||
|
{ "button": "Создать", "command": "СоздатьЭлемент" },
|
||||||
|
{ "buttonGroup": "Печать", "children": [ … ] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- массив `[ … ]` — краткая запись для `{ "children": [ … ] }`;
|
||||||
|
- объект — `children` плюс необязательные `autofill` и `horizontalAlign`.
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `children` | array | Содержимое панели — обычная грамматика кнопок (см. основную инструкцию) |
|
||||||
|
| `autofill` | bool | `false` — подавить автозаполнение панели стандартными командами. Необязательно (по умолчанию панель автозаполняется) |
|
||||||
|
| `horizontalAlign` | string | Горизонтальное выравнивание содержимого: `Left` / `Center` / `Right`. Необязательно |
|
||||||
|
|
||||||
|
`children` — кнопки: `button` (с `command` / `commandName` / `stdCommand`), `buttonGroup`, `popup` — как в основной инструкции по кнопкам.
|
||||||
|
|
||||||
|
> Для таблицы динамического списка панель по умолчанию подавлена (чтобы не дублировать командную панель формы). Чтобы оставить автозаполняемую панель у самой таблицы — задайте `commandBar: { "autofill": true }`.
|
||||||
|
|
||||||
|
## Контекстное меню (`contextMenu`)
|
||||||
|
|
||||||
|
Собственное контекстное меню элемента. Грамматика та же, что у `commandBar`, но без `horizontalAlign`.
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
"contextMenu": [ { "button": "Карта маршрута", "commandName": "CommonCommand.КартаМаршрута" } ]
|
||||||
|
|
||||||
|
"contextMenu": {
|
||||||
|
"autofill": false,
|
||||||
|
"children": [
|
||||||
|
{ "button": "Скопировать ссылку", "command": "СкопироватьСсылку" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `children` | array | Пункты меню — обычная грамматика кнопок |
|
||||||
|
| `autofill` | bool | `false` — подавить автозаполнение меню. Необязательно |
|
||||||
|
|
||||||
|
## Пример: таблица со своим меню и инфо-баннером
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{ "table": "Заказы", "path": "Объект.Заказы",
|
||||||
|
"extendedTooltip": {
|
||||||
|
"text": "Строки с просрочкой выделены <color web:FireBrick>красным</>",
|
||||||
|
"formatted": true
|
||||||
|
},
|
||||||
|
"commandBar": {
|
||||||
|
"autofill": false,
|
||||||
|
"horizontalAlign": "Right",
|
||||||
|
"children": [
|
||||||
|
{ "button": "Добавить", "command": "ДобавитьЗаказ" },
|
||||||
|
{ "button": "Удалить", "command": "УдалитьЗаказ" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"contextMenu": {
|
||||||
|
"children": [
|
||||||
|
{ "button": "Открыть документ", "command": "ОткрытьЗаказ" },
|
||||||
|
{ "buttonGroup": "Экспорт", "children": [
|
||||||
|
{ "button": "В Excel", "command": "ВыгрузитьВExcel" } ] }
|
||||||
|
]
|
||||||
|
} }
|
||||||
|
```
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
# Динамический список
|
||||||
|
|
||||||
|
Реквизит с `type: "DynamicList"` (обычно `main: true`) — основа формы списка. Объект `settings` описывает источник данных и настройки списка. Минимум — указать источник:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Список", "type": "DynamicList", "main": true,
|
||||||
|
"settings": { "mainTable": "Catalog.Контрагенты" } }
|
||||||
|
```
|
||||||
|
|
||||||
|
К списку привязывается таблица-элемент (`table`), ссылающаяся на реквизит через `path` — см. основную инструкцию.
|
||||||
|
|
||||||
|
## Источник данных
|
||||||
|
|
||||||
|
Два взаимоисключающих режима:
|
||||||
|
|
||||||
|
**Таблично-ориентированный** — основная таблица метаданных:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"settings": { "mainTable": "Catalog.Контрагенты" }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Запросный** — произвольный запрос:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"settings": {
|
||||||
|
"query": "ВЫБРАТЬ Т.Ссылка, Т.Наименование, Т.Сумма ИЗ Документ.Заказ КАК Т ГДЕ Т.Сумма > &Порог",
|
||||||
|
"mainTable": "Document.Заказ"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `mainTable` | string | Основная таблица (`Catalog.X` / `Document.X` / …). Можно вместе с `query` |
|
||||||
|
| `query` | string | Текст запроса. Поддерживает `@file.sql` (путь к файлу запроса рядом с JSON) |
|
||||||
|
| `keyType` | string | Запросный список без `mainTable`: тип ключа набора — `FieldValue` / `RowKey` / `RowNumber` |
|
||||||
|
| `keyFields` | array | Поля ключа набора (для `keyType` без `mainTable`) |
|
||||||
|
|
||||||
|
Параметры запроса (`&Имя`) задаются в `parameters` (ниже).
|
||||||
|
|
||||||
|
`"dynamicDataRead": false` отключает динамическое считывание (список читается обычным запросом, без фонового обновления) — нужно для тяжёлых/агрегатных запросов.
|
||||||
|
|
||||||
|
## Параметры запроса (`parameters`)
|
||||||
|
|
||||||
|
Значения для `&параметров` текста запроса. Shorthand `"Имя [Заголовок]: тип = Значение"` (всё кроме имени необязательно) либо объект:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"settings": {
|
||||||
|
"query": "… ГДЕ Т.Артикул = &Артикул И Т.Цена ПОДОБНО &Маска",
|
||||||
|
"parameters": [
|
||||||
|
"Артикул",
|
||||||
|
"Маска: string = %",
|
||||||
|
{ "name": "ВидЦен", "valueListAllowed": true },
|
||||||
|
{ "name": "Период", "type": "dateTime" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключи объекта: `name`, `title`, `type` (грамматика типов — см. основную инструкцию), `value`, `valueListAllowed` (разрешить список значений), `availableValues` (`[{ value, presentation }]`), `expression`, `use`.
|
||||||
|
|
||||||
|
## Значения параметров в настройках (`dataParameters`)
|
||||||
|
|
||||||
|
Предустановленные значения параметров на уровне настроек списка. Shorthand `"Имя = Значение"` или объект `{ parameter, value?, use?, viewMode? }`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"dataParameters": [ "Организация = _", "ВидЦен" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Поля набора (`fields`)
|
||||||
|
|
||||||
|
Обычно поля выводятся из источника сами — `fields` нужен **только чтобы переопределить** свойства отдельного поля:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"fields": [
|
||||||
|
{ "field": "Сумма", "title": "Сумма, руб", "appearance": { "Формат": "ЧДЦ=2" } },
|
||||||
|
{ "field": "Остаток", "valueType": "number(15,2)" }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключи поля: `field`, `dataPath`, `title`, `valueType`, `appearance` (как в условном оформлении), `presentationExpression`, `inputParameters` (связь по параметрам выбора), `typeLink` (`{ field, linkItem }` — связь по типу, напр. субконто).
|
||||||
|
|
||||||
|
## Вычисляемые поля (`calculatedFields`)
|
||||||
|
|
||||||
|
Поля, считаемые выражением. Shorthand `"Имя [Заголовок]: тип = Выражение"`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"calculatedFields": [
|
||||||
|
"Метка = Code + \" \" + Description",
|
||||||
|
"Маржа [Маржа, руб]: number(15,2) = Цена - Закупка"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Объектная форма — для `presentationExpression` / `orderExpression`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "dataPath": "Сорт", "expression": "Code", "title": "Сорт",
|
||||||
|
"valueType": "string(10)", "presentationExpression": "Code" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Отбор (`filter`)
|
||||||
|
|
||||||
|
Shorthand `"Поле оператор значение @флаги"` или объект:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"filter": [
|
||||||
|
"Организация = _ @off @user",
|
||||||
|
"Сумма > 1000",
|
||||||
|
{ "field": "Дата", "op": ">=", "value": "2024-01-01T00:00:00" },
|
||||||
|
{ "group": "Or", "items": [ "Статус = 1", "Статус = 2" ] }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Операторы:** `=` `<>` `>` `>=` `<` `<=`, `in` / `notIn`, `inHierarchy`, `contains` / `notContains`, `beginsWith` / `notBeginsWith`, `like` / `notLike` (`%`-шаблон), `filled` / `notFilled`.
|
||||||
|
- **Флаги:** `@off` (отключён), `@user` (в пользовательских настройках), `@quickAccess`; `_` = пустое значение.
|
||||||
|
- **Группа:** `{ group: "And"|"Or"|"Not", items: [...] }`.
|
||||||
|
- **Дата-значение:** ISO-дата `"2024-01-01T00:00:00"` — фиксированная дата. Именованный относительный период — строкой с типом: `{ "value": "BeginningOfThisWeek", "valueType": "v8:StandardBeginningDate" }` (варианты `BeginningOfThisDay`/`BeginningOfThisWeek`/`BeginningOfThisMonth`/`BeginningOfThisYear`/…).
|
||||||
|
|
||||||
|
## Сортировка (`order`)
|
||||||
|
|
||||||
|
Строка `"Поле"` (по возр.) / `"Поле desc"`, либо объект `{ field, direction? }`. `"Auto"` — автосортировка:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"order": [ "Дата desc", "Наименование", "Auto" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Группировка строк (`grouping`)
|
||||||
|
|
||||||
|
Линейная цепочка уровней (внешний → внутренний). Шорткат `>` или массив:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"grouping": "Контрагент > Договор"
|
||||||
|
"grouping": [ "Контрагент", { "field": "Дата", "groupType": "Hierarchy" } ]
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключи уровня-объекта: `field`, `groupType` (`Items` / `Hierarchy`).
|
||||||
|
|
||||||
|
## Условное оформление (`conditionalAppearance`)
|
||||||
|
|
||||||
|
```json
|
||||||
|
"conditionalAppearance": [
|
||||||
|
{ "filter": [ "Просрочено = true" ], "appearance": { "ЦветТекста": "web:Red" } }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
`filter` — та же грамматика, что выше. `appearance` — словарь «параметр платформы: значение» (`ЦветТекста`, `ЦветФона`, `Шрифт`, `Текст`, `Формат`, …). Значение `Текст`/`Заголовок`/`Формат`: голая строка — нелокализованный литерал; `{ru,en}` — локализуемая строка; `{ field: "путь" }` — ссылка на поле. Подробнее об оформлении — `references/appearance.md`.
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# Продвинутая раскладка
|
||||||
|
|
||||||
|
Тонкая настройка размещения элемента внутри родителя сверх базовой геометрии (`width`/`height`/`horizontalStretch`/`verticalStretch`/`visible`/`enabled` и ориентации групп/страниц — они в основной инструкции). Все ключи ниже задаются прямо на элементе и **необязательны** — без них действует поведение платформы по умолчанию.
|
||||||
|
|
||||||
|
## Выравнивание внутри родителя
|
||||||
|
|
||||||
|
Различают **выравнивание самого элемента** в отведённой ему ячейке и **выравнивание содержимого** элемента.
|
||||||
|
|
||||||
|
| Ключ | Значения | Что выравнивает |
|
||||||
|
|------|----------|-----------------|
|
||||||
|
| `groupHorizontalAlign` | `Left` / `Center` / `Right` | Положение **элемента** по горизонтали в родительской группе (когда элемент у́же доступного места) |
|
||||||
|
| `groupVerticalAlign` | `Top` / `Center` / `Bottom` | Положение **элемента** по вертикали в родительской группе |
|
||||||
|
| `horizontalAlign` | `Left` / `Center` / `Right` | Выравнивание **содержимого** (текста/значения) внутри самого элемента |
|
||||||
|
| `verticalAlign` | `Top` / `Center` / `Bottom` | Выравнивание содержимого по вертикали внутри элемента |
|
||||||
|
|
||||||
|
`group*Align` отвечает на вопрос «куда сдвинуть нерастянутый элемент в его ячейке», `horizontalAlign`/`verticalAlign` — «как разместить текст внутри элемента». Это разные оси настройки, их часто комбинируют.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "button": "ОК", "groupHorizontalAlign": "Right" }
|
||||||
|
{ "input": "Сумма", "path": "Объект.Сумма", "horizontalAlign": "Right" }
|
||||||
|
{ "label": "Итого", "groupHorizontalAlign": "Center", "horizontalAlign": "Center" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ограничение максимального размера
|
||||||
|
|
||||||
|
По умолчанию растягивающийся элемент имеет авто-вычисляемый предел ширины/высоты. Чтобы задать жёсткий предел или вовсе снять авто-предел:
|
||||||
|
|
||||||
|
| Ключ | Значения | Назначение |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| `maxWidth` | число | Жёсткий максимум ширины элемента |
|
||||||
|
| `maxHeight` | число | Жёсткий максимум высоты элемента |
|
||||||
|
| `autoMaxWidth` | `false` | Отключить авто-предел ширины (элемент тянется без ограничения сверху) |
|
||||||
|
| `autoMaxHeight` | `false` | Отключить авто-предел высоты |
|
||||||
|
|
||||||
|
`autoMaxWidth: false` нужен, например, для широкого многострочного поля или растянутого по всей форме поля ввода, чтобы платформа не «прижимала» его к авто-пределу. Указывают именно отклонение от дефолта; обычное значение `true` писать не нужно.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Комментарий", "path": "Объект.Комментарий", "multiLine": true,
|
||||||
|
"horizontalStretch": true, "autoMaxWidth": false }
|
||||||
|
{ "input": "Поиск", "path": "СтрокаПоиска", "horizontalStretch": true, "maxWidth": 600 }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Поведение при вводе и активации
|
||||||
|
|
||||||
|
| Ключ | Значения | Назначение |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| `skipOnInput` | `true` / `false` | Пропускать элемент при обходе по Enter/Tab (фокус через него не проходит). Указывают явно, в т.ч. `false` чтобы вернуть в обход поле, которое платформа пропустила бы |
|
||||||
|
| `defaultItem` | `true` | Элемент получает фокус по умолчанию при открытии формы (поле/таблица для немедленного ввода) |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Идентификатор", "path": "Объект.Идентификатор", "skipOnInput": true }
|
||||||
|
{ "input": "Штрихкод", "path": "Штрихкод", "defaultItem": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
`skipOnInput: true` — для служебных/расчётных полей, которые видны, но не редактируются вводом с клавиатуры в общем потоке. `defaultItem: true` ставят на одном элементе формы — точке, с которой пользователь начнёт работу.
|
||||||
|
|
||||||
|
## Перетаскивание
|
||||||
|
|
||||||
|
| Ключ | Значения | Назначение |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| `enableStartDrag` | `true` | Разрешить начинать перетаскивание из элемента (источник drag-n-drop) |
|
||||||
|
|
||||||
|
Для таблиц приём/перемещение строк управляется ключами таблицы (`enableDrag`, `changeRowOrder`) — см. основную инструкцию; `enableStartDrag` — общий низкоуровневый флаг «этот элемент может быть источником перетаскивания».
|
||||||
|
|
||||||
|
## Закрепление колонки в таблице (`fixingInTable`)
|
||||||
|
|
||||||
|
Свойство поля-колонки внутри таблицы: закрепить колонку у края, чтобы она не уходила при горизонтальной прокрутке.
|
||||||
|
|
||||||
|
| Значения |
|
||||||
|
|----------|
|
||||||
|
| `None` (по умолчанию — не закреплена) / `Left` / `Right` |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Товары", "path": "Объект.Товары", "columns": [
|
||||||
|
{ "input": "Номенклатура", "path": "Объект.Товары.Номенклатура", "fixingInTable": "Left" },
|
||||||
|
{ "input": "Количество", "path": "Объект.Товары.Количество" },
|
||||||
|
{ "input": "Сумма", "path": "Объект.Товары.Сумма", "fixingInTable": "Right" } ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
Закрепляют ключевые колонки (идентифицирующую слева, итоговую справа), чтобы они оставались видны при прокрутке широкой таблицы.
|
||||||
|
|
||||||
|
## Ячейки колонок: шапка и подвал
|
||||||
|
|
||||||
|
Для поля-колонки внутри таблицы (и `columnGroup`) — размещение в шапке/подвале и выравнивание текста ячеек. Применять только к элементам внутри `columns` таблицы.
|
||||||
|
|
||||||
|
| Ключ | Значения | Назначение |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| `showInHeader` | `true` / `false` | Показывать колонку в шапке таблицы |
|
||||||
|
| `showInFooter` | `true` / `false` | Показывать колонку в подвале (нужно для итогов; подвал самой таблицы включается `footer: true`) |
|
||||||
|
| `headerHorizontalAlign` | `Left` / `Right` / `Center` / `Auto` | Выравнивание текста в шапке колонки |
|
||||||
|
| `footerHorizontalAlign` | `Left` / `Right` / `Center` | Выравнивание текста в подвале колонки |
|
||||||
|
| `autoCellHeight` | `true` / `false` | Авто-высота ячейки (перенос содержимого на несколько строк) |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Товары", "path": "Объект.Товары", "footer": true, "columns": [
|
||||||
|
{ "input": "Номенклатура", "path": "Объект.Товары.Номенклатура", "autoCellHeight": true },
|
||||||
|
{ "input": "Сумма", "path": "Объект.Товары.Сумма",
|
||||||
|
"headerHorizontalAlign": "Right", "showInFooter": true, "footerHorizontalAlign": "Right" } ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Адаптивная важность (`displayImportance`)
|
||||||
|
|
||||||
|
| Значения |
|
||||||
|
|----------|
|
||||||
|
| `VeryHigh` / `High` / `Usual` / `VeryLow` / `Low` |
|
||||||
|
|
||||||
|
Приоритет элемента при адаптивной перекомпоновке формы на узких/мобильных экранах: элементы с меньшей важностью сворачиваются/прячутся первыми. Применимо к любому элементу.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Комментарий", "path": "Объект.Комментарий", "displayImportance": "Low" }
|
||||||
|
```
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# Форма отчёта
|
||||||
|
|
||||||
|
Форма, подключённая к объекту-отчёту (`Report`). Кроме обычных свойств формы у неё есть несколько свойств в `properties`, связывающих форму с механизмом компоновки (СКД): куда выводится результат, где данные расшифровки, какого она типа. Все они задаются в блоке `properties` верхнего уровня.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"properties": {
|
||||||
|
"reportFormType": "Main",
|
||||||
|
"reportResult": "РезультатОтчета",
|
||||||
|
"detailsData": "ДанныеРасшифровки"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ни одно из этих свойств не обязательно — указывайте только те, что нужны конкретной форме.
|
||||||
|
|
||||||
|
## Тип формы отчёта (`reportFormType`)
|
||||||
|
|
||||||
|
Роль формы в составе отчёта:
|
||||||
|
|
||||||
|
| Значение | Назначение |
|
||||||
|
|----------|-----------|
|
||||||
|
| `Main` | Основная форма отчёта (результат + настройки) |
|
||||||
|
| `Settings` | Форма настроек |
|
||||||
|
| `Variant` | Форма варианта |
|
||||||
|
|
||||||
|
```json
|
||||||
|
"reportFormType": "Main"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Привязка к компоновке
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `reportResult` | string | Имя реквизита-результата формы (табличный документ, куда выводится отчёт) |
|
||||||
|
| `detailsData` | string | Имя реквизита данных расшифровки |
|
||||||
|
| `variantAppearance` | string | Имя реквизита оформления варианта |
|
||||||
|
|
||||||
|
Значение каждого ключа — имя реквизита формы (а не путь к данным). Реквизит с таким именем должен присутствовать в `attributes` формы.
|
||||||
|
|
||||||
|
## Группа пользовательских настроек (`customSettingsFolder`)
|
||||||
|
|
||||||
|
Группа-элемент формы, в которую генерируются пользовательские настройки компоновщика. Задаётся **по имени** элемента-группы:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"customSettingsFolder": "ГруппаПользовательскихНастроек"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Прочие свойства компоновки
|
||||||
|
|
||||||
|
Редкие, задавайте только при явной необходимости:
|
||||||
|
|
||||||
|
| Ключ | Значения | Назначение |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| `autoShowState` | `Auto`, `DontShow`, `ShowOnComposition` | Автопоказ состояния формирования |
|
||||||
|
| `reportResultViewMode` | `Auto` | Режим просмотра результата |
|
||||||
|
| `viewModeApplicationOnSetReportResult` | `Auto` | Применение режима просмотра при установке результата |
|
||||||
|
|
||||||
|
## Реалистичный пример
|
||||||
|
|
||||||
|
Основная форма отчёта со СКД: реквизит-результат, данные расшифровки и группа пользовательских настроек.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"reportFormType": "Main",
|
||||||
|
"reportResult": "РезультатОтчета",
|
||||||
|
"detailsData": "ДанныеРасшифровки",
|
||||||
|
"customSettingsFolder": "ГруппаПользовательскихНастроек"
|
||||||
|
},
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "РезультатОтчета", "type": "SpreadsheetDocument" },
|
||||||
|
{ "name": "ДанныеРасшифровки", "type": "DataCompositionDetailsData" }
|
||||||
|
],
|
||||||
|
"elements": [
|
||||||
|
{ "group": "vertical", "name": "ГруппаПользовательскихНастроек" },
|
||||||
|
{ "spreadsheet": "РезультатОтчета", "path": "РезультатОтчета",
|
||||||
|
"titleLocation": "none" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Доступ по ролям
|
||||||
|
|
||||||
|
Единый механизм платформы для разграничения по ролям: задаётся общее значение для всех ролей плюс исключения для конкретных ролей. Один и тот же формат значения у четырёх ключей — каждый на своём владельце:
|
||||||
|
|
||||||
|
| Ключ | Владелец | Смысл |
|
||||||
|
|------|----------|-------|
|
||||||
|
| `userVisible` | элемент формы | пользовательская видимость элемента |
|
||||||
|
| `view` | реквизит формы | право просмотра |
|
||||||
|
| `edit` | реквизит формы | право редактирования |
|
||||||
|
| `use` | команда формы | доступность команды |
|
||||||
|
|
||||||
|
Ключ необязателен: его отсутствие = полный доступ для всех ролей.
|
||||||
|
|
||||||
|
## Значение
|
||||||
|
|
||||||
|
Две формы (одинаковы для всех четырёх ключей):
|
||||||
|
|
||||||
|
**Скаляр** `true` / `false` — общее значение для всех ролей, без исключений:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Поле", "userVisible": false }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Объект** `{ "common": <bool>, "roles": { "ИмяРоли": <bool>, … } }` — общее значение `common` плюс явные исключения по ролям:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Реквизит",
|
||||||
|
"edit": { "common": false, "roles": { "ПолныеПрава": true } } }
|
||||||
|
```
|
||||||
|
|
||||||
|
Роль, **не указанная** в `roles`, наследует `common`. Указанная — задаёт явный `true`/`false` (может и совпадать с `common`).
|
||||||
|
|
||||||
|
## Имя роли
|
||||||
|
|
||||||
|
Ключи в `roles` — имена ролей конфигурации (`ПолныеПрава`, `Бухгалтер`, …).
|
||||||
|
|
||||||
|
## Примеры
|
||||||
|
|
||||||
|
Элемент скрыт у всех пользователей:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "input": "Комментарий", "userVisible": false }
|
||||||
|
```
|
||||||
|
|
||||||
|
Реквизит не виден никому и редактируется только одной ролью:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "СуммаБонуса",
|
||||||
|
"view": false,
|
||||||
|
"edit": { "common": false, "roles": { "ПолныеПрава": true } } }
|
||||||
|
```
|
||||||
|
|
||||||
|
Поле доступно для просмотра всем, но редактируемо только администратору:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Статус",
|
||||||
|
"view": true,
|
||||||
|
"edit": { "common": false, "roles": { "Администратор": true } } }
|
||||||
|
```
|
||||||
|
|
||||||
|
Команда недоступна по умолчанию, разрешена только бухгалтеру:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "ПровестиЗакрытие",
|
||||||
|
"use": { "common": false, "roles": { "Бухгалтер": true } } }
|
||||||
|
```
|
||||||
|
|
||||||
|
Обратный случай — доступно всем, кроме одной роли:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "РедактироватьЦену",
|
||||||
|
"edit": { "common": true, "roles": { "Кладовщик": false } } }
|
||||||
|
```
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
# Спец-поля «документ/датчик»
|
||||||
|
|
||||||
|
Поля для отображения специальных данных: табличный документ, HTML, текст, форматированный документ, индикатор, ползунок. Каждое привязывается к реквизиту своего платформенного типа.
|
||||||
|
|
||||||
|
Структурно это обычные поля — поддерживают общий скелет поля (`path`, `title`, `titleLocation`, флаги `readOnly`/`enabled`/`visible`, `layout`, оформление, события). Ниже — только ключ `type` (имя элемента задаётся значением ключа) и собственные скаляры каждого семейства. Все скаляры необязательны.
|
||||||
|
|
||||||
|
| Ключ типа | Тип реквизита |
|
||||||
|
|-----------|---------------|
|
||||||
|
| `spreadsheet` | `mxl:SpreadsheetDocument` (ТабличныйДокумент) |
|
||||||
|
| `html` | `string` |
|
||||||
|
| `textDoc` | `d5p1:TextDocument` (ТекстовыйДокумент) |
|
||||||
|
| `formattedDoc` | `fd:FormattedDocument` (ФорматированныйДокумент) |
|
||||||
|
| `progressBar` | число |
|
||||||
|
| `trackBar` | число |
|
||||||
|
|
||||||
|
## spreadsheet — поле табличного документа
|
||||||
|
|
||||||
|
Просмотр/редактирование табличного документа (отчёт, печатная форма).
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "spreadsheet": "ТаблицаОтчета", "path": "ТаблицаОтчета",
|
||||||
|
"titleLocation": "none", "readOnly": true,
|
||||||
|
"output": "Disable", "protection": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `output` | string | Использование вывода: `Enable` / `Disable` |
|
||||||
|
| `protection` | bool | Защита от изменений |
|
||||||
|
| `edit` | bool | Разрешить редактирование |
|
||||||
|
| `showGrid` | bool | Показывать сетку |
|
||||||
|
| `showHeaders` | bool | Показывать заголовки строк/колонок |
|
||||||
|
| `showGroups` | bool | Показывать группировки |
|
||||||
|
| `showRowAndColumnNames` | bool | Показывать имена строк и колонок |
|
||||||
|
| `showCellNames` | bool | Показывать имена ячеек |
|
||||||
|
| `verticalScrollBar` / `horizontalScrollBar` | string | Режим полос прокрутки |
|
||||||
|
| `viewScalingMode` | string | Режим масштабирования просмотра |
|
||||||
|
| `selectionShowMode` | string | Режим отображения выделения |
|
||||||
|
| `pointerType` | string | Тип указателя |
|
||||||
|
| `enableDrag` / `enableStartDrag` | bool | Разрешить перетаскивание / начало перетаскивания |
|
||||||
|
|
||||||
|
## html — поле HTML-документа
|
||||||
|
|
||||||
|
Просмотр HTML. Реквизит — строка (содержит HTML-текст или адрес).
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "html": "Просмотр", "path": "СодержимоеHTML", "titleLocation": "none",
|
||||||
|
"output": "Enable", "warningOnEditRepresentation": false }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `output` | string | Использование вывода: `Enable` / `Disable` |
|
||||||
|
| `warningOnEditRepresentation` | bool | Предупреждать при изменении представления |
|
||||||
|
|
||||||
|
## textDoc — поле текстового документа
|
||||||
|
|
||||||
|
Просмотр/редактирование текстового документа.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "textDoc": "Текст", "path": "ТекстДокумента", "editMode": "Edit" }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `editMode` | string | Режим редактирования (напр. `Edit` / `View`) |
|
||||||
|
|
||||||
|
## formattedDoc — поле форматированного документа
|
||||||
|
|
||||||
|
Просмотр/редактирование форматированного документа.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "formattedDoc": "Описание", "path": "ФорматированноеОписание", "editMode": "Edit" }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `editMode` | string | Режим редактирования (напр. `Edit` / `View`) |
|
||||||
|
|
||||||
|
## progressBar — поле индикатора
|
||||||
|
|
||||||
|
Индикатор прогресса. Реквизит — числовой.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "progressBar": "Прогресс", "path": "Прогресс",
|
||||||
|
"minValue": 0, "maxValue": 100, "showPercent": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `minValue` / `maxValue` | число | Минимальное / максимальное значение |
|
||||||
|
| `showPercent` | bool | Показывать проценты |
|
||||||
|
|
||||||
|
## trackBar — поле ползунка
|
||||||
|
|
||||||
|
Регулятор-ползунок. Реквизит — числовой.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "trackBar": "Масштаб", "path": "Масштаб",
|
||||||
|
"minValue": 20, "maxValue": 400, "markingStep": 20 }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `minValue` / `maxValue` | число | Минимальное / максимальное значение |
|
||||||
|
| `step` | число | Шаг изменения |
|
||||||
|
| `largeStep` | число | Крупный шаг |
|
||||||
|
| `markingStep` | число | Шаг разметки |
|
||||||
|
| `markingAppearance` | string | Оформление разметки |
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
# Таблица — продвинутые возможности
|
||||||
|
|
||||||
|
Базовый элемент таблицы (`type: "table"`, колонки, основные свойства) описан в основной инструкции, раздел «Таблица (table)». Здесь — продвинутые возможности: дополнения командной панели, специфика таблицы динамического списка и неочевидные свойства/режимы.
|
||||||
|
|
||||||
|
## Представление (`representation`)
|
||||||
|
|
||||||
|
Как таблица рисует строки:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список", "representation": "Tree" }
|
||||||
|
```
|
||||||
|
|
||||||
|
`List` — плоский список (по умолчанию), `Tree` — дерево, `HierarchicalList` — иерархический список (группы + элементы на одном уровне).
|
||||||
|
|
||||||
|
Для дерева/иерархии управляйте раскрытием уровней через `initialTreeView` (`ExpandTopLevel` / `ExpandAllLevels` / `NoExpand`).
|
||||||
|
|
||||||
|
## Выделение и текущая строка
|
||||||
|
|
||||||
|
| Ключ | Значения | Назначение |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| `selectionMode` | `SingleRow` / `MultiRow` | Режим выделения строк |
|
||||||
|
| `multipleChoice` | bool | Разрешить множественный выбор (для форм выбора) |
|
||||||
|
| `currentRowUse` | `DontUse` / `Use` / `SelectionPresentation` / `SelectionPresentationAndChoice` / `Choice` | Использование текущей строки таблицы |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список", "selectionMode": "MultiRow", "multipleChoice": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Поиск при вводе (`searchOnInput`)
|
||||||
|
|
||||||
|
Поведение встроенного поиска при наборе текста в таблице:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список", "searchOnInput": "Use" }
|
||||||
|
```
|
||||||
|
|
||||||
|
`Auto` (по умолчанию) / `Use` (искать) / `DontUse` (не искать).
|
||||||
|
|
||||||
|
Где располагать сами элементы поиска — управляется `searchStringLocation` / `viewStatusLocation` / `searchControlLocation` (`None` / `Top` / `Bottom` / `CommandBar` / `Auto`).
|
||||||
|
|
||||||
|
## Прочие свойства таблицы
|
||||||
|
|
||||||
|
| Ключ | Тип | Назначение |
|
||||||
|
|------|-----|-----------|
|
||||||
|
| `useAlternationRowColor` | bool | Чередование цвета строк |
|
||||||
|
| `verticalLines` / `horizontalLines` | bool | Линии сетки (укажите `false`, чтобы скрыть) |
|
||||||
|
| `markIncomplete` | bool | Автоотметка незаполненных ячеек |
|
||||||
|
| `heightInTableRows` | int | Высота элемента в строках (отдельно от `height`) |
|
||||||
|
| `autoInsertNewRow` | bool | Автодобавление новой строки при вводе в последнюю |
|
||||||
|
| `rowsPicture` | string \| object | Картинка строк. Ссылка (`"CommonPicture.X"`, `"abs:..."`) либо объект `{ src, loadTransparent?, transparentPixel? }` |
|
||||||
|
| `tooltipRepresentation` | string | Режим показа подсказки таблицы: `None`, `Button`, `ShowBottom`, `ShowTop`, `ShowLeft`, `ShowRight`, `ShowAuto`, `Balloon` |
|
||||||
|
|
||||||
|
## Фиксация колонки (`fixingInTable`)
|
||||||
|
|
||||||
|
Свойство **колонки** (на `input` / `labelField` / `check` / `picField` внутри `columns`), а не самой таблицы. Закрепляет колонку у края при горизонтальной прокрутке:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Товары", "path": "Объект.Товары", "columns": [
|
||||||
|
{ "input": "Номенклатура", "path": "Объект.Товары.Номенклатура", "fixingInTable": "Left" },
|
||||||
|
{ "input": "Количество", "path": "Объект.Товары.Количество" }
|
||||||
|
]}
|
||||||
|
```
|
||||||
|
|
||||||
|
`Left` / `Right` / `None`.
|
||||||
|
|
||||||
|
## Исключённые команды (`excludedCommands`)
|
||||||
|
|
||||||
|
Убрать стандартные команды редактора таблицы (кнопки добавления/перемещения/сортировки):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Товары", "path": "Объект.Товары",
|
||||||
|
"excludedCommands": [ "Add", "Delete", "MoveUp", "SortListAsc" ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство работает на любом поле и на уровне формы; для таблицы значимы команды вида `Add` / `Delete` / `MoveUp` / `MoveDown` / `SortListAsc` / `SortListDesc`.
|
||||||
|
|
||||||
|
## Дополнения командной панели (`additions`)
|
||||||
|
|
||||||
|
Дополнения — это «представления» встроенного поиска таблицы:
|
||||||
|
|
||||||
|
- `searchString` — отображение строки поиска,
|
||||||
|
- `viewStatus` — состояние просмотра,
|
||||||
|
- `searchControl` — управление поиском.
|
||||||
|
|
||||||
|
Каждое дополнение — полноценный элемент (полный набор свойств поля). Размещать их можно двумя способами.
|
||||||
|
|
||||||
|
**(1) Стандартные дополнения** генерирует платформа на уровне таблицы. В DSL указывайте **только отклонения** от стандартного вида — через карту `additions` (ключ = тип дополнения):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список",
|
||||||
|
"additions": { "viewStatus": { "horizontalLocation": "left" } } }
|
||||||
|
```
|
||||||
|
|
||||||
|
**(2) Кастомное дополнение**, размещённое прямо в командной панели — обычный элемент в `commandBar` с ключом-типом:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список", "commandBar": [
|
||||||
|
{ "searchString": "ПоискСписка", "source": "Список", "width": 15, "horizontalStretch": true }
|
||||||
|
]}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Тип-ключ: `searchString` / `viewStatus` / `searchControl`.
|
||||||
|
- `source` — имя таблицы-источника; необязательно, по умолчанию = имя родительской таблицы.
|
||||||
|
- `horizontalLocation`: `auto` (по умолчанию) / `left` / `right`. Применимо и к обычным элементам командных панелей.
|
||||||
|
- Прочие свойства как у поля: `title`, `visible`, `userVisible`, `enabled`, `tooltip`, оформление, `width` / `maxWidth` / `autoMaxWidth` / `horizontalStretch` / `groupHorizontalAlign` и др.
|
||||||
|
|
||||||
|
## Таблица динамического списка
|
||||||
|
|
||||||
|
Когда `path` таблицы указывает на реквизит `type: "DynamicList"` (см. `references/dynamic-list.md`), доступен блок специфичных свойств. Указывайте **только отличия** от умолчания.
|
||||||
|
|
||||||
|
| Ключ | Тип | Умолчание | Назначение |
|
||||||
|
|------|-----|-----------|-----------|
|
||||||
|
| `rowPictureDataPath` | string | картинка осн. таблицы | Путь к картинке строки. `""` — подавить картинку |
|
||||||
|
| `rowsPicture` | string | — | Картинка строк (`"CommonPicture.X"`) |
|
||||||
|
| `autoRefresh` | bool | `false` | Автообновление списка |
|
||||||
|
| `autoRefreshPeriod` | int | `60` | Период автообновления, сек |
|
||||||
|
| `updateOnDataChange` | string | `Auto` | Обновлять при изменении данных: `Auto` / `DontUpdate` |
|
||||||
|
| `choiceFoldersAndItems` | string | `Items` | Что выбирать: `Items` / `Folders` / `FoldersAndItems` |
|
||||||
|
| `restoreCurrentRow` | bool | `false` | Восстанавливать текущую строку при обновлении |
|
||||||
|
| `showRoot` | bool | `true` | Показывать корень |
|
||||||
|
| `allowRootChoice` | bool | `false` | Разрешить выбор корня |
|
||||||
|
| `allowGettingCurrentRowURL` | bool | `true` | Разрешить получение URL текущей строки |
|
||||||
|
| `userSettingsGroup` | string | — | Группа пользовательских настроек (привязка к одноимённой группе настроек) |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список",
|
||||||
|
"representation": "Tree",
|
||||||
|
"rowPictureDataPath": "Список.DefaultPicture",
|
||||||
|
"choiceFoldersAndItems": "FoldersAndItems",
|
||||||
|
"allowRootChoice": true,
|
||||||
|
"updateOnDataChange": "DontUpdate" }
|
||||||
|
```
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# Продвинутые конструкции типов
|
||||||
|
|
||||||
|
Примитивы (`string(n)`, `number(p,s)`, `boolean`, `date`/`dateTime`, …) и одиночные ссылки (`CatalogRef.Контрагенты`, `DocumentRef.Заказ`, `EnumRef.X`, …) описаны в основной инструкции. Здесь — типы, которые нельзя выразить одним именем: составные типы, наборы типов и платформенные наборы ссылок.
|
||||||
|
|
||||||
|
Любая из этих конструкций пишется в поле `type` реквизита, реквизита-параметра или поля.
|
||||||
|
|
||||||
|
## Составные типы
|
||||||
|
|
||||||
|
Несколько типов на одном реквизите — части перечисляются через разделитель `" | "` (можно `+`). Реквизит сможет принимать значение любого из перечисленных типов:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Плательщик",
|
||||||
|
"type": "CatalogRef.Организации | CatalogRef.ИндивидуальныеПредприниматели" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Смешивать можно типы из разных категорий — ссылки, примитивы, наборы типов:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Источник",
|
||||||
|
"type": "CatalogRef.Контрагенты | DocumentRef.Заказ | string(150)" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Каждая часть — самостоятельный токен из этого файла или из основной инструкции. Порядок частей произвольный.
|
||||||
|
|
||||||
|
## Наборы типов (TypeSet)
|
||||||
|
|
||||||
|
«Набор типов» подставляется вместо конкретного типа — это один токен, а не перечисление. Применимо и в составном типе как одна из частей.
|
||||||
|
|
||||||
|
| Токен `type` | Смысл |
|
||||||
|
|------|-------|
|
||||||
|
| `"DefinedType.ИмяТипа"` | определяемый тип конфигурации |
|
||||||
|
| `"Characteristic.ИмяПлана"` | тип значения характеристики (по плану видов характеристик) |
|
||||||
|
| `"AnyRef"` | любая ссылка |
|
||||||
|
| `"AnyIBRef"` | любая ссылка информационной базы |
|
||||||
|
|
||||||
|
Определяемый тип — реквизит принимает то, что задано в определяемом типе конфигурации (например `DefinedType.ДенежнаяСумма`):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Сумма", "type": "DefinedType.ДенежнаяСумма" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Характеристика — тип значения берётся из плана видов характеристик:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Значение", "type": "Characteristic.ДополнительныеРеквизиты" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Платформенные наборы ссылок
|
||||||
|
|
||||||
|
«Голый» ссылочный токен **без `.Имя`** означает «любая ссылка этой категории объектов»:
|
||||||
|
|
||||||
|
| Токен `type` | Смысл |
|
||||||
|
|------|-------|
|
||||||
|
| `"CatalogRef"` | любая ссылка справочника |
|
||||||
|
| `"DocumentRef"` | любая ссылка документа |
|
||||||
|
| `"EnumRef"` | любая ссылка перечисления |
|
||||||
|
| `"ExchangePlanRef"` | любая ссылка плана обмена |
|
||||||
|
| `"TaskRef"` | любая ссылка задачи |
|
||||||
|
| `"BusinessProcessRef"` | любая ссылка бизнес-процесса |
|
||||||
|
| `"ChartOfCharacteristicTypesRef"` | любая ссылка плана видов характеристик |
|
||||||
|
| `"ChartOfAccountsRef"` | любая ссылка плана счетов |
|
||||||
|
| `"ChartOfCalculationTypesRef"` | любая ссылка плана видов расчёта |
|
||||||
|
|
||||||
|
Различие с одиночной ссылкой — только в наличии `.Имя`:
|
||||||
|
|
||||||
|
- `"CatalogRef.Валюты"` — конкретный справочник «Валюты»;
|
||||||
|
- `"CatalogRef"` — любой справочник.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "ЛюбойСправочник", "type": "CatalogRef" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Эти наборы тоже комбинируются в составном типе:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Объект", "type": "CatalogRef | DocumentRef" }
|
||||||
|
```
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
name: form-decompile
|
||||||
|
description: Декомпиляция управляемой формы 1С (Form.xml) в JSON-черновик в формате form-compile. Используй для scaffold новой формы по образцу или структурного рефакторинга. Не для точечных правок
|
||||||
|
argument-hint: <FormPath> [-OutputPath <out.json>]
|
||||||
|
disable-model-invocation: true
|
||||||
|
allowed-tools:
|
||||||
|
- Bash
|
||||||
|
- Read
|
||||||
|
- Write
|
||||||
|
- Glob
|
||||||
|
---
|
||||||
|
|
||||||
|
# /form-decompile — JSON-черновик из Form.xml управляемой формы
|
||||||
|
|
||||||
|
Читает Form.xml и эмитит компактный JSON в формате `form-compile`. **Результат — черновик**, а не обратимое представление: см. раздел «Что получаешь».
|
||||||
|
|
||||||
|
## Когда использовать
|
||||||
|
|
||||||
|
- **Scaffold новой формы по образцу** — взять существующую форму, получить JSON, поправить и скомпилировать в новую.
|
||||||
|
- **Структурный рефакторинг** — перебрать дерево элементов, реквизиты, команды.
|
||||||
|
|
||||||
|
## Когда **не** использовать
|
||||||
|
|
||||||
|
- **Точечные правки готовой формы** (добавить элемент, реквизит, команду) → `/form-edit`. Цикл «декомпиляция → правка JSON → компиляция» переписывает форму целиком, может терять непокрытые конструкции и даёт большой diff. `/form-edit` правит адресно.
|
||||||
|
|
||||||
|
## Параметры
|
||||||
|
|
||||||
|
| Параметр | Описание |
|
||||||
|
|----------|----------|
|
||||||
|
| `FormPath` | Путь к Form.xml (обязательный) |
|
||||||
|
| `OutputPath` | Путь к выходному JSON. Если не задан — JSON в stdout |
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-decompile.ps1" -FormPath "<Form.xml>" -OutputPath "<out.json>"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Что получаешь
|
||||||
|
|
||||||
|
JSON-черновик в формате `/form-compile` — **не полное обратимое представление**: раундтрип `xml → json → xml` не гарантируется, часть конструкций DSL не покрывает и **теряет молча**.
|
||||||
|
|
||||||
|
Критичные конструкции (`ConditionalAppearance` со scope, design-time диаграммы/планировщики на реквизите, неизвестный тип элемента, не-Form root) → скрипт падает с ненулевым кодом и сообщением в stderr; для правок такой формы — `/form-edit`.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
1. `/form-decompile <Form.xml> -OutputPath draft.json` — получить черновик.
|
||||||
|
2. Поправить JSON под задачу.
|
||||||
|
3. `/form-compile -JsonPath draft.json -OutputPath new/Form.xml` — собрать обратно.
|
||||||
|
4. `/form-validate` + `/form-info` — проверить результат.
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
# form-edit v1.0 — Edit 1C managed form elements
|
# form-edit v1.1 — Edit 1C managed form elements
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -291,6 +291,16 @@ function Get-ElementName {
|
|||||||
return "$($el.$typeKey)"
|
return "$($el.$typeKey)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Уникальность имён внутри JSON-определения (1С: своя коллекция — свой неймспейс).
|
||||||
|
function Assert-EditUnique {
|
||||||
|
param([string]$name, [hashtable]$seen, [string]$ctx)
|
||||||
|
if ($seen.ContainsKey($name)) {
|
||||||
|
Write-Host "[ERROR] Duplicate $ctx '$name' in JSON definition — names must be unique in 1C form"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$seen[$name] = $true
|
||||||
|
}
|
||||||
|
|
||||||
$script:knownEvents = @{
|
$script:knownEvents = @{
|
||||||
"input" = @("OnChange","StartChoice","ChoiceProcessing","AutoComplete","TextEditEnd","Clearing","Creating","EditTextChange")
|
"input" = @("OnChange","StartChoice","ChoiceProcessing","AutoComplete","TextEditEnd","Clearing","Creating","EditTextChange")
|
||||||
"check" = @("OnChange")
|
"check" = @("OnChange")
|
||||||
@@ -864,17 +874,31 @@ if ($def.elements -and $def.elements.Count -gt 0) {
|
|||||||
# Detect indent level
|
# Detect indent level
|
||||||
$childIndent = Get-ChildIndent $targetCI
|
$childIndent = Get-ChildIndent $targetCI
|
||||||
|
|
||||||
# Check for duplicate element names
|
# Имена элементов уникальны (требование 1С). Сначала — внутри самого JSON-определения
|
||||||
|
# (рекурсивно по children/columns).
|
||||||
|
$elemTypeKeys = @("group","input","check","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")
|
||||||
|
function Walk-ElemNames($el, [hashtable]$seen) {
|
||||||
|
$tk = $null
|
||||||
|
foreach ($k in $elemTypeKeys) { if ($el.$k -ne $null) { $tk = $k; break } }
|
||||||
|
if ($tk) { Assert-EditUnique -name (Get-ElementName -el $el -typeKey $tk) -seen $seen -ctx 'element name' }
|
||||||
|
if ($el.children) { foreach ($c in $el.children) { Walk-ElemNames $c $seen } }
|
||||||
|
if ($el.columns) { foreach ($c in $el.columns) { Walk-ElemNames $c $seen } }
|
||||||
|
}
|
||||||
|
$dslElemNames = @{}
|
||||||
|
foreach ($el in $def.elements) { Walk-ElemNames $el $dslElemNames }
|
||||||
|
|
||||||
|
# Затем — против уже существующих элементов формы (дубль = битый XML, форма не откроется)
|
||||||
foreach ($el in $def.elements) {
|
foreach ($el in $def.elements) {
|
||||||
$typeKey = $null
|
$typeKey = $null
|
||||||
foreach ($key in @("group","input","check","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) {
|
foreach ($key in $elemTypeKeys) {
|
||||||
if ($el.$key -ne $null) { $typeKey = $key; break }
|
if ($el.$key -ne $null) { $typeKey = $key; break }
|
||||||
}
|
}
|
||||||
if ($typeKey) {
|
if ($typeKey) {
|
||||||
$elName = Get-ElementName -el $el -typeKey $typeKey
|
$elName = Get-ElementName -el $el -typeKey $typeKey
|
||||||
$existing = Find-Element $rootCI $elName
|
$existing = Find-Element $rootCI $elName
|
||||||
if ($existing) {
|
if ($existing) {
|
||||||
Write-Host "[WARN] Element '$elName' already exists in form (id=$($existing.GetAttribute('id')))"
|
Write-Host "[ERROR] Element '$elName' already exists in form (id=$($existing.GetAttribute('id'))) — element names must be unique"
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -953,6 +977,22 @@ if ($def.attributes -and $def.attributes.Count -gt 0) {
|
|||||||
$attrChildIndent = Get-ChildIndent $attrsSection
|
$attrChildIndent = Get-ChildIndent $attrsSection
|
||||||
if (-not $attrChildIndent -or $attrChildIndent -eq "") { $attrChildIndent = "`t`t" }
|
if (-not $attrChildIndent -or $attrChildIndent -eq "") { $attrChildIndent = "`t`t" }
|
||||||
|
|
||||||
|
# Уникальность имён реквизитов: внутри JSON-определения (+ колонки в пределах реквизита) и
|
||||||
|
# против уже существующих реквизитов формы.
|
||||||
|
$dslAttrNames = @{}
|
||||||
|
foreach ($attr in $def.attributes) {
|
||||||
|
Assert-EditUnique -name "$($attr.name)" -seen $dslAttrNames -ctx 'attribute name'
|
||||||
|
if ($attr.columns) {
|
||||||
|
$dslColNames = @{}
|
||||||
|
foreach ($col in $attr.columns) { Assert-EditUnique -name "$($col.name)" -seen $dslColNames -ctx "column name of '$($attr.name)'" }
|
||||||
|
}
|
||||||
|
$existingAttr = $attrsSection.SelectSingleNode("f:Attribute[@name='$($attr.name)']", $nsMgr)
|
||||||
|
if ($existingAttr) {
|
||||||
|
Write-Host "[ERROR] Attribute '$($attr.name)' already exists in form — attribute names must be unique"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Generate attribute fragments
|
# Generate attribute fragments
|
||||||
$script:xml = New-Object System.Text.StringBuilder 2048
|
$script:xml = New-Object System.Text.StringBuilder 2048
|
||||||
X "<_F $allNsDecl>"
|
X "<_F $allNsDecl>"
|
||||||
@@ -1021,6 +1061,17 @@ if ($def.commands -and $def.commands.Count -gt 0) {
|
|||||||
$cmdChildIndent = Get-ChildIndent $cmdsSection
|
$cmdChildIndent = Get-ChildIndent $cmdsSection
|
||||||
if (-not $cmdChildIndent -or $cmdChildIndent -eq "") { $cmdChildIndent = "`t`t" }
|
if (-not $cmdChildIndent -or $cmdChildIndent -eq "") { $cmdChildIndent = "`t`t" }
|
||||||
|
|
||||||
|
# Уникальность имён команд: внутри JSON-определения и против существующих команд формы.
|
||||||
|
$dslCmdNames = @{}
|
||||||
|
foreach ($cmd in $def.commands) {
|
||||||
|
Assert-EditUnique -name "$($cmd.name)" -seen $dslCmdNames -ctx 'command name'
|
||||||
|
$existingCmd = $cmdsSection.SelectSingleNode("f:Command[@name='$($cmd.name)']", $nsMgr)
|
||||||
|
if ($existingCmd) {
|
||||||
|
Write-Host "[ERROR] Command '$($cmd.name)' already exists in form — command names must be unique"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Generate command fragments
|
# Generate command fragments
|
||||||
$script:xml = New-Object System.Text.StringBuilder 1024
|
$script:xml = New-Object System.Text.StringBuilder 1024
|
||||||
X "<_F $allNsDecl>"
|
X "<_F $allNsDecl>"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-edit v1.0 — Edit 1C managed form elements (Python port)
|
# form-edit v1.1 — Edit 1C managed form elements (Python port)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
@@ -365,6 +365,14 @@ def get_element_name(el, type_key):
|
|||||||
return str(el[type_key])
|
return str(el[type_key])
|
||||||
|
|
||||||
|
|
||||||
|
def _assert_edit_unique(name, seen, ctx):
|
||||||
|
# Уникальность имён внутри JSON-определения (1С: своя коллекция — свой неймспейс).
|
||||||
|
if name in seen:
|
||||||
|
print(f"[ERROR] Duplicate {ctx} '{name}' in JSON definition — names must be unique in 1C form")
|
||||||
|
sys.exit(1)
|
||||||
|
seen.add(name)
|
||||||
|
|
||||||
|
|
||||||
known_events = {
|
known_events = {
|
||||||
"input": ["OnChange", "StartChoice", "ChoiceProcessing", "AutoComplete", "TextEditEnd", "Clearing", "Creating", "EditTextChange"],
|
"input": ["OnChange", "StartChoice", "ChoiceProcessing", "AutoComplete", "TextEditEnd", "Clearing", "Creating", "EditTextChange"],
|
||||||
"check": ["OnChange"],
|
"check": ["OnChange"],
|
||||||
@@ -988,7 +996,26 @@ if elements_list:
|
|||||||
# Detect indent level
|
# Detect indent level
|
||||||
child_indent = get_child_indent(target_ci)
|
child_indent = get_child_indent(target_ci)
|
||||||
|
|
||||||
# Check for duplicate element names
|
# Имена элементов уникальны (требование 1С). Сначала — внутри самого JSON-определения
|
||||||
|
# (рекурсивно по children/columns).
|
||||||
|
def _walk_elem_names(el, seen):
|
||||||
|
tk = None
|
||||||
|
for key in ELEMENT_KEYS:
|
||||||
|
if key in el and el[key] is not None:
|
||||||
|
tk = key
|
||||||
|
break
|
||||||
|
if tk:
|
||||||
|
_assert_edit_unique(get_element_name(el, tk), seen, "element name")
|
||||||
|
for c in el.get("children", []):
|
||||||
|
_walk_elem_names(c, seen)
|
||||||
|
for c in el.get("columns", []):
|
||||||
|
_walk_elem_names(c, seen)
|
||||||
|
|
||||||
|
dsl_elem_names = set()
|
||||||
|
for el in elements_list:
|
||||||
|
_walk_elem_names(el, dsl_elem_names)
|
||||||
|
|
||||||
|
# Затем — против уже существующих элементов формы (дубль = битый XML, форма не откроется).
|
||||||
for el in elements_list:
|
for el in elements_list:
|
||||||
type_key = None
|
type_key = None
|
||||||
for key in ELEMENT_KEYS:
|
for key in ELEMENT_KEYS:
|
||||||
@@ -999,7 +1026,8 @@ if elements_list:
|
|||||||
el_name = get_element_name(el, type_key)
|
el_name = get_element_name(el, type_key)
|
||||||
existing = find_element(root_ci, el_name) if root_ci is not None else None
|
existing = find_element(root_ci, el_name) if root_ci is not None else None
|
||||||
if existing is not None:
|
if existing is not None:
|
||||||
print(f"[WARN] Element '{el_name}' already exists in form (id={existing.get('id')})")
|
print(f"[ERROR] Element '{el_name}' already exists in form (id={existing.get('id')}) — element names must be unique")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# Remember starting element ID for companion counting
|
# Remember starting element ID for companion counting
|
||||||
start_elem_id = next_elem_id
|
start_elem_id = next_elem_id
|
||||||
@@ -1055,6 +1083,19 @@ if attrs_list:
|
|||||||
if not attr_child_indent:
|
if not attr_child_indent:
|
||||||
attr_child_indent = "\t\t"
|
attr_child_indent = "\t\t"
|
||||||
|
|
||||||
|
# Уникальность имён реквизитов: внутри JSON-определения (+ колонки в пределах реквизита) и
|
||||||
|
# против уже существующих реквизитов формы.
|
||||||
|
dsl_attr_names = set()
|
||||||
|
for attr in attrs_list:
|
||||||
|
_assert_edit_unique(str(attr["name"]), dsl_attr_names, "attribute name")
|
||||||
|
if attr.get("columns"):
|
||||||
|
dsl_col_names = set()
|
||||||
|
for col in attr["columns"]:
|
||||||
|
_assert_edit_unique(str(col["name"]), dsl_col_names, f"column name of '{attr['name']}'")
|
||||||
|
if attrs_section.find(f"f:Attribute[@name='{attr['name']}']", NS) is not None:
|
||||||
|
print(f"[ERROR] Attribute '{attr['name']}' already exists in form — attribute names must be unique")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# Generate attribute fragments
|
# Generate attribute fragments
|
||||||
xml_lines.clear()
|
xml_lines.clear()
|
||||||
X(f"<_F {ALL_NS_DECL}>")
|
X(f"<_F {ALL_NS_DECL}>")
|
||||||
@@ -1116,6 +1157,14 @@ if cmds_list:
|
|||||||
if not cmd_child_indent:
|
if not cmd_child_indent:
|
||||||
cmd_child_indent = "\t\t"
|
cmd_child_indent = "\t\t"
|
||||||
|
|
||||||
|
# Уникальность имён команд: внутри JSON-определения и против существующих команд формы.
|
||||||
|
dsl_cmd_names = set()
|
||||||
|
for cmd in cmds_list:
|
||||||
|
_assert_edit_unique(str(cmd["name"]), dsl_cmd_names, "command name")
|
||||||
|
if cmds_section.find(f"f:Command[@name='{cmd['name']}']", NS) is not None:
|
||||||
|
print(f"[ERROR] Command '{cmd['name']}' already exists in form — command names must be unique")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
xml_lines.clear()
|
xml_lines.clear()
|
||||||
X(f"<_F {ALL_NS_DECL}>")
|
X(f"<_F {ALL_NS_DECL}>")
|
||||||
for cmd in cmds_list:
|
for cmd in cmds_list:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-validate v1.6 — Validate 1C managed form
|
# form-validate v1.7 — Validate 1C managed form
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -155,7 +155,8 @@ if (-not $stopped) {
|
|||||||
|
|
||||||
# --- Collect all elements with IDs ---
|
# --- Collect all elements with IDs ---
|
||||||
|
|
||||||
$elementIds = @{} # id -> name (element ID pool)
|
$elementIds = @{} # id -> name (element ID pool)
|
||||||
|
$elementNames = @{} # name -> id (имена элементов уникальны в пределах формы)
|
||||||
$allElements = @() # @{Name; Tag; Id; ParentName; Node}
|
$allElements = @() # @{Name; Tag; Id; ParentName; Node}
|
||||||
|
|
||||||
function Collect-Elements {
|
function Collect-Elements {
|
||||||
@@ -185,6 +186,13 @@ function Collect-Elements {
|
|||||||
} else {
|
} else {
|
||||||
$elementIds[$id] = $name
|
$elementIds[$id] = $name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Имена элементов уникальны (требование 1С)
|
||||||
|
if ($elementNames.ContainsKey($name)) {
|
||||||
|
Report-Error "Duplicate element name '$name': id=${id} and id=$($elementNames[$name])"
|
||||||
|
} else {
|
||||||
|
$elementNames[$name] = $id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Recurse into ChildItems
|
# Recurse into ChildItems
|
||||||
@@ -229,6 +237,10 @@ foreach ($attr in $attrNodes) {
|
|||||||
$attrName = $attr.GetAttribute("name")
|
$attrName = $attr.GetAttribute("name")
|
||||||
$attrId = $attr.GetAttribute("id")
|
$attrId = $attr.GetAttribute("id")
|
||||||
if ($attrName) {
|
if ($attrName) {
|
||||||
|
# Имена реквизитов уникальны среди реквизитов (отдельный неймспейс от элементов)
|
||||||
|
if ($attrMap.ContainsKey($attrName)) {
|
||||||
|
Report-Error "Duplicate attribute name '$attrName': id=${attrId} and id=$($attrMap[$attrName].GetAttribute('id'))"
|
||||||
|
}
|
||||||
$attrMap[$attrName] = $attr
|
$attrMap[$attrName] = $attr
|
||||||
}
|
}
|
||||||
if ($attrId -and $attrId -ne "") {
|
if ($attrId -and $attrId -ne "") {
|
||||||
@@ -241,6 +253,7 @@ foreach ($attr in $attrNodes) {
|
|||||||
|
|
||||||
# Column IDs are a separate sub-pool per attribute — check uniqueness within parent
|
# Column IDs are a separate sub-pool per attribute — check uniqueness within parent
|
||||||
$colIds = @{}
|
$colIds = @{}
|
||||||
|
$colNames = @{} # имена колонок уникальны в пределах своего реквизита
|
||||||
foreach ($col in $attr.SelectNodes("f:Columns/f:Column", $nsMgr)) {
|
foreach ($col in $attr.SelectNodes("f:Columns/f:Column", $nsMgr)) {
|
||||||
$colId = $col.GetAttribute("id")
|
$colId = $col.GetAttribute("id")
|
||||||
$colName = $col.GetAttribute("name")
|
$colName = $col.GetAttribute("name")
|
||||||
@@ -251,6 +264,13 @@ foreach ($attr in $attrNodes) {
|
|||||||
$colIds[$colId] = $colName
|
$colIds[$colId] = $colName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($colName) {
|
||||||
|
if ($colNames.ContainsKey($colName)) {
|
||||||
|
Report-Error "Duplicate column name '$colName' in '$attrName': id=${colId} and id=$($colNames[$colName])"
|
||||||
|
} else {
|
||||||
|
$colNames[$colName] = $colId
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +290,10 @@ foreach ($cmd in $cmdNodes) {
|
|||||||
$cmdName = $cmd.GetAttribute("name")
|
$cmdName = $cmd.GetAttribute("name")
|
||||||
$cmdId = $cmd.GetAttribute("id")
|
$cmdId = $cmd.GetAttribute("id")
|
||||||
if ($cmdName) {
|
if ($cmdName) {
|
||||||
|
# Имена команд уникальны среди команд (отдельный неймспейс)
|
||||||
|
if ($cmdMap.ContainsKey($cmdName)) {
|
||||||
|
Report-Error "Duplicate command name '$cmdName': id=${cmdId} and id=$($cmdMap[$cmdName].GetAttribute('id'))"
|
||||||
|
}
|
||||||
$cmdMap[$cmdName] = $cmd
|
$cmdMap[$cmdName] = $cmd
|
||||||
}
|
}
|
||||||
if ($cmdId -and $cmdId -ne "") {
|
if ($cmdId -and $cmdId -ne "") {
|
||||||
@@ -290,6 +314,20 @@ if (-not $stopped) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# --- Collect parameters (separate name pool, без id) ---
|
||||||
|
|
||||||
|
$paramNames = @{} # name -> $true (имена параметров уникальны среди параметров)
|
||||||
|
foreach ($param in $root.SelectNodes("f:Parameters/f:Parameter", $nsMgr)) {
|
||||||
|
$paramName = $param.GetAttribute("name")
|
||||||
|
if ($paramName) {
|
||||||
|
if ($paramNames.ContainsKey($paramName)) {
|
||||||
|
Report-Error "Duplicate parameter name '$paramName'"
|
||||||
|
} else {
|
||||||
|
$paramNames[$paramName] = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# --- Check 4: Companion elements ---
|
# --- Check 4: Companion elements ---
|
||||||
|
|
||||||
# Define required companions per element type
|
# Define required companions per element type
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# form-validate v1.6 — Validate 1C managed form
|
# form-validate v1.7 — Validate 1C managed form
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -182,7 +182,8 @@ def main():
|
|||||||
report_error("AutoCommandBar element missing")
|
report_error("AutoCommandBar element missing")
|
||||||
|
|
||||||
# --- Collect all elements with IDs ---
|
# --- Collect all elements with IDs ---
|
||||||
element_ids = {} # id -> name
|
element_ids = {} # id -> name
|
||||||
|
element_names = {} # name -> id (имена элементов уникальны в пределах формы)
|
||||||
all_elements = [] # list of dicts {Name, Tag, Id, ParentName, Node}
|
all_elements = [] # list of dicts {Name, Tag, Id, ParentName, Node}
|
||||||
|
|
||||||
def collect_elements(node, parent_name):
|
def collect_elements(node, parent_name):
|
||||||
@@ -211,6 +212,12 @@ def main():
|
|||||||
else:
|
else:
|
||||||
element_ids[eid] = name
|
element_ids[eid] = name
|
||||||
|
|
||||||
|
# Имена элементов уникальны (требование 1С)
|
||||||
|
if name in element_names:
|
||||||
|
report_error(f"Duplicate element name '{name}': id={eid} and id={element_names[name]}")
|
||||||
|
else:
|
||||||
|
element_names[name] = eid
|
||||||
|
|
||||||
child_items = child.find(f"{{{F_NS}}}ChildItems")
|
child_items = child.find(f"{{{F_NS}}}ChildItems")
|
||||||
if child_items is not None:
|
if child_items is not None:
|
||||||
collect_elements(child_items, name)
|
collect_elements(child_items, name)
|
||||||
@@ -252,6 +259,9 @@ def main():
|
|||||||
attr_name = attr.get("name", "")
|
attr_name = attr.get("name", "")
|
||||||
attr_id = attr.get("id", "")
|
attr_id = attr.get("id", "")
|
||||||
if attr_name:
|
if attr_name:
|
||||||
|
# Имена реквизитов уникальны среди реквизитов (отдельный неймспейс от элементов)
|
||||||
|
if attr_name in attr_map:
|
||||||
|
report_error(f"Duplicate attribute name '{attr_name}': id={attr_id} and id={attr_map[attr_name].get('id', '')}")
|
||||||
attr_map[attr_name] = attr
|
attr_map[attr_name] = attr
|
||||||
if attr_id:
|
if attr_id:
|
||||||
if attr_id in attr_ids:
|
if attr_id in attr_ids:
|
||||||
@@ -261,6 +271,7 @@ def main():
|
|||||||
|
|
||||||
# Column IDs uniqueness within parent
|
# Column IDs uniqueness within parent
|
||||||
col_ids = {}
|
col_ids = {}
|
||||||
|
col_names = {} # имена колонок уникальны в пределах своего реквизита
|
||||||
columns = attr.find(f"{{{F_NS}}}Columns")
|
columns = attr.find(f"{{{F_NS}}}Columns")
|
||||||
if columns is not None:
|
if columns is not None:
|
||||||
for col in columns.findall(f"{{{F_NS}}}Column"):
|
for col in columns.findall(f"{{{F_NS}}}Column"):
|
||||||
@@ -271,6 +282,11 @@ def main():
|
|||||||
report_error(f"Duplicate column id={col_id} in '{attr_name}': '{col_name}' and '{col_ids[col_id]}'")
|
report_error(f"Duplicate column id={col_id} in '{attr_name}': '{col_name}' and '{col_ids[col_id]}'")
|
||||||
else:
|
else:
|
||||||
col_ids[col_id] = col_name
|
col_ids[col_id] = col_name
|
||||||
|
if col_name:
|
||||||
|
if col_name in col_names:
|
||||||
|
report_error(f"Duplicate column name '{col_name}' in '{attr_name}': id={col_id} and id={col_names[col_name]}")
|
||||||
|
else:
|
||||||
|
col_names[col_name] = col_id
|
||||||
|
|
||||||
if not stopped:
|
if not stopped:
|
||||||
if attr_ids:
|
if attr_ids:
|
||||||
@@ -289,6 +305,9 @@ def main():
|
|||||||
cmd_name = cmd.get("name", "")
|
cmd_name = cmd.get("name", "")
|
||||||
cmd_id = cmd.get("id", "")
|
cmd_id = cmd.get("id", "")
|
||||||
if cmd_name:
|
if cmd_name:
|
||||||
|
# Имена команд уникальны среди команд (отдельный неймспейс)
|
||||||
|
if cmd_name in cmd_map:
|
||||||
|
report_error(f"Duplicate command name '{cmd_name}': id={cmd_id} and id={cmd_map[cmd_name].get('id', '')}")
|
||||||
cmd_map[cmd_name] = cmd
|
cmd_map[cmd_name] = cmd
|
||||||
if cmd_id:
|
if cmd_id:
|
||||||
if cmd_id in cmd_ids:
|
if cmd_id in cmd_ids:
|
||||||
@@ -300,6 +319,18 @@ def main():
|
|||||||
if cmd_ids:
|
if cmd_ids:
|
||||||
report_ok(f"Unique command IDs: {len(cmd_ids)} entries")
|
report_ok(f"Unique command IDs: {len(cmd_ids)} entries")
|
||||||
|
|
||||||
|
# --- Collect parameters (separate name pool, без id) ---
|
||||||
|
param_names = {} # name -> True (имена параметров уникальны среди параметров)
|
||||||
|
params_parent = root.find(f"{{{F_NS}}}Parameters")
|
||||||
|
if params_parent is not None:
|
||||||
|
for param in params_parent.findall(f"{{{F_NS}}}Parameter"):
|
||||||
|
param_name = param.get("name", "")
|
||||||
|
if param_name:
|
||||||
|
if param_name in param_names:
|
||||||
|
report_error(f"Duplicate parameter name '{param_name}'")
|
||||||
|
else:
|
||||||
|
param_names[param_name] = True
|
||||||
|
|
||||||
# --- Check 4: Companion elements ---
|
# --- Check 4: Companion elements ---
|
||||||
companion_rules = {
|
companion_rules = {
|
||||||
"InputField": ["ContextMenu", "ExtendedTooltip"],
|
"InputField": ["ContextMenu", "ExtendedTooltip"],
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-info v1.1 — Compact summary of 1C metadata object
|
# meta-info v1.2 — Compact summary of 1C metadata object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)][Alias('Path')][string]$ObjectPath,
|
[Parameter(Mandatory=$true)][Alias('Path')][string]$ObjectPath,
|
||||||
@@ -422,6 +422,22 @@ $objName = $props.SelectSingleNode("md:Name", $ns).InnerText
|
|||||||
$synNode = $props.SelectSingleNode("md:Synonym", $ns)
|
$synNode = $props.SelectSingleNode("md:Synonym", $ns)
|
||||||
$synonym = Get-MLText $synNode
|
$synonym = Get-MLText $synNode
|
||||||
|
|
||||||
|
# Presentations (type-choice dialogs show "Представление объекта" as the ref type name)
|
||||||
|
$objPresentation = Get-MLText $props.SelectSingleNode("md:ObjectPresentation", $ns)
|
||||||
|
$extObjPresentation = Get-MLText $props.SelectSingleNode("md:ExtendedObjectPresentation", $ns)
|
||||||
|
$listPresentation = Get-MLText $props.SelectSingleNode("md:ListPresentation", $ns)
|
||||||
|
$extListPresentation = Get-MLText $props.SelectSingleNode("md:ExtendedListPresentation", $ns)
|
||||||
|
|
||||||
|
# Reference (ref-typed) metadata objects — those with a ...Ref type
|
||||||
|
$refMdTypes = @("Catalog","Document","Enum","ChartOfAccounts","ChartOfCharacteristicTypes",
|
||||||
|
"ChartOfCalculationTypes","ExchangePlan","BusinessProcess","Task")
|
||||||
|
$isRefObject = $refMdTypes -contains $mdType
|
||||||
|
|
||||||
|
# Effective type presentation: ObjectPresentation -> Synonym -> Name
|
||||||
|
$typePresentation = if ($objPresentation) { $objPresentation }
|
||||||
|
elseif ($synonym) { $synonym }
|
||||||
|
else { $objName }
|
||||||
|
|
||||||
# --- Handle -Name drill-down ---
|
# --- Handle -Name drill-down ---
|
||||||
$drillDone = $false
|
$drillDone = $false
|
||||||
if ($Name -and $childObjs) {
|
if ($Name -and $childObjs) {
|
||||||
@@ -593,6 +609,17 @@ if (-not $drillDone) {
|
|||||||
$header += " ==="
|
$header += " ==="
|
||||||
Out $header
|
Out $header
|
||||||
|
|
||||||
|
# --- Type presentation (ref objects) ---
|
||||||
|
if ($isRefObject) {
|
||||||
|
Out "Представление типа: $typePresentation"
|
||||||
|
if ($Mode -eq "full") {
|
||||||
|
if ($objPresentation) { Out "Представление объекта: $objPresentation" }
|
||||||
|
if ($extObjPresentation) { Out "Расширенное представление объекта: $extObjPresentation" }
|
||||||
|
if ($listPresentation) { Out "Представление списка: $listPresentation" }
|
||||||
|
if ($extListPresentation) { Out "Расширенное представление списка: $extListPresentation" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# --- Mode: brief ---
|
# --- Mode: brief ---
|
||||||
if ($Mode -eq "brief") {
|
if ($Mode -eq "brief") {
|
||||||
# Attributes
|
# Attributes
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-info v1.1 — Compact summary of 1C metadata object (Python port)
|
# meta-info v1.2 — Compact summary of 1C metadata object (Python port)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -477,6 +477,21 @@ obj_name = inner_text(find(props, "md:Name"))
|
|||||||
syn_node = find(props, "md:Synonym")
|
syn_node = find(props, "md:Synonym")
|
||||||
synonym = get_ml_text(syn_node)
|
synonym = get_ml_text(syn_node)
|
||||||
|
|
||||||
|
# Presentations (type-choice dialogs show "Представление объекта" as the ref type name)
|
||||||
|
obj_presentation = get_ml_text(find(props, "md:ObjectPresentation"))
|
||||||
|
ext_obj_presentation = get_ml_text(find(props, "md:ExtendedObjectPresentation"))
|
||||||
|
list_presentation = get_ml_text(find(props, "md:ListPresentation"))
|
||||||
|
ext_list_presentation = get_ml_text(find(props, "md:ExtendedListPresentation"))
|
||||||
|
|
||||||
|
# Reference (ref-typed) metadata objects — those with a ...Ref type
|
||||||
|
ref_md_types = {"Catalog", "Document", "Enum", "ChartOfAccounts",
|
||||||
|
"ChartOfCharacteristicTypes", "ChartOfCalculationTypes",
|
||||||
|
"ExchangePlan", "BusinessProcess", "Task"}
|
||||||
|
is_ref_object = md_type in ref_md_types
|
||||||
|
|
||||||
|
# Effective type presentation: ObjectPresentation -> Synonym -> Name
|
||||||
|
type_presentation = obj_presentation or synonym or obj_name
|
||||||
|
|
||||||
# ── Handle -Name drill-down ──────────────────────────────────
|
# ── Handle -Name drill-down ──────────────────────────────────
|
||||||
|
|
||||||
drill_done = False
|
drill_done = False
|
||||||
@@ -636,6 +651,19 @@ if not drill_done:
|
|||||||
header += " ==="
|
header += " ==="
|
||||||
out(header)
|
out(header)
|
||||||
|
|
||||||
|
# Type presentation (ref objects)
|
||||||
|
if is_ref_object:
|
||||||
|
out(f"Представление типа: {type_presentation}")
|
||||||
|
if mode == "full":
|
||||||
|
if obj_presentation:
|
||||||
|
out(f"Представление объекта: {obj_presentation}")
|
||||||
|
if ext_obj_presentation:
|
||||||
|
out(f"Расширенное представление объекта: {ext_obj_presentation}")
|
||||||
|
if list_presentation:
|
||||||
|
out(f"Представление списка: {list_presentation}")
|
||||||
|
if ext_list_presentation:
|
||||||
|
out(f"Расширенное представление списка: {ext_list_presentation}")
|
||||||
|
|
||||||
if mode == "brief":
|
if mode == "brief":
|
||||||
# Attributes
|
# Attributes
|
||||||
attrs = get_attributes(child_objs) if child_objs is not None else []
|
attrs = get_attributes(child_objs) if child_objs is not None else []
|
||||||
|
|||||||
@@ -152,11 +152,19 @@ Shorthand: `"Имя [Заголовок]: тип = значение @флаги"
|
|||||||
|
|
||||||
Флаги shorthand:
|
Флаги shorthand:
|
||||||
- `@autoDates` — добавляет к параметру StandardPeriod пару дат `НачалоПериода`/`КонецПериода`, вычисляемых из него. Используй их в тексте запроса как `&НачалоПериода`/`&КонецПериода`; пользователь выбирает только сам период. По умолчанию сам параметр получает `use=Always` и `denyIncompleteValues=true` (чтобы производные даты всегда были заполнены); в объектной форме можно явно переопределить.
|
- `@autoDates` — добавляет к параметру StandardPeriod пару дат `НачалоПериода`/`КонецПериода`, вычисляемых из него. Используй их в тексте запроса как `&НачалоПериода`/`&КонецПериода`; пользователь выбирает только сам период. По умолчанию сам параметр получает `use=Always` и `denyIncompleteValues=true` (чтобы производные даты всегда были заполнены); в объектной форме можно явно переопределить.
|
||||||
- `@valueList` — `<valueListAllowed>true</valueListAllowed>` — разрешает передавать список значений
|
- `@valueList` — `<valueListAllowed>true</valueListAllowed>` — разрешает передавать список значений (при значении-списке ниже подразумевается автоматически)
|
||||||
- `@hidden` — скрытый параметр: `availableAsField=false` + исключается из `"dataParameters": "auto"`
|
- `@hidden` — скрытый параметр: `availableAsField=false` + исключается из `"dataParameters": "auto"`
|
||||||
|
|
||||||
Объектная форма: `title`, `hidden: true`, `valueListAllowed: true`, `availableAsField: false`, `denyIncompleteValues: true`, `use: "Always"`.
|
Объектная форма: `title`, `hidden: true`, `valueListAllowed: true`, `availableAsField: false`, `denyIncompleteValues: true`, `use: "Always"`.
|
||||||
|
|
||||||
|
Значение-список: несколько значений по умолчанию через запятую в `значение` (для запятой внутри значения — кавычки `'...'`). В объектной форме — массив в `value`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"parameters": [
|
||||||
|
"Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
Если значения по умолчанию нет — пропусти `=` в shorthand или укажи `"value": null` в объектной форме.
|
Если значения по умолчанию нет — пропусти `=` в shorthand или укажи `"value": null` в объектной форме.
|
||||||
|
|
||||||
Список допустимых значений (availableValues):
|
Список допустимых значений (availableValues):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-compile v1.104 — Compile 1C DCS from JSON
|
# skd-compile v1.105 — Compile 1C DCS from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[string]$DefinitionFile,
|
[string]$DefinitionFile,
|
||||||
@@ -475,6 +475,31 @@ function Parse-TotalShorthand {
|
|||||||
|
|
||||||
# --- 7. Parameter shorthand parser ---
|
# --- 7. Parameter shorthand parser ---
|
||||||
|
|
||||||
|
function Split-ValueListCsv {
|
||||||
|
# Split on top-level commas (respecting 'single'/"double" quotes), strip quotes,
|
||||||
|
# drop empties. No ':' handling — values may contain colons (dateTime).
|
||||||
|
param([string]$s)
|
||||||
|
$result = @()
|
||||||
|
if ($null -eq $s) { return ,$result }
|
||||||
|
$items = @()
|
||||||
|
$buf = New-Object System.Text.StringBuilder
|
||||||
|
$inQuote = $null
|
||||||
|
for ($i = 0; $i -lt $s.Length; $i++) {
|
||||||
|
$ch = $s[$i]
|
||||||
|
if ($inQuote) { [void]$buf.Append($ch); if ($ch -eq $inQuote) { $inQuote = $null } }
|
||||||
|
elseif ($ch -eq "'" -or $ch -eq '"') { $inQuote = $ch; [void]$buf.Append($ch) }
|
||||||
|
elseif ($ch -eq ',') { $items += $buf.ToString(); [void]$buf.Clear() }
|
||||||
|
else { [void]$buf.Append($ch) }
|
||||||
|
}
|
||||||
|
if ($buf.Length -gt 0) { $items += $buf.ToString() }
|
||||||
|
foreach ($raw in $items) {
|
||||||
|
$t = $raw.Trim()
|
||||||
|
if ($t.Length -ge 2 -and (($t[0] -eq "'" -and $t[-1] -eq "'") -or ($t[0] -eq '"' -and $t[-1] -eq '"'))) { $t = $t.Substring(1, $t.Length - 2) }
|
||||||
|
if ($t -ne "") { $result += $t }
|
||||||
|
}
|
||||||
|
return ,$result
|
||||||
|
}
|
||||||
|
|
||||||
function Parse-ParamShorthand {
|
function Parse-ParamShorthand {
|
||||||
param([string]$s)
|
param([string]$s)
|
||||||
|
|
||||||
@@ -509,7 +534,17 @@ function Parse-ParamShorthand {
|
|||||||
$result.name = $Matches[1].Trim()
|
$result.name = $Matches[1].Trim()
|
||||||
$result.type = Resolve-TypeStr ($Matches[2].Trim())
|
$result.type = Resolve-TypeStr ($Matches[2].Trim())
|
||||||
if ($Matches[4]) {
|
if ($Matches[4]) {
|
||||||
$result.value = $Matches[4].Trim()
|
$rhs = $Matches[4].Trim()
|
||||||
|
$items = Split-ValueListCsv $rhs
|
||||||
|
if ($items.Count -ge 2) {
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
$result.value = $items
|
||||||
|
$result.valueListAllowed = $true
|
||||||
|
} elseif ($items.Count -eq 1) {
|
||||||
|
$result.value = $items[0]
|
||||||
|
} else {
|
||||||
|
$result.value = $rhs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result.name = $s.Trim()
|
$result.name = $s.Trim()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# skd-compile v1.104 — Compile 1C DCS from JSON
|
# skd-compile v1.105 — Compile 1C DCS from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
@@ -325,6 +325,39 @@ def parse_total_shorthand(s):
|
|||||||
|
|
||||||
# --- Parameter shorthand parser ---
|
# --- Parameter shorthand parser ---
|
||||||
|
|
||||||
|
def split_value_list_csv(s):
|
||||||
|
"""Split on top-level commas (respecting single/double quotes), strip quotes,
|
||||||
|
drop empties. No ':' handling — values may contain colons (dateTime)."""
|
||||||
|
result = []
|
||||||
|
if s is None:
|
||||||
|
return result
|
||||||
|
items = []
|
||||||
|
buf = []
|
||||||
|
in_quote = None
|
||||||
|
for ch in s:
|
||||||
|
if in_quote:
|
||||||
|
buf.append(ch)
|
||||||
|
if ch == in_quote:
|
||||||
|
in_quote = None
|
||||||
|
elif ch in ("'", '"'):
|
||||||
|
in_quote = ch
|
||||||
|
buf.append(ch)
|
||||||
|
elif ch == ',':
|
||||||
|
items.append("".join(buf))
|
||||||
|
buf = []
|
||||||
|
else:
|
||||||
|
buf.append(ch)
|
||||||
|
if buf:
|
||||||
|
items.append("".join(buf))
|
||||||
|
for raw in items:
|
||||||
|
t = raw.strip()
|
||||||
|
if len(t) >= 2 and ((t[0] == "'" and t[-1] == "'") or (t[0] == '"' and t[-1] == '"')):
|
||||||
|
t = t[1:-1]
|
||||||
|
if t != "":
|
||||||
|
result.append(t)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def parse_param_shorthand(s):
|
def parse_param_shorthand(s):
|
||||||
result = {'name': '', 'type': '', 'value': None, 'autoDates': False, 'title': None}
|
result = {'name': '', 'type': '', 'value': None, 'autoDates': False, 'title': None}
|
||||||
|
|
||||||
@@ -355,7 +388,16 @@ def parse_param_shorthand(s):
|
|||||||
result['name'] = m.group(1).strip()
|
result['name'] = m.group(1).strip()
|
||||||
result['type'] = resolve_type_str(m.group(2).strip())
|
result['type'] = resolve_type_str(m.group(2).strip())
|
||||||
if m.group(4):
|
if m.group(4):
|
||||||
result['value'] = m.group(4).strip()
|
rhs = m.group(4).strip()
|
||||||
|
items = split_value_list_csv(rhs)
|
||||||
|
if len(items) >= 2:
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
result['value'] = items
|
||||||
|
result['valueListAllowed'] = True
|
||||||
|
elif len(items) == 1:
|
||||||
|
result['value'] = items[0]
|
||||||
|
else:
|
||||||
|
result['value'] = rhs
|
||||||
else:
|
else:
|
||||||
result['name'] = s.strip()
|
result['name'] = s.strip()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-decompile v0.89 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
# skd-decompile v0.90 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -2494,9 +2494,22 @@ function Build-Structure {
|
|||||||
return ,$items
|
return ,$items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# True when selection/order is just the single auto element ("Auto") that the
|
||||||
|
# compiler adds by default to every shorthand group — folding such a group back
|
||||||
|
# to shorthand is bit-perfect (Parse-StructureShorthand re-adds it on compile).
|
||||||
|
# Disabled auto ({auto,use}), mixed lists ("Поле","Auto") and explicit fields
|
||||||
|
# are objects / non-singleton lists and won't match → those keep object form.
|
||||||
|
function Is-AutoOnly($val) {
|
||||||
|
if ($null -eq $val) { return $false }
|
||||||
|
$arr = @($val)
|
||||||
|
if ($arr.Count -ne 1) { return $false }
|
||||||
|
return ($arr[0] -is [string]) -and ($arr[0] -eq 'Auto')
|
||||||
|
}
|
||||||
|
|
||||||
# Try to fold a structure tree into string shorthand "A > B > details".
|
# Try to fold a structure tree into string shorthand "A > B > details".
|
||||||
# Conditions: linear chain (each level has exactly one child), each level is
|
# Conditions: linear chain (each level has exactly one child), each level is
|
||||||
# a plain group with single groupField and no local selection/order/filter.
|
# a plain group with single groupField and no local filter; selection/order are
|
||||||
|
# allowed only when they are the default single "Auto" element (see Is-AutoOnly).
|
||||||
function Try-StructureShorthand {
|
function Try-StructureShorthand {
|
||||||
param($items)
|
param($items)
|
||||||
if ($items.Count -ne 1) { return $null }
|
if ($items.Count -ne 1) { return $null }
|
||||||
@@ -2506,8 +2519,8 @@ function Try-StructureShorthand {
|
|||||||
# Disallow extras
|
# Disallow extras
|
||||||
if ($cur.Contains('type') -and $cur['type'] -ne 'group') { return $null }
|
if ($cur.Contains('type') -and $cur['type'] -ne 'group') { return $null }
|
||||||
if ($cur.Contains('name')) { return $null }
|
if ($cur.Contains('name')) { return $null }
|
||||||
if ($cur.Contains('selection')) { return $null }
|
if ($cur.Contains('selection') -and -not (Is-AutoOnly $cur['selection'])) { return $null }
|
||||||
if ($cur.Contains('order')) { return $null }
|
if ($cur.Contains('order') -and -not (Is-AutoOnly $cur['order'])) { return $null }
|
||||||
if ($cur.Contains('filter')) { return $null }
|
if ($cur.Contains('filter')) { return $null }
|
||||||
if ($cur.Contains('viewMode')) { return $null }
|
if ($cur.Contains('viewMode')) { return $null }
|
||||||
if ($cur.Contains('itemsViewMode')) { return $null }
|
if ($cur.Contains('itemsViewMode')) { return $null }
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# skd-decompile v0.89 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
# skd-decompile v0.90 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -2600,6 +2600,17 @@ def build_structure(node, loc):
|
|||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
def is_auto_only(val):
|
||||||
|
# True when selection/order is just the single auto element ("Auto") that the
|
||||||
|
# compiler adds by default to every shorthand group — folding such a group back
|
||||||
|
# to shorthand is bit-perfect (parse re-adds it on compile). Disabled auto
|
||||||
|
# ({auto,use}), mixed lists and explicit fields won't match → keep object form.
|
||||||
|
if val is None:
|
||||||
|
return False
|
||||||
|
arr = val if isinstance(val, list) else [val]
|
||||||
|
return len(arr) == 1 and isinstance(arr[0], str) and arr[0] == 'Auto'
|
||||||
|
|
||||||
|
|
||||||
def try_structure_shorthand(items):
|
def try_structure_shorthand(items):
|
||||||
if len(items) != 1:
|
if len(items) != 1:
|
||||||
return None
|
return None
|
||||||
@@ -2610,9 +2621,9 @@ def try_structure_shorthand(items):
|
|||||||
return None
|
return None
|
||||||
if 'name' in cur:
|
if 'name' in cur:
|
||||||
return None
|
return None
|
||||||
if 'selection' in cur:
|
if 'selection' in cur and not is_auto_only(cur['selection']):
|
||||||
return None
|
return None
|
||||||
if 'order' in cur:
|
if 'order' in cur and not is_auto_only(cur['order']):
|
||||||
return None
|
return None
|
||||||
if 'filter' in cur:
|
if 'filter' in cur:
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -91,6 +91,13 @@ Shorthand: `"Имя [Заголовок]: тип = значение [availableVa
|
|||||||
- `@autoDates` — генерирует пару скрытых параметров `ДатаНачала`/`ДатаОкончания` для StandardPeriod-параметра.
|
- `@autoDates` — генерирует пару скрытых параметров `ДатаНачала`/`ДатаОкончания` для StandardPeriod-параметра.
|
||||||
- `@hidden` — скрывает параметр от пользовательских настроек (для параметров-констант, используемых в запросе).
|
- `@hidden` — скрывает параметр от пользовательских настроек (для параметров-констант, используемых в запросе).
|
||||||
- `@always` — параметр всегда подставляется в запрос. Часто вместе с `@hidden`, но используется и отдельно (для видимых обязательных параметров типа отчётного периода).
|
- `@always` — параметр всегда подставляется в запрос. Часто вместе с `@hidden`, но используется и отдельно (для видимых обязательных параметров типа отчётного периода).
|
||||||
|
- `@valueList` — разрешает передавать в параметр список значений (при значении-списке ниже подразумевается автоматически, отдельно указывать не обязательно).
|
||||||
|
|
||||||
|
Значение-список: несколько значений по умолчанию задаются через запятую в `значение`. Для запятой внутри одного значения — кавычки `'...'`.
|
||||||
|
|
||||||
|
```
|
||||||
|
"Виды [Виды субконто]: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
"ПС: CatalogRef.Контрагенты = Справочник.Контрагенты.ПустаяСсылка @hidden"
|
"ПС: CatalogRef.Контрагенты = Справочник.Контрагенты.ПустаяСсылка @hidden"
|
||||||
@@ -115,6 +122,7 @@ Shorthand: `"ИмяПараметра [Заголовок] [ключ=значе
|
|||||||
"ПериодОтчета [Отчетный период]" # только title
|
"ПериодОтчета [Отчетный период]" # только title
|
||||||
"ПорядокОкругления availableValue=Перечисление.Округления.Окр1: руб., Перечисление.Округления.Окр1000: тыс."
|
"ПорядокОкругления availableValue=Перечисление.Округления.Окр1: руб., Перечисление.Округления.Окр1000: тыс."
|
||||||
"СчетПС value=ПланСчетов.Хозрасчетный.КассаПредприятия"
|
"СчетПС value=ПланСчетов.Хозрасчетный.КассаПредприятия"
|
||||||
|
"Виды value=ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
"Контрагент @hidden @always"
|
"Контрагент @hidden @always"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -122,7 +130,7 @@ Shorthand: `"ИмяПараметра [Заголовок] [ключ=значе
|
|||||||
|
|
||||||
`availableValue=` **заменяет весь список** допустимых значений (старые удаляются). Формат и кавычки — те же, что в `add-parameter`.
|
`availableValue=` **заменяет весь список** допустимых значений (старые удаляются). Формат и кавычки — те же, что в `add-parameter`.
|
||||||
|
|
||||||
`value=` заменяет значение параметра (тип значения подбирается автоматически по объявленному типу параметра).
|
`value=` заменяет значение параметра. Несколько значений через запятую → **список значений** (заменяет все прежние); для запятой внутри значения — кавычки `'...'`.
|
||||||
|
|
||||||
Флаги `@hidden` / `@always` — те же, что и в `add-parameter`. Идемпотентны.
|
Флаги `@hidden` / `@always` — те же, что и в `add-parameter`. Идемпотентны.
|
||||||
|
|
||||||
@@ -256,6 +264,8 @@ Value — имена ресурсов (как в полях/вычисляемы
|
|||||||
|
|
||||||
Не поддерживает пакетный режим. Value — полный текст запроса или `@path/to/file.sql` (ссылка на внешний файл). Путь разрешается относительно Template.xml, затем CWD.
|
Не поддерживает пакетный режим. Value — полный текст запроса или `@path/to/file.sql` (ссылка на внешний файл). Путь разрешается относительно Template.xml, затем CWD.
|
||||||
|
|
||||||
|
Когда что: **существенная переработка** (добавить поля, соединения, переписать пакет) → выгрузи запрос через `/skd-info <tpl> -Mode query -Name <набор> -Raw -OutFile file.sql`, отредактируй файл, верни `set-query @file`. `-Raw` отдаёт запрос целиком без декораций, поэтому выгрузка ↔ возврат точны (включая многопакетные запросы). **Точечная замена** (переименовать идентификатор, заменить подстроку) → выгрузка не нужна, используй `patch-query` ниже.
|
||||||
|
|
||||||
### patch-query — точечная замена в тексте запроса
|
### patch-query — точечная замена в тексте запроса
|
||||||
|
|
||||||
Shorthand: `"старое => новое [@once]"`. По умолчанию заменяет все вхождения подстроки. Поддерживает пакетный режим и `-DataSet`.
|
Shorthand: `"старое => новое [@once]"`. По умолчанию заменяет все вхождения подстроки. Поддерживает пакетный режим и `-DataSet`.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-edit v1.24 — Atomic 1C DCS editor
|
# skd-edit v1.25 — Atomic 1C DCS editor
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -378,7 +378,19 @@ function Parse-ParamShorthand {
|
|||||||
$hasEq = $null -ne $Matches[3]
|
$hasEq = $null -ne $Matches[3]
|
||||||
$rhs = $Matches[4]
|
$rhs = $Matches[4]
|
||||||
if ($hasEq) {
|
if ($hasEq) {
|
||||||
$result.value = if ($rhs) { $rhs.Trim() } else { "" }
|
if ($rhs -and $rhs.Trim()) {
|
||||||
|
$items = Parse-ValueList $rhs.Trim()
|
||||||
|
if ($items.Count -ge 2) {
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
$result.value = $items
|
||||||
|
$result.valueListAllowed = $true
|
||||||
|
} else {
|
||||||
|
# Scalar (single item, quotes stripped) or empty sentinel
|
||||||
|
$result.value = if ($items.Count -eq 1) { $items[0] } else { "" }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result.value = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result.name = $s.Trim()
|
$result.name = $s.Trim()
|
||||||
@@ -679,16 +691,13 @@ function Parse-OutputParamShorthand {
|
|||||||
return @{ key = $s.Trim(); value = "" }
|
return @{ key = $s.Trim(); value = "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
function Parse-AvailableValueList {
|
function Split-QuotedCsv {
|
||||||
# Returns array of @{ value=...; presentation=... } from comma-separated list.
|
# Splits on top-level commas, respecting 'single' and "double" quoted spans.
|
||||||
# Items can use 'single' or "double" quotes (stripped). Quoted spans preserve commas/colons.
|
# Returns raw (un-stripped, un-trimmed) item spans. Used by both availableValue
|
||||||
|
# (value:presentation) and value-list (values only) parsing.
|
||||||
param([string]$s)
|
param([string]$s)
|
||||||
|
|
||||||
$result = @()
|
|
||||||
if (-not $s) { return ,$result }
|
|
||||||
|
|
||||||
# Tokenize by ',' respecting quoted spans
|
|
||||||
$items = @()
|
$items = @()
|
||||||
|
if ($null -eq $s) { return ,$items }
|
||||||
$buf = New-Object System.Text.StringBuilder
|
$buf = New-Object System.Text.StringBuilder
|
||||||
$inQuote = $null
|
$inQuote = $null
|
||||||
for ($i = 0; $i -lt $s.Length; $i++) {
|
for ($i = 0; $i -lt $s.Length; $i++) {
|
||||||
@@ -707,16 +716,42 @@ function Parse-AvailableValueList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($buf.Length -gt 0) { $items += $buf.ToString() }
|
if ($buf.Length -gt 0) { $items += $buf.ToString() }
|
||||||
|
return ,$items
|
||||||
|
}
|
||||||
|
|
||||||
# For each item: split into value[:presentation], strip quotes
|
function Strip-Quotes {
|
||||||
$stripQuotes = {
|
# Strips a single surrounding pair of matching quotes; trims first.
|
||||||
param($t)
|
param([string]$t)
|
||||||
$t = $t.Trim()
|
$t = $t.Trim()
|
||||||
if ($t.Length -ge 2 -and (($t[0] -eq "'" -and $t[-1] -eq "'") -or ($t[0] -eq '"' -and $t[-1] -eq '"'))) {
|
if ($t.Length -ge 2 -and (($t[0] -eq "'" -and $t[-1] -eq "'") -or ($t[0] -eq '"' -and $t[-1] -eq '"'))) {
|
||||||
return $t.Substring(1, $t.Length - 2)
|
return $t.Substring(1, $t.Length - 2)
|
||||||
}
|
|
||||||
return $t
|
|
||||||
}
|
}
|
||||||
|
return $t
|
||||||
|
}
|
||||||
|
|
||||||
|
function Parse-ValueList {
|
||||||
|
# Returns array of value strings (quotes stripped) split by top-level commas.
|
||||||
|
# No ':' handling — values may contain colons (e.g. dateTime 2024-01-01T12:30:00).
|
||||||
|
param([string]$s)
|
||||||
|
$result = @()
|
||||||
|
if ($null -eq $s) { return ,$result }
|
||||||
|
foreach ($raw in (Split-QuotedCsv $s)) {
|
||||||
|
$v = Strip-Quotes $raw
|
||||||
|
if ($v -ne "") { $result += $v }
|
||||||
|
}
|
||||||
|
return ,$result
|
||||||
|
}
|
||||||
|
|
||||||
|
function Parse-AvailableValueList {
|
||||||
|
# Returns array of @{ value=...; presentation=... } from comma-separated list.
|
||||||
|
# Items can use 'single' or "double" quotes (stripped). Quoted spans preserve commas/colons.
|
||||||
|
param([string]$s)
|
||||||
|
|
||||||
|
$result = @()
|
||||||
|
if (-not $s) { return ,$result }
|
||||||
|
|
||||||
|
$items = Split-QuotedCsv $s
|
||||||
|
$stripQuotes = { param($t) Strip-Quotes $t }
|
||||||
|
|
||||||
foreach ($raw in $items) {
|
foreach ($raw in $items) {
|
||||||
$item = $raw.Trim()
|
$item = $raw.Trim()
|
||||||
@@ -1135,7 +1170,14 @@ function Build-ParamFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$vla = [bool]$parsed.valueListAllowed
|
$vla = [bool]$parsed.valueListAllowed
|
||||||
if ($null -ne $parsed.value) {
|
$valIsArray = ($parsed.value -is [array]) -or ($parsed.value -is [System.Collections.IList] -and $parsed.value -isnot [string])
|
||||||
|
if ($valIsArray) {
|
||||||
|
# Multi-value default (value-list): one <value> per item
|
||||||
|
foreach ($v in $parsed.value) {
|
||||||
|
$valueLines = Build-ParamValueXml -type $parsed.type -value $v -indent "$i`t"
|
||||||
|
foreach ($vl in $valueLines) { $lines += $vl }
|
||||||
|
}
|
||||||
|
} elseif ($null -ne $parsed.value) {
|
||||||
if (Test-EmptyValue $parsed.value) {
|
if (Test-EmptyValue $parsed.value) {
|
||||||
$emptyXml = Build-EmptyValueXml -type $parsed.type -indent "$i`t" -tagPrefix "" -tagName "value" -valueListAllowed $vla
|
$emptyXml = Build-EmptyValueXml -type $parsed.type -indent "$i`t" -tagPrefix "" -tagName "value" -valueListAllowed $vla
|
||||||
if ($emptyXml) { $lines += $emptyXml }
|
if ($emptyXml) { $lines += $emptyXml }
|
||||||
@@ -2292,6 +2334,20 @@ switch ($Operation) {
|
|||||||
$avPart = $rest.Substring($avIdx)
|
$avPart = $rest.Substring($avIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Separate a multi-value value=... (list) — kv-regex below grabs only a single
|
||||||
|
# \S+ token, so a comma-separated list (with spaces) wouldn't be captured.
|
||||||
|
# availableValue already peeled, so 'value=' here is the real value key.
|
||||||
|
$valueListItems = $null
|
||||||
|
$vlIdx = $simpleRest.IndexOf('value=')
|
||||||
|
if ($vlIdx -ge 0) {
|
||||||
|
$vlRhs = $simpleRest.Substring($vlIdx + 'value='.Length)
|
||||||
|
$cand = Parse-ValueList $vlRhs
|
||||||
|
if ($cand.Count -ge 2) {
|
||||||
|
$valueListItems = $cand
|
||||||
|
$simpleRest = $simpleRest.Substring(0, $vlIdx).Trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Process simple key=value pairs (use, denyIncompleteValues, value, etc.)
|
# Process simple key=value pairs (use, denyIncompleteValues, value, etc.)
|
||||||
if ($simpleRest) {
|
if ($simpleRest) {
|
||||||
$kvPairs = [regex]::Matches($simpleRest, '(\w+)=(\S+)')
|
$kvPairs = [regex]::Matches($simpleRest, '(\w+)=(\S+)')
|
||||||
@@ -2337,14 +2393,20 @@ switch ($Operation) {
|
|||||||
$fragXml = $valueLines -join "`n"
|
$fragXml = $valueLines -join "`n"
|
||||||
}
|
}
|
||||||
|
|
||||||
$wasExisting = ($null -ne $existing)
|
# Collect ALL existing <value> (a param may carry a value-list) — scalar
|
||||||
if ($existing) {
|
# value= collapses them to one, so remove every <value>, not just the first.
|
||||||
# Capture position by next-element sibling, then remove existing
|
$allValueEls = @()
|
||||||
$refNode = $existing.NextSibling
|
foreach ($ch in $paramEl.ChildNodes) {
|
||||||
|
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'value' -and $ch.NamespaceURI -eq $schNs) { $allValueEls += $ch }
|
||||||
|
}
|
||||||
|
$wasExisting = ($allValueEls.Count -gt 0)
|
||||||
|
if ($wasExisting) {
|
||||||
|
# Capture position after the last existing value, then remove all
|
||||||
|
$refNode = $allValueEls[$allValueEls.Count - 1].NextSibling
|
||||||
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) {
|
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) {
|
||||||
$refNode = $refNode.NextSibling
|
$refNode = $refNode.NextSibling
|
||||||
}
|
}
|
||||||
Remove-NodeWithWhitespace $existing
|
foreach ($ve in $allValueEls) { Remove-NodeWithWhitespace $ve }
|
||||||
} else {
|
} else {
|
||||||
# Insert before useRestriction/availableValue/denyIncompleteValues/use
|
# Insert before useRestriction/availableValue/denyIncompleteValues/use
|
||||||
$refNode = $null
|
$refNode = $null
|
||||||
@@ -2385,6 +2447,60 @@ switch ($Operation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Process multi-value list (value=v1, v2, ...) — replace ALL <value>, ensure valueListAllowed=true
|
||||||
|
if ($valueListItems) {
|
||||||
|
# Declared type from <valueType>
|
||||||
|
$declaredType = ""
|
||||||
|
$vtEl = $null
|
||||||
|
foreach ($ch in $paramEl.ChildNodes) {
|
||||||
|
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'valueType' -and $ch.NamespaceURI -eq $schNs) { $vtEl = $ch; break }
|
||||||
|
}
|
||||||
|
if ($vtEl) {
|
||||||
|
foreach ($tnode in $vtEl.ChildNodes) {
|
||||||
|
if ($tnode.NodeType -eq 'Element' -and $tnode.LocalName -eq 'Type') {
|
||||||
|
$declaredType = $tnode.InnerText.Trim() -replace '^d\d+p\d+:', ''
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Remove ALL existing <value>; capture insertion ref after the last one
|
||||||
|
$valueEls = @()
|
||||||
|
foreach ($child in $paramEl.ChildNodes) {
|
||||||
|
if ($child.NodeType -eq 'Element' -and $child.LocalName -eq 'value' -and $child.NamespaceURI -eq $schNs) { $valueEls += $child }
|
||||||
|
}
|
||||||
|
$refNode = $null
|
||||||
|
if ($valueEls.Count -gt 0) {
|
||||||
|
$refNode = $valueEls[$valueEls.Count - 1].NextSibling
|
||||||
|
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) { $refNode = $refNode.NextSibling }
|
||||||
|
foreach ($ve in $valueEls) { Remove-NodeWithWhitespace $ve }
|
||||||
|
} else {
|
||||||
|
foreach ($child in $paramEl.ChildNodes) {
|
||||||
|
if ($child.NodeType -eq 'Element' -and $child.LocalName -in @('useRestriction','availableValue','denyIncompleteValues','use')) { $refNode = $child; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($v in $valueListItems) {
|
||||||
|
$fragXml = (Build-ParamValueXml -type $declaredType -value $v -indent $childIndent) -join "`n"
|
||||||
|
$nodes = Import-Fragment $xmlDoc $fragXml
|
||||||
|
foreach ($node in $nodes) { Insert-BeforeElement $paramEl $node $refNode $childIndent }
|
||||||
|
}
|
||||||
|
# Ensure <valueListAllowed>true</valueListAllowed> (schema order: after useRestriction, before availableValue/use)
|
||||||
|
$vlaEl = $null
|
||||||
|
foreach ($ch in $paramEl.ChildNodes) {
|
||||||
|
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'valueListAllowed' -and $ch.NamespaceURI -eq $schNs) { $vlaEl = $ch; break }
|
||||||
|
}
|
||||||
|
if ($vlaEl) {
|
||||||
|
if ($vlaEl.InnerText.Trim() -ne 'true') { $vlaEl.InnerText = 'true' }
|
||||||
|
} else {
|
||||||
|
$refVla = $null
|
||||||
|
foreach ($child in $paramEl.ChildNodes) {
|
||||||
|
if ($child.NodeType -eq 'Element' -and $child.LocalName -in @('availableValue','denyIncompleteValues','use')) { $refVla = $child; break }
|
||||||
|
}
|
||||||
|
$nodes = Import-Fragment $xmlDoc "$childIndent<valueListAllowed>true</valueListAllowed>"
|
||||||
|
foreach ($node in $nodes) { Insert-BeforeElement $paramEl $node $refVla $childIndent }
|
||||||
|
}
|
||||||
|
$script:Dirty = $true; Write-Host "[OK] Parameter `"$paramName`": value set to list of $($valueListItems.Count) item(s)"
|
||||||
|
}
|
||||||
|
|
||||||
# Process availableValue — replace whole list with new items
|
# Process availableValue — replace whole list with new items
|
||||||
if ($avPart) {
|
if ($avPart) {
|
||||||
$avRest = ($avPart -replace '^availableValue=', '').Trim()
|
$avRest = ($avPart -replace '^availableValue=', '').Trim()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-edit v1.24 — Atomic 1C DCS editor (Python port)
|
# skd-edit v1.25 — Atomic 1C DCS editor (Python port)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -371,7 +371,18 @@ def parse_param_shorthand(s):
|
|||||||
result["name"] = m.group(1).strip()
|
result["name"] = m.group(1).strip()
|
||||||
result["type"] = resolve_type_str(m.group(2).strip())
|
result["type"] = resolve_type_str(m.group(2).strip())
|
||||||
if m.group(3) is not None:
|
if m.group(3) is not None:
|
||||||
result["value"] = m.group(4).strip() if m.group(4) else ""
|
rhs = m.group(4)
|
||||||
|
if rhs and rhs.strip():
|
||||||
|
items = parse_value_list(rhs.strip())
|
||||||
|
if len(items) >= 2:
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
result["value"] = items
|
||||||
|
result["valueListAllowed"] = True
|
||||||
|
else:
|
||||||
|
# Scalar (single item, quotes stripped) or empty sentinel
|
||||||
|
result["value"] = items[0] if len(items) == 1 else ""
|
||||||
|
else:
|
||||||
|
result["value"] = ""
|
||||||
else:
|
else:
|
||||||
result["name"] = s.strip()
|
result["name"] = s.strip()
|
||||||
|
|
||||||
@@ -631,14 +642,12 @@ def parse_output_param_shorthand(s):
|
|||||||
return {"key": s.strip(), "value": ""}
|
return {"key": s.strip(), "value": ""}
|
||||||
|
|
||||||
|
|
||||||
def parse_available_value_list(s):
|
def split_quoted_csv(s):
|
||||||
"""Returns list of {value, presentation} from comma-separated list.
|
"""Split on top-level commas, respecting single/double quoted spans.
|
||||||
Items can use single/double quotes (stripped). Quoted spans preserve commas/colons."""
|
Returns raw (un-stripped) item spans. Shared by availableValue and value-list parsing."""
|
||||||
if not s:
|
|
||||||
return []
|
|
||||||
|
|
||||||
# Tokenize by ',' respecting quoted spans
|
|
||||||
items = []
|
items = []
|
||||||
|
if s is None:
|
||||||
|
return items
|
||||||
buf = []
|
buf = []
|
||||||
in_quote = None
|
in_quote = None
|
||||||
for ch in s:
|
for ch in s:
|
||||||
@@ -656,12 +665,37 @@ def parse_available_value_list(s):
|
|||||||
buf.append(ch)
|
buf.append(ch)
|
||||||
if buf:
|
if buf:
|
||||||
items.append("".join(buf))
|
items.append("".join(buf))
|
||||||
|
return items
|
||||||
|
|
||||||
def strip_quotes(t):
|
|
||||||
t = t.strip()
|
def strip_quotes(t):
|
||||||
if len(t) >= 2 and ((t[0] == "'" and t[-1] == "'") or (t[0] == '"' and t[-1] == '"')):
|
"""Strip a single surrounding pair of matching quotes; trims first."""
|
||||||
return t[1:-1]
|
t = t.strip()
|
||||||
return t
|
if len(t) >= 2 and ((t[0] == "'" and t[-1] == "'") or (t[0] == '"' and t[-1] == '"')):
|
||||||
|
return t[1:-1]
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
def parse_value_list(s):
|
||||||
|
"""Return list of value strings (quotes stripped) split by top-level commas.
|
||||||
|
No ':' handling — values may contain colons (e.g. dateTime 2024-01-01T12:30:00)."""
|
||||||
|
if s is None:
|
||||||
|
return []
|
||||||
|
result = []
|
||||||
|
for raw in split_quoted_csv(s):
|
||||||
|
v = strip_quotes(raw)
|
||||||
|
if v != "":
|
||||||
|
result.append(v)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def parse_available_value_list(s):
|
||||||
|
"""Returns list of {value, presentation} from comma-separated list.
|
||||||
|
Items can use single/double quotes (stripped). Quoted spans preserve commas/colons."""
|
||||||
|
if not s:
|
||||||
|
return []
|
||||||
|
|
||||||
|
items = split_quoted_csv(s)
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for raw in items:
|
for raw in items:
|
||||||
@@ -1012,7 +1046,12 @@ def build_param_fragment(parsed, indent):
|
|||||||
lines.append(f"{i}\t</valueType>")
|
lines.append(f"{i}\t</valueType>")
|
||||||
|
|
||||||
vla = bool(parsed.get("valueListAllowed"))
|
vla = bool(parsed.get("valueListAllowed"))
|
||||||
if parsed["value"] is not None:
|
if isinstance(parsed["value"], list):
|
||||||
|
# Multi-value default (value-list): one <value> per item
|
||||||
|
for v in parsed["value"]:
|
||||||
|
for vl in build_param_value_xml(parsed.get("type", ""), v, f"{i}\t"):
|
||||||
|
lines.append(vl)
|
||||||
|
elif parsed["value"] is not None:
|
||||||
if is_empty_value(parsed["value"]):
|
if is_empty_value(parsed["value"]):
|
||||||
empty_xml = build_empty_value_xml(parsed.get("type", ""), f"{i}\t", "", "value", vla)
|
empty_xml = build_empty_value_xml(parsed.get("type", ""), f"{i}\t", "", "value", vla)
|
||||||
if empty_xml:
|
if empty_xml:
|
||||||
@@ -1987,6 +2026,17 @@ elif operation == "modify-parameter":
|
|||||||
simple_rest = rest[:av_idx].strip()
|
simple_rest = rest[:av_idx].strip()
|
||||||
av_part = rest[av_idx:]
|
av_part = rest[av_idx:]
|
||||||
|
|
||||||
|
# Separate a multi-value value=... (list) — kv-regex below grabs only a single
|
||||||
|
# \S+ token, so a comma-separated list (with spaces) wouldn't be captured.
|
||||||
|
value_list_items = None
|
||||||
|
vl_idx = simple_rest.find("value=")
|
||||||
|
if vl_idx >= 0:
|
||||||
|
vl_rhs = simple_rest[vl_idx + len("value="):]
|
||||||
|
cand = parse_value_list(vl_rhs)
|
||||||
|
if len(cand) >= 2:
|
||||||
|
value_list_items = cand
|
||||||
|
simple_rest = simple_rest[:vl_idx].strip()
|
||||||
|
|
||||||
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
|
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
|
||||||
if simple_rest:
|
if simple_rest:
|
||||||
for m in re.finditer(r'(\w+)=(\S+)', simple_rest):
|
for m in re.finditer(r'(\w+)=(\S+)', simple_rest):
|
||||||
@@ -2012,12 +2062,15 @@ elif operation == "modify-parameter":
|
|||||||
else:
|
else:
|
||||||
value_lines = build_param_value_xml(declared_type, value, child_indent)
|
value_lines = build_param_value_xml(declared_type, value, child_indent)
|
||||||
frag_xml = "\n".join(value_lines)
|
frag_xml = "\n".join(value_lines)
|
||||||
was_existing = existing is not None
|
# Collect ALL existing <value> (a param may carry a value-list) — scalar
|
||||||
if existing is not None:
|
# value= collapses them to one, so remove every <value>, not just the first.
|
||||||
# Find next-element sibling as ref before removing
|
all_value_els = [ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "value" and etree.QName(ch.tag).namespace == SCH_NS]
|
||||||
idx = list(param_el).index(existing)
|
was_existing = len(all_value_els) > 0
|
||||||
ref_node = param_el[idx + 1] if idx + 1 < len(param_el) else None
|
if was_existing:
|
||||||
remove_node_with_whitespace(existing)
|
last_idx = list(param_el).index(all_value_els[-1])
|
||||||
|
ref_node = param_el[last_idx + 1] if last_idx + 1 < len(param_el) else None
|
||||||
|
for ve in all_value_els:
|
||||||
|
remove_node_with_whitespace(ve)
|
||||||
else:
|
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)
|
ref_node = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("useRestriction", "availableValue", "denyIncompleteValues", "use")), None)
|
||||||
if frag_xml:
|
if frag_xml:
|
||||||
@@ -2040,6 +2093,39 @@ elif operation == "modify-parameter":
|
|||||||
insert_before_element(param_el, node, ref_node, child_indent)
|
insert_before_element(param_el, node, ref_node, child_indent)
|
||||||
dirty = True; print(f'[OK] Parameter "{param_name}": {key}={value} added')
|
dirty = True; print(f'[OK] Parameter "{param_name}": {key}={value} added')
|
||||||
|
|
||||||
|
# Process multi-value list (value=v1, v2, ...) — replace ALL <value>, ensure valueListAllowed=true
|
||||||
|
if value_list_items:
|
||||||
|
declared_type = ""
|
||||||
|
vt_el = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "valueType" and etree.QName(ch.tag).namespace == SCH_NS), None)
|
||||||
|
if vt_el is not None:
|
||||||
|
for tnode in vt_el:
|
||||||
|
if isinstance(tnode.tag, str) and local_name(tnode) == "Type":
|
||||||
|
declared_type = re.sub(r'^d\d+p\d+:', '', (tnode.text or "").strip())
|
||||||
|
break
|
||||||
|
# Remove ALL existing <value>; capture insertion ref after the last one
|
||||||
|
value_els = [ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "value" and etree.QName(ch.tag).namespace == SCH_NS]
|
||||||
|
if value_els:
|
||||||
|
last_idx = list(param_el).index(value_els[-1])
|
||||||
|
ref_node = param_el[last_idx + 1] if last_idx + 1 < len(param_el) else None
|
||||||
|
for ve in value_els:
|
||||||
|
remove_node_with_whitespace(ve)
|
||||||
|
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)
|
||||||
|
for v in value_list_items:
|
||||||
|
frag_xml = "\n".join(build_param_value_xml(declared_type, v, child_indent))
|
||||||
|
for node in import_fragment(xml_doc, frag_xml):
|
||||||
|
insert_before_element(param_el, node, ref_node, child_indent)
|
||||||
|
# Ensure <valueListAllowed>true</valueListAllowed> (schema order: after useRestriction, before availableValue/use)
|
||||||
|
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:
|
||||||
|
if (vla_el.text or "").strip() != "true":
|
||||||
|
vla_el.text = "true"
|
||||||
|
else:
|
||||||
|
ref_vla = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("availableValue", "denyIncompleteValues", "use")), None)
|
||||||
|
for node in import_fragment(xml_doc, f"{child_indent}<valueListAllowed>true</valueListAllowed>"):
|
||||||
|
insert_before_element(param_el, node, ref_vla, child_indent)
|
||||||
|
dirty = True; print(f'[OK] Parameter "{param_name}": value set to list of {len(value_list_items)} item(s)')
|
||||||
|
|
||||||
# Process availableValue
|
# Process availableValue
|
||||||
if av_part:
|
if av_part:
|
||||||
av_rest = av_part[len("availableValue="):].strip()
|
av_rest = av_part[len("availableValue="):].strip()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: skd-info
|
name: skd-info
|
||||||
description: Анализ структуры схемы компоновки данных 1С (СКД) — наборы, поля, параметры, варианты. Используй для понимания отчёта — источник данных (запрос), доступные поля, параметры
|
description: Анализ структуры схемы компоновки данных 1С (СКД) — наборы, поля, параметры, варианты. Используй для понимания отчёта — источник данных (запрос), доступные поля, параметры
|
||||||
argument-hint: <TemplatePath> [-Mode overview|query|fields|links|calculated|resources|params|variant|templates|trace|full] [-Name <dataset|variant|field|group>]
|
argument-hint: <TemplatePath> [-Mode overview|query|fields|links|calculated|resources|params|variant|templates|trace|full] [-Name <dataset|variant|field|group>] [-Raw]
|
||||||
allowed-tools:
|
allowed-tools:
|
||||||
- Bash
|
- Bash
|
||||||
- Read
|
- Read
|
||||||
@@ -20,7 +20,8 @@ allowed-tools:
|
|||||||
| `Mode` | Режим анализа (по умолчанию `overview`) |
|
| `Mode` | Режим анализа (по умолчанию `overview`) |
|
||||||
| `Name` | Имя набора (query), поля (fields/calculated/resources/trace), варианта (variant) или группировки/поля (templates) |
|
| `Name` | Имя набора (query), поля (fields/calculated/resources/trace), варианта (variant) или группировки/поля (templates) |
|
||||||
| `Batch` | Номер пакета запроса, 0 = все (только query) |
|
| `Batch` | Номер пакета запроса, 0 = все (только query) |
|
||||||
| `Limit` / `Offset` | Пагинация (по умолчанию 150 строк) |
|
| `Raw` | (только query) сырой текст запроса целиком, без заголовков/оглавления/разделителей пакетов. Для выгрузки в `.sql` и возврата через `skd-edit set-query @file` |
|
||||||
|
| `Limit` / `Offset` | Пагинация (по умолчанию 150 строк; `-Raw` не усекается) |
|
||||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -31,6 +32,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
|||||||
```powershell
|
```powershell
|
||||||
... -Mode query -Name НоменклатураСЦенами
|
... -Mode query -Name НоменклатураСЦенами
|
||||||
... -Mode query -Name ДанныеТ13 -Batch 3
|
... -Mode query -Name ДанныеТ13 -Batch 3
|
||||||
|
... -Mode query -Name ДанныеТ13 -Raw -OutFile query.sql
|
||||||
... -Mode fields -Name КадастроваяСтоимость
|
... -Mode fields -Name КадастроваяСтоимость
|
||||||
... -Mode calculated -Name КоэффициентКи
|
... -Mode calculated -Name КоэффициентКи
|
||||||
... -Mode resources -Name СуммаНалога
|
... -Mode resources -Name СуммаНалога
|
||||||
@@ -45,7 +47,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
|||||||
| Режим | Без `-Name` | С `-Name` |
|
| Режим | Без `-Name` | С `-Name` |
|
||||||
|-------|-------------|-----------|
|
|-------|-------------|-----------|
|
||||||
| `overview` | Навигационная карта схемы + подсказки Next | — |
|
| `overview` | Навигационная карта схемы + подсказки Next | — |
|
||||||
| `query` | — | Текст запроса набора (с оглавлением батчей) |
|
| `query` | — | Текст запроса набора (с оглавлением батчей); `-Raw` — чистая выгрузка для правки |
|
||||||
| `fields` | Карта: имена полей по наборам | Деталь поля: набор, тип, роль, формат |
|
| `fields` | Карта: имена полей по наборам | Деталь поля: набор, тип, роль, формат |
|
||||||
| `links` | Все связи наборов | — |
|
| `links` | Все связи наборов | — |
|
||||||
| `calculated` | Карта: имена вычисляемых полей | Выражение + заголовок + ограничения |
|
| `calculated` | Карта: имена вычисляемых полей | Выражение + заголовок + ограничения |
|
||||||
@@ -65,7 +67,10 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
|||||||
3. `query -Name <набор>` — посмотреть текст SQL-запроса
|
3. `query -Name <набор>` — посмотреть текст SQL-запроса
|
||||||
4. `variant -Name <N>` — посмотреть группировки и фильтры варианта
|
4. `variant -Name <N>` — посмотреть группировки и фильтры варианта
|
||||||
|
|
||||||
Подробные примеры вывода каждого режима — в `modes-reference.md`.
|
Переработка запроса (round-trip): `query -Name <набор> -Raw -OutFile q.sql` →
|
||||||
|
правка `q.sql` → `/skd-edit <tpl> -Operation set-query -Value "@q.sql"`. Флаг
|
||||||
|
`-Raw` отдаёт запрос целиком без декораций, поэтому выгрузка ↔ возврат
|
||||||
|
точны (включая многопакетные запросы с временными таблицами).
|
||||||
|
|
||||||
## Верификация
|
## Верификация
|
||||||
|
|
||||||
|
|||||||
@@ -1,246 +0,0 @@
|
|||||||
# /skd-info — полная справка по режимам
|
|
||||||
|
|
||||||
Компактное описание — в [SKILL.md](SKILL.md).
|
|
||||||
|
|
||||||
## overview (по умолчанию) — карта схемы
|
|
||||||
|
|
||||||
Компактная навигационная карта (10-25 строк). Показывает структуру и подсказывает следующие шаги:
|
|
||||||
|
|
||||||
```
|
|
||||||
=== DCS: ОсновнаяСхемаКомпоновкиДанных (362 lines) ===
|
|
||||||
|
|
||||||
Sources: ИсточникДанных1 (Local)
|
|
||||||
|
|
||||||
Datasets:
|
|
||||||
[Query] НоменклатураСЦенами 7 fields, query 40 lines
|
|
||||||
Calculated: 1
|
|
||||||
Resources: 1
|
|
||||||
Templates: 1 templates, 1 group bindings
|
|
||||||
Params: (none)
|
|
||||||
|
|
||||||
Variants:
|
|
||||||
[1] НоменклатураИЦены "Номенклатура и цены" Table(detail) 3 filters
|
|
||||||
[2] НоменклатураБезЦен "Номенклатура без цен" Group(detail) 2 filters
|
|
||||||
|
|
||||||
Next:
|
|
||||||
-Mode query query text
|
|
||||||
-Mode fields field tables by dataset
|
|
||||||
-Mode calculated calculated field expressions
|
|
||||||
-Mode resources resource aggregation
|
|
||||||
-Mode variant -Name <N> variant structure (1..2)
|
|
||||||
```
|
|
||||||
|
|
||||||
Для DataSetUnion — дерево наборов + связи:
|
|
||||||
```
|
|
||||||
Datasets:
|
|
||||||
[Union] РасчетНалогаНаИмущество 52 fields
|
|
||||||
├─ [Query] РасчетНалогаНаИмущество 51 fields, query 181 lines
|
|
||||||
├─ [Query] ДанныеПоКадастровой 29 fields, query 40 lines
|
|
||||||
├─ [Query] ДанныеПоСреднегодовой 34 fields, query 41 lines
|
|
||||||
Links: РасчетНалогаНаИмущество -> СостояниеОС (2 fields)
|
|
||||||
```
|
|
||||||
|
|
||||||
Параметры разделяются на видимые/скрытые:
|
|
||||||
```
|
|
||||||
Params: 18 (7 visible, 11 hidden): Период, Ответственный, ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## query — текст запроса
|
|
||||||
|
|
||||||
`-Name <набор>` — имя DataSet (обязателен если наборов > 1).
|
|
||||||
|
|
||||||
Извлекает raw-текст запроса с деэкранированием XML (`&`→`&`, `>`→`>`). Для пакетных запросов — оглавление батчей:
|
|
||||||
|
|
||||||
```
|
|
||||||
=== Query: ДанныеТ13 (334 lines, 13 batches) ===
|
|
||||||
Batch 1: lines 1-8 → ПОМЕСТИТЬ Представления_Периоды
|
|
||||||
Batch 2: lines 9-26 → ПОМЕСТИТЬ Представления_СотрудникиОрганизации
|
|
||||||
...
|
|
||||||
--- Batch 1 ---
|
|
||||||
ВЫБРАТЬ
|
|
||||||
ДАТАВРЕМЯ(1, 1, 1) КАК Период
|
|
||||||
ПОМЕСТИТЬ Представления_Периоды
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Фильтр по номеру батча: `-Batch 3` покажет только 3-й пакет.
|
|
||||||
|
|
||||||
## fields — поля наборов данных
|
|
||||||
|
|
||||||
Без `-Name` — карта: имена полей по наборам:
|
|
||||||
```
|
|
||||||
=== Fields map ===
|
|
||||||
СостояниеОС [Query] (3): Организация, ОсновноеСредство, ДатаСостояния
|
|
||||||
РасчетНалогаНаИмущество [Union] (52): ДоляСтоимостиЧислитель, ...
|
|
||||||
РасчетНалогаНаИмущество [Query] (51): КадастроваяСтоимость, ...
|
|
||||||
```
|
|
||||||
|
|
||||||
С `-Name <поле>` — детали конкретного поля:
|
|
||||||
```
|
|
||||||
=== Field: ДатаСостояния "Дата ввода в эксплуатацию" ===
|
|
||||||
|
|
||||||
Dataset: СостояниеОС [Query]
|
|
||||||
Format: ДФ=dd.MM.yyyy
|
|
||||||
```
|
|
||||||
|
|
||||||
Показывает: dataset, title, type, role, useRestriction, format, presentationExpression.
|
|
||||||
|
|
||||||
## links — связи наборов данных
|
|
||||||
|
|
||||||
```
|
|
||||||
=== Links (4) ===
|
|
||||||
|
|
||||||
РасчетНалогаНаИмущество -> СостояниеОС :
|
|
||||||
Организация -> Организация
|
|
||||||
ОсновноеСредство -> ОсновноеСредство
|
|
||||||
```
|
|
||||||
|
|
||||||
Группирует по парам наборов. Показывает поля связи и параметры.
|
|
||||||
|
|
||||||
## calculated — вычисляемые поля
|
|
||||||
|
|
||||||
Без `-Name` — карта: имена и заголовки:
|
|
||||||
```
|
|
||||||
=== Calculated fields (23) ===
|
|
||||||
ДоляСтоимости "Доля стоимости"
|
|
||||||
КоэффициентКи "Коэффициент Ки"
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
С `-Name <поле>` — полное выражение:
|
|
||||||
```
|
|
||||||
=== Calculated: ДоляСтоимости ===
|
|
||||||
|
|
||||||
Expression:
|
|
||||||
ВЫБОР КОГДА ... ТОГДА "1" ИНАЧЕ ... КОНЕЦ
|
|
||||||
Title: Доля стоимости
|
|
||||||
Restrict: condition
|
|
||||||
```
|
|
||||||
|
|
||||||
## resources — ресурсы (итоги по группировкам)
|
|
||||||
|
|
||||||
Без `-Name` — карта: имена полей, `*` = есть формулы по группировкам:
|
|
||||||
```
|
|
||||||
=== Resources (51) ===
|
|
||||||
НалоговаяБаза
|
|
||||||
КоэффициентКи *
|
|
||||||
...
|
|
||||||
* = has group-level formulas
|
|
||||||
```
|
|
||||||
|
|
||||||
С `-Name <поле>` — формулы агрегации:
|
|
||||||
```
|
|
||||||
=== Resource: ДатаСостояния ===
|
|
||||||
|
|
||||||
[ОсновноеСредство] ЕстьNull(ДатаСостояния, "")
|
|
||||||
```
|
|
||||||
|
|
||||||
## params — параметры схемы
|
|
||||||
|
|
||||||
```
|
|
||||||
=== Parameters (16) ===
|
|
||||||
Name Type Default Visible Expression
|
|
||||||
Период StandardPeriod LastMonth yes -
|
|
||||||
НачалоПериода DateTime - hidden &Период.ДатаНачала
|
|
||||||
Организация CatalogRef.Организации null yes -
|
|
||||||
```
|
|
||||||
|
|
||||||
## variant — варианты отчёта
|
|
||||||
|
|
||||||
Без `-Name` — список вариантов:
|
|
||||||
```
|
|
||||||
=== Variants (2) ===
|
|
||||||
[1] НоменклатураИЦены "Номенклатура и цены" Table(detail) 3 filters
|
|
||||||
[2] НоменклатураБезЦен "Номенклатура без цен" Group(detail) 2 filters
|
|
||||||
```
|
|
||||||
|
|
||||||
С `-Name <N|имя>` — структура конкретного варианта:
|
|
||||||
```
|
|
||||||
=== Variant [1]: НоменклатураИЦены "Номенклатура и цены" ===
|
|
||||||
|
|
||||||
Structure:
|
|
||||||
Table "Таблица"
|
|
||||||
├── Columns: [ТипЦен Items]
|
|
||||||
│ Selection: Auto, Цена
|
|
||||||
└── Rows: [Номенклатура Items]
|
|
||||||
Selection: Номенклатура, УИД, Auto
|
|
||||||
|
|
||||||
Filter:
|
|
||||||
[ ] Номенклатура InHierarchy [user]
|
|
||||||
[ ] ТипЦен Equal
|
|
||||||
[x] ВАрхиве = false "Исключая скрытые товары"
|
|
||||||
|
|
||||||
DataParams: КлючВарианта="НоменклатураИЦены"
|
|
||||||
Output: style=ЧерноБелый groups=Separately totalsH=None totalsV=None
|
|
||||||
```
|
|
||||||
|
|
||||||
## templates — привязки шаблонов вывода
|
|
||||||
|
|
||||||
Три типа привязок: `fieldTemplate` (к полю), `groupTemplate` (к группировке, Header/Footer), `groupHeaderTemplate` (заголовок группы).
|
|
||||||
|
|
||||||
Без `-Name` — карта привязок:
|
|
||||||
```
|
|
||||||
=== Templates (70 defined: 49 field, 37 group) ===
|
|
||||||
|
|
||||||
Field bindings (49): (all trivial)
|
|
||||||
ОстаточнаяСтоимостьНа0101, ОстаточнаяСтоимостьНа0102, ...
|
|
||||||
|
|
||||||
Group bindings (37):
|
|
||||||
ВидНалоговойБазы
|
|
||||||
Header -> Макет3 (1 rows, 1 params)
|
|
||||||
СреднегодоваяСтоимость2019
|
|
||||||
Footer -> Макет50 (1 rows) spacer
|
|
||||||
GroupHeader -> Макет40 (3 rows)
|
|
||||||
```
|
|
||||||
|
|
||||||
С `-Name <группировка|поле>` — содержимое шаблонов:
|
|
||||||
```
|
|
||||||
=== Templates: СреднегодоваяСтоимость2019 ===
|
|
||||||
|
|
||||||
Footer -> Макет50 [1 rows, 1 cells]:
|
|
||||||
Row 1: (empty)
|
|
||||||
|
|
||||||
GroupHeader -> Макет40 [3 rows, 78 cells]:
|
|
||||||
Row 1: "№ п/п" | "###Группировки1###" | "Инв. номер" | ...
|
|
||||||
Row 2: "01.01" | "01.02" | ... | "31.12"
|
|
||||||
Row 3: "1" | "2" | ... | "26"
|
|
||||||
```
|
|
||||||
|
|
||||||
Для field-привязок:
|
|
||||||
```
|
|
||||||
=== Field template: ОстаточнаяСтоимостьНа0101 -> Макет4 ===
|
|
||||||
[1 rows, 1 cells]
|
|
||||||
Row 1: {ОстаточнаяСтоимостьНа0101}
|
|
||||||
(all params trivial)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Тривиальность выражений**: `Поле = Поле` и `Поле = Представление(Поле)` считаются тривиальными и НЕ выводятся. Показываются только нетривиальные — когда выражение содержит другое поле, вызов метода, пустую строку и т.д.
|
|
||||||
|
|
||||||
## trace — трассировка поля от заголовка до запроса
|
|
||||||
|
|
||||||
Ищет поле по dataPath ИЛИ заголовку (включая подстроку) и показывает полную цепочку происхождения за один вызов:
|
|
||||||
|
|
||||||
```
|
|
||||||
=== Trace: КоэффициентКи "Коэффициент Ки" ===
|
|
||||||
|
|
||||||
Dataset: (schema-level only, not in dataset fields)
|
|
||||||
|
|
||||||
Calculated:
|
|
||||||
ВЫБОР КОГДА ... ТОГДА 0 ИНАЧЕ ... КОНЕЦ
|
|
||||||
Operands:
|
|
||||||
КоличествоМесяцевИспользования -> РасчетНалогаНаИмущество [Query]
|
|
||||||
КоличествоМесяцевВладения -> РасчетНалогаНаИмущество [Query]
|
|
||||||
|
|
||||||
Resource:
|
|
||||||
[ОсновноеСредство] Сумма(КоэффициентКи)
|
|
||||||
```
|
|
||||||
|
|
||||||
Типичный сценарий: пользователь видит колонку "Коэффициент Ки" в отчёте и спрашивает как она считается. Один вызов `trace` показывает: формулу вычисления, откуда берутся операнды, как агрегируется в ресурс.
|
|
||||||
|
|
||||||
## Что не выводится
|
|
||||||
|
|
||||||
- XML namespace-декларации
|
|
||||||
- Обёртки v8:item/v8:lang/v8:content (извлекаем чистый текст)
|
|
||||||
- userSettingID (GUID-ы пользовательских настроек)
|
|
||||||
- Дефолтные periodAdditionBegin/End = 0001-01-01
|
|
||||||
- viewMode
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-info v1.5 — Analyze 1C DCS structure
|
# skd-info v1.6 — Analyze 1C DCS structure
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
@@ -10,7 +10,8 @@ param(
|
|||||||
[int]$Batch = 0,
|
[int]$Batch = 0,
|
||||||
[int]$Limit = 150,
|
[int]$Limit = 150,
|
||||||
[int]$Offset = 0,
|
[int]$Offset = 0,
|
||||||
[string]$OutFile
|
[string]$OutFile,
|
||||||
|
[switch]$Raw
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
@@ -655,6 +656,13 @@ function Show-Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$rawQuery = Unescape-Xml $queryNode.InnerText
|
$rawQuery = Unescape-Xml $queryNode.InnerText
|
||||||
|
|
||||||
|
# Raw mode: emit verbatim query text only (no headers/TOC/batch split) for round-trip
|
||||||
|
if ($Raw) {
|
||||||
|
foreach ($ql in ($rawQuery.Trim() -split "`n")) { $lines.Add($ql.TrimEnd()) }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
$dsNameStr = $targetDs.SelectSingleNode("s:name", $ns).InnerText
|
$dsNameStr = $targetDs.SelectSingleNode("s:name", $ns).InnerText
|
||||||
|
|
||||||
# Split into batches
|
# Split into batches
|
||||||
@@ -1894,7 +1902,7 @@ if ($Offset -gt 0) {
|
|||||||
$result = $result[$Offset..($totalLines - 1)]
|
$result = $result[$Offset..($totalLines - 1)]
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($result.Count -gt $Limit) {
|
if (-not $Raw -and $result.Count -gt $Limit) {
|
||||||
$shown = $result[0..($Limit - 1)]
|
$shown = $result[0..($Limit - 1)]
|
||||||
foreach ($l in $shown) { Write-Host $l }
|
foreach ($l in $shown) { Write-Host $l }
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# skd-info v1.5 — Analyze 1C DCS structure
|
# skd-info v1.6 — Analyze 1C DCS structure
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -278,6 +278,7 @@ def main():
|
|||||||
parser.add_argument("-Limit", type=int, default=150)
|
parser.add_argument("-Limit", type=int, default=150)
|
||||||
parser.add_argument("-Offset", type=int, default=0)
|
parser.add_argument("-Offset", type=int, default=0)
|
||||||
parser.add_argument("-OutFile", default=None)
|
parser.add_argument("-OutFile", default=None)
|
||||||
|
parser.add_argument("-Raw", action="store_true")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# --- Resolve path ---
|
# --- Resolve path ---
|
||||||
@@ -634,6 +635,13 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
raw_query = unescape_xml("".join(query_node.itertext()))
|
raw_query = unescape_xml("".join(query_node.itertext()))
|
||||||
|
|
||||||
|
# Raw mode: emit verbatim query text only (no headers/TOC/batch split) for round-trip
|
||||||
|
if args.Raw:
|
||||||
|
for ql in raw_query.strip().split("\n"):
|
||||||
|
lines.append(ql.rstrip())
|
||||||
|
return
|
||||||
|
|
||||||
ds_name_str = (target_ds.find("s:name", NSMAP).text or "")
|
ds_name_str = (target_ds.find("s:name", NSMAP).text or "")
|
||||||
|
|
||||||
# Split into batches
|
# Split into batches
|
||||||
@@ -1719,7 +1727,7 @@ def main():
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
result = result[args.Offset:]
|
result = result[args.Offset:]
|
||||||
|
|
||||||
if len(result) > args.Limit:
|
if not args.Raw and len(result) > args.Limit:
|
||||||
shown = result[:args.Limit]
|
shown = result[:args.Limit]
|
||||||
for line in shown:
|
for line in shown:
|
||||||
print(line)
|
print(line)
|
||||||
|
|||||||
@@ -351,7 +351,8 @@ Returns form state with `filled: [{ field, ok, ...}]`. Items are `{ field, ok: t
|
|||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| `tab` | Switch to tab before filling |
|
| `tab` | Switch to tab before filling |
|
||||||
| `add` | Add new row before filling |
|
| `add` | Add new row before filling |
|
||||||
| `row` | Edit existing row by 0-based index |
|
| `row` | Edit existing row: 0-based index, **or** a `{ col: value }` filter (one or more columns) to locate the row by its cell values |
|
||||||
|
| `scroll` | With a `row` filter — scan beyond the current DOM window (`true` = up to 50 PageDowns, number = limit) |
|
||||||
| `table` | Grid name from `tables[]` (for multi-grid forms) |
|
| `table` | Grid name from `tables[]` (for multi-grid forms) |
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -360,11 +361,14 @@ await fillTableRow(
|
|||||||
{ 'Номенклатура': 'Бумага', 'Количество': '10', 'Цена': '100' },
|
{ 'Номенклатура': 'Бумага', 'Количество': '10', 'Цена': '100' },
|
||||||
{ tab: 'Товары', add: true }
|
{ tab: 'Товары', add: true }
|
||||||
);
|
);
|
||||||
// Edit existing row:
|
// Edit existing row by index:
|
||||||
await fillTableRow(
|
await fillTableRow(
|
||||||
{ 'Количество': '20' },
|
{ 'Количество': '20' },
|
||||||
{ tab: 'Товары', row: 0 }
|
{ tab: 'Товары', row: 0 }
|
||||||
);
|
);
|
||||||
|
// Edit existing row located by cell values (одна или несколько колонок):
|
||||||
|
await fillTableRow({ 'Цена': '120' }, { table: 'Товары', row: { 'Номенклатура': 'Бумага' } });
|
||||||
|
await fillTableRow({ 'Сумма': '500' }, { row: { 'Номер': '0000-000601', 'Дата': '29.12.2016' }, scroll: true });
|
||||||
// Multi-grid form — add row to specific table:
|
// Multi-grid form — add row to specific table:
|
||||||
await fillTableRow(
|
await fillTableRow(
|
||||||
{ 'Объект': 'БДДС' },
|
{ 'Объект': 'БДДС' },
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ Use this when the user asks to cover a 1C solution with automated regression tes
|
|||||||
The runner is the same `run.mjs`. The mode is `test`:
|
The runner is the same `run.mjs`. The mode is `test`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node $RUN test [url] <dir|file> [flags]
|
node $RUN test <dir|file>... [flags]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Positional args are test paths (files and/or dirs, multiple allowed). URL is NOT positional — it comes from `webtest.config.mjs`; override with `--url=<url>`.
|
||||||
|
|
||||||
Tests live next to the project they cover (not inside the skill). Convention: `tests/` at the project root, with `_hooks.mjs` and `webtest.config.mjs` at the suite root. Tests are ES modules with `*.test.mjs` suffix.
|
Tests live next to the project they cover (not inside the skill). Convention: `tests/` at the project root, with `_hooks.mjs` and `webtest.config.mjs` at the suite root. Tests are ES modules with `*.test.mjs` suffix.
|
||||||
|
|
||||||
## When to choose `test` over `exec`
|
## When to choose `test` over `exec`
|
||||||
@@ -362,6 +364,7 @@ Each `params` entry becomes its own test in the report. `{key}` placeholders in
|
|||||||
node $RUN test tests/<app-name>/ # full app suite
|
node $RUN test tests/<app-name>/ # full app suite
|
||||||
node $RUN test tests/<app-name>/03-goods-receipt/ # one feature folder
|
node $RUN test tests/<app-name>/03-goods-receipt/ # one feature folder
|
||||||
node $RUN test tests/<app-name>/02-counterparties/01-create.test.mjs # one file
|
node $RUN test tests/<app-name>/02-counterparties/01-create.test.mjs # one file
|
||||||
|
node $RUN test tests/<app-name>/02-x.test.mjs tests/<app-name>/05-y.test.mjs # several files
|
||||||
node $RUN test tests/<app-name>/ --tags=smoke # by tag (intersection)
|
node $RUN test tests/<app-name>/ --tags=smoke # by tag (intersection)
|
||||||
node $RUN test tests/<app-name>/ --grep='накладн' # by name regex
|
node $RUN test tests/<app-name>/ --grep='накладн' # by name regex
|
||||||
node $RUN test tests/<app-name>/ --bail --retry=1 # stop on first fail, allow 1 retry
|
node $RUN test tests/<app-name>/ --bail --retry=1 # stop on first fail, allow 1 retry
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test cli/commands/test v1.2 — regression test runner
|
// web-test cli/commands/test v1.3 — regression test runner
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import { existsSync, writeFileSync, mkdirSync } from 'fs';
|
import { existsSync, writeFileSync, mkdirSync } from 'fs';
|
||||||
import { resolve, dirname, basename, relative } from 'path';
|
import { resolve, dirname, basename, relative } from 'path';
|
||||||
@@ -20,11 +20,12 @@ export async function cmdTest(rawArgs) {
|
|||||||
|
|
||||||
// Parse flags
|
// Parse flags
|
||||||
const opts = { bail: false, retry: 0, timeout: 30000, report: null, format: 'json', screenshot: null, reportDir: null, record: false };
|
const opts = { bail: false, retry: 0, timeout: 30000, report: null, format: 'json', screenshot: null, reportDir: null, record: false };
|
||||||
let tags = null, grep = null;
|
let tags = null, grep = null, urlFlag = null;
|
||||||
const positional = [];
|
const positional = [];
|
||||||
for (const a of ownArgs) {
|
for (const a of ownArgs) {
|
||||||
if (a.startsWith('--tags=')) tags = a.slice(7).split(',');
|
if (a.startsWith('--tags=')) tags = a.slice(7).split(',');
|
||||||
else if (a.startsWith('--grep=')) grep = new RegExp(a.slice(7), 'i');
|
else if (a.startsWith('--grep=')) grep = new RegExp(a.slice(7), 'i');
|
||||||
|
else if (a.startsWith('--url=')) urlFlag = a.slice(6);
|
||||||
else if (a === '--bail') opts.bail = true;
|
else if (a === '--bail') opts.bail = true;
|
||||||
else if (a.startsWith('--retry=')) opts.retry = parseInt(a.slice(8)) || 0;
|
else if (a.startsWith('--retry=')) opts.retry = parseInt(a.slice(8)) || 0;
|
||||||
else if (a.startsWith('--timeout=')) opts.timeout = parseInt(a.slice(10)) || 30000;
|
else if (a.startsWith('--timeout=')) opts.timeout = parseInt(a.slice(10)) || 30000;
|
||||||
@@ -36,20 +37,28 @@ export async function cmdTest(rawArgs) {
|
|||||||
else if (!a.startsWith('--')) positional.push(a);
|
else if (!a.startsWith('--')) positional.push(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine URL and test path
|
// Positional args are ALWAYS test paths (one or many). URL comes from --url= or config
|
||||||
let url, testPath;
|
// (see webtest.config.mjs). This matches pytest/jest/playwright; a positional that looks
|
||||||
if (positional.length === 2) {
|
// like a URL is a mistake → fail fast with a hint instead of feeding it to page.goto().
|
||||||
url = positional[0];
|
const isUrl = (s) => /^https?:\/\//i.test(s);
|
||||||
testPath = resolve(positional[1]);
|
let url = urlFlag || null;
|
||||||
} else if (positional.length === 1) {
|
const testPaths = [...positional];
|
||||||
testPath = resolve(positional[0]);
|
if (testPaths.length === 0) {
|
||||||
} else {
|
die('Usage: node run.mjs test <dir|file>... [--url=URL] [--tags=...] [--grep=...] [--bail] [--retry=N] [--timeout=ms] [--report=path]');
|
||||||
die('Usage: node run.mjs test [url] <dir|file> [--tags=...] [--bail] [--retry=N] [--timeout=ms] [--report=path]');
|
}
|
||||||
|
for (const p of testPaths) {
|
||||||
|
if (existsSync(resolve(p))) continue;
|
||||||
|
if (isUrl(p)) {
|
||||||
|
die(`"${p}" looks like a URL — use --url=<url>; positional args are test paths.`);
|
||||||
|
}
|
||||||
|
die(`Test path not found: "${p}". To run a subset use --grep= / --tags=, or pass an existing dir/file.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config if exists
|
// Load config if exists. config (webtest.config.mjs) and hooks (_hooks.mjs) resolve from
|
||||||
const isFile = testPath.endsWith('.test.mjs');
|
// the FIRST path's directory — list paths from the same suite folder.
|
||||||
const testDir = isFile ? dirname(testPath) : testPath;
|
const firstPath = resolve(testPaths[0]);
|
||||||
|
const isFile = firstPath.endsWith('.test.mjs');
|
||||||
|
const testDir = isFile ? dirname(firstPath) : firstPath;
|
||||||
const configPath = resolve(testDir, 'webtest.config.mjs');
|
const configPath = resolve(testDir, 'webtest.config.mjs');
|
||||||
let config = {};
|
let config = {};
|
||||||
if (existsSync(configPath)) {
|
if (existsSync(configPath)) {
|
||||||
@@ -110,8 +119,8 @@ export async function cmdTest(rawArgs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Discover test files
|
// Discover test files
|
||||||
const testFiles = discoverTests(testPath);
|
const testFiles = discoverTests(testPaths);
|
||||||
if (!testFiles.length) die(`No *.test.mjs files found in ${testPath}`);
|
if (!testFiles.length) die(`No *.test.mjs files found in ${testPaths.join(', ')}`);
|
||||||
|
|
||||||
// Import and filter tests
|
// Import and filter tests
|
||||||
const tests = [];
|
const tests = [];
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
// web-test cli/test-runner/discover v1.0 — test file discovery + state reset between tests
|
// web-test cli/test-runner/discover v1.1 — test file discovery + state reset between tests
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import { existsSync, readdirSync } from 'fs';
|
import { existsSync, readdirSync } from 'fs';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
|
||||||
export function discoverTests(testPath) {
|
// Accepts a single path or an array of paths (files and/or dirs). Each .test.mjs file is
|
||||||
if (testPath.endsWith('.test.mjs')) return existsSync(testPath) ? [testPath] : [];
|
// taken directly; each directory is walked recursively (skipping _ / . prefixes). Results
|
||||||
|
// are deduped and sorted — sorting preserves the numeric-prefix order the suite relies on
|
||||||
|
// (00-, 01-, …) even when paths are listed out of order.
|
||||||
|
export function discoverTests(testPaths) {
|
||||||
|
const paths = Array.isArray(testPaths) ? testPaths : [testPaths];
|
||||||
const files = [];
|
const files = [];
|
||||||
function walk(dir) {
|
function walk(dir) {
|
||||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||||
@@ -14,8 +18,15 @@ export function discoverTests(testPath) {
|
|||||||
else if (entry.name.endsWith('.test.mjs')) files.push(full);
|
else if (entry.name.endsWith('.test.mjs')) files.push(full);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
walk(testPath);
|
for (const p of paths) {
|
||||||
return files.sort();
|
const full = resolve(p);
|
||||||
|
if (full.endsWith('.test.mjs')) {
|
||||||
|
if (existsSync(full)) files.push(full);
|
||||||
|
} else if (existsSync(full)) {
|
||||||
|
walk(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...new Set(files)].sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resetState(ctx) {
|
export async function resetState(ctx) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test cli/util v1.1 — generic helpers for CLI commands
|
// web-test cli/util v1.2 — generic helpers for CLI commands
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
export function out(obj) {
|
export function out(obj) {
|
||||||
@@ -85,7 +85,7 @@ Commands:
|
|||||||
shot [file] Take screenshot (default: shot.png)
|
shot [file] Take screenshot (default: shot.png)
|
||||||
stop Logout and close browser
|
stop Logout and close browser
|
||||||
status Check session status
|
status Check session status
|
||||||
test [url] <dir|file> Run regression tests (*.test.mjs)
|
test <dir|file>... Run regression tests (*.test.mjs); accepts multiple paths
|
||||||
|
|
||||||
Options for exec:
|
Options for exec:
|
||||||
--no-record Skip video recording (record() becomes no-op)
|
--no-record Skip video recording (record() becomes no-op)
|
||||||
@@ -95,6 +95,7 @@ Global options (any command):
|
|||||||
Default: on (env: WEB_TEST_PRESERVE_CLIPBOARD=0 to disable globally).
|
Default: on (env: WEB_TEST_PRESERVE_CLIPBOARD=0 to disable globally).
|
||||||
|
|
||||||
Options for test:
|
Options for test:
|
||||||
|
--url=URL Override the base URL (default: from webtest.config.mjs)
|
||||||
--tags=smoke,crud Filter tests by tags
|
--tags=smoke,crud Filter tests by tags
|
||||||
--grep=pattern Filter tests by name (regex)
|
--grep=pattern Filter tests by name (regex)
|
||||||
--bail Stop on first failure
|
--bail Stop on first failure
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test dom/grid v1.8 — grid resolution + table reading + edit-time helpers
|
// web-test dom/grid v1.9 — grid resolution + table reading + edit-time helpers
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -677,7 +677,10 @@ export function snapshotGridScript(gridSelector) {
|
|||||||
const body = grid.querySelector('.gridBody');
|
const body = grid.querySelector('.gridBody');
|
||||||
if (!body) return null;
|
if (!body) return null;
|
||||||
const lines = body.querySelectorAll('.gridLine');
|
const lines = body.querySelectorAll('.gridLine');
|
||||||
const txt = ln => ln?.querySelector('.gridBoxText')?.innerText?.trim() || '';
|
// Full-row signature: join EVERY cell's text, not just the first column.
|
||||||
|
// A low-cardinality first column (e.g. all "Товар 0X") would otherwise make
|
||||||
|
// two different windows look identical and abort the reveal-loop early.
|
||||||
|
const txt = ln => ln ? [...ln.querySelectorAll('.gridBoxText')].map(b => (b.innerText || '').trim()).join('|') : '';
|
||||||
const selIdx = [...lines].findIndex(l => l.classList.contains('selRow') || l.classList.contains('select'));
|
const selIdx = [...lines].findIndex(l => l.classList.contains('selRow') || l.classList.contains('select'));
|
||||||
// hasBelow priority: (1) dynamic-list turn buttons, (2) tabular scrollbar tracks, (3) scrollHeight.
|
// hasBelow priority: (1) dynamic-list turn buttons, (2) tabular scrollbar tracks, (3) scrollHeight.
|
||||||
let hasBelow;
|
let hasBelow;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test forms/select-value v1.21 — Reference & composite-type value selection: selectValue, fillReferenceField, selection/type-dialog pickers.
|
// web-test forms/select-value v1.24 — Reference & composite-type value selection: selectValue, fillReferenceField, selection/type-dialog pickers.
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
} from '../core/helpers.mjs';
|
} from '../core/helpers.mjs';
|
||||||
import { pasteText } from '../core/clipboard.mjs';
|
import { pasteText } from '../core/clipboard.mjs';
|
||||||
import { getFormState } from './state.mjs';
|
import { getFormState } from './state.mjs';
|
||||||
|
import { filterList } from '../table/filter.mjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan visible grid rows for a text match (exact → startsWith → includes).
|
* Scan visible grid rows for a text match (exact → startsWith → includes).
|
||||||
@@ -165,7 +166,15 @@ export async function pickFromSelectionForm(selFormNum, fieldName, search, origF
|
|||||||
if (typeof search === 'object' && search) {
|
if (typeof search === 'object' && search) {
|
||||||
// Per-field advanced search via filterList(val, {field})
|
// Per-field advanced search via filterList(val, {field})
|
||||||
for (const [fld, val] of Object.entries(search)) {
|
for (const [fld, val] of Object.entries(search)) {
|
||||||
try { await filterList(String(val), { field: fld }); } catch { /* proceed */ }
|
try {
|
||||||
|
await filterList(String(val), { field: fld });
|
||||||
|
} catch (e) {
|
||||||
|
// Re-throw programming errors (e.g. a missing import surfacing as
|
||||||
|
// ReferenceError) — only field-filter failures (not found / unsupported
|
||||||
|
// column) should be swallowed so we fall through to the re-scan.
|
||||||
|
if (e instanceof ReferenceError || e instanceof TypeError) throw e;
|
||||||
|
/* proceed */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (searchLower) {
|
} else if (searchLower) {
|
||||||
// Inline advanced search (Alt+F, "по части строки")
|
// Inline advanced search (Alt+F, "по части строки")
|
||||||
@@ -279,33 +288,44 @@ export async function pickFromTypeDialog(formNum, typeName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1: Scan visible rows (fast path — no Ctrl+F needed for small lists)
|
// Exact-match preference: substring search can surface several types that merely CONTAIN the
|
||||||
const scan = await readVisibleRows();
|
// requested name (e.g. "Контрагент" → "Банковская карта контрагента", "Договор с контрагентом",
|
||||||
|
// …, "Контрагент"). Prefer the row equal to the requested name; only the absence of a single
|
||||||
if (scan.matches.length === 1) {
|
// exact match among multiple substring hits is a genuine ambiguity.
|
||||||
// Single match — click to select, then OK
|
function resolveExact(matches) {
|
||||||
await page.mouse.click(scan.matches[0].x, scan.matches[0].y);
|
if (!matches || matches.length === 0) return null;
|
||||||
|
if (matches.length === 1) return matches[0];
|
||||||
|
const exact = matches.filter(m => normYo((m.text || '').toLowerCase()) === typeNorm);
|
||||||
|
return exact.length === 1 ? exact[0] : null;
|
||||||
|
}
|
||||||
|
async function selectRowAndOk(row) {
|
||||||
|
await page.mouse.click(row.x, row.y);
|
||||||
await page.waitForTimeout(200);
|
await page.waitForTimeout(200);
|
||||||
await page.click(`#form${formNum}_OK`, { force: true });
|
await page.click(`#form${formNum}_OK`, { force: true });
|
||||||
await page.waitForTimeout(ACTION_WAIT);
|
await page.waitForTimeout(ACTION_WAIT);
|
||||||
return;
|
}
|
||||||
|
// Focus the grid via evaluate (does NOT punch through the modal overlay like page.click).
|
||||||
|
async function focusGrid() {
|
||||||
|
await page.evaluate(`(() => {
|
||||||
|
const grid = document.getElementById('form${formNum}_ValueList');
|
||||||
|
if (!grid) return;
|
||||||
|
const body = grid.querySelector('.gridBody');
|
||||||
|
if (body) body.focus(); else grid.focus();
|
||||||
|
})()`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 1: Scan visible rows (fast path — no Ctrl+F needed for small lists)
|
||||||
|
const scan = await readVisibleRows();
|
||||||
|
const scanPick = resolveExact(scan.matches);
|
||||||
|
if (scanPick) { await selectRowAndOk(scanPick); return; }
|
||||||
if (scan.matches.length > 1) {
|
if (scan.matches.length > 1) {
|
||||||
await dismissTypeDialog();
|
await dismissTypeDialog();
|
||||||
await waitForStable();
|
await waitForStable();
|
||||||
throw new Error(`selectValue: multiple types match "${typeName}": ${scan.matches.map(m => '"' + m.text + '"').join(', ')}. Specify a more precise type name`);
|
throw new Error(`selectValue: multiple types match "${typeName}": ${scan.matches.map(m => '"' + m.text + '"').join(', ')}. Specify a more precise type name`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Not found in visible rows — use Ctrl+F (virtual grid may have more items)
|
// Step 2: Not in visible rows — Ctrl+F jumps near the match in the large virtual list.
|
||||||
|
await focusGrid();
|
||||||
// Focus the grid via evaluate (does NOT punch through modal like page.click)
|
|
||||||
await page.evaluate(`(() => {
|
|
||||||
const grid = document.getElementById('form${formNum}_ValueList');
|
|
||||||
if (!grid) return;
|
|
||||||
const body = grid.querySelector('.gridBody');
|
|
||||||
if (body) body.focus(); else grid.focus();
|
|
||||||
})()`);
|
|
||||||
await page.waitForTimeout(300);
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
// Ctrl+F to open "Найти" dialog
|
// Ctrl+F to open "Найти" dialog
|
||||||
@@ -326,29 +346,40 @@ export async function pickFromTypeDialog(formNum, typeName) {
|
|||||||
throw new Error('selectValue: Ctrl+F did not open "Найти" dialog in type selection');
|
throw new Error('selectValue: Ctrl+F did not open "Найти" dialog in type selection');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Click "Найти" — search is client-side (no server round-trip), 500ms is enough
|
// Click "Найти" — search is client-side (no server round-trip)
|
||||||
await page.click(`#form${findFormNum}_Find`, { force: true });
|
await page.click(`#form${findFormNum}_Find`, { force: true });
|
||||||
await page.waitForTimeout(500);
|
|
||||||
|
|
||||||
// Re-read visible rows after search scrolled to match
|
// "Найти" positions at the first match; the exact row is at or just below it. Read, and if the
|
||||||
const afterSearch = await readVisibleRows();
|
// exact match is not yet in view, PageDown a few times (bounded) — virtualised grid, scrollTop
|
||||||
|
// stays 0 but the visible window changes. Poll each window for matches to settle.
|
||||||
|
let resolved = null, lastMatches = [], sawMatches = false;
|
||||||
|
for (let pageStep = 0; pageStep <= 3; pageStep++) {
|
||||||
|
if (pageStep > 0) { await focusGrid(); await page.keyboard.press('PageDown'); }
|
||||||
|
let v = null;
|
||||||
|
for (let w = 0; w < 5; w++) {
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
v = await readVisibleRows();
|
||||||
|
if (v.matches.length) break;
|
||||||
|
}
|
||||||
|
if (v && v.matches.length) {
|
||||||
|
sawMatches = true;
|
||||||
|
lastMatches = v.matches;
|
||||||
|
resolved = resolveExact(v.matches);
|
||||||
|
if (resolved) break;
|
||||||
|
// matches present but no single exact in this window — scroll to look just below
|
||||||
|
} else if (sawMatches) {
|
||||||
|
break; // scrolled past the matches without finding an exact one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resolved) { await selectRowAndOk(resolved); return; }
|
||||||
|
|
||||||
if (afterSearch.matches.length === 0) {
|
await dismissTypeDialog();
|
||||||
await dismissTypeDialog();
|
await waitForStable();
|
||||||
await waitForStable();
|
if (!sawMatches) {
|
||||||
throw new Error(`selectValue: type "${typeName}" not found in type selection dialog` +
|
throw new Error(`selectValue: type "${typeName}" not found in type selection dialog` +
|
||||||
`. Visible: ${(scan.visible || []).join(', ')}`);
|
`. Visible: ${(scan.visible || []).join(', ')}`);
|
||||||
}
|
}
|
||||||
|
throw new Error(`selectValue: multiple types match "${typeName}": ${lastMatches.map(m => '"' + m.text + '"').join(', ')}. Specify a more precise type name`);
|
||||||
if (afterSearch.matches.length > 1) {
|
|
||||||
await dismissTypeDialog();
|
|
||||||
await waitForStable();
|
|
||||||
throw new Error(`selectValue: multiple types match "${typeName}": ${afterSearch.matches.map(m => '"' + m.text + '"').join(', ')}. Specify a more precise type name`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Click OK on type dialog via page.click({force:true}) — bypasses "Найти" modal
|
|
||||||
await page.click(`#form${formNum}_OK`, { force: true });
|
|
||||||
await page.waitForTimeout(ACTION_WAIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -714,6 +745,21 @@ export async function selectValue(fieldName, searchText, { type } = {}) {
|
|||||||
const regularItems = popupItems.filter(i => i.kind !== 'showAll');
|
const regularItems = popupItems.filter(i => i.kind !== 'showAll');
|
||||||
const showAllItem = popupItems.find(i => i.kind === 'showAll');
|
const showAllItem = popupItems.find(i => i.kind === 'showAll');
|
||||||
|
|
||||||
|
if (searchText && typeof searchText !== 'string') {
|
||||||
|
// Object search ({field: value}) can't be matched against dropdown item
|
||||||
|
// text — close the typeahead popup and open the full selection form, which
|
||||||
|
// handles per-field advanced search (pickFromSelectionForm → filterList).
|
||||||
|
await page.keyboard.press('Escape');
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
const inputId = await findFieldInputId(formNum, btn.fieldName);
|
||||||
|
if (inputId) { await page.click(`[id="${inputId}"]`); await page.waitForTimeout(300); }
|
||||||
|
await page.keyboard.press('F4');
|
||||||
|
await page.waitForTimeout(ACTION_WAIT);
|
||||||
|
const formResult = await openFormAndPick();
|
||||||
|
if (formResult) return formResult;
|
||||||
|
throw new Error(`selectValue: object search ${JSON.stringify(searchText)} for "${btn.fieldName}" did not open a selection form`);
|
||||||
|
}
|
||||||
|
|
||||||
if (searchText) {
|
if (searchText) {
|
||||||
const target = normYo(searchText.toLowerCase());
|
const target = normYo(searchText.toLowerCase());
|
||||||
// Try to find match among regular dropdown items
|
// Try to find match among regular dropdown items
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test spreadsheet v1.19 — readSpreadsheet + helpers for SpreadsheetDocument (отчёты, печатные формы).
|
// web-test spreadsheet v1.20 — readSpreadsheet + helpers for SpreadsheetDocument (отчёты, печатные формы).
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import { page, ensureConnected } from '../core/state.mjs';
|
import { page, ensureConnected } from '../core/state.mjs';
|
||||||
@@ -7,6 +7,7 @@ import { waitForStable } from '../core/wait.mjs';
|
|||||||
import { getFormState } from '../forms/state.mjs';
|
import { getFormState } from '../forms/state.mjs';
|
||||||
import { returnFormState } from '../core/helpers.mjs';
|
import { returnFormState } from '../core/helpers.mjs';
|
||||||
import { scrollHorizontallyByKey } from '../core/scroll-horiz.mjs';
|
import { scrollHorizontallyByKey } from '../core/scroll-horiz.mjs';
|
||||||
|
import { checkForErrors } from '../core/errors.mjs';
|
||||||
|
|
||||||
// --- Spreadsheet helpers (shared by readSpreadsheet and clickElement) ---
|
// --- Spreadsheet helpers (shared by readSpreadsheet and clickElement) ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test table/click-cell v1.3 — click a cell in a form grid by (row, column).
|
// web-test table/click-cell v1.4 — click a cell in a form grid by (row, column).
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
//
|
//
|
||||||
// Routed from core/click.mjs when the user calls clickElement({row, column}) and
|
// Routed from core/click.mjs when the user calls clickElement({row, column}) and
|
||||||
@@ -32,6 +32,48 @@ const REVEAL_DEFAULT_LIMIT = 50;
|
|||||||
const PD_WAIT_MS = 300;
|
const PD_WAIT_MS = 300;
|
||||||
const FOCUS_WAIT_MS = 150;
|
const FOCUS_WAIT_MS = 150;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guard: a 'pic:N' filter value is a readTable picture token, not real cell text.
|
||||||
|
* Picture cells render an icon (no text), so they can't select a row — fail fast
|
||||||
|
* with guidance instead of a confusing 'row_not_found'.
|
||||||
|
*/
|
||||||
|
function assertNotPictureFilter(filter) {
|
||||||
|
for (const [k, v] of Object.entries(filter)) {
|
||||||
|
if (typeof v === 'string' && /^pic:\d+$/.test(v.trim())) {
|
||||||
|
throw new Error(`clickElement: "${v}" is a readTable picture value (column "${k}"), not selectable text — it can't be used as a row filter. Filter by a text column (e.g. name/number) instead.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a `{ col: value }` row filter to a numeric index into the grid's current
|
||||||
|
* DOM window (`body.querySelectorAll('.gridLine')`). Reused by fillTableRow so it
|
||||||
|
* can target an existing row by cell values, mirroring clickElement.
|
||||||
|
*
|
||||||
|
* The filter matches across ALL columns (AND). `findGridCellScript` requires a
|
||||||
|
* `column`, so we pass the first filter key as a placeholder — it only affects the
|
||||||
|
* returned coordinates (which we ignore), not row selection. The matched row
|
||||||
|
* guarantees that key's cell is in the DOM, so no `cell_not_in_dom` for it.
|
||||||
|
*
|
||||||
|
* @param {object} args
|
||||||
|
* @param {number} args.formNum
|
||||||
|
* @param {string} [args.gridSelector] - CSS selector for the target grid (same grid the caller edits)
|
||||||
|
* @param {object} args.filter - `{ col: value }` (one or more columns)
|
||||||
|
* @param {string} [args.gridName] - for diagnostics in error messages
|
||||||
|
* @param {boolean|number} [args.scroll] - reveal-loop beyond the DOM window (true = 50 PageDowns, number = limit)
|
||||||
|
* @returns {Promise<number>} resolved row index
|
||||||
|
*/
|
||||||
|
export async function resolveRowIndexByFilter({ formNum, gridSelector, filter, gridName, scroll }) {
|
||||||
|
assertNotPictureFilter(filter);
|
||||||
|
const target = { row: filter, column: Object.keys(filter)[0] };
|
||||||
|
let cell = await page.evaluate(findGridCellScript(formNum, gridSelector, target));
|
||||||
|
if (cell?.error === 'row_not_found' && scroll) {
|
||||||
|
cell = await revealAndFindCell({ formNum, gridSelector, target, scroll });
|
||||||
|
}
|
||||||
|
if (cell?.error) throw cellError(cell, target, gridName, scroll, 'fillTableRow');
|
||||||
|
return cell.rowIdx;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Click a cell in a form grid by (row, column). Called from core/click.mjs.
|
* Click a cell in a form grid by (row, column). Called from core/click.mjs.
|
||||||
*
|
*
|
||||||
@@ -47,16 +89,7 @@ const FOCUS_WAIT_MS = 150;
|
|||||||
export async function clickGridCell(target, ctx) {
|
export async function clickGridCell(target, ctx) {
|
||||||
const { formNum, gridSelector, gridName, modifier, dblclick, scroll } = ctx;
|
const { formNum, gridSelector, gridName, modifier, dblclick, scroll } = ctx;
|
||||||
|
|
||||||
// Guard: a 'pic:N' filter value is a readTable picture token, not real cell text.
|
if (target?.row && typeof target.row === 'object') assertNotPictureFilter(target.row);
|
||||||
// Picture cells render an icon (no text), so they can't select a row — fail fast
|
|
||||||
// with guidance instead of a confusing 'row_not_found'.
|
|
||||||
if (target?.row && typeof target.row === 'object') {
|
|
||||||
for (const [k, v] of Object.entries(target.row)) {
|
|
||||||
if (typeof v === 'string' && /^pic:\d+$/.test(v.trim())) {
|
|
||||||
throw new Error(`clickElement: "${v}" is a readTable picture value (column "${k}"), not selectable text — it can't be used as a row filter. Filter by a text column (e.g. name/number) instead.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. Try to find the cell in current DOM window.
|
// 1. Try to find the cell in current DOM window.
|
||||||
let cell = await page.evaluate(findGridCellScript(formNum, gridSelector, target));
|
let cell = await page.evaluate(findGridCellScript(formNum, gridSelector, target));
|
||||||
@@ -97,21 +130,21 @@ export async function clickGridCell(target, ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function cellError(cell, target, gridName, scroll) {
|
function cellError(cell, target, gridName, scroll, who = 'clickElement') {
|
||||||
const ctxMsg = gridName ? ` in table "${gridName}"` : '';
|
const ctxMsg = gridName ? ` in table "${gridName}"` : '';
|
||||||
if (cell.error === 'row_not_found') {
|
if (cell.error === 'row_not_found') {
|
||||||
const hint = scroll
|
const hint = scroll
|
||||||
? ' (reveal-loop exhausted)'
|
? ' (reveal-loop exhausted)'
|
||||||
: ' — pass { scroll: true } to scan beyond the current DOM window';
|
: ' — pass { scroll: true } to scan beyond the current DOM window';
|
||||||
return new Error(`clickElement: row matching ${JSON.stringify(target.row)} not found${ctxMsg}${hint}.`);
|
return new Error(`${who}: row matching ${JSON.stringify(target.row)} not found${ctxMsg}${hint}.`);
|
||||||
}
|
}
|
||||||
if (cell.error === 'column_not_found' || cell.error === 'filter_column_not_found') {
|
if (cell.error === 'column_not_found' || cell.error === 'filter_column_not_found') {
|
||||||
return new Error(`clickElement: column "${cell.column}" not found${ctxMsg}. Available: ${(cell.available || []).join(', ')}`);
|
return new Error(`${who}: column "${cell.column}" not found${ctxMsg}. Available: ${(cell.available || []).join(', ')}`);
|
||||||
}
|
}
|
||||||
if (cell.error === 'row_out_of_range') {
|
if (cell.error === 'row_out_of_range') {
|
||||||
return new Error(`clickElement: row index ${cell.row} out of range${ctxMsg} (loaded: ${cell.loaded}). Note: row index is into current DOM window, not absolute — long lists are virtualized.`);
|
return new Error(`${who}: row index ${cell.row} out of range${ctxMsg} (loaded: ${cell.loaded}). Note: row index is into current DOM window, not absolute — long lists are virtualized.`);
|
||||||
}
|
}
|
||||||
return new Error(`clickElement: cannot resolve cell ${JSON.stringify(target)}${ctxMsg}: ${cell.error}`);
|
return new Error(`${who}: cannot resolve cell ${JSON.stringify(target)}${ctxMsg}: ${cell.error}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,12 +175,20 @@ async function revealAndFindCell({ formNum, gridSelector, target, scroll }) {
|
|||||||
if (!cell?.error) return cell;
|
if (!cell?.error) return cell;
|
||||||
|
|
||||||
const snap = await page.evaluate(snapshotGridScript(gridSelector));
|
const snap = await page.evaluate(snapshotGridScript(gridSelector));
|
||||||
const stable = snap
|
// Reached the end of the list. Primary signal: nothing remains below
|
||||||
&& snap.firstText === prevSnap?.firstText
|
// (`hasBelow === false`) — the reliable cross-grid-type signal. Content
|
||||||
&& snap.lastText === prevSnap?.lastText
|
// stability is only a fallback when hasBelow is unknown: it compares the
|
||||||
&& snap.selIdx === prevSnap?.selIdx
|
// full-row text (snapshotGridScript joins every cell), so a low-cardinality
|
||||||
&& snap.lineCount === prevSnap?.lineCount;
|
// first column (e.g. all "Товар 0X") can't look "stable" mid-scroll.
|
||||||
if (stable) return { error: 'row_not_found', filter: target.row };
|
const reachedEnd = snap && (
|
||||||
|
snap.hasBelow === false
|
||||||
|
|| (snap.hasBelow == null
|
||||||
|
&& snap.firstText === prevSnap?.firstText
|
||||||
|
&& snap.lastText === prevSnap?.lastText
|
||||||
|
&& snap.selIdx === prevSnap?.selIdx
|
||||||
|
&& snap.lineCount === prevSnap?.lineCount)
|
||||||
|
);
|
||||||
|
if (reachedEnd) return { error: 'row_not_found', filter: target.row };
|
||||||
prevSnap = snap;
|
prevSnap = snap;
|
||||||
}
|
}
|
||||||
return { error: 'row_not_found', filter: target.row };
|
return { error: 'row_not_found', filter: target.row };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// web-test table/row-fill v1.20 — fillTableRow — заполнение строки табличной части/списка через Tab-навигацию и попутный выбор значений.
|
// web-test table/row-fill v1.23 — fillTableRow — заполнение строки табличной части/списка через Tab-навигацию и попутный выбор значений.
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -24,12 +24,122 @@ import {
|
|||||||
readEdd, isEddVisible, clickEddItemViaDispatch,
|
readEdd, isEddVisible, clickEddItemViaDispatch,
|
||||||
} from '../core/helpers.mjs';
|
} from '../core/helpers.mjs';
|
||||||
import { clickElement } from '../core/click.mjs';
|
import { clickElement } from '../core/click.mjs';
|
||||||
|
import { resolveRowIndexByFilter } from './click-cell.mjs';
|
||||||
import {
|
import {
|
||||||
pickFromSelectionForm, isTypeDialog, pickFromTypeDialog,
|
pickFromSelectionForm, isTypeDialog, pickFromTypeDialog,
|
||||||
fillReferenceField, selectValue,
|
fillReferenceField, selectValue,
|
||||||
} from '../forms/select-value.mjs';
|
} from '../forms/select-value.mjs';
|
||||||
import { pasteText } from '../core/clipboard.mjs';
|
import { pasteText } from '../core/clipboard.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a choice cell (_CB iCB, buttonKind==='choice') whose INPUT is already focused.
|
||||||
|
*
|
||||||
|
* Two kinds of cell carry the same choice button and are INDISTINGUISHABLE in the DOM
|
||||||
|
* (both `editInput`, readOnly:false):
|
||||||
|
* (a) editable value cell (Произвольный/примитив, РедактированиеТекста=Истина) — typed text sticks;
|
||||||
|
* (b) pick-from-list cell (НачалоВыбора / РедактированиеТекста=Ложь) — typed text is rejected.
|
||||||
|
* The only reliable discriminator is behavioral: paste and watch the input value.
|
||||||
|
* stuck → editable cell → leave value in the INPUT (caller's Tab/commit persists it), method 'direct';
|
||||||
|
* rejected → F4 → form: isTypeDialog ? pickFromTypeDialog ('choice') : pickFromSelectionForm ('form').
|
||||||
|
*
|
||||||
|
* Does NOT navigate between cells — caller owns Tab/dblclick/row-commit.
|
||||||
|
*
|
||||||
|
* @param {number} formNum base form number (for new-form detection)
|
||||||
|
* @param {string} text value to fill
|
||||||
|
* @param {Object} [opts]
|
||||||
|
* @param {string|null} [opts.type] explicit type for composite/value-list pick
|
||||||
|
* @param {string} [opts.fieldLabel] field name for diagnostics / selection-form search
|
||||||
|
* @returns {{ ok, method, error?, message?, value? }}
|
||||||
|
*/
|
||||||
|
async function fillChoiceCell(formNum, text, { type = null, fieldLabel = '' } = {}) {
|
||||||
|
const norm = (s) => normYo((s || '').toLowerCase());
|
||||||
|
const before = await page.evaluate(`document.activeElement?.value || ''`);
|
||||||
|
// Re-fill guard: cell already holds the target (paste wouldn't change it → false "rejected").
|
||||||
|
if (before && norm(before).includes(norm(text))) {
|
||||||
|
return { ok: true, method: 'skip', value: before };
|
||||||
|
}
|
||||||
|
// Paste, then poll. Three outcomes, distinguished BEHAVIORALLY (not by value equality):
|
||||||
|
// (1) EDD autocomplete appears → reference/list cell → pick from the dropdown;
|
||||||
|
// (2) input changes to non-empty, no EDD → editable cell → leave value, method 'direct';
|
||||||
|
// (3) input unchanged (rejected) → НачалоВыбора pick-from-list → F4 selection form.
|
||||||
|
// A value-equality check on `after` is UNRELIABLE: numeric/date masks reformat the pasted
|
||||||
|
// text (grouping nbsp, decimal comma, padding) — e.g. "1234.56" → "1 234,56", "0,000"
|
||||||
|
// baseline. So we test "did the input change to non-empty" + "no autocomplete", never
|
||||||
|
// "does after contain text" (that false-negatives on reformatting → F4 → stray calculator).
|
||||||
|
await pasteText(text, { confirm: ['Control+a', 'Control+v'] });
|
||||||
|
let after = before, changed = false, eddSeen = false;
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
await page.waitForTimeout(100);
|
||||||
|
if (await isEddVisible()) { eddSeen = true; break; }
|
||||||
|
after = await page.evaluate(`document.activeElement?.value || ''`);
|
||||||
|
if (after !== before && after !== '') changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eddSeen) {
|
||||||
|
// Reference/list cell — pick a MATCHING item from the autocomplete. Only accept an
|
||||||
|
// exact (parenthetical-stripped) or substring match; never blind-pick items[0] — for a
|
||||||
|
// non-existent value 1C still lists unrelated entries, and picking the first silently
|
||||||
|
// writes the wrong reference. No match → fall through to the F4 selection form, which
|
||||||
|
// searches the full list and returns not_found if the value is truly absent.
|
||||||
|
const edd = await readEdd();
|
||||||
|
const items = (edd.items || []).map(i => i.name)
|
||||||
|
.filter(i => !/^Создать[\s:]/.test(i) && !/не найдено/i.test(i) && !/показать все/i.test(i));
|
||||||
|
const tgt = norm(text);
|
||||||
|
const pick = items.find(i => norm(i.replace(/\s*\([^)]*\)\s*$/, '')) === tgt)
|
||||||
|
|| items.find(i => norm(i).includes(tgt));
|
||||||
|
if (pick) {
|
||||||
|
await clickEddItemViaDispatch(pick);
|
||||||
|
await waitForStable();
|
||||||
|
return { ok: true, method: 'dropdown', value: pick.replace(/\s*\([^)]*\)\s*$/, '') };
|
||||||
|
}
|
||||||
|
// No matching item — dismiss the autocomplete and fall through to the F4 selection form.
|
||||||
|
await page.keyboard.press('Escape'); await page.waitForTimeout(200);
|
||||||
|
} else if (changed) {
|
||||||
|
// Editable cell — value lives in the INPUT; caller's Tab / end-of-row commit persists it.
|
||||||
|
return { ok: true, method: 'direct', value: after };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text rejected (pick-from-list cell) — nothing typed to clear (field is not text-editable).
|
||||||
|
// Dismiss any autocomplete hint, then open the choice form via F4.
|
||||||
|
if (await isEddVisible()) { await page.keyboard.press('Escape'); await page.waitForTimeout(200); }
|
||||||
|
await page.keyboard.press('F4');
|
||||||
|
let choiceForm = null;
|
||||||
|
for (let cw = 0; cw < 8; cw++) {
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
choiceForm = await helperDetectNewForm(formNum);
|
||||||
|
if (choiceForm !== null) break;
|
||||||
|
}
|
||||||
|
if (choiceForm === null) {
|
||||||
|
// F4 safety net: on an editable numeric/date cell mis-routed here, F4 opens a
|
||||||
|
// calculator/calendar (NOT a selection form). Close it — never leave the popup open
|
||||||
|
// (it blocks the UI) — and salvage: if the cell now holds a value, count it as 'direct'.
|
||||||
|
if (await findOpenPopup()) {
|
||||||
|
await page.keyboard.press('Escape');
|
||||||
|
for (let dw = 0; dw < 4; dw++) { await page.waitForTimeout(150); if (!(await findOpenPopup())) break; }
|
||||||
|
const nowVal = await page.evaluate(`document.activeElement?.value || ''`);
|
||||||
|
if (nowVal && nowVal !== before) return { ok: true, method: 'direct', value: nowVal };
|
||||||
|
}
|
||||||
|
return { ok: false, error: 'no_selection_form', message: `Cell "${fieldLabel || text}": F4 did not open a choice form` };
|
||||||
|
}
|
||||||
|
if (await isTypeDialog(choiceForm)) {
|
||||||
|
try {
|
||||||
|
await pickFromTypeDialog(choiceForm, type || text);
|
||||||
|
} catch (e) {
|
||||||
|
return { ok: false, error: 'not_found', message: e.message };
|
||||||
|
}
|
||||||
|
await waitForStable(formNum);
|
||||||
|
// A value form opened after the type pick → composite-value cell needs { value, type }.
|
||||||
|
const valForm = await helperDetectNewForm(formNum);
|
||||||
|
if (valForm !== null) {
|
||||||
|
await page.keyboard.press('Escape'); await page.waitForTimeout(300);
|
||||||
|
return { ok: false, error: 'type_required', message: `Cell "${fieldLabel || text}" expects { value, type }` };
|
||||||
|
}
|
||||||
|
return { ok: true, method: 'choice', value: text };
|
||||||
|
}
|
||||||
|
const pr = await pickFromSelectionForm(choiceForm, fieldLabel || text, text, formNum);
|
||||||
|
return pr.ok ? { ok: true, method: 'form' } : { ok: false, error: pr.error, message: pr.message };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill cells in the current table row via Tab navigation.
|
* Fill cells in the current table row via Tab navigation.
|
||||||
* Grid cells are only accessible sequentially (Tab) — no random access.
|
* Grid cells are only accessible sequentially (Tab) — no random access.
|
||||||
@@ -42,9 +152,13 @@ import { pasteText } from '../core/clipboard.mjs';
|
|||||||
* @param {Object} [options]
|
* @param {Object} [options]
|
||||||
* @param {string} [options.tab] - Switch to this form tab before operating
|
* @param {string} [options.tab] - Switch to this form tab before operating
|
||||||
* @param {boolean} [options.add] - Click "Добавить" to create a new row first
|
* @param {boolean} [options.add] - Click "Добавить" to create a new row first
|
||||||
|
* @param {number|Object} [options.row] - Edit existing row: 0-based DOM-window index, or
|
||||||
|
* a `{ col: value }` filter (one or more columns, AND-matched) to locate the row by cell values
|
||||||
|
* @param {boolean|number} [options.scroll] - When `row` is a filter, scan beyond the current
|
||||||
|
* DOM window via PageDown (true = up to 50 presses, number = exact limit)
|
||||||
* @returns {{ filled[], notFilled[]?, form }}
|
* @returns {{ filled[], notFilled[]?, form }}
|
||||||
*/
|
*/
|
||||||
export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
export async function fillTableRow(fields, { tab, add, row, table, scroll } = {}) {
|
||||||
ensureConnected();
|
ensureConnected();
|
||||||
await dismissPendingErrors();
|
await dismissPendingErrors();
|
||||||
const formNum = await page.evaluate(detectFormScript());
|
const formNum = await page.evaluate(detectFormScript());
|
||||||
@@ -64,6 +178,13 @@ export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
|||||||
await clickElement(tab);
|
await clickElement(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1b. Resolve a { col: value } row filter to a numeric DOM-window index (mirrors
|
||||||
|
// clickElement). After this, `row` is a number and all downstream code/recursion
|
||||||
|
// works unchanged. Filter targets an EXISTING row — incompatible with `add`.
|
||||||
|
if (row != null && typeof row === 'object') {
|
||||||
|
row = await resolveRowIndexByFilter({ formNum, gridSelector, filter: row, gridName: table, scroll });
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Add new row if requested
|
// 2. Add new row if requested
|
||||||
let addedRowIdx = -1;
|
let addedRowIdx = -1;
|
||||||
if (add) {
|
if (add) {
|
||||||
@@ -306,23 +427,16 @@ export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
|||||||
// Also check if a selection form already appeared
|
// Also check if a selection form already appeared
|
||||||
let selForm = await helperDetectNewForm(formNum);
|
let selForm = await helperDetectNewForm(formNum);
|
||||||
if (selForm === null && inInputAfterDblclick) {
|
if (selForm === null && inInputAfterDblclick) {
|
||||||
// Choice cell (bare _CB list-pick) — paste would revert silently; open via F4.
|
// Choice cell (bare _CB iCB) — editable value (text sticks) or pick-from-list
|
||||||
|
// (text rejected → F4 form). fillChoiceCell discriminates; row commit persists 'direct'.
|
||||||
const activeCell = await page.evaluate(readActiveGridCellScript());
|
const activeCell = await page.evaluate(readActiveGridCellScript());
|
||||||
if (activeCell.buttonKind === 'choice') {
|
if (activeCell.buttonKind === 'choice') {
|
||||||
await page.keyboard.press('F4');
|
const r = await fillChoiceCell(formNum, info.value, { type: info.type, fieldLabel: key });
|
||||||
let cForm = null;
|
info.filled = true;
|
||||||
for (let cw = 0; cw < 8; cw++) {
|
results.push(r.ok
|
||||||
await page.waitForTimeout(200);
|
? { field: key, ok: true, method: r.method, ...(r.value !== undefined ? { value: r.value } : {}) }
|
||||||
cForm = await helperDetectNewForm(formNum);
|
: { field: key, ok: false, error: r.error, message: r.message });
|
||||||
if (cForm !== null) break;
|
continue;
|
||||||
}
|
|
||||||
if (cForm !== null) {
|
|
||||||
const pr = await directEditPick(cForm, key, info);
|
|
||||||
info.filled = true;
|
|
||||||
results.push(pr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// F4 opened nothing — fall through to paste (best effort)
|
|
||||||
}
|
}
|
||||||
// Plain text/numeric field — fill via clipboard paste
|
// Plain text/numeric field — fill via clipboard paste
|
||||||
await pasteText(info.value, { confirm: ['Control+a', 'Control+v'] });
|
await pasteText(info.value, { confirm: ['Control+a', 'Control+v'] });
|
||||||
@@ -559,57 +673,16 @@ export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choice cell: value is picked from a programmatic list (field with НачалоВыбора →
|
// Choice cell (_CB iCB): either an editable value cell (text sticks → direct input) or a
|
||||||
// ПоказатьВыборЭлемента, e.g. a "Выбрать тип" list). Plain paste reverts silently,
|
// pick-from-list cell (НачалоВыбора / РедактированиеТекста=Ложь → text rejected → F4 form).
|
||||||
// so open the choice form via F4 and pick from it.
|
// fillChoiceCell discriminates behaviorally; both kinds are indistinguishable in the DOM.
|
||||||
if (cell.buttonKind === 'choice') {
|
if (cell.buttonKind === 'choice') {
|
||||||
await page.keyboard.press('F4');
|
const r = await fillChoiceCell(formNum, text, { type: info.type, fieldLabel: matchedKey });
|
||||||
let choiceForm = null;
|
|
||||||
for (let cw = 0; cw < 8; cw++) {
|
|
||||||
await page.waitForTimeout(200);
|
|
||||||
choiceForm = await helperDetectNewForm(formNum);
|
|
||||||
if (choiceForm !== null) break;
|
|
||||||
}
|
|
||||||
if (choiceForm === null) {
|
|
||||||
info.filled = true;
|
|
||||||
results.push({ field: matchedKey, cell: cell.fullName, ok: false,
|
|
||||||
error: 'no_selection_form', message: `Cell "${matchedKey}": F4 did not open a choice form` });
|
|
||||||
await page.keyboard.press('Tab'); await page.waitForTimeout(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (await isTypeDialog(choiceForm)) {
|
|
||||||
try {
|
|
||||||
await pickFromTypeDialog(choiceForm, text);
|
|
||||||
} catch (e) {
|
|
||||||
info.filled = true;
|
|
||||||
results.push({ field: matchedKey, cell: cell.fullName, ok: false,
|
|
||||||
error: 'not_found', message: e.message });
|
|
||||||
await page.keyboard.press('Tab'); await page.waitForTimeout(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
await waitForStable(formNum);
|
|
||||||
// If a value form opened after the pick, this was a composite-value cell → needs {value, type}
|
|
||||||
const valForm = await helperDetectNewForm(formNum);
|
|
||||||
if (valForm !== null) {
|
|
||||||
await page.keyboard.press('Escape'); await page.waitForTimeout(300);
|
|
||||||
info.filled = true;
|
|
||||||
results.push({ field: matchedKey, cell: cell.fullName, ok: false,
|
|
||||||
error: 'type_required', message: `Cell "${matchedKey}" expects { value, type }` });
|
|
||||||
await page.keyboard.press('Tab'); await page.waitForTimeout(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
info.filled = true;
|
|
||||||
results.push({ field: matchedKey, cell: cell.fullName, ok: true, method: 'choice', value: text });
|
|
||||||
if ([...pending.values()].every(p => p.filled)) break;
|
|
||||||
await page.keyboard.press('Tab'); await page.waitForTimeout(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// F4 opened a regular selection form (reference via CB) — pick from it
|
|
||||||
const pr = await pickFromSelectionForm(choiceForm, matchedKey, text, formNum);
|
|
||||||
info.filled = true;
|
info.filled = true;
|
||||||
results.push(pr.ok
|
results.push(r.ok
|
||||||
? { field: matchedKey, cell: cell.fullName, ok: true, method: 'form' }
|
? { field: matchedKey, cell: cell.fullName, ok: true, method: r.method, ...(r.value !== undefined ? { value: r.value } : {}) }
|
||||||
: { field: matchedKey, cell: cell.fullName, ok: false, error: pr.error, message: pr.message });
|
: { field: matchedKey, cell: cell.fullName, ok: false, error: r.error, message: r.message });
|
||||||
|
// 'direct' leaves text in the INPUT — caller's Tab (or end-of-row commit on the last field) persists it.
|
||||||
if ([...pending.values()].every(p => p.filled)) break;
|
if ([...pending.values()].every(p => p.filled)) break;
|
||||||
await page.keyboard.press('Tab'); await page.waitForTimeout(500);
|
await page.keyboard.press('Tab'); await page.waitForTimeout(500);
|
||||||
continue;
|
continue;
|
||||||
@@ -648,14 +721,28 @@ export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
|||||||
let pick = realItems.find(i =>
|
let pick = realItems.find(i =>
|
||||||
normYo(i.replace(/\s*\([^)]*\)\s*$/, '').toLowerCase()) === tgt);
|
normYo(i.replace(/\s*\([^)]*\)\s*$/, '').toLowerCase()) === tgt);
|
||||||
if (!pick) pick = realItems.find(i => normYo(i.toLowerCase()).includes(tgt));
|
if (!pick) pick = realItems.find(i => normYo(i.toLowerCase()).includes(tgt));
|
||||||
if (!pick) pick = realItems[0];
|
|
||||||
|
|
||||||
// Click EDD item via dispatchEvent (bypasses div.surface overlay)
|
if (pick) {
|
||||||
await clickEddItemViaDispatch(pick);
|
// Click EDD item via dispatchEvent (bypasses div.surface overlay)
|
||||||
await waitForStable();
|
await clickEddItemViaDispatch(pick);
|
||||||
info.filled = true;
|
await waitForStable();
|
||||||
results.push({ field: matchedKey, cell: cell.fullName, ok: true,
|
info.filled = true;
|
||||||
method: 'dropdown', value: pick.replace(/\s*\([^)]*\)\s*$/, '') });
|
results.push({ field: matchedKey, cell: cell.fullName, ok: true,
|
||||||
|
method: 'dropdown', value: pick.replace(/\s*\([^)]*\)\s*$/, '') });
|
||||||
|
} else {
|
||||||
|
// EDD listed items but NONE matches the requested value. Do NOT blind-pick the
|
||||||
|
// first item — when the typed text has no hit, 1C still shows unrelated entries
|
||||||
|
// (recent/full list), so items[0] would silently write the wrong reference.
|
||||||
|
// Dismiss, clear the typed text, report not_found.
|
||||||
|
await page.keyboard.press('Escape');
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
await page.keyboard.press('Control+A');
|
||||||
|
await page.keyboard.press('Delete');
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
info.filled = true;
|
||||||
|
results.push({ field: matchedKey, cell: cell.fullName, ok: false,
|
||||||
|
error: 'not_found', message: `No match for "${text}" in autocomplete` });
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Only "Создать:" items — value not found in autocomplete
|
// Only "Создать:" items — value not found in autocomplete
|
||||||
await page.keyboard.press('Escape');
|
await page.keyboard.press('Escape');
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
// web-test run v1.17 — CLI entry-point (распилено по cli/)
|
// web-test run v1.18 — CLI entry-point (распилено по cli/)
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
/**
|
/**
|
||||||
* CLI runner for 1C web client automation.
|
* CLI runner for 1C web client automation.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* node src/run.mjs shot [file] — take screenshot
|
* node src/run.mjs shot [file] — take screenshot
|
||||||
* node src/run.mjs stop — logout + close browser
|
* node src/run.mjs stop — logout + close browser
|
||||||
* node src/run.mjs status — check session
|
* node src/run.mjs status — check session
|
||||||
* node src/run.mjs test [url] <dir|file> — run regression tests
|
* node src/run.mjs test <dir|file>... [--url] — run regression tests
|
||||||
*
|
*
|
||||||
* Внутренности живут в cli/: util, session, exec-context, server,
|
* Внутренности живут в cli/: util, session, exec-context, server,
|
||||||
* commands/{start,run,exec,shot,stop,status,test}, test-runner/*.
|
* commands/{start,run,exec,shot,stop,status,test}, test-runner/*.
|
||||||
|
|||||||
@@ -138,6 +138,16 @@ jobs:
|
|||||||
branch: port-windsurf-py
|
branch: port-windsurf-py
|
||||||
label: Windsurf
|
label: Windsurf
|
||||||
target_dir: .windsurf/skills
|
target_dir: .windsurf/skills
|
||||||
|
- platform: codeassistant
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-codeassistant
|
||||||
|
label: Yandex Code Assistant
|
||||||
|
target_dir: .codeassistant/skills
|
||||||
|
- platform: codeassistant
|
||||||
|
runtime: python
|
||||||
|
branch: port-codeassistant-py
|
||||||
|
label: Yandex Code Assistant
|
||||||
|
target_dir: .codeassistant/skills
|
||||||
- platform: agents
|
- platform: agents
|
||||||
runtime: powershell
|
runtime: powershell
|
||||||
branch: port-agents
|
branch: port-agents
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ python tools/cc-1c-skills/scripts/switch.py
|
|||||||
| OpenCode | `.opencode/skills/` | [port-opencode](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-opencode) | [port-opencode-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-opencode-py) |
|
| OpenCode | `.opencode/skills/` | [port-opencode](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-opencode) | [port-opencode-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-opencode-py) |
|
||||||
| Roo Code | `.roo/skills/` | [port-roo](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-roo) | [port-roo-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-roo-py) |
|
| Roo Code | `.roo/skills/` | [port-roo](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-roo) | [port-roo-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-roo-py) |
|
||||||
| Windsurf | `.windsurf/skills/` | [port-windsurf](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-windsurf) | [port-windsurf-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-windsurf-py) |
|
| Windsurf | `.windsurf/skills/` | [port-windsurf](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-windsurf) | [port-windsurf-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-windsurf-py) |
|
||||||
|
| Yandex Code Assistant | `.codeassistant/skills/` | [port-codeassistant](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-codeassistant) | [port-codeassistant-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-codeassistant-py) |
|
||||||
| Agent Skills | `.agents/skills/` | [port-agents](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-agents) | [port-agents-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-agents-py) |
|
| Agent Skills | `.agents/skills/` | [port-agents](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-agents) | [port-agents-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-agents-py) |
|
||||||
|
|
||||||
Готовые ветки `port-*` пересобираются автоматически на каждое изменение в навыках. Если нужна свежая сборка прямо сейчас — соберите [локально через `switch.py`](#альтернативный-способ--собрать-локально-через-switchpy).
|
Готовые ветки `port-*` пересобираются автоматически на каждое изменение в навыках. Если нужна свежая сборка прямо сейчас — соберите [локально через `switch.py`](#альтернативный-способ--собрать-локально-через-switchpy).
|
||||||
|
|||||||
@@ -530,6 +530,26 @@ DataCompositionSchema
|
|||||||
|
|
||||||
Стандартные варианты периодов (`v8:StandardPeriodVariant`): `Custom`, `Today`, `ThisWeek`, `ThisMonth`, `ThisQuarter`, `ThisYear`, `LastMonth`, `LastQuarter`, `LastYear` и др.
|
Стандартные варианты периодов (`v8:StandardPeriodVariant`): `Custom`, `Today`, `ThisWeek`, `ThisMonth`, `ThisQuarter`, `ThisYear`, `LastMonth`, `LastQuarter`, `LastYear` и др.
|
||||||
|
|
||||||
|
#### Значение-список (несколько значений по умолчанию)
|
||||||
|
|
||||||
|
Значением параметра может быть список — несколько элементов `<value>` подряд внутри
|
||||||
|
`<parameter>`, при `<valueListAllowed>true</valueListAllowed>`:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<parameter>
|
||||||
|
<name>ВидыСубконто</name>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные</v8:Type>
|
||||||
|
</valueType>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты</value>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры</value>
|
||||||
|
<useRestriction>true</useRestriction>
|
||||||
|
<valueListAllowed>true</valueListAllowed>
|
||||||
|
</parameter>
|
||||||
|
```
|
||||||
|
|
||||||
|
Порядок элементов: `name, title, valueType, value*, useRestriction, …, valueListAllowed`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Макеты областей (template)
|
## 9. Макеты областей (template)
|
||||||
|
|||||||
+819
-44
File diff suppressed because it is too large
Load Diff
@@ -339,6 +339,12 @@ XML-маппинг — по `<group>` на каждый элемент:
|
|||||||
|
|
||||||
**Парсинг:** `"A: T = V"` → `name=A`, `type=T`, `value=V`. Значение `LastMonth` и другие варианты периодов → `v8:StandardPeriod` с `v8:variant`.
|
**Парсинг:** `"A: T = V"` → `name=A`, `type=T`, `value=V`. Значение `LastMonth` и другие варианты периодов → `v8:StandardPeriod` с `v8:variant`.
|
||||||
|
|
||||||
|
`<default>` может быть **списком** — несколько значений через запятую (с `'...'` для запятой внутри значения). В этом случае эмитятся несколько `<value>`, а `valueListAllowed=true` выводится автоматически (явный `@valueList` не нужен). Эквивалент объектной формы `"value": [ ... ]`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"parameters": ["Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"]
|
||||||
|
```
|
||||||
|
|
||||||
### @autoDates
|
### @autoDates
|
||||||
|
|
||||||
Флаг `@autoDates` в shorthand параметра автоматически генерирует два дополнительных параметра:
|
Флаг `@autoDates` в shorthand параметра автоматически генерирует два дополнительных параметра:
|
||||||
|
|||||||
@@ -12,11 +12,14 @@
|
|||||||
## 1. Командная строка
|
## 1. Командная строка
|
||||||
|
|
||||||
```
|
```
|
||||||
node run.mjs test [url] <dir|file> [флаги]
|
node run.mjs test <dir|file>... [флаги]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Позиционные аргументы — это пути к тестам (файлы `*.test.mjs` и/или каталоги), можно указать несколько: `node run.mjs test a.test.mjs b.test.mjs dir/`. Файлы из каталогов обходятся рекурсивно; итоговый набор дедуплицируется и сортируется (порядок по числовым префиксам `00-`, `01-`, … сохраняется независимо от порядка аргументов). Путь, которого нет на диске, → ранняя понятная ошибка (аргумент, похожий на URL, подскажет про `--url=`).
|
||||||
|
|
||||||
| Флаг | По умолчанию | Описание |
|
| Флаг | По умолчанию | Описание |
|
||||||
|------|-------------|----------|
|
|------|-------------|----------|
|
||||||
|
| `--url=URL` | (из конфига) | Переопределить базовый URL дефолтного контекста |
|
||||||
| `--tags=smoke,crud` | (все) | Фильтр тестов по тегам (пересечение) |
|
| `--tags=smoke,crud` | (все) | Фильтр тестов по тегам (пересечение) |
|
||||||
| `--grep=pattern` | (все) | Фильтр тестов по имени (регулярное выражение) |
|
| `--grep=pattern` | (все) | Фильтр тестов по имени (регулярное выражение) |
|
||||||
| `--bail` | false | Остановиться при первом падении |
|
| `--bail` | false | Остановиться при первом падении |
|
||||||
@@ -30,7 +33,7 @@ node run.mjs test [url] <dir|file> [флаги]
|
|||||||
| `--record` | false | Записывать видео для каждого теста (mp4 в `--report-dir`) |
|
| `--record` | false | Записывать видео для каждого теста (mp4 в `--report-dir`) |
|
||||||
| `-- <hookArgs…>` | — | Всё после `--` пробрасывается в `_hooks.mjs` как `hookArgs` (см. §6.1) |
|
| `-- <hookArgs…>` | — | Всё после `--` пробрасывается в `_hooks.mjs` как `hookArgs` (см. §6.1) |
|
||||||
|
|
||||||
URL необязателен, если в каталоге тестов есть `webtest.config.mjs`. CLI URL переопределяет URL дефолтного контекста.
|
URL не передаётся позиционно — он берётся из `webtest.config.mjs` в каталоге тестов, а флаг `--url=` переопределяет URL дефолтного контекста. `webtest.config.mjs` и `_hooks.mjs` резолвятся от каталога **первого** пути, поэтому перечисляемые файлы должны лежать в одной папке сьюта.
|
||||||
|
|
||||||
### Валидация CLI
|
### Валидация CLI
|
||||||
|
|
||||||
@@ -876,6 +879,7 @@ tests/myapp/
|
|||||||
|--------|-----------|
|
|--------|-----------|
|
||||||
| Обход | Рекурсивный; файлы и каталоги, имя которых начинается на `_` или `.`, пропускаются |
|
| Обход | Рекурсивный; файлы и каталоги, имя которых начинается на `_` или `.`, пропускаются |
|
||||||
| Шаблон имени | Только `*.test.mjs` |
|
| Шаблон имени | Только `*.test.mjs` |
|
||||||
|
| Несколько путей | `node run.mjs test a.test.mjs b.test.mjs dir/` — наборы объединяются, дублируются и сортируются |
|
||||||
| Порядок | Сортировка по полному относительному пути (`sales/01` идёт до `warehouse/01`) |
|
| Порядок | Сортировка по полному относительному пути (`sales/01` идёт до `warehouse/01`) |
|
||||||
| `file` в отчёте | `relative(testDir, file)` с разделителем `/`, например `sales/01-order-create.test.mjs` |
|
| `file` в отчёте | `relative(testDir, file)` с разделителем `/`, например `sales/01-order-create.test.mjs` |
|
||||||
| Фильтр по пути с CLI | `node run.mjs test tests/myapp/sales/` запустит только подкаталог |
|
| Фильтр по пути с CLI | `node run.mjs test tests/myapp/sales/` запустит только подкаталог |
|
||||||
|
|||||||
+5
-2
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# switch.py v1.6 — Переключение навыков 1С между AI-платформами и рантаймами
|
# switch.py v1.7 — Переключение навыков 1С между AI-платформами и рантаймами
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
"""
|
"""
|
||||||
Копирует (или создаёт ссылки на) навыки из .claude/skills/ на другие AI-платформы
|
Копирует (или создаёт ссылки на) навыки из .claude/skills/ на другие AI-платформы
|
||||||
@@ -30,6 +30,7 @@ PLATFORMS = {
|
|||||||
'agents': '.agents/skills',
|
'agents': '.agents/skills',
|
||||||
'augment': '.augment/skills',
|
'augment': '.augment/skills',
|
||||||
'cline': '.cline/skills',
|
'cline': '.cline/skills',
|
||||||
|
'codeassistant': '.codeassistant/skills',
|
||||||
'codex': '.codex/skills',
|
'codex': '.codex/skills',
|
||||||
'cursor': '.cursor/skills',
|
'cursor': '.cursor/skills',
|
||||||
'copilot': '.github/skills',
|
'copilot': '.github/skills',
|
||||||
@@ -612,11 +613,13 @@ def interactive_mode():
|
|||||||
("OpenCode", ".opencode/skills/"),
|
("OpenCode", ".opencode/skills/"),
|
||||||
("Roo Code", ".roo/skills/"),
|
("Roo Code", ".roo/skills/"),
|
||||||
("Windsurf", ".windsurf/skills/"),
|
("Windsurf", ".windsurf/skills/"),
|
||||||
|
("Code Assistant", ".codeassistant/skills/"),
|
||||||
("Agent Skills", ".agents/skills/"),
|
("Agent Skills", ".agents/skills/"),
|
||||||
]
|
]
|
||||||
platform_keys = [
|
platform_keys = [
|
||||||
'claude-code', 'augment', 'cline', 'cursor', 'copilot', 'kilo',
|
'claude-code', 'augment', 'cline', 'cursor', 'copilot', 'kilo',
|
||||||
'kiro', 'codex', 'gemini', 'opencode', 'roo', 'windsurf', 'agents',
|
'kiro', 'codex', 'gemini', 'opencode', 'roo', 'windsurf',
|
||||||
|
'codeassistant', 'agents',
|
||||||
]
|
]
|
||||||
|
|
||||||
choice = ask_choice("Для какой платформы настроить навыки?", platform_options)
|
choice = ask_choice("Для какой платформы настроить навыки?", platform_options)
|
||||||
|
|||||||
+15
-1
@@ -108,6 +108,20 @@ node tests/skills/verify-snapshots.mjs --help # полный
|
|||||||
|
|
||||||
`params` — параметры для навыка. Используются через `case.<field>` и `workPath` в `_skill.json`.
|
`params` — параметры для навыка. Используются через `case.<field>` и `workPath` в `_skill.json`.
|
||||||
|
|
||||||
|
`expect.stdoutContains` / `expect.stdoutNotContains` — строка **или массив строк**. Каждая подстрока проверяется на наличие (`stdoutContains`) или отсутствие (`stdoutNotContains`) в stdout навыка. Удобно для info-навыков: проверить, что нужная строка есть, а лишней — нет.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Представление типа у ПВХ",
|
||||||
|
"setup": "external:C:/WS/tasks/cfsrc/erp_8.3.24",
|
||||||
|
"params": { "objectPath": "ChartsOfCharacteristicTypes/ВидыСубконтоХозрасчетные" },
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": ["Представление типа: Вид субконто", "Представление объекта: Вид субконто"],
|
||||||
|
"stdoutNotContains": "Представление списка:"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### С дополнительными CLI-аргументами
|
### С дополнительными CLI-аргументами
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -175,7 +189,7 @@ node tests/skills/verify-snapshots.mjs --help # полный
|
|||||||
| `outputPath` | нет | Относительный путь для навыков с `-OutputPath` |
|
| `outputPath` | нет | Относительный путь для навыков с `-OutputPath` |
|
||||||
| `args_extra` | нет | Массив дополнительных CLI-аргументов |
|
| `args_extra` | нет | Массив дополнительных CLI-аргументов |
|
||||||
| `preRun` | нет | Массив шагов подготовки (создание объектов и т.п.) |
|
| `preRun` | нет | Массив шагов подготовки (создание объектов и т.п.) |
|
||||||
| `expect` | нет | Дополнительные проверки: `files`, `stdoutContains` |
|
| `expect` | нет | Дополнительные проверки: `files`, `stdoutContains` (строка/массив), `stdoutNotContains` (строка/массив) |
|
||||||
| `expectError` | нет | `true` или строка — ожидается ошибка |
|
| `expectError` | нет | `true` или строка — ожидается ошибка |
|
||||||
|
|
||||||
## Эталоны (snapshots)
|
## Эталоны (snapshots)
|
||||||
|
|||||||
+81
-29
@@ -13,67 +13,119 @@
|
|||||||
<DataPath>Список</DataPath>
|
<DataPath>Список</DataPath>
|
||||||
<CommandBarLocation>None</CommandBarLocation>
|
<CommandBarLocation>None</CommandBarLocation>
|
||||||
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
||||||
|
<AutoRefresh>false</AutoRefresh>
|
||||||
|
<AutoRefreshPeriod>60</AutoRefreshPeriod>
|
||||||
|
<Period>
|
||||||
|
<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>
|
||||||
|
</Period>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<RestoreCurrentRow>false</RestoreCurrentRow>
|
||||||
|
<TopLevelParent xsi:nil="true"/>
|
||||||
|
<ShowRoot>true</ShowRoot>
|
||||||
|
<AllowRootChoice>false</AllowRootChoice>
|
||||||
|
<UpdateOnDataChange>Auto</UpdateOnDataChange>
|
||||||
|
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
|
||||||
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
||||||
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
||||||
<Autofill>false</Autofill>
|
<Autofill>false</Autofill>
|
||||||
</AutoCommandBar>
|
</AutoCommandBar>
|
||||||
<SearchStringAddition name="СписокСтрокаПоиска" id="4"/>
|
<ExtendedTooltip name="СписокРасширеннаяПодсказка" id="4"/>
|
||||||
<ViewStatusAddition name="СписокСостояниеПросмотра" id="5"/>
|
<SearchStringAddition name="СписокСтрокаПоиска" id="5">
|
||||||
<SearchControlAddition name="СписокУправлениеПоиском" id="6"/>
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСтрокаПоискаКонтекстноеМеню" id="6"/>
|
||||||
|
<ExtendedTooltip name="СписокСтрокаПоискаРасширеннаяПодсказка" id="7"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="СписокСостояниеПросмотра" id="8">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСостояниеПросмотраКонтекстноеМеню" id="9"/>
|
||||||
|
<ExtendedTooltip name="СписокСостояниеПросмотраРасширеннаяПодсказка" id="10"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="СписокУправлениеПоиском" id="11">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокУправлениеПоискомКонтекстноеМеню" id="12"/>
|
||||||
|
<ExtendedTooltip name="СписокУправлениеПоискомРасширеннаяПодсказка" id="13"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<LabelField name="Период" id="7">
|
<LabelField name="Период" id="14">
|
||||||
<DataPath>Список.Period</DataPath>
|
<DataPath>Список.Period</DataPath>
|
||||||
<ContextMenu name="ПериодКонтекстноеМеню" id="8"/>
|
<ContextMenu name="ПериодКонтекстноеМеню" id="15"/>
|
||||||
<ExtendedTooltip name="ПериодРасширеннаяПодсказка" id="9"/>
|
<ExtendedTooltip name="ПериодРасширеннаяПодсказка" id="16"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Регистратор" id="10">
|
<LabelField name="Регистратор" id="17">
|
||||||
<DataPath>Список.Recorder</DataPath>
|
<DataPath>Список.Recorder</DataPath>
|
||||||
<ContextMenu name="РегистраторКонтекстноеМеню" id="11"/>
|
<ContextMenu name="РегистраторКонтекстноеМеню" id="18"/>
|
||||||
<ExtendedTooltip name="РегистраторРасширеннаяПодсказка" id="12"/>
|
<ExtendedTooltip name="РегистраторРасширеннаяПодсказка" id="19"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="НомерСтроки" id="13">
|
<LabelField name="НомерСтроки" id="20">
|
||||||
<DataPath>Список.LineNumber</DataPath>
|
<DataPath>Список.LineNumber</DataPath>
|
||||||
<ContextMenu name="НомерСтрокиКонтекстноеМеню" id="14"/>
|
<ContextMenu name="НомерСтрокиКонтекстноеМеню" id="21"/>
|
||||||
<ExtendedTooltip name="НомерСтрокиРасширеннаяПодсказка" id="15"/>
|
<ExtendedTooltip name="НомерСтрокиРасширеннаяПодсказка" id="22"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Организация" id="16">
|
<LabelField name="Организация" id="23">
|
||||||
<DataPath>Список.Организация</DataPath>
|
<DataPath>Список.Организация</DataPath>
|
||||||
<ContextMenu name="ОрганизацияКонтекстноеМеню" id="17"/>
|
<ContextMenu name="ОрганизацияКонтекстноеМеню" id="24"/>
|
||||||
<ExtendedTooltip name="ОрганизацияРасширеннаяПодсказка" id="18"/>
|
<ExtendedTooltip name="ОрганизацияРасширеннаяПодсказка" id="25"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="БанковскийСчет" id="19">
|
<LabelField name="БанковскийСчет" id="26">
|
||||||
<DataPath>Список.БанковскийСчет</DataPath>
|
<DataPath>Список.БанковскийСчет</DataPath>
|
||||||
<ContextMenu name="БанковскийСчетКонтекстноеМеню" id="20"/>
|
<ContextMenu name="БанковскийСчетКонтекстноеМеню" id="27"/>
|
||||||
<ExtendedTooltip name="БанковскийСчетРасширеннаяПодсказка" id="21"/>
|
<ExtendedTooltip name="БанковскийСчетРасширеннаяПодсказка" id="28"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Сумма" id="22">
|
<LabelField name="Сумма" id="29">
|
||||||
<DataPath>Список.Сумма</DataPath>
|
<DataPath>Список.Сумма</DataPath>
|
||||||
<ContextMenu name="СуммаКонтекстноеМеню" id="23"/>
|
<ContextMenu name="СуммаКонтекстноеМеню" id="30"/>
|
||||||
<ExtendedTooltip name="СуммаРасширеннаяПодсказка" id="24"/>
|
<ExtendedTooltip name="СуммаРасширеннаяПодсказка" id="31"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="СуммаВалютная" id="25">
|
<LabelField name="СуммаВалютная" id="32">
|
||||||
<DataPath>Список.СуммаВалютная</DataPath>
|
<DataPath>Список.СуммаВалютная</DataPath>
|
||||||
<ContextMenu name="СуммаВалютнаяКонтекстноеМеню" id="26"/>
|
<ContextMenu name="СуммаВалютнаяКонтекстноеМеню" id="33"/>
|
||||||
<ExtendedTooltip name="СуммаВалютнаяРасширеннаяПодсказка" id="27"/>
|
<ExtendedTooltip name="СуммаВалютнаяРасширеннаяПодсказка" id="34"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="СуммаУпр" id="28">
|
<LabelField name="СуммаУпр" id="35">
|
||||||
<DataPath>Список.СуммаУпр</DataPath>
|
<DataPath>Список.СуммаУпр</DataPath>
|
||||||
<ContextMenu name="СуммаУпрКонтекстноеМеню" id="29"/>
|
<ContextMenu name="СуммаУпрКонтекстноеМеню" id="36"/>
|
||||||
<ExtendedTooltip name="СуммаУпрРасширеннаяПодсказка" id="30"/>
|
<ExtendedTooltip name="СуммаУпрРасширеннаяПодсказка" id="37"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Список" id="31">
|
<Attribute name="Список" id="38">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DynamicList</v8:Type>
|
<v8:Type>cfg:DynamicList</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
<MainAttribute>true</MainAttribute>
|
<MainAttribute>true</MainAttribute>
|
||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<MainTable>AccumulationRegister.ДенежныеСредства</MainTable>
|
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<MainTable>AccumulationRegister.ДенежныеСредства</MainTable>
|
||||||
|
<ListSettings>
|
||||||
|
<dcsset:filter>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||||
|
</dcsset:filter>
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:conditionalAppearance>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
|
</dcsset:conditionalAppearance>
|
||||||
|
<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>
|
||||||
|
<dcsset:itemsUserSettingID>UUID-004</dcsset:itemsUserSettingID>
|
||||||
|
</ListSettings>
|
||||||
</Settings>
|
</Settings>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
|
|||||||
+1
@@ -35,6 +35,7 @@
|
|||||||
</UsualGroup>
|
</UsualGroup>
|
||||||
<CheckBoxField name="ЗагружаетсяИзИнтернета" id="11">
|
<CheckBoxField name="ЗагружаетсяИзИнтернета" id="11">
|
||||||
<DataPath>Объект.ЗагружаетсяИзИнтернета</DataPath>
|
<DataPath>Объект.ЗагружаетсяИзИнтернета</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="ЗагружаетсяИзИнтернетаКонтекстноеМеню" id="12"/>
|
<ContextMenu name="ЗагружаетсяИзИнтернетаКонтекстноеМеню" id="12"/>
|
||||||
<ExtendedTooltip name="ЗагружаетсяИзИнтернетаРасширеннаяПодсказка" id="13"/>
|
<ExtendedTooltip name="ЗагружаетсяИзИнтернетаРасширеннаяПодсказка" id="13"/>
|
||||||
|
|||||||
+87
-35
@@ -13,80 +13,132 @@
|
|||||||
<DataPath>Список</DataPath>
|
<DataPath>Список</DataPath>
|
||||||
<CommandBarLocation>None</CommandBarLocation>
|
<CommandBarLocation>None</CommandBarLocation>
|
||||||
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
||||||
|
<AutoRefresh>false</AutoRefresh>
|
||||||
|
<AutoRefreshPeriod>60</AutoRefreshPeriod>
|
||||||
|
<Period>
|
||||||
|
<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>
|
||||||
|
</Period>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<RestoreCurrentRow>false</RestoreCurrentRow>
|
||||||
|
<TopLevelParent xsi:nil="true"/>
|
||||||
|
<ShowRoot>true</ShowRoot>
|
||||||
|
<AllowRootChoice>false</AllowRootChoice>
|
||||||
|
<UpdateOnDataChange>Auto</UpdateOnDataChange>
|
||||||
|
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
|
||||||
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
||||||
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
||||||
<Autofill>false</Autofill>
|
<Autofill>false</Autofill>
|
||||||
</AutoCommandBar>
|
</AutoCommandBar>
|
||||||
<SearchStringAddition name="СписокСтрокаПоиска" id="4"/>
|
<ExtendedTooltip name="СписокРасширеннаяПодсказка" id="4"/>
|
||||||
<ViewStatusAddition name="СписокСостояниеПросмотра" id="5"/>
|
<SearchStringAddition name="СписокСтрокаПоиска" id="5">
|
||||||
<SearchControlAddition name="СписокУправлениеПоиском" id="6"/>
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСтрокаПоискаКонтекстноеМеню" id="6"/>
|
||||||
|
<ExtendedTooltip name="СписокСтрокаПоискаРасширеннаяПодсказка" id="7"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="СписокСостояниеПросмотра" id="8">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСостояниеПросмотраКонтекстноеМеню" id="9"/>
|
||||||
|
<ExtendedTooltip name="СписокСостояниеПросмотраРасширеннаяПодсказка" id="10"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="СписокУправлениеПоиском" id="11">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокУправлениеПоискомКонтекстноеМеню" id="12"/>
|
||||||
|
<ExtendedTooltip name="СписокУправлениеПоискомРасширеннаяПодсказка" id="13"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<LabelField name="Наименование" id="7">
|
<LabelField name="Наименование" id="14">
|
||||||
<DataPath>Список.Description</DataPath>
|
<DataPath>Список.Description</DataPath>
|
||||||
<ContextMenu name="НаименованиеКонтекстноеМеню" id="8"/>
|
<ContextMenu name="НаименованиеКонтекстноеМеню" id="15"/>
|
||||||
<ExtendedTooltip name="НаименованиеРасширеннаяПодсказка" id="9"/>
|
<ExtendedTooltip name="НаименованиеРасширеннаяПодсказка" id="16"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Код" id="10">
|
<LabelField name="Код" id="17">
|
||||||
<DataPath>Список.Code</DataPath>
|
<DataPath>Список.Code</DataPath>
|
||||||
<ContextMenu name="КодКонтекстноеМеню" id="11"/>
|
<ContextMenu name="КодКонтекстноеМеню" id="18"/>
|
||||||
<ExtendedTooltip name="КодРасширеннаяПодсказка" id="12"/>
|
<ExtendedTooltip name="КодРасширеннаяПодсказка" id="19"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ЗагружаетсяИзИнтернета" id="13">
|
<LabelField name="ЗагружаетсяИзИнтернета" id="20">
|
||||||
<DataPath>Список.ЗагружаетсяИзИнтернета</DataPath>
|
<DataPath>Список.ЗагружаетсяИзИнтернета</DataPath>
|
||||||
<ContextMenu name="ЗагружаетсяИзИнтернетаКонтекстноеМеню" id="14"/>
|
<ContextMenu name="ЗагружаетсяИзИнтернетаКонтекстноеМеню" id="21"/>
|
||||||
<ExtendedTooltip name="ЗагружаетсяИзИнтернетаРасширеннаяПодсказка" id="15"/>
|
<ExtendedTooltip name="ЗагружаетсяИзИнтернетаРасширеннаяПодсказка" id="22"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="НаименованиеПолное" id="16">
|
<LabelField name="НаименованиеПолное" id="23">
|
||||||
<DataPath>Список.НаименованиеПолное</DataPath>
|
<DataPath>Список.НаименованиеПолное</DataPath>
|
||||||
<ContextMenu name="НаименованиеПолноеКонтекстноеМеню" id="17"/>
|
<ContextMenu name="НаименованиеПолноеКонтекстноеМеню" id="24"/>
|
||||||
<ExtendedTooltip name="НаименованиеПолноеРасширеннаяПодсказка" id="18"/>
|
<ExtendedTooltip name="НаименованиеПолноеРасширеннаяПодсказка" id="25"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Наценка" id="19">
|
<LabelField name="Наценка" id="26">
|
||||||
<DataPath>Список.Наценка</DataPath>
|
<DataPath>Список.Наценка</DataPath>
|
||||||
<ContextMenu name="НаценкаКонтекстноеМеню" id="20"/>
|
<ContextMenu name="НаценкаКонтекстноеМеню" id="27"/>
|
||||||
<ExtendedTooltip name="НаценкаРасширеннаяПодсказка" id="21"/>
|
<ExtendedTooltip name="НаценкаРасширеннаяПодсказка" id="28"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ОсновнаяВалюта" id="22">
|
<LabelField name="ОсновнаяВалюта" id="29">
|
||||||
<DataPath>Список.ОсновнаяВалюта</DataPath>
|
<DataPath>Список.ОсновнаяВалюта</DataPath>
|
||||||
<ContextMenu name="ОсновнаяВалютаКонтекстноеМеню" id="23"/>
|
<ContextMenu name="ОсновнаяВалютаКонтекстноеМеню" id="30"/>
|
||||||
<ExtendedTooltip name="ОсновнаяВалютаРасширеннаяПодсказка" id="24"/>
|
<ExtendedTooltip name="ОсновнаяВалютаРасширеннаяПодсказка" id="31"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ПараметрыПрописи" id="25">
|
<LabelField name="ПараметрыПрописи" id="32">
|
||||||
<DataPath>Список.ПараметрыПрописи</DataPath>
|
<DataPath>Список.ПараметрыПрописи</DataPath>
|
||||||
<ContextMenu name="ПараметрыПрописиКонтекстноеМеню" id="26"/>
|
<ContextMenu name="ПараметрыПрописиКонтекстноеМеню" id="33"/>
|
||||||
<ExtendedTooltip name="ПараметрыПрописиРасширеннаяПодсказка" id="27"/>
|
<ExtendedTooltip name="ПараметрыПрописиРасширеннаяПодсказка" id="34"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ФормулаРасчетаКурса" id="28">
|
<LabelField name="ФормулаРасчетаКурса" id="35">
|
||||||
<DataPath>Список.ФормулаРасчетаКурса</DataPath>
|
<DataPath>Список.ФормулаРасчетаКурса</DataPath>
|
||||||
<ContextMenu name="ФормулаРасчетаКурсаКонтекстноеМеню" id="29"/>
|
<ContextMenu name="ФормулаРасчетаКурсаКонтекстноеМеню" id="36"/>
|
||||||
<ExtendedTooltip name="ФормулаРасчетаКурсаРасширеннаяПодсказка" id="30"/>
|
<ExtendedTooltip name="ФормулаРасчетаКурсаРасширеннаяПодсказка" id="37"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="СпособУстановкиКурса" id="31">
|
<LabelField name="СпособУстановкиКурса" id="38">
|
||||||
<DataPath>Список.СпособУстановкиКурса</DataPath>
|
<DataPath>Список.СпособУстановкиКурса</DataPath>
|
||||||
<ContextMenu name="СпособУстановкиКурсаКонтекстноеМеню" id="32"/>
|
<ContextMenu name="СпособУстановкиКурсаКонтекстноеМеню" id="39"/>
|
||||||
<ExtendedTooltip name="СпособУстановкиКурсаРасширеннаяПодсказка" id="33"/>
|
<ExtendedTooltip name="СпособУстановкиКурсаРасширеннаяПодсказка" id="40"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Ссылка" id="34">
|
<LabelField name="Ссылка" id="41">
|
||||||
<DataPath>Список.Ref</DataPath>
|
<DataPath>Список.Ref</DataPath>
|
||||||
<UserVisible>
|
<UserVisible>
|
||||||
<xr:Common>false</xr:Common>
|
<xr:Common>false</xr:Common>
|
||||||
</UserVisible>
|
</UserVisible>
|
||||||
<ContextMenu name="СсылкаКонтекстноеМеню" id="35"/>
|
<ContextMenu name="СсылкаКонтекстноеМеню" id="42"/>
|
||||||
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="36"/>
|
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="43"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Список" id="37">
|
<Attribute name="Список" id="44">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DynamicList</v8:Type>
|
<v8:Type>cfg:DynamicList</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
<MainAttribute>true</MainAttribute>
|
<MainAttribute>true</MainAttribute>
|
||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<MainTable>Catalog.Валюты</MainTable>
|
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<MainTable>Catalog.Валюты</MainTable>
|
||||||
|
<ListSettings>
|
||||||
|
<dcsset:filter>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||||
|
</dcsset:filter>
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:conditionalAppearance>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
|
</dcsset:conditionalAppearance>
|
||||||
|
<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>
|
||||||
|
<dcsset:itemsUserSettingID>UUID-004</dcsset:itemsUserSettingID>
|
||||||
|
</ListSettings>
|
||||||
</Settings>
|
</Settings>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
|
|||||||
+44
-16
@@ -54,6 +54,7 @@
|
|||||||
</InputField>
|
</InputField>
|
||||||
<CheckBoxField name="Забалансовый" id="16">
|
<CheckBoxField name="Забалансовый" id="16">
|
||||||
<DataPath>Объект.OffBalance</DataPath>
|
<DataPath>Объект.OffBalance</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="ЗабалансовыйКонтекстноеМеню" id="17"/>
|
<ContextMenu name="ЗабалансовыйКонтекстноеМеню" id="17"/>
|
||||||
<ExtendedTooltip name="ЗабалансовыйРасширеннаяПодсказка" id="18"/>
|
<ExtendedTooltip name="ЗабалансовыйРасширеннаяПодсказка" id="18"/>
|
||||||
@@ -70,12 +71,14 @@
|
|||||||
<ChildItems>
|
<ChildItems>
|
||||||
<CheckBoxField name="Валютный" id="21">
|
<CheckBoxField name="Валютный" id="21">
|
||||||
<DataPath>Объект.Валютный</DataPath>
|
<DataPath>Объект.Валютный</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="ВалютныйКонтекстноеМеню" id="22"/>
|
<ContextMenu name="ВалютныйКонтекстноеМеню" id="22"/>
|
||||||
<ExtendedTooltip name="ВалютныйРасширеннаяПодсказка" id="23"/>
|
<ExtendedTooltip name="ВалютныйРасширеннаяПодсказка" id="23"/>
|
||||||
</CheckBoxField>
|
</CheckBoxField>
|
||||||
<CheckBoxField name="Количественный" id="24">
|
<CheckBoxField name="Количественный" id="24">
|
||||||
<DataPath>Объект.Количественный</DataPath>
|
<DataPath>Объект.Количественный</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="КоличественныйКонтекстноеМеню" id="25"/>
|
<ContextMenu name="КоличественныйКонтекстноеМеню" id="25"/>
|
||||||
<ExtendedTooltip name="КоличественныйРасширеннаяПодсказка" id="26"/>
|
<ExtendedTooltip name="КоличественныйРасширеннаяПодсказка" id="26"/>
|
||||||
@@ -86,38 +89,63 @@
|
|||||||
<DataPath>Объект.ExtDimensionTypes</DataPath>
|
<DataPath>Объект.ExtDimensionTypes</DataPath>
|
||||||
<ContextMenu name="ВидыСубконтоКонтекстноеМеню" id="28"/>
|
<ContextMenu name="ВидыСубконтоКонтекстноеМеню" id="28"/>
|
||||||
<AutoCommandBar name="ВидыСубконтоКоманднаяПанель" id="29"/>
|
<AutoCommandBar name="ВидыСубконтоКоманднаяПанель" id="29"/>
|
||||||
<SearchStringAddition name="ВидыСубконтоСтрокаПоиска" id="30"/>
|
<ExtendedTooltip name="ВидыСубконтоРасширеннаяПодсказка" id="30"/>
|
||||||
<ViewStatusAddition name="ВидыСубконтоСостояниеПросмотра" id="31"/>
|
<SearchStringAddition name="ВидыСубконтоСтрокаПоиска" id="31">
|
||||||
<SearchControlAddition name="ВидыСубконтоУправлениеПоиском" id="32"/>
|
<AdditionSource>
|
||||||
|
<Item>ВидыСубконто</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="ВидыСубконтоСтрокаПоискаКонтекстноеМеню" id="32"/>
|
||||||
|
<ExtendedTooltip name="ВидыСубконтоСтрокаПоискаРасширеннаяПодсказка" id="33"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="ВидыСубконтоСостояниеПросмотра" id="34">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>ВидыСубконто</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="ВидыСубконтоСостояниеПросмотраКонтекстноеМеню" id="35"/>
|
||||||
|
<ExtendedTooltip name="ВидыСубконтоСостояниеПросмотраРасширеннаяПодсказка" id="36"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="ВидыСубконтоУправлениеПоиском" id="37">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>ВидыСубконто</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="ВидыСубконтоУправлениеПоискомКонтекстноеМеню" id="38"/>
|
||||||
|
<ExtendedTooltip name="ВидыСубконтоУправлениеПоискомРасширеннаяПодсказка" id="39"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<InputField name="ВидСубконто" id="33">
|
<InputField name="ВидыСубконтоВидСубконто" id="40">
|
||||||
<DataPath>Объект.ExtDimensionTypes.ExtDimensionType</DataPath>
|
<DataPath>Объект.ExtDimensionTypes.ExtDimensionType</DataPath>
|
||||||
<ContextMenu name="ВидСубконтоКонтекстноеМеню" id="34"/>
|
<ContextMenu name="ВидыСубконтоВидСубконтоКонтекстноеМеню" id="41"/>
|
||||||
<ExtendedTooltip name="ВидСубконтоРасширеннаяПодсказка" id="35"/>
|
<ExtendedTooltip name="ВидыСубконтоВидСубконтоРасширеннаяПодсказка" id="42"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<CheckBoxField name="ТолькоОбороты" id="36">
|
<CheckBoxField name="ВидыСубконтоТолькоОбороты" id="43">
|
||||||
<DataPath>Объект.ExtDimensionTypes.TurnoversOnly</DataPath>
|
<DataPath>Объект.ExtDimensionTypes.TurnoversOnly</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="ТолькоОборотыКонтекстноеМеню" id="37"/>
|
<ContextMenu name="ВидыСубконтоТолькоОборотыКонтекстноеМеню" id="44"/>
|
||||||
<ExtendedTooltip name="ТолькоОборотыРасширеннаяПодсказка" id="38"/>
|
<ExtendedTooltip name="ВидыСубконтоТолькоОборотыРасширеннаяПодсказка" id="45"/>
|
||||||
</CheckBoxField>
|
</CheckBoxField>
|
||||||
<CheckBoxField name="Валютный" id="39">
|
<CheckBoxField name="ВидыСубконтоВалютный" id="46">
|
||||||
<DataPath>Объект.ExtDimensionTypes.Валютный</DataPath>
|
<DataPath>Объект.ExtDimensionTypes.Валютный</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="ВалютныйКонтекстноеМеню" id="40"/>
|
<ContextMenu name="ВидыСубконтоВалютныйКонтекстноеМеню" id="47"/>
|
||||||
<ExtendedTooltip name="ВалютныйРасширеннаяПодсказка" id="41"/>
|
<ExtendedTooltip name="ВидыСубконтоВалютныйРасширеннаяПодсказка" id="48"/>
|
||||||
</CheckBoxField>
|
</CheckBoxField>
|
||||||
<CheckBoxField name="Количественный" id="42">
|
<CheckBoxField name="ВидыСубконтоКоличественный" id="49">
|
||||||
<DataPath>Объект.ExtDimensionTypes.Количественный</DataPath>
|
<DataPath>Объект.ExtDimensionTypes.Количественный</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="КоличественныйКонтекстноеМеню" id="43"/>
|
<ContextMenu name="ВидыСубконтоКоличественныйКонтекстноеМеню" id="50"/>
|
||||||
<ExtendedTooltip name="КоличественныйРасширеннаяПодсказка" id="44"/>
|
<ExtendedTooltip name="ВидыСубконтоКоличественныйРасширеннаяПодсказка" id="51"/>
|
||||||
</CheckBoxField>
|
</CheckBoxField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Объект" id="45">
|
<Attribute name="Объект" id="52">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:ChartOfAccountsObject.Хозрасчетный</v8:Type>
|
<v8:Type>cfg:ChartOfAccountsObject.Хозрасчетный</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
|
|||||||
+67
-15
@@ -13,48 +13,100 @@
|
|||||||
<DataPath>Список</DataPath>
|
<DataPath>Список</DataPath>
|
||||||
<CommandBarLocation>None</CommandBarLocation>
|
<CommandBarLocation>None</CommandBarLocation>
|
||||||
<InitialTreeView>ExpandTopLevel</InitialTreeView>
|
<InitialTreeView>ExpandTopLevel</InitialTreeView>
|
||||||
<EnableStartDrag>true</EnableStartDrag>
|
|
||||||
<EnableDrag>true</EnableDrag>
|
<EnableDrag>true</EnableDrag>
|
||||||
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
||||||
|
<AutoRefresh>false</AutoRefresh>
|
||||||
|
<AutoRefreshPeriod>60</AutoRefreshPeriod>
|
||||||
|
<Period>
|
||||||
|
<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>
|
||||||
|
</Period>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<RestoreCurrentRow>false</RestoreCurrentRow>
|
||||||
|
<TopLevelParent xsi:nil="true"/>
|
||||||
|
<ShowRoot>true</ShowRoot>
|
||||||
|
<AllowRootChoice>false</AllowRootChoice>
|
||||||
|
<UpdateOnDataChange>Auto</UpdateOnDataChange>
|
||||||
|
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
|
||||||
|
<EnableStartDrag>true</EnableStartDrag>
|
||||||
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
||||||
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
||||||
<Autofill>false</Autofill>
|
<Autofill>false</Autofill>
|
||||||
</AutoCommandBar>
|
</AutoCommandBar>
|
||||||
<SearchStringAddition name="СписокСтрокаПоиска" id="4"/>
|
<ExtendedTooltip name="СписокРасширеннаяПодсказка" id="4"/>
|
||||||
<ViewStatusAddition name="СписокСостояниеПросмотра" id="5"/>
|
<SearchStringAddition name="СписокСтрокаПоиска" id="5">
|
||||||
<SearchControlAddition name="СписокУправлениеПоиском" id="6"/>
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСтрокаПоискаКонтекстноеМеню" id="6"/>
|
||||||
|
<ExtendedTooltip name="СписокСтрокаПоискаРасширеннаяПодсказка" id="7"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="СписокСостояниеПросмотра" id="8">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСостояниеПросмотраКонтекстноеМеню" id="9"/>
|
||||||
|
<ExtendedTooltip name="СписокСостояниеПросмотраРасширеннаяПодсказка" id="10"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="СписокУправлениеПоиском" id="11">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокУправлениеПоискомКонтекстноеМеню" id="12"/>
|
||||||
|
<ExtendedTooltip name="СписокУправлениеПоискомРасширеннаяПодсказка" id="13"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<LabelField name="Наименование" id="7">
|
<LabelField name="Наименование" id="14">
|
||||||
<DataPath>Список.Description</DataPath>
|
<DataPath>Список.Description</DataPath>
|
||||||
<ContextMenu name="НаименованиеКонтекстноеМеню" id="8"/>
|
<ContextMenu name="НаименованиеКонтекстноеМеню" id="15"/>
|
||||||
<ExtendedTooltip name="НаименованиеРасширеннаяПодсказка" id="9"/>
|
<ExtendedTooltip name="НаименованиеРасширеннаяПодсказка" id="16"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Код" id="10">
|
<LabelField name="Код" id="17">
|
||||||
<DataPath>Список.Code</DataPath>
|
<DataPath>Список.Code</DataPath>
|
||||||
<ContextMenu name="КодКонтекстноеМеню" id="11"/>
|
<ContextMenu name="КодКонтекстноеМеню" id="18"/>
|
||||||
<ExtendedTooltip name="КодРасширеннаяПодсказка" id="12"/>
|
<ExtendedTooltip name="КодРасширеннаяПодсказка" id="19"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Ссылка" id="13">
|
<LabelField name="Ссылка" id="20">
|
||||||
<DataPath>Список.Ref</DataPath>
|
<DataPath>Список.Ref</DataPath>
|
||||||
<UserVisible>
|
<UserVisible>
|
||||||
<xr:Common>false</xr:Common>
|
<xr:Common>false</xr:Common>
|
||||||
</UserVisible>
|
</UserVisible>
|
||||||
<ContextMenu name="СсылкаКонтекстноеМеню" id="14"/>
|
<ContextMenu name="СсылкаКонтекстноеМеню" id="21"/>
|
||||||
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="15"/>
|
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="22"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Список" id="16">
|
<Attribute name="Список" id="23">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DynamicList</v8:Type>
|
<v8:Type>cfg:DynamicList</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
<MainAttribute>true</MainAttribute>
|
<MainAttribute>true</MainAttribute>
|
||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<MainTable>ChartOfAccounts.Хозрасчетный</MainTable>
|
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<MainTable>ChartOfAccounts.Хозрасчетный</MainTable>
|
||||||
|
<ListSettings>
|
||||||
|
<dcsset:filter>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||||
|
</dcsset:filter>
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:conditionalAppearance>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
|
</dcsset:conditionalAppearance>
|
||||||
|
<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>
|
||||||
|
<dcsset:itemsUserSettingID>UUID-004</dcsset:itemsUserSettingID>
|
||||||
|
</ListSettings>
|
||||||
</Settings>
|
</Settings>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
|
|||||||
+70
-47
@@ -111,6 +111,7 @@
|
|||||||
</InputField>
|
</InputField>
|
||||||
<CheckBoxField name="Исправление" id="46">
|
<CheckBoxField name="Исправление" id="46">
|
||||||
<DataPath>Объект.Исправление</DataPath>
|
<DataPath>Объект.Исправление</DataPath>
|
||||||
|
<CheckBoxType>Auto</CheckBoxType>
|
||||||
<TitleLocation>Right</TitleLocation>
|
<TitleLocation>Right</TitleLocation>
|
||||||
<ContextMenu name="ИсправлениеКонтекстноеМеню" id="47"/>
|
<ContextMenu name="ИсправлениеКонтекстноеМеню" id="47"/>
|
||||||
<ExtendedTooltip name="ИсправлениеРасширеннаяПодсказка" id="48"/>
|
<ExtendedTooltip name="ИсправлениеРасширеннаяПодсказка" id="48"/>
|
||||||
@@ -139,98 +140,120 @@
|
|||||||
<DataPath>Объект.Товары</DataPath>
|
<DataPath>Объект.Товары</DataPath>
|
||||||
<ContextMenu name="ТоварыКонтекстноеМеню" id="55"/>
|
<ContextMenu name="ТоварыКонтекстноеМеню" id="55"/>
|
||||||
<AutoCommandBar name="ТоварыКоманднаяПанель" id="56"/>
|
<AutoCommandBar name="ТоварыКоманднаяПанель" id="56"/>
|
||||||
<SearchStringAddition name="ТоварыСтрокаПоиска" id="57"/>
|
<ExtendedTooltip name="ТоварыРасширеннаяПодсказка" id="57"/>
|
||||||
<ViewStatusAddition name="ТоварыСостояниеПросмотра" id="58"/>
|
<SearchStringAddition name="ТоварыСтрокаПоиска" id="58">
|
||||||
<SearchControlAddition name="ТоварыУправлениеПоиском" id="59"/>
|
<AdditionSource>
|
||||||
|
<Item>Товары</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="ТоварыСтрокаПоискаКонтекстноеМеню" id="59"/>
|
||||||
|
<ExtendedTooltip name="ТоварыСтрокаПоискаРасширеннаяПодсказка" id="60"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="ТоварыСостояниеПросмотра" id="61">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Товары</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="ТоварыСостояниеПросмотраКонтекстноеМеню" id="62"/>
|
||||||
|
<ExtendedTooltip name="ТоварыСостояниеПросмотраРасширеннаяПодсказка" id="63"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="ТоварыУправлениеПоиском" id="64">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Товары</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="ТоварыУправлениеПоискомКонтекстноеМеню" id="65"/>
|
||||||
|
<ExtendedTooltip name="ТоварыУправлениеПоискомРасширеннаяПодсказка" id="66"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<LabelField name="ТоварыНомерСтроки" id="60">
|
<LabelField name="ТоварыНомерСтроки" id="67">
|
||||||
<DataPath>Объект.Товары.LineNumber</DataPath>
|
<DataPath>Объект.Товары.LineNumber</DataPath>
|
||||||
<ContextMenu name="ТоварыНомерСтрокиКонтекстноеМеню" id="61"/>
|
<ContextMenu name="ТоварыНомерСтрокиКонтекстноеМеню" id="68"/>
|
||||||
<ExtendedTooltip name="ТоварыНомерСтрокиРасширеннаяПодсказка" id="62"/>
|
<ExtendedTooltip name="ТоварыНомерСтрокиРасширеннаяПодсказка" id="69"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<InputField name="ТоварыНоменклатура" id="63">
|
<InputField name="ТоварыНоменклатура" id="70">
|
||||||
<DataPath>Объект.Товары.Номенклатура</DataPath>
|
<DataPath>Объект.Товары.Номенклатура</DataPath>
|
||||||
<ContextMenu name="ТоварыНоменклатураКонтекстноеМеню" id="64"/>
|
<ContextMenu name="ТоварыНоменклатураКонтекстноеМеню" id="71"/>
|
||||||
<ExtendedTooltip name="ТоварыНоменклатураРасширеннаяПодсказка" id="65"/>
|
<ExtendedTooltip name="ТоварыНоменклатураРасширеннаяПодсказка" id="72"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыХарактеристика" id="66">
|
<InputField name="ТоварыХарактеристика" id="73">
|
||||||
<DataPath>Объект.Товары.Характеристика</DataPath>
|
<DataPath>Объект.Товары.Характеристика</DataPath>
|
||||||
<ContextMenu name="ТоварыХарактеристикаКонтекстноеМеню" id="67"/>
|
<ContextMenu name="ТоварыХарактеристикаКонтекстноеМеню" id="74"/>
|
||||||
<ExtendedTooltip name="ТоварыХарактеристикаРасширеннаяПодсказка" id="68"/>
|
<ExtendedTooltip name="ТоварыХарактеристикаРасширеннаяПодсказка" id="75"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыНазначение" id="69">
|
<InputField name="ТоварыНазначение" id="76">
|
||||||
<DataPath>Объект.Товары.Назначение</DataPath>
|
<DataPath>Объект.Товары.Назначение</DataPath>
|
||||||
<ContextMenu name="ТоварыНазначениеКонтекстноеМеню" id="70"/>
|
<ContextMenu name="ТоварыНазначениеКонтекстноеМеню" id="77"/>
|
||||||
<ExtendedTooltip name="ТоварыНазначениеРасширеннаяПодсказка" id="71"/>
|
<ExtendedTooltip name="ТоварыНазначениеРасширеннаяПодсказка" id="78"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыУпаковка" id="72">
|
<InputField name="ТоварыУпаковка" id="79">
|
||||||
<DataPath>Объект.Товары.Упаковка</DataPath>
|
<DataPath>Объект.Товары.Упаковка</DataPath>
|
||||||
<ContextMenu name="ТоварыУпаковкаКонтекстноеМеню" id="73"/>
|
<ContextMenu name="ТоварыУпаковкаКонтекстноеМеню" id="80"/>
|
||||||
<ExtendedTooltip name="ТоварыУпаковкаРасширеннаяПодсказка" id="74"/>
|
<ExtendedTooltip name="ТоварыУпаковкаРасширеннаяПодсказка" id="81"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыКоличествоУпаковок" id="75">
|
<InputField name="ТоварыКоличествоУпаковок" id="82">
|
||||||
<DataPath>Объект.Товары.КоличествоУпаковок</DataPath>
|
<DataPath>Объект.Товары.КоличествоУпаковок</DataPath>
|
||||||
<ContextMenu name="ТоварыКоличествоУпаковокКонтекстноеМеню" id="76"/>
|
<ContextMenu name="ТоварыКоличествоУпаковокКонтекстноеМеню" id="83"/>
|
||||||
<ExtendedTooltip name="ТоварыКоличествоУпаковокРасширеннаяПодсказка" id="77"/>
|
<ExtendedTooltip name="ТоварыКоличествоУпаковокРасширеннаяПодсказка" id="84"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыКоличество" id="78">
|
<InputField name="ТоварыКоличество" id="85">
|
||||||
<DataPath>Объект.Товары.Количество</DataPath>
|
<DataPath>Объект.Товары.Количество</DataPath>
|
||||||
<ContextMenu name="ТоварыКоличествоКонтекстноеМеню" id="79"/>
|
<ContextMenu name="ТоварыКоличествоКонтекстноеМеню" id="86"/>
|
||||||
<ExtendedTooltip name="ТоварыКоличествоРасширеннаяПодсказка" id="80"/>
|
<ExtendedTooltip name="ТоварыКоличествоРасширеннаяПодсказка" id="87"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыПодразделение" id="81">
|
<InputField name="ТоварыПодразделение" id="88">
|
||||||
<DataPath>Объект.Товары.Подразделение</DataPath>
|
<DataPath>Объект.Товары.Подразделение</DataPath>
|
||||||
<ContextMenu name="ТоварыПодразделениеКонтекстноеМеню" id="82"/>
|
<ContextMenu name="ТоварыПодразделениеКонтекстноеМеню" id="89"/>
|
||||||
<ExtendedTooltip name="ТоварыПодразделениеРасширеннаяПодсказка" id="83"/>
|
<ExtendedTooltip name="ТоварыПодразделениеРасширеннаяПодсказка" id="90"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыГруппаПродукции" id="84">
|
<InputField name="ТоварыГруппаПродукции" id="91">
|
||||||
<DataPath>Объект.Товары.ГруппаПродукции</DataPath>
|
<DataPath>Объект.Товары.ГруппаПродукции</DataPath>
|
||||||
<ContextMenu name="ТоварыГруппаПродукцииКонтекстноеМеню" id="85"/>
|
<ContextMenu name="ТоварыГруппаПродукцииКонтекстноеМеню" id="92"/>
|
||||||
<ExtendedTooltip name="ТоварыГруппаПродукцииРасширеннаяПодсказка" id="86"/>
|
<ExtendedTooltip name="ТоварыГруппаПродукцииРасширеннаяПодсказка" id="93"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыАналитикаУчетаНоменклатуры" id="87">
|
<InputField name="ТоварыАналитикаУчетаНоменклатуры" id="94">
|
||||||
<DataPath>Объект.Товары.АналитикаУчетаНоменклатуры</DataPath>
|
<DataPath>Объект.Товары.АналитикаУчетаНоменклатуры</DataPath>
|
||||||
<ContextMenu name="ТоварыАналитикаУчетаНоменклатурыКонтекстноеМеню" id="88"/>
|
<ContextMenu name="ТоварыАналитикаУчетаНоменклатурыКонтекстноеМеню" id="95"/>
|
||||||
<ExtendedTooltip name="ТоварыАналитикаУчетаНоменклатурыРасширеннаяПодсказка" id="89"/>
|
<ExtendedTooltip name="ТоварыАналитикаУчетаНоменклатурыРасширеннаяПодсказка" id="96"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="ТоварыИдентификаторСтроки" id="90">
|
<InputField name="ТоварыИдентификаторСтроки" id="97">
|
||||||
<DataPath>Объект.Товары.ИдентификаторСтроки</DataPath>
|
<DataPath>Объект.Товары.ИдентификаторСтроки</DataPath>
|
||||||
<ContextMenu name="ТоварыИдентификаторСтрокиКонтекстноеМеню" id="91"/>
|
<ContextMenu name="ТоварыИдентификаторСтрокиКонтекстноеМеню" id="98"/>
|
||||||
<ExtendedTooltip name="ТоварыИдентификаторСтрокиРасширеннаяПодсказка" id="92"/>
|
<ExtendedTooltip name="ТоварыИдентификаторСтрокиРасширеннаяПодсказка" id="99"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Page>
|
</Page>
|
||||||
<Page name="ГруппаДополнительно" id="93">
|
<Page name="ГруппаДополнительно" id="100">
|
||||||
<Title>
|
<Title>
|
||||||
<v8:item>
|
<v8:item>
|
||||||
<v8:lang>ru</v8:lang>
|
<v8:lang>ru</v8:lang>
|
||||||
<v8:content>Дополнительно</v8:content>
|
<v8:content>Дополнительно</v8:content>
|
||||||
</v8:item>
|
</v8:item>
|
||||||
</Title>
|
</Title>
|
||||||
<ExtendedTooltip name="ГруппаДополнительноРасширеннаяПодсказка" id="94"/>
|
<ExtendedTooltip name="ГруппаДополнительноРасширеннаяПодсказка" id="101"/>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<UsualGroup name="ГруппаПараметры" id="95">
|
<UsualGroup name="ГруппаПараметры" id="102">
|
||||||
<Group>Horizontal</Group>
|
<Group>Horizontal</Group>
|
||||||
<ShowTitle>false</ShowTitle>
|
<ShowTitle>false</ShowTitle>
|
||||||
<ExtendedTooltip name="ГруппаПараметрыРасширеннаяПодсказка" id="96"/>
|
<ExtendedTooltip name="ГруппаПараметрыРасширеннаяПодсказка" id="103"/>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<UsualGroup name="ГруппаПараметрыЛево" id="97">
|
<UsualGroup name="ГруппаПараметрыЛево" id="104">
|
||||||
<Group>Vertical</Group>
|
<Group>Vertical</Group>
|
||||||
<ShowTitle>false</ShowTitle>
|
<ShowTitle>false</ShowTitle>
|
||||||
<ExtendedTooltip name="ГруппаПараметрыЛевоРасширеннаяПодсказка" id="98"/>
|
<ExtendedTooltip name="ГруппаПараметрыЛевоРасширеннаяПодсказка" id="105"/>
|
||||||
</UsualGroup>
|
</UsualGroup>
|
||||||
<UsualGroup name="ГруппаПараметрыПраво" id="99">
|
<UsualGroup name="ГруппаПараметрыПраво" id="106">
|
||||||
<Group>Vertical</Group>
|
<Group>Vertical</Group>
|
||||||
<ShowTitle>false</ShowTitle>
|
<ShowTitle>false</ShowTitle>
|
||||||
<ExtendedTooltip name="ГруппаПараметрыПравоРасширеннаяПодсказка" id="100"/>
|
<ExtendedTooltip name="ГруппаПараметрыПравоРасширеннаяПодсказка" id="107"/>
|
||||||
</UsualGroup>
|
</UsualGroup>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</UsualGroup>
|
</UsualGroup>
|
||||||
<UsualGroup name="ГруппаДополнительныеРеквизиты" id="101">
|
<UsualGroup name="ГруппаДополнительныеРеквизиты" id="108">
|
||||||
<Group>Vertical</Group>
|
<Group>Vertical</Group>
|
||||||
<ExtendedTooltip name="ГруппаДополнительныеРеквизитыРасширеннаяПодсказка" id="102"/>
|
<ExtendedTooltip name="ГруппаДополнительныеРеквизитыРасширеннаяПодсказка" id="109"/>
|
||||||
</UsualGroup>
|
</UsualGroup>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Page>
|
</Page>
|
||||||
@@ -238,7 +261,7 @@
|
|||||||
</Pages>
|
</Pages>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Объект" id="103">
|
<Attribute name="Объект" id="110">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DocumentObject.АктВыполненныхВнутреннихРабот</v8:Type>
|
<v8:Type>cfg:DocumentObject.АктВыполненныхВнутреннихРабот</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
|
|||||||
+99
-47
@@ -13,100 +13,152 @@
|
|||||||
<DataPath>Список</DataPath>
|
<DataPath>Список</DataPath>
|
||||||
<CommandBarLocation>None</CommandBarLocation>
|
<CommandBarLocation>None</CommandBarLocation>
|
||||||
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
||||||
|
<AutoRefresh>false</AutoRefresh>
|
||||||
|
<AutoRefreshPeriod>60</AutoRefreshPeriod>
|
||||||
|
<Period>
|
||||||
|
<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>
|
||||||
|
</Period>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<RestoreCurrentRow>false</RestoreCurrentRow>
|
||||||
|
<TopLevelParent xsi:nil="true"/>
|
||||||
|
<ShowRoot>true</ShowRoot>
|
||||||
|
<AllowRootChoice>false</AllowRootChoice>
|
||||||
|
<UpdateOnDataChange>Auto</UpdateOnDataChange>
|
||||||
|
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
|
||||||
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
||||||
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
||||||
<Autofill>false</Autofill>
|
<Autofill>false</Autofill>
|
||||||
</AutoCommandBar>
|
</AutoCommandBar>
|
||||||
<SearchStringAddition name="СписокСтрокаПоиска" id="4"/>
|
<ExtendedTooltip name="СписокРасширеннаяПодсказка" id="4"/>
|
||||||
<ViewStatusAddition name="СписокСостояниеПросмотра" id="5"/>
|
<SearchStringAddition name="СписокСтрокаПоиска" id="5">
|
||||||
<SearchControlAddition name="СписокУправлениеПоиском" id="6"/>
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСтрокаПоискаКонтекстноеМеню" id="6"/>
|
||||||
|
<ExtendedTooltip name="СписокСтрокаПоискаРасширеннаяПодсказка" id="7"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="СписокСостояниеПросмотра" id="8">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСостояниеПросмотраКонтекстноеМеню" id="9"/>
|
||||||
|
<ExtendedTooltip name="СписокСостояниеПросмотраРасширеннаяПодсказка" id="10"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="СписокУправлениеПоиском" id="11">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокУправлениеПоискомКонтекстноеМеню" id="12"/>
|
||||||
|
<ExtendedTooltip name="СписокУправлениеПоискомРасширеннаяПодсказка" id="13"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<LabelField name="Номер" id="7">
|
<LabelField name="Номер" id="14">
|
||||||
<DataPath>Список.Number</DataPath>
|
<DataPath>Список.Number</DataPath>
|
||||||
<ContextMenu name="НомерКонтекстноеМеню" id="8"/>
|
<ContextMenu name="НомерКонтекстноеМеню" id="15"/>
|
||||||
<ExtendedTooltip name="НомерРасширеннаяПодсказка" id="9"/>
|
<ExtendedTooltip name="НомерРасширеннаяПодсказка" id="16"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Дата" id="10">
|
<LabelField name="Дата" id="17">
|
||||||
<DataPath>Список.Date</DataPath>
|
<DataPath>Список.Date</DataPath>
|
||||||
<ContextMenu name="ДатаКонтекстноеМеню" id="11"/>
|
<ContextMenu name="ДатаКонтекстноеМеню" id="18"/>
|
||||||
<ExtendedTooltip name="ДатаРасширеннаяПодсказка" id="12"/>
|
<ExtendedTooltip name="ДатаРасширеннаяПодсказка" id="19"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Организация" id="13">
|
<LabelField name="Организация" id="20">
|
||||||
<DataPath>Список.Организация</DataPath>
|
<DataPath>Список.Организация</DataPath>
|
||||||
<ContextMenu name="ОрганизацияКонтекстноеМеню" id="14"/>
|
<ContextMenu name="ОрганизацияКонтекстноеМеню" id="21"/>
|
||||||
<ExtendedTooltip name="ОрганизацияРасширеннаяПодсказка" id="15"/>
|
<ExtendedTooltip name="ОрганизацияРасширеннаяПодсказка" id="22"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ОрганизацияПолучатель" id="16">
|
<LabelField name="ОрганизацияПолучатель" id="23">
|
||||||
<DataPath>Список.ОрганизацияПолучатель</DataPath>
|
<DataPath>Список.ОрганизацияПолучатель</DataPath>
|
||||||
<ContextMenu name="ОрганизацияПолучательКонтекстноеМеню" id="17"/>
|
<ContextMenu name="ОрганизацияПолучательКонтекстноеМеню" id="24"/>
|
||||||
<ExtendedTooltip name="ОрганизацияПолучательРасширеннаяПодсказка" id="18"/>
|
<ExtendedTooltip name="ОрганизацияПолучательРасширеннаяПодсказка" id="25"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Подразделение" id="19">
|
<LabelField name="Подразделение" id="26">
|
||||||
<DataPath>Список.Подразделение</DataPath>
|
<DataPath>Список.Подразделение</DataPath>
|
||||||
<ContextMenu name="ПодразделениеКонтекстноеМеню" id="20"/>
|
<ContextMenu name="ПодразделениеКонтекстноеМеню" id="27"/>
|
||||||
<ExtendedTooltip name="ПодразделениеРасширеннаяПодсказка" id="21"/>
|
<ExtendedTooltip name="ПодразделениеРасширеннаяПодсказка" id="28"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ХозяйственнаяОперация" id="22">
|
<LabelField name="ХозяйственнаяОперация" id="29">
|
||||||
<DataPath>Список.ХозяйственнаяОперация</DataPath>
|
<DataPath>Список.ХозяйственнаяОперация</DataPath>
|
||||||
<ContextMenu name="ХозяйственнаяОперацияКонтекстноеМеню" id="23"/>
|
<ContextMenu name="ХозяйственнаяОперацияКонтекстноеМеню" id="30"/>
|
||||||
<ExtendedTooltip name="ХозяйственнаяОперацияРасширеннаяПодсказка" id="24"/>
|
<ExtendedTooltip name="ХозяйственнаяОперацияРасширеннаяПодсказка" id="31"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ПеремещениеПодДеятельность" id="25">
|
<LabelField name="ПеремещениеПодДеятельность" id="32">
|
||||||
<DataPath>Список.ПеремещениеПодДеятельность</DataPath>
|
<DataPath>Список.ПеремещениеПодДеятельность</DataPath>
|
||||||
<ContextMenu name="ПеремещениеПодДеятельностьКонтекстноеМеню" id="26"/>
|
<ContextMenu name="ПеремещениеПодДеятельностьКонтекстноеМеню" id="33"/>
|
||||||
<ExtendedTooltip name="ПеремещениеПодДеятельностьРасширеннаяПодсказка" id="27"/>
|
<ExtendedTooltip name="ПеремещениеПодДеятельностьРасширеннаяПодсказка" id="34"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="НаправлениеДеятельности" id="28">
|
<LabelField name="НаправлениеДеятельности" id="35">
|
||||||
<DataPath>Список.НаправлениеДеятельности</DataPath>
|
<DataPath>Список.НаправлениеДеятельности</DataPath>
|
||||||
<ContextMenu name="НаправлениеДеятельностиКонтекстноеМеню" id="29"/>
|
<ContextMenu name="НаправлениеДеятельностиКонтекстноеМеню" id="36"/>
|
||||||
<ExtendedTooltip name="НаправлениеДеятельностиРасширеннаяПодсказка" id="30"/>
|
<ExtendedTooltip name="НаправлениеДеятельностиРасширеннаяПодсказка" id="37"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Ответственный" id="31">
|
<LabelField name="Ответственный" id="38">
|
||||||
<DataPath>Список.Ответственный</DataPath>
|
<DataPath>Список.Ответственный</DataPath>
|
||||||
<ContextMenu name="ОтветственныйКонтекстноеМеню" id="32"/>
|
<ContextMenu name="ОтветственныйКонтекстноеМеню" id="39"/>
|
||||||
<ExtendedTooltip name="ОтветственныйРасширеннаяПодсказка" id="33"/>
|
<ExtendedTooltip name="ОтветственныйРасширеннаяПодсказка" id="40"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="СторнируемыйДокумент" id="34">
|
<LabelField name="СторнируемыйДокумент" id="41">
|
||||||
<DataPath>Список.СторнируемыйДокумент</DataPath>
|
<DataPath>Список.СторнируемыйДокумент</DataPath>
|
||||||
<ContextMenu name="СторнируемыйДокументКонтекстноеМеню" id="35"/>
|
<ContextMenu name="СторнируемыйДокументКонтекстноеМеню" id="42"/>
|
||||||
<ExtendedTooltip name="СторнируемыйДокументРасширеннаяПодсказка" id="36"/>
|
<ExtendedTooltip name="СторнируемыйДокументРасширеннаяПодсказка" id="43"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ИсправляемыйДокумент" id="37">
|
<LabelField name="ИсправляемыйДокумент" id="44">
|
||||||
<DataPath>Список.ИсправляемыйДокумент</DataPath>
|
<DataPath>Список.ИсправляемыйДокумент</DataPath>
|
||||||
<ContextMenu name="ИсправляемыйДокументКонтекстноеМеню" id="38"/>
|
<ContextMenu name="ИсправляемыйДокументКонтекстноеМеню" id="45"/>
|
||||||
<ExtendedTooltip name="ИсправляемыйДокументРасширеннаяПодсказка" id="39"/>
|
<ExtendedTooltip name="ИсправляемыйДокументРасширеннаяПодсказка" id="46"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Комментарий" id="40">
|
<LabelField name="Комментарий" id="47">
|
||||||
<DataPath>Список.Комментарий</DataPath>
|
<DataPath>Список.Комментарий</DataPath>
|
||||||
<ContextMenu name="КомментарийКонтекстноеМеню" id="41"/>
|
<ContextMenu name="КомментарийКонтекстноеМеню" id="48"/>
|
||||||
<ExtendedTooltip name="КомментарийРасширеннаяПодсказка" id="42"/>
|
<ExtendedTooltip name="КомментарийРасширеннаяПодсказка" id="49"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Исправление" id="43">
|
<LabelField name="Исправление" id="50">
|
||||||
<DataPath>Список.Исправление</DataPath>
|
<DataPath>Список.Исправление</DataPath>
|
||||||
<ContextMenu name="ИсправлениеКонтекстноеМеню" id="44"/>
|
<ContextMenu name="ИсправлениеКонтекстноеМеню" id="51"/>
|
||||||
<ExtendedTooltip name="ИсправлениеРасширеннаяПодсказка" id="45"/>
|
<ExtendedTooltip name="ИсправлениеРасширеннаяПодсказка" id="52"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Ссылка" id="46">
|
<LabelField name="Ссылка" id="53">
|
||||||
<DataPath>Список.Ref</DataPath>
|
<DataPath>Список.Ref</DataPath>
|
||||||
<UserVisible>
|
<UserVisible>
|
||||||
<xr:Common>false</xr:Common>
|
<xr:Common>false</xr:Common>
|
||||||
</UserVisible>
|
</UserVisible>
|
||||||
<ContextMenu name="СсылкаКонтекстноеМеню" id="47"/>
|
<ContextMenu name="СсылкаКонтекстноеМеню" id="54"/>
|
||||||
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="48"/>
|
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="55"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Список" id="49">
|
<Attribute name="Список" id="56">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DynamicList</v8:Type>
|
<v8:Type>cfg:DynamicList</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
<MainAttribute>true</MainAttribute>
|
<MainAttribute>true</MainAttribute>
|
||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<MainTable>Document.АктВыполненныхВнутреннихРабот</MainTable>
|
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<MainTable>Document.АктВыполненныхВнутреннихРабот</MainTable>
|
||||||
|
<ListSettings>
|
||||||
|
<dcsset:filter>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||||
|
</dcsset:filter>
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:conditionalAppearance>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
|
</dcsset:conditionalAppearance>
|
||||||
|
<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>
|
||||||
|
<dcsset:itemsUserSettingID>UUID-004</dcsset:itemsUserSettingID>
|
||||||
|
</ListSettings>
|
||||||
</Settings>
|
</Settings>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
|
|||||||
+75
-23
@@ -13,57 +13,109 @@
|
|||||||
<DataPath>Список</DataPath>
|
<DataPath>Список</DataPath>
|
||||||
<CommandBarLocation>None</CommandBarLocation>
|
<CommandBarLocation>None</CommandBarLocation>
|
||||||
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
||||||
|
<AutoRefresh>false</AutoRefresh>
|
||||||
|
<AutoRefreshPeriod>60</AutoRefreshPeriod>
|
||||||
|
<Period>
|
||||||
|
<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>
|
||||||
|
</Period>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<RestoreCurrentRow>false</RestoreCurrentRow>
|
||||||
|
<TopLevelParent xsi:nil="true"/>
|
||||||
|
<ShowRoot>true</ShowRoot>
|
||||||
|
<AllowRootChoice>false</AllowRootChoice>
|
||||||
|
<UpdateOnDataChange>Auto</UpdateOnDataChange>
|
||||||
|
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
|
||||||
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
|
||||||
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
|
||||||
<Autofill>false</Autofill>
|
<Autofill>false</Autofill>
|
||||||
</AutoCommandBar>
|
</AutoCommandBar>
|
||||||
<SearchStringAddition name="СписокСтрокаПоиска" id="4"/>
|
<ExtendedTooltip name="СписокРасширеннаяПодсказка" id="4"/>
|
||||||
<ViewStatusAddition name="СписокСостояниеПросмотра" id="5"/>
|
<SearchStringAddition name="СписокСтрокаПоиска" id="5">
|
||||||
<SearchControlAddition name="СписокУправлениеПоиском" id="6"/>
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСтрокаПоискаКонтекстноеМеню" id="6"/>
|
||||||
|
<ExtendedTooltip name="СписокСтрокаПоискаРасширеннаяПодсказка" id="7"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="СписокСостояниеПросмотра" id="8">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСостояниеПросмотраКонтекстноеМеню" id="9"/>
|
||||||
|
<ExtendedTooltip name="СписокСостояниеПросмотраРасширеннаяПодсказка" id="10"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="СписокУправлениеПоиском" id="11">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокУправлениеПоискомКонтекстноеМеню" id="12"/>
|
||||||
|
<ExtendedTooltip name="СписокУправлениеПоискомРасширеннаяПодсказка" id="13"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<LabelField name="Период" id="7">
|
<LabelField name="Период" id="14">
|
||||||
<DataPath>Список.Period</DataPath>
|
<DataPath>Список.Period</DataPath>
|
||||||
<ContextMenu name="ПериодКонтекстноеМеню" id="8"/>
|
<ContextMenu name="ПериодКонтекстноеМеню" id="15"/>
|
||||||
<ExtendedTooltip name="ПериодРасширеннаяПодсказка" id="9"/>
|
<ExtendedTooltip name="ПериодРасширеннаяПодсказка" id="16"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Регистратор" id="10">
|
<LabelField name="Регистратор" id="17">
|
||||||
<DataPath>Список.Recorder</DataPath>
|
<DataPath>Список.Recorder</DataPath>
|
||||||
<ContextMenu name="РегистраторКонтекстноеМеню" id="11"/>
|
<ContextMenu name="РегистраторКонтекстноеМеню" id="18"/>
|
||||||
<ExtendedTooltip name="РегистраторРасширеннаяПодсказка" id="12"/>
|
<ExtendedTooltip name="РегистраторРасширеннаяПодсказка" id="19"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="НомерСтроки" id="13">
|
<LabelField name="НомерСтроки" id="20">
|
||||||
<DataPath>Список.LineNumber</DataPath>
|
<DataPath>Список.LineNumber</DataPath>
|
||||||
<ContextMenu name="НомерСтрокиКонтекстноеМеню" id="14"/>
|
<ContextMenu name="НомерСтрокиКонтекстноеМеню" id="21"/>
|
||||||
<ExtendedTooltip name="НомерСтрокиРасширеннаяПодсказка" id="15"/>
|
<ExtendedTooltip name="НомерСтрокиРасширеннаяПодсказка" id="22"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Номенклатура" id="16">
|
<LabelField name="Номенклатура" id="23">
|
||||||
<DataPath>Список.Номенклатура</DataPath>
|
<DataPath>Список.Номенклатура</DataPath>
|
||||||
<ContextMenu name="НоменклатураКонтекстноеМеню" id="17"/>
|
<ContextMenu name="НоменклатураКонтекстноеМеню" id="24"/>
|
||||||
<ExtendedTooltip name="НоменклатураРасширеннаяПодсказка" id="18"/>
|
<ExtendedTooltip name="НоменклатураРасширеннаяПодсказка" id="25"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="ВидЦены" id="19">
|
<LabelField name="ВидЦены" id="26">
|
||||||
<DataPath>Список.ВидЦены</DataPath>
|
<DataPath>Список.ВидЦены</DataPath>
|
||||||
<ContextMenu name="ВидЦеныКонтекстноеМеню" id="20"/>
|
<ContextMenu name="ВидЦеныКонтекстноеМеню" id="27"/>
|
||||||
<ExtendedTooltip name="ВидЦеныРасширеннаяПодсказка" id="21"/>
|
<ExtendedTooltip name="ВидЦеныРасширеннаяПодсказка" id="28"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
<LabelField name="Цена" id="22">
|
<LabelField name="Цена" id="29">
|
||||||
<DataPath>Список.Цена</DataPath>
|
<DataPath>Список.Цена</DataPath>
|
||||||
<ContextMenu name="ЦенаКонтекстноеМеню" id="23"/>
|
<ContextMenu name="ЦенаКонтекстноеМеню" id="30"/>
|
||||||
<ExtendedTooltip name="ЦенаРасширеннаяПодсказка" id="24"/>
|
<ExtendedTooltip name="ЦенаРасширеннаяПодсказка" id="31"/>
|
||||||
</LabelField>
|
</LabelField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Список" id="25">
|
<Attribute name="Список" id="32">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DynamicList</v8:Type>
|
<v8:Type>cfg:DynamicList</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
<MainAttribute>true</MainAttribute>
|
<MainAttribute>true</MainAttribute>
|
||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<MainTable>InformationRegister.ЦеныНоменклатуры</MainTable>
|
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<MainTable>InformationRegister.ЦеныНоменклатуры</MainTable>
|
||||||
|
<ListSettings>
|
||||||
|
<dcsset:filter>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||||
|
</dcsset:filter>
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:conditionalAppearance>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
|
</dcsset:conditionalAppearance>
|
||||||
|
<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>
|
||||||
|
<dcsset:itemsUserSettingID>UUID-004</dcsset:itemsUserSettingID>
|
||||||
|
</ListSettings>
|
||||||
</Settings>
|
</Settings>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "Доп. колонки табличной части объекта (AdditionalColumns)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": {
|
||||||
|
"type": "DataProcessor",
|
||||||
|
"name": "ДопКолонки",
|
||||||
|
"tabularSections": [
|
||||||
|
{ "name": "Прочее", "attributes": [ { "name": "Значение", "type": "String", "length": 50 } ] },
|
||||||
|
{ "name": "ЕщёТаблица", "attributes": [ { "name": "Поле", "type": "String", "length": 10 } ] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/ДопКолонки.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/ДопКолонки/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"validatePath": "DataProcessors/ДопКолонки/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Доп. колонки",
|
||||||
|
"elements": [
|
||||||
|
{ "label": "Подпись", "title": "Форма с доп. колонками табличной части" }
|
||||||
|
],
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.ДопКолонки", "main": true,
|
||||||
|
"additionalColumns": [
|
||||||
|
{ "table": "Объект.Прочее", "columns": [
|
||||||
|
{ "name": "Доступность", "type": "boolean" },
|
||||||
|
{ "name": "Служебная", "type": "string" }
|
||||||
|
]},
|
||||||
|
{ "table": "Объект.ЕщёТаблица", "columns": [] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,16 +17,27 @@
|
|||||||
"title": "Разные типы",
|
"title": "Разные типы",
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "input": "Строка", "path": "Строка" },
|
{ "input": "Строка", "path": "Строка" },
|
||||||
{ "input": "Число", "path": "Число" },
|
{ "input": "Число", "path": "Число", "userVisible": false },
|
||||||
{ "input": "Дата", "path": "Дата" },
|
{ "input": "Дата", "path": "Дата" },
|
||||||
{ "input": "Булево", "path": "Булево" }
|
{ "input": "Булево", "path": "Булево" }
|
||||||
],
|
],
|
||||||
"attributes": [
|
"attributes": [
|
||||||
{ "name": "Объект", "type": "DataProcessorObject.Типы", "main": true },
|
{ "name": "Объект", "type": "DataProcessorObject.Типы", "main": true },
|
||||||
{ "name": "Строка", "type": "string(200)" },
|
{ "name": "Строка", "type": "string(200)", "view": false, "save": true, "fillCheck": true },
|
||||||
{ "name": "Число", "type": "decimal(10,0,nonneg)" },
|
{ "name": "Число", "type": "decimal(10,0,nonneg)", "edit": { "common": false, "roles": { "a1b2c3d4-1111-2222-3333-444455556666": true } } },
|
||||||
{ "name": "Дата", "type": "dateTime" },
|
{ "name": "Дата", "type": "dateTime", "title": "" },
|
||||||
{ "name": "Булево", "type": "boolean" }
|
{ "name": "Булево", "type": "boolean" },
|
||||||
|
{ "name": "Период", "type": "СтандартныйПериод", "save": ["Период", "EndDate", "StartDate", "Variant"] },
|
||||||
|
{ "name": "СписокЗначений", "type": "ValueList", "valueType": "string(50) | decimal(10,2)" },
|
||||||
|
{ "name": "СписокЛюбой", "type": "ValueList", "valueType": "" },
|
||||||
|
{ "name": "Идентификатор", "type": "v8:UUID" },
|
||||||
|
{ "name": "НаборКонстант", "type": "ConstantsSet" },
|
||||||
|
{ "name": "ОбъектОтчета", "type": "ReportObject" },
|
||||||
|
{ "name": "Таблица", "type": "ValueTable", "title": "Таблица", "columns": [
|
||||||
|
{ "name": "ИНН", "type": "string(12,fixed)" },
|
||||||
|
{ "name": "Код", "type": "string(9,fixed)" },
|
||||||
|
{ "name": "Имя", "type": "string(100)" }
|
||||||
|
]}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "ButtonGroup в командной панели + команды с tooltip/currentRowUse",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "ГруппыКнопок" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/ГруппыКнопок.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/ГруппыКнопок/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"validatePath": "DataProcessors/ГруппыКнопок/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Группы кнопок",
|
||||||
|
"elements": [
|
||||||
|
{ "cmdBar": "Панель", "children": [
|
||||||
|
{ "button": "Выполнить", "command": "Выполнить", "defaultButton": true },
|
||||||
|
{ "buttonGroup": "ГруппаПереместить", "title": "Переместить", "children": [
|
||||||
|
{ "button": "Вверх", "command": "Вверх" },
|
||||||
|
{ "button": "Вниз", "command": "Вниз" }
|
||||||
|
]},
|
||||||
|
{ "buttonGroup": "ГруппаГлобальныеКоманды", "commandSource": "FormCommandPanelGlobalCommands" },
|
||||||
|
{ "popup": "ПодменюПечать", "title": "Печать", "picture": "StdPicture.Print", "loadTransparent": false, "representation": "PictureAndText", "titleTextColor": "style:ButtonTextColor", "titleFont": "style:ВажнаяНадписьШрифт", "children": [
|
||||||
|
{ "button": "ПечатьСчёта", "command": "Выполнить" }
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
],
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.ГруппыКнопок", "main": true }
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
{ "name": "Выполнить", "action": "ВыполнитьОбработка", "tooltip": "Запустить обработку", "shortcut": "Ctrl+Enter" },
|
||||||
|
{ "name": "Вверх", "action": "ВверхОбработка", "currentRowUse": "DontUse" },
|
||||||
|
{ "name": "Вниз", "action": "ВнизОбработка", "currentRowUse": "DontUse" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "Форма с полем календаря",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "Календарь" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/Календарь.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/Календарь/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"validatePath": "DataProcessors/Календарь/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Календарь",
|
||||||
|
"elements": [
|
||||||
|
{ "calendar": "Календарь", "path": "Дата", "titleLocation": "none", "selectionMode": "Interval", "showCurrentDate": false, "widthInMonths": 2, "events": { "OnActivateDate": "КалендарьПриАктивизацииДаты" } },
|
||||||
|
{ "calendar": "КалендарьМесяцы", "path": "ДатаМесяцы", "showMonthsPanel": true, "heightInMonths": 0 }
|
||||||
|
],
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.Календарь", "main": true },
|
||||||
|
{ "name": "Дата", "type": "date" },
|
||||||
|
{ "name": "ДатаМесяцы", "type": "date" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "Форма с полями диаграмм + design-time Settings планировщика",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "Диаграммы" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/Диаграммы.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/Диаграммы/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"validatePath": "DataProcessors/Диаграммы/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Диаграммы",
|
||||||
|
"elements": [
|
||||||
|
{ "chart": "Диаграмма", "path": "Диаграмма", "titleLocation": "none" },
|
||||||
|
{ "graphicalSchema": "Схема", "path": "Схема", "titleLocation": "none", "edit": false },
|
||||||
|
{ "periodField": "Период", "path": "Период", "titleLocation": "none" },
|
||||||
|
{ "ganttChart": "Ганта", "path": "Ганта", "titleLocation": "none",
|
||||||
|
"ganttTable": { "table": "ТаблицаГанта", "path": "Ганта", "height": 3 } },
|
||||||
|
{ "dendrogram": "Дендро", "path": "Дендро", "titleLocation": "none" },
|
||||||
|
{ "planner": "Планировщик", "path": "Планировщик", "titleLocation": "none" }
|
||||||
|
],
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.Диаграммы", "main": true },
|
||||||
|
{ "name": "Диаграмма", "type": "d5p1:Chart" },
|
||||||
|
{ "name": "Схема", "type": "d5p1:FlowchartContextType" },
|
||||||
|
{ "name": "Период", "type": "v8:StandardPeriod" },
|
||||||
|
{ "name": "Ганта", "type": "d5p1:GanttChart" },
|
||||||
|
{ "name": "Дендро", "type": "d5p1:Dendrogram" },
|
||||||
|
{ "name": "Планировщик", "type": "pl:Planner", "planner": {
|
||||||
|
"items": [
|
||||||
|
{ "text": "Встреча", "begin": "2026-06-09T01:00:00", "end": "2026-06-09T04:00:00" }
|
||||||
|
],
|
||||||
|
"dimensions": [
|
||||||
|
{ "text": "Измерение", "elements": [
|
||||||
|
{ "value": "А", "text": "Элемент А", "showOnlySubordinatesAreas": true }
|
||||||
|
] }
|
||||||
|
],
|
||||||
|
"period": { "begin": "2026-06-09T00:00:00", "end": "2026-06-09T23:59:59" }
|
||||||
|
} }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
{
|
||||||
|
"name": "Форма с design-time диаграммой Ганта (d4p1:GanttChart Settings)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": {
|
||||||
|
"type": "DataProcessor",
|
||||||
|
"name": "ДиаграммаГанта"
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"-JsonPath": "{inputFile}",
|
||||||
|
"-OutputDir": "{workDir}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": {
|
||||||
|
"-ObjectPath": "{workDir}/DataProcessors/ДиаграммаГанта.xml",
|
||||||
|
"-FormName": "Форма"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"outputPath": "DataProcessors/ДиаграммаГанта/Forms/Форма/Ext/Form.xml"
|
||||||
|
},
|
||||||
|
"validatePath": "DataProcessors/ДиаграммаГанта/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Диаграмма Ганта",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"ganttChart": "Ганта",
|
||||||
|
"path": "Ганта",
|
||||||
|
"titleLocation": "none",
|
||||||
|
"ganttTable": {
|
||||||
|
"table": "ТаблицаГанта",
|
||||||
|
"path": "Ганта",
|
||||||
|
"height": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"name": "Объект",
|
||||||
|
"type": "DataProcessorObject.ДиаграммаГанта",
|
||||||
|
"main": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ганта",
|
||||||
|
"type": "d5p1:GanttChart",
|
||||||
|
"chart": {
|
||||||
|
"chart": {
|
||||||
|
"seriesCurId": "1",
|
||||||
|
"pointsCurId": "0",
|
||||||
|
"isSeriesDesign": true,
|
||||||
|
"realSeriesCount": "0",
|
||||||
|
"realExSeriesData": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"color": "#991919",
|
||||||
|
"line": {
|
||||||
|
"width": 2,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"marker": "Rhomb",
|
||||||
|
"text": {
|
||||||
|
"#": "Сводная"
|
||||||
|
},
|
||||||
|
"strIsChanged": false,
|
||||||
|
"isExpand": false,
|
||||||
|
"isIndicator": false,
|
||||||
|
"colorPriority": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isPointsDesign": true,
|
||||||
|
"realPointCount": "0",
|
||||||
|
"curSeries": "-1",
|
||||||
|
"curPoint": "0",
|
||||||
|
"chartType": "Column3D",
|
||||||
|
"circleLabelType": "None",
|
||||||
|
"labelsDelimiter": ", ",
|
||||||
|
"labelsLocation": "Edge",
|
||||||
|
"lbFormat": "",
|
||||||
|
"lbpFormat": "",
|
||||||
|
"labelsColor": "style:FormTextColor",
|
||||||
|
"labelsFont": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"transparentLabelsBkg": true,
|
||||||
|
"labelsBkgColor": "auto",
|
||||||
|
"labelsBorder": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "Single"
|
||||||
|
},
|
||||||
|
"labelsBorderColor": "auto",
|
||||||
|
"circleExpandMode": "None",
|
||||||
|
"chart3Dcrd": "SouthWest",
|
||||||
|
"title": "",
|
||||||
|
"isShowTitle": true,
|
||||||
|
"isShowLegend": false,
|
||||||
|
"ttlBorder": {
|
||||||
|
"width": 0,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"ttlBorderColor": "style:BorderColor",
|
||||||
|
"lgBorder": {
|
||||||
|
"width": 0,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"lgBorderColor": "style:BorderColor",
|
||||||
|
"chBorder": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "Single"
|
||||||
|
},
|
||||||
|
"chBorderColor": "style:BorderColor",
|
||||||
|
"transparent": false,
|
||||||
|
"bkgColor": "style:FieldBackColor",
|
||||||
|
"isTrnspTtl": false,
|
||||||
|
"ttlColor": "style:FieldBackColor",
|
||||||
|
"isTrnspLeg": false,
|
||||||
|
"legColor": "style:FieldBackColor",
|
||||||
|
"isTrnspCh": false,
|
||||||
|
"chColor": "style:FieldBackColor",
|
||||||
|
"ttlTxtColor": "style:FormTextColor",
|
||||||
|
"legTxtColor": "style:FormTextColor",
|
||||||
|
"chTxtColor": "style:FormTextColor",
|
||||||
|
"ttlFont": {
|
||||||
|
"ref": "style:TextFont",
|
||||||
|
"kind": "StyleItem"
|
||||||
|
},
|
||||||
|
"legFont": {
|
||||||
|
"ref": "style:TextFont",
|
||||||
|
"kind": "StyleItem"
|
||||||
|
},
|
||||||
|
"chFont": {
|
||||||
|
"ref": "style:TextFont",
|
||||||
|
"kind": "StyleItem"
|
||||||
|
},
|
||||||
|
"isShowScale": true,
|
||||||
|
"isShowScaleVL": true,
|
||||||
|
"isShowSeriesScale": true,
|
||||||
|
"isShowPointsScale": true,
|
||||||
|
"isShowValuesScale": true,
|
||||||
|
"vsFormat": "",
|
||||||
|
"xLabelsOrientation": "Auto",
|
||||||
|
"scaleLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"scaleColor": "#A9A9A9",
|
||||||
|
"isAutoSeriesName": true,
|
||||||
|
"isAutoPointName": true,
|
||||||
|
"maxMode": "NotDefined",
|
||||||
|
"maxSeries": "4",
|
||||||
|
"maxSeriesPrc": "30",
|
||||||
|
"spaceMode": "Half",
|
||||||
|
"baseVal": "0",
|
||||||
|
"isOutline": false,
|
||||||
|
"realPiePoint": "0",
|
||||||
|
"realStockSeries": "0",
|
||||||
|
"isLight": true,
|
||||||
|
"isGradient": false,
|
||||||
|
"isTransposition": false,
|
||||||
|
"hideBaseVal": false,
|
||||||
|
"dataTable": false,
|
||||||
|
"dtVerLines": true,
|
||||||
|
"dtHorLines": true,
|
||||||
|
"dtHAlign": "Right",
|
||||||
|
"dtFormat": "",
|
||||||
|
"dtKeys": true,
|
||||||
|
"paletteKind": "Auto",
|
||||||
|
"animation": "Auto",
|
||||||
|
"rebuildTime": "0",
|
||||||
|
"isTransposed": false,
|
||||||
|
"autoTransposition": false,
|
||||||
|
"legendScrollEnable": true,
|
||||||
|
"surfaceColor": "#A90000",
|
||||||
|
"radarScaleType": "Circle",
|
||||||
|
"gaugeValuesPresentation": "Needle",
|
||||||
|
"gaugeQualityBands": {
|
||||||
|
"useTextStr": false,
|
||||||
|
"useTooltipStr": false
|
||||||
|
},
|
||||||
|
"beginGaugeAngle": "0",
|
||||||
|
"endGaugeAngle": "180",
|
||||||
|
"gaugeThickness": "5",
|
||||||
|
"gaugeLabelsLocation": "InsideScale",
|
||||||
|
"gaugeLabelsArcDirection": false,
|
||||||
|
"gaugeBushThickness": "4",
|
||||||
|
"gaugeBushColor": "#A9A9A9",
|
||||||
|
"autoMaxValue": true,
|
||||||
|
"userMaxValue": "0",
|
||||||
|
"autoMinValue": true,
|
||||||
|
"userMinValue": "0",
|
||||||
|
"elementsIsInit": true,
|
||||||
|
"titleIsInit": true,
|
||||||
|
"legendIsInit": true,
|
||||||
|
"chartIsInit": true,
|
||||||
|
"elementsChart": {
|
||||||
|
"left": "0",
|
||||||
|
"right": "0",
|
||||||
|
"top": "0",
|
||||||
|
"bottom": "0"
|
||||||
|
},
|
||||||
|
"elementsLegend": {
|
||||||
|
"left": "0.913738019169329",
|
||||||
|
"right": "0",
|
||||||
|
"top": "0.0407725321888412",
|
||||||
|
"bottom": "0"
|
||||||
|
},
|
||||||
|
"elementsTitle": {
|
||||||
|
"left": "0.8328025477707",
|
||||||
|
"right": "0",
|
||||||
|
"top": "0",
|
||||||
|
"bottom": "0.959401709401709"
|
||||||
|
},
|
||||||
|
"borderColor": "style:BorderColor",
|
||||||
|
"border": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "Single"
|
||||||
|
},
|
||||||
|
"dataSourceDescription": "",
|
||||||
|
"isDataSourceMode": false,
|
||||||
|
"isRandomizedNewValues": true,
|
||||||
|
"splineStrain": "95",
|
||||||
|
"translucencePercent": "0",
|
||||||
|
"funnelNeckHeightPercent": "10",
|
||||||
|
"funnelNeckWidthPercent": "10",
|
||||||
|
"funnelGapSumPercent": "3",
|
||||||
|
"multiStageLinkLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"multiStageLinkColor": "#000000",
|
||||||
|
"valuesAxis": "",
|
||||||
|
"pointsAxis": "",
|
||||||
|
"legendPlacement": "None",
|
||||||
|
"plotAreaPlacement": "UseCoordinates",
|
||||||
|
"titleAreaPlacement": "UseCoordinates"
|
||||||
|
},
|
||||||
|
"points": {
|
||||||
|
"testMode": false,
|
||||||
|
"value": {
|
||||||
|
"itemKey": "0",
|
||||||
|
"key": "0",
|
||||||
|
"parentKey": "0",
|
||||||
|
"leftKey": "0",
|
||||||
|
"rightKey": "0",
|
||||||
|
"extKey": "0",
|
||||||
|
"title": "",
|
||||||
|
"cacheKey": "0",
|
||||||
|
"baseData": "4294901761",
|
||||||
|
"font": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"picture": ""
|
||||||
|
},
|
||||||
|
"contentCacheItem": {
|
||||||
|
"mainColor": "#000000",
|
||||||
|
"secondColor": "#000000",
|
||||||
|
"backColor": "auto",
|
||||||
|
"textColor": "auto"
|
||||||
|
},
|
||||||
|
"autoText": true,
|
||||||
|
"useValuesReverseBehavior": false
|
||||||
|
},
|
||||||
|
"series": {
|
||||||
|
"testMode": false,
|
||||||
|
"value": {
|
||||||
|
"itemKey": "0",
|
||||||
|
"key": "0",
|
||||||
|
"parentKey": "0",
|
||||||
|
"leftKey": "0",
|
||||||
|
"rightKey": "0",
|
||||||
|
"extKey": "0",
|
||||||
|
"title": "",
|
||||||
|
"cacheKey": "0",
|
||||||
|
"baseData": "4294902785"
|
||||||
|
},
|
||||||
|
"contentCacheItem": {
|
||||||
|
"mainColor": "#000000",
|
||||||
|
"secondColor": "#000000",
|
||||||
|
"hatchBetweenIntervalsColor": "#000000"
|
||||||
|
},
|
||||||
|
"autoText": true,
|
||||||
|
"useValuesReverseBehavior": false
|
||||||
|
},
|
||||||
|
"drawEmpty": true,
|
||||||
|
"timeScale": {
|
||||||
|
"placement": "Top",
|
||||||
|
"level": {
|
||||||
|
"measure": "Day",
|
||||||
|
"interval": "1",
|
||||||
|
"show": true,
|
||||||
|
"line": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Dotted"
|
||||||
|
},
|
||||||
|
"scaleColor": "#C0C0C0",
|
||||||
|
"dayFormatRule": "MonthDayWeekDay",
|
||||||
|
"format": "",
|
||||||
|
"labels": {
|
||||||
|
"ticks": "0"
|
||||||
|
},
|
||||||
|
"backColor": "auto",
|
||||||
|
"textColor": "auto",
|
||||||
|
"showPereodicalLabels": true
|
||||||
|
},
|
||||||
|
"transparent": false,
|
||||||
|
"backColor": "style:FieldBackColor",
|
||||||
|
"textColor": "style:FormTextColor",
|
||||||
|
"currentLevel": "0"
|
||||||
|
},
|
||||||
|
"keepScaleVariant": "AllData",
|
||||||
|
"fixedVariantMeasure": "Month",
|
||||||
|
"fixedVariantInterval": "1",
|
||||||
|
"autoFullInterval": true,
|
||||||
|
"fullIntervalBegin": "2016-05-01T00:00:00",
|
||||||
|
"fullIntervalEnd": "2016-06-01T00:00:00",
|
||||||
|
"visualBegin": "2016-05-01T00:00:00",
|
||||||
|
"intervalDrawType": "Gradient",
|
||||||
|
"noneVariantChars": "3",
|
||||||
|
"noneVariantMeasure": "Day",
|
||||||
|
"verticalStretch": "None",
|
||||||
|
"verticalScrollEnable": true,
|
||||||
|
"showValueText": "None",
|
||||||
|
"extTitle": "",
|
||||||
|
"outboundColor": "#FFFFFF",
|
||||||
|
"backIntervals": {
|
||||||
|
"collection": {
|
||||||
|
"ticks": "0"
|
||||||
|
},
|
||||||
|
"ticks": "0"
|
||||||
|
},
|
||||||
|
"linksColor": "#000080",
|
||||||
|
"linksLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"showPointsText": "Auto",
|
||||||
|
"showData": "Auto",
|
||||||
|
"textPlacement": "Auto",
|
||||||
|
"intervalTextRepresentation": "Auto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,357 @@
|
|||||||
|
{
|
||||||
|
"name": "Форма с design-time диаграммой (d4p1:Chart Settings)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": {
|
||||||
|
"type": "DataProcessor",
|
||||||
|
"name": "Диаграмма"
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"-JsonPath": "{inputFile}",
|
||||||
|
"-OutputDir": "{workDir}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": {
|
||||||
|
"-ObjectPath": "{workDir}/DataProcessors/Диаграмма.xml",
|
||||||
|
"-FormName": "Форма"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"outputPath": "DataProcessors/Диаграмма/Forms/Форма/Ext/Form.xml"
|
||||||
|
},
|
||||||
|
"validatePath": "DataProcessors/Диаграмма/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Диаграмма",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"chart": "Диаграмма",
|
||||||
|
"path": "Диаграмма",
|
||||||
|
"titleLocation": "none"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"name": "Объект",
|
||||||
|
"type": "DataProcessorObject.Диаграмма",
|
||||||
|
"main": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Диаграмма",
|
||||||
|
"type": "d5p1:Chart",
|
||||||
|
"chart": {
|
||||||
|
"seriesCurId": "7",
|
||||||
|
"pointsCurId": "0",
|
||||||
|
"isSeriesDesign": true,
|
||||||
|
"realSeriesCount": "4",
|
||||||
|
"realSeriesData": [
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"color": "auto",
|
||||||
|
"line": {
|
||||||
|
"width": 2,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"marker": "Auto",
|
||||||
|
"text": "Серия 1",
|
||||||
|
"strIsChanged": false,
|
||||||
|
"isExpand": false,
|
||||||
|
"isIndicator": false,
|
||||||
|
"colorPriority": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"color": "auto",
|
||||||
|
"line": {
|
||||||
|
"width": 2,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"marker": "Auto",
|
||||||
|
"text": "Серия 2",
|
||||||
|
"strIsChanged": false,
|
||||||
|
"isExpand": false,
|
||||||
|
"isIndicator": false,
|
||||||
|
"colorPriority": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"color": "auto",
|
||||||
|
"line": {
|
||||||
|
"width": 2,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"marker": "Auto",
|
||||||
|
"text": "Серия 3",
|
||||||
|
"strIsChanged": false,
|
||||||
|
"isExpand": false,
|
||||||
|
"isIndicator": false,
|
||||||
|
"colorPriority": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6",
|
||||||
|
"color": "auto",
|
||||||
|
"line": {
|
||||||
|
"width": 2,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"marker": "Auto",
|
||||||
|
"text": "Серия 4",
|
||||||
|
"strIsChanged": false,
|
||||||
|
"isExpand": false,
|
||||||
|
"isIndicator": false,
|
||||||
|
"colorPriority": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"realExSeriesData": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"color": "auto",
|
||||||
|
"line": {
|
||||||
|
"width": 2,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"marker": "Auto",
|
||||||
|
"text": "Сводная",
|
||||||
|
"strIsChanged": false,
|
||||||
|
"isExpand": false,
|
||||||
|
"isIndicator": false,
|
||||||
|
"colorPriority": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isPointsDesign": true,
|
||||||
|
"realPointCount": "0",
|
||||||
|
"curSeries": "-1",
|
||||||
|
"curPoint": "0",
|
||||||
|
"chartType": "Line",
|
||||||
|
"circleLabelType": "None",
|
||||||
|
"labelsDelimiter": ", ",
|
||||||
|
"labelsLocation": "Edge",
|
||||||
|
"lbFormat": "",
|
||||||
|
"lbpFormat": "",
|
||||||
|
"labelsColor": "style:FormTextColor",
|
||||||
|
"labelsFont": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"transparentLabelsBkg": true,
|
||||||
|
"labelsBkgColor": "auto",
|
||||||
|
"labelsBorder": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"labelsBorderColor": "auto",
|
||||||
|
"circleExpandMode": "None",
|
||||||
|
"chart3Dcrd": "SouthWest",
|
||||||
|
"title": "",
|
||||||
|
"isShowTitle": false,
|
||||||
|
"isShowLegend": true,
|
||||||
|
"ttlBorder": {
|
||||||
|
"width": 0,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"ttlBorderColor": "style:BorderColor",
|
||||||
|
"lgBorder": {
|
||||||
|
"width": 0,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"lgBorderColor": "style:BorderColor",
|
||||||
|
"chBorder": {
|
||||||
|
"width": 0,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"chBorderColor": "style:BorderColor",
|
||||||
|
"transparent": false,
|
||||||
|
"bkgColor": "style:FieldBackColor",
|
||||||
|
"isTrnspTtl": false,
|
||||||
|
"ttlColor": "style:FieldBackColor",
|
||||||
|
"isTrnspLeg": false,
|
||||||
|
"legColor": "style:FieldBackColor",
|
||||||
|
"isTrnspCh": false,
|
||||||
|
"chColor": "style:FieldBackColor",
|
||||||
|
"ttlTxtColor": "style:FormTextColor",
|
||||||
|
"legTxtColor": "style:FormTextColor",
|
||||||
|
"chTxtColor": "style:FormTextColor",
|
||||||
|
"ttlFont": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"legFont": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"chFont": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"isShowScale": true,
|
||||||
|
"isShowScaleVL": true,
|
||||||
|
"isShowSeriesScale": true,
|
||||||
|
"isShowPointsScale": true,
|
||||||
|
"isShowValuesScale": true,
|
||||||
|
"vsFormat": "ЧС=6; ЧГ=3,0",
|
||||||
|
"xLabelsOrientation": "Auto",
|
||||||
|
"scaleLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Dotted"
|
||||||
|
},
|
||||||
|
"scaleColor": "auto",
|
||||||
|
"isAutoSeriesName": true,
|
||||||
|
"isAutoPointName": true,
|
||||||
|
"maxMode": "NotDefined",
|
||||||
|
"maxSeries": "4",
|
||||||
|
"maxSeriesPrc": "30",
|
||||||
|
"spaceMode": "Half",
|
||||||
|
"baseVal": "0",
|
||||||
|
"isOutline": false,
|
||||||
|
"realPiePoint": "0",
|
||||||
|
"realStockSeries": "0",
|
||||||
|
"isLight": true,
|
||||||
|
"isGradient": false,
|
||||||
|
"isTransposition": false,
|
||||||
|
"hideBaseVal": false,
|
||||||
|
"dataTable": false,
|
||||||
|
"dtVerLines": true,
|
||||||
|
"dtHorLines": true,
|
||||||
|
"dtHAlign": "Right",
|
||||||
|
"dtFormat": "",
|
||||||
|
"dtKeys": true,
|
||||||
|
"paletteKind": "Auto",
|
||||||
|
"animation": "Auto",
|
||||||
|
"rebuildTime": "2099248",
|
||||||
|
"isTransposed": false,
|
||||||
|
"autoTransposition": false,
|
||||||
|
"legendScrollEnable": false,
|
||||||
|
"surfaceColor": "#A90000",
|
||||||
|
"radarScaleType": "Circle",
|
||||||
|
"gaugeValuesPresentation": "Needle",
|
||||||
|
"gaugeQualityBands": {
|
||||||
|
"useTextStr": false,
|
||||||
|
"useTooltipStr": false
|
||||||
|
},
|
||||||
|
"beginGaugeAngle": "0",
|
||||||
|
"endGaugeAngle": "180",
|
||||||
|
"gaugeThickness": "5",
|
||||||
|
"gaugeLabelsLocation": "InsideScale",
|
||||||
|
"gaugeLabelsArcDirection": false,
|
||||||
|
"gaugeBushThickness": "4",
|
||||||
|
"gaugeBushColor": "#A9A9A9",
|
||||||
|
"autoMaxValue": true,
|
||||||
|
"userMaxValue": "0",
|
||||||
|
"autoMinValue": true,
|
||||||
|
"userMinValue": "0",
|
||||||
|
"elementsIsInit": false,
|
||||||
|
"titleIsInit": true,
|
||||||
|
"legendIsInit": true,
|
||||||
|
"chartIsInit": true,
|
||||||
|
"elementsChart": {
|
||||||
|
"left": "0",
|
||||||
|
"right": "0.17",
|
||||||
|
"top": "0",
|
||||||
|
"bottom": "0"
|
||||||
|
},
|
||||||
|
"elementsLegend": {
|
||||||
|
"left": "0.14968152866242038",
|
||||||
|
"right": "0.06210191082802548",
|
||||||
|
"top": "0.9615384615384616",
|
||||||
|
"bottom": "0"
|
||||||
|
},
|
||||||
|
"elementsTitle": {
|
||||||
|
"left": "0.83",
|
||||||
|
"right": "0",
|
||||||
|
"top": "0",
|
||||||
|
"bottom": "0.92"
|
||||||
|
},
|
||||||
|
"borderColor": "style:BorderColor",
|
||||||
|
"border": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"dataSourceDescription": "",
|
||||||
|
"isDataSourceMode": false,
|
||||||
|
"isRandomizedNewValues": true,
|
||||||
|
"splineMode": "SmoothCurve",
|
||||||
|
"splineStrain": "95",
|
||||||
|
"translucencePercent": "0",
|
||||||
|
"funnelNeckHeightPercent": "10",
|
||||||
|
"funnelNeckWidthPercent": "10",
|
||||||
|
"funnelGapSumPercent": "3",
|
||||||
|
"multiStageLinkLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Solid"
|
||||||
|
},
|
||||||
|
"multiStageLinkColor": "#000000",
|
||||||
|
"valuesAxis": "",
|
||||||
|
"pointsAxis": "",
|
||||||
|
"pointsScale": {
|
||||||
|
"titleArea": {
|
||||||
|
"font": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"textColor": "auto",
|
||||||
|
"backColor": "auto",
|
||||||
|
"border": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"borderColor": "auto"
|
||||||
|
},
|
||||||
|
"gridLinesShowMode": "Show",
|
||||||
|
"gridLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Dotted"
|
||||||
|
},
|
||||||
|
"labelColor": "#B4B4B4"
|
||||||
|
},
|
||||||
|
"valuesScale": {
|
||||||
|
"showTitle": "DontShow",
|
||||||
|
"titleArea": {
|
||||||
|
"font": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"textColor": "auto",
|
||||||
|
"backColor": "auto",
|
||||||
|
"border": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"borderColor": "auto"
|
||||||
|
},
|
||||||
|
"labelFormat": "ЧС=6; ЧГ=3,0"
|
||||||
|
},
|
||||||
|
"seriesScale": {
|
||||||
|
"titleArea": {
|
||||||
|
"font": {
|
||||||
|
"kind": "AutoFont"
|
||||||
|
},
|
||||||
|
"textColor": "auto",
|
||||||
|
"backColor": "auto",
|
||||||
|
"border": {
|
||||||
|
"width": 1,
|
||||||
|
"style": "WithoutBorder"
|
||||||
|
},
|
||||||
|
"borderColor": "auto"
|
||||||
|
},
|
||||||
|
"gridLine": {
|
||||||
|
"width": 1,
|
||||||
|
"gap": false,
|
||||||
|
"style": "Dotted"
|
||||||
|
},
|
||||||
|
"showInChart": "DontShow"
|
||||||
|
},
|
||||||
|
"legendPlacement": "Bottom",
|
||||||
|
"titleAreaPlacement": "None",
|
||||||
|
"valuesToolTipShowMode": "ShowOnHover",
|
||||||
|
"pointsDropLinesShowMode": "DontShow",
|
||||||
|
"valuesDropLinesShowMode": "DontShow"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"elements": [
|
"elements": [
|
||||||
{ "table": "Список", "path": "Список", "columns": [
|
{ "table": "Список", "path": "Список", "columns": [
|
||||||
{ "input": "Наименование", "path": "Список.Наименование" },
|
{ "input": "Наименование", "path": "Список.Наименование" },
|
||||||
{ "columnGroup": "horizontal", "name": "ГруппаСрок", "title": "Срок", "children": [
|
{ "columnGroup": "horizontal", "name": "ГруппаСрок", "title": "Срок", "headerPicture": "StdPicture.ExecuteTask", "children": [
|
||||||
{ "input": "ДатаНачала", "path": "Список.ДатаНачала" },
|
{ "input": "ДатаНачала", "path": "Список.ДатаНачала" },
|
||||||
{ "input": "ДатаОкончания", "path": "Список.ДатаОкончания" }
|
{ "input": "ДатаОкончания", "path": "Список.ДатаОкончания" }
|
||||||
]},
|
]},
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "Форма с командами и кнопками",
|
"name": "Форма с командами и кнопками",
|
||||||
"preRun": [
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "Catalog", "name": "Справочник1" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"script": "meta-compile/scripts/meta-compile",
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
"input": { "type": "DataProcessor", "name": "Команды" },
|
"input": { "type": "DataProcessor", "name": "Команды" },
|
||||||
@@ -15,10 +20,12 @@
|
|||||||
"validatePath": "DataProcessors/Команды/Forms/Форма/Ext/Form.xml",
|
"validatePath": "DataProcessors/Команды/Forms/Форма/Ext/Form.xml",
|
||||||
"input": {
|
"input": {
|
||||||
"title": "Форма с командами",
|
"title": "Форма с командами",
|
||||||
|
"mobileCommandBarContent": ["Панель", "Выполнить"],
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "cmdBar": "Панель", "children": [
|
{ "cmdBar": "Панель", "horizontalLocation": "right", "children": [
|
||||||
{ "button": "Выполнить", "command": "Выполнить", "defaultButton": true },
|
{ "button": "Выполнить", "command": "Выполнить", "defaultButton": true },
|
||||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
{ "button": "Закрыть", "stdCommand": "Close", "representationInContextMenu": "None" },
|
||||||
|
{ "button": "СоздатьПоТипу", "command": "Выполнить", "параметр": { "type": "CatalogRef.Справочник1" } }
|
||||||
]},
|
]},
|
||||||
{ "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true }
|
{ "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true }
|
||||||
],
|
],
|
||||||
@@ -27,7 +34,15 @@
|
|||||||
{ "name": "Результат", "type": "string" }
|
{ "name": "Результат", "type": "string" }
|
||||||
],
|
],
|
||||||
"commands": [
|
"commands": [
|
||||||
{ "name": "Выполнить", "action": "ВыполнитьОбработка", "shortcut": "Ctrl+Enter" }
|
{ "name": "Выполнить", "action": "ВыполнитьОбработка", "shortcut": "Ctrl+Enter", "use": false, "modifiesSavedData": true, "picture": { "src": "StdPicture.ExecuteTask", "transparentPixel": { "x": 1, "y": 1 } } },
|
||||||
]
|
{ "name": "БезЗаголовка", "action": "БезЗаголовкаОбработка", "title": "", "representation": "Picture", "picture": { "src": "StdPicture.Refresh" } }
|
||||||
|
],
|
||||||
|
"commandInterface": {
|
||||||
|
"commandBar": {
|
||||||
|
"important": [
|
||||||
|
{ "command": "Form.Command.Выполнить", "defaultVisible": false, "index": 0, "visible": false }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "Дубликат имени команды → [ERROR] exit 1",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "ТестДубльКом" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/ТестДубльКом.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/ТестДубльКом/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"expectError": "Duplicate command name",
|
||||||
|
"input": {
|
||||||
|
"title": "Дубль команды",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.ТестДубльКом", "main": true }
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
{ "name": "Выполнить", "action": "Выполнить" },
|
||||||
|
{ "name": "Выполнить", "action": "ВыполнитьЕщё" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "Дубликат имени элемента → [ERROR] exit 1",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "ТестДубльЭл" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/ТестДубльЭл.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/ТестДубльЭл/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"expectError": "Duplicate element name",
|
||||||
|
"input": {
|
||||||
|
"title": "Дубль элемента",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.ТестДубльЭл", "main": true }
|
||||||
|
],
|
||||||
|
"elements": [
|
||||||
|
{ "input": "Поле", "name": "Дубль", "path": "Объект" },
|
||||||
|
{ "check": "Флаг", "name": "Дубль" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,14 +15,41 @@
|
|||||||
"validatePath": "Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml",
|
"validatePath": "Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml",
|
||||||
"input": {
|
"input": {
|
||||||
"title": "Товары",
|
"title": "Товары",
|
||||||
|
"properties": { "saveWindowSettings": false, "collapseItemsByImportanceVariant": "DontUse", "groupList": "2:02023637-7868-4a5f-8576-835a76e0c9ba" },
|
||||||
"attributes": [
|
"attributes": [
|
||||||
{ "name": "Список", "type": "DynamicList", "settings": { "mainTable": "Catalog.Товары", "dynamicDataRead": true } }
|
{ "name": "Список", "type": "DynamicList", "useAlways": ["~Артикул", "Список.Code", "Description"], "settings": {
|
||||||
|
"mainTable": "Catalog.Товары", "dynamicDataRead": true, "autoSaveUserSettings": false,
|
||||||
|
"parameters": [ { "name": "ВыборТовара", "type": "CatalogRef.Товары", "valueListAllowed": true, "value": null } ],
|
||||||
|
"fields": [
|
||||||
|
{ "field": "Code", "title": "Код", "presentationExpression": "\"№\" + Code",
|
||||||
|
"useRestriction": { "condition": true, "group": true },
|
||||||
|
"attributeUseRestriction": { "field": true },
|
||||||
|
"appearance": { "Формат": "ДЛ=9", "ЦветТекста": "web:Gray" } }
|
||||||
|
],
|
||||||
|
"grouping": "Description > Code",
|
||||||
|
"calculatedFields": [
|
||||||
|
"Метка [Метка строки]: string = Code + \" \" + Description #noFilter #noGroup",
|
||||||
|
{ "dataPath": "Сорт", "expression": "Code", "title": "Сорт", "valueType": "string(10)",
|
||||||
|
"presentationExpression": "Code", "orderExpression": [ { "expression": "Code" } ] }
|
||||||
|
],
|
||||||
|
"order": [ "Description", "Code desc" ],
|
||||||
|
"filter": [ "Артикул = _ @off @user", "Артикул like %тест%", "Description подобно %abc%",
|
||||||
|
{ "field": "Code", "op": "=", "userSettingID": "auto", "userSettingPresentation": "Код товара", "presentation": { "ru": "Код равно" } },
|
||||||
|
{ "field": "Description", "op": "=", "userSettingID": "auto", "userSettingPresentation": { "ru": "Наименование", "en": "Name" }, "presentation": "Имя равно" } ],
|
||||||
|
"dataParameters": [ "ВыборТовара @off" ],
|
||||||
|
"conditionalAppearance": [ { "filter": ["Артикул = _"], "appearance": { "ЦветТекста": "web:Red" }, "presentation": { "ru": "Выделение пустых" } } ]
|
||||||
|
} }
|
||||||
],
|
],
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "table": "Список", "path": "Список", "columns": [
|
{ "table": "Список", "path": "Список", "refreshRequest": "PullFromTop",
|
||||||
{ "input": "Код", "path": "Список.Code" },
|
"additions": { "viewStatus": { "horizontalLocation": "left" } },
|
||||||
{ "input": "Наименование", "path": "Список.Description" }
|
"commandBar": [
|
||||||
]}
|
{ "searchString": "ПоискСписка", "source": "Список", "width": 15, "horizontalStretch": true }
|
||||||
|
],
|
||||||
|
"columns": [
|
||||||
|
{ "input": "Код", "path": "Список.Code" },
|
||||||
|
{ "input": "Наименование", "path": "Список.Description" }
|
||||||
|
]}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "DynamicList — schema-параметры (DataCompositionSchemaParameter): shorthand + объект + полная грамматика",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "Catalog", "name": "Товары", "attributes": [{ "name": "Артикул", "type": "String", "length": 25 }] },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/Catalogs/Товары.xml", "-FormName": "ФормаСписка", "-Purpose": "List" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml" },
|
||||||
|
"validatePath": "Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Товары",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Список", "type": "DynamicList", "main": true, "settings": {
|
||||||
|
"mainTable": "Catalog.Товары",
|
||||||
|
"query": "ВЫБРАТЬ\n\tТовары.Ссылка КАК Ссылка,\n\tТовары.Код КАК Код,\n\tТовары.Наименование КАК Наименование,\n\tТовары.Артикул КАК Артикул\nИЗ\n\tСправочник.Товары КАК Товары\nГДЕ\n\tТовары.Артикул = &Артикул\n\tИ Товары.Наименование ПОДОБНО &Маска",
|
||||||
|
"parameters": [
|
||||||
|
"Артикул",
|
||||||
|
"Маска: string = %",
|
||||||
|
"Получатель: DocumentRef | CatalogRef",
|
||||||
|
{ "name": "ВидЦен", "valueListAllowed": true },
|
||||||
|
{ "name": "Период", "type": "dateTime", "useRestriction": false },
|
||||||
|
{
|
||||||
|
"name": "Порог", "type": "decimal(10,2)", "value": 0,
|
||||||
|
"title": "Порог округления",
|
||||||
|
"availableValues": [
|
||||||
|
{ "value": null, "presentation": "Нет" },
|
||||||
|
{ "value": 1, "presentation": "Один" }
|
||||||
|
],
|
||||||
|
"denyIncompleteValues": true,
|
||||||
|
"use": "Always"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} }
|
||||||
|
],
|
||||||
|
"elements": [
|
||||||
|
{ "table": "Список", "path": "Список", "backColor": "web:Honeydew", "borderColor": "style:BorderColor", "columns": [
|
||||||
|
{ "input": "Код", "path": "Список.Код" },
|
||||||
|
{ "input": "Наименование", "path": "Список.Наименование", "titleTextColor": "web:FireBrick", "border": { "width": 1, "style": "Single" } }
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "Оформление элементов — цвета/шрифты/граница на decoration/input/button/group/picture (профили порядка)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "Catalog", "name": "Товары", "attributes": [{ "name": "Цена", "type": "Number", "length": 10, "precision": 2 }] },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/Catalogs/Товары.xml", "-FormName": "ФормаЭлемента", "-Purpose": "Object" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml" },
|
||||||
|
"validatePath": "Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Товары",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "CatalogObject.Товары", "main": true }
|
||||||
|
],
|
||||||
|
"elements": [
|
||||||
|
{ "label": "Внимание!",
|
||||||
|
"textColor": "web:FireBrick",
|
||||||
|
"font": { "faceName": "Arial", "height": 12, "bold": true, "italic": false, "underline": false, "strikeout": false, "kind": "Absolute", "scale": 100 },
|
||||||
|
"border": { "width": 1, "style": "Single" } },
|
||||||
|
{ "input": "Цена", "path": "Объект.Цена",
|
||||||
|
"textColor": "#FF0000",
|
||||||
|
"borderColor": "style:BorderColor" },
|
||||||
|
{ "label": "Из стиля",
|
||||||
|
"textColor": "web:DimGray",
|
||||||
|
"font": "style:NormalTextFont",
|
||||||
|
"border": "style:ControlBorder" },
|
||||||
|
{ "button": "ОК", "title": "ОК",
|
||||||
|
"shape": "Oval", "pictureLocation": "Right",
|
||||||
|
"backColor": "web:Honeydew",
|
||||||
|
"borderColor": "style:BorderColor",
|
||||||
|
"font": "style:NormalTextFont" },
|
||||||
|
{ "group": "ГруппаОформление", "backColor": "web:Honeydew", "children": [
|
||||||
|
{ "input": "Цена2", "path": "Объект.Цена", "textColor": "web:DimGray" }
|
||||||
|
]},
|
||||||
|
{ "picture": "Логотип", "src": "StdPicture.Print",
|
||||||
|
"imageScale": 150, "zoomable": true, "nonselectedPictureText": "Нет изображения",
|
||||||
|
"textColor": "web:FireBrick", "font": "style:NormalTextFont",
|
||||||
|
"border": { "width": 1, "style": "Single" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,9 @@
|
|||||||
"title": "События",
|
"title": "События",
|
||||||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере", "OnOpen": "ПриОткрытии" },
|
"events": { "OnCreateAtServer": "ПриСозданииНаСервере", "OnOpen": "ПриОткрытии" },
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "input": "Организация", "path": "Организация", "on": ["OnChange", "StartChoice"] },
|
{ "input": "Организация", "path": "Организация", "events": { "OnChange": "ОрганизацияПриИзменении", "StartChoice": "ОрганизацияНачалоВыбора" } },
|
||||||
{ "input": "Период", "path": "Период", "handlers": { "OnChange": "ПериодПриИзменении" } },
|
{ "input": "Период", "path": "Период", "events": { "OnChange": "ПериодПриИзменении" } },
|
||||||
{ "label": "Подсказка", "title": "Нажмите для перехода", "hyperlink": true, "on": ["Click"] }
|
{ "label": "Подсказка", "title": "Нажмите для перехода", "hyperlink": true, "tooltipRepresentation": "Button", "events": { "Click": null } }
|
||||||
],
|
],
|
||||||
"attributes": [
|
"attributes": [
|
||||||
{ "name": "Объект", "type": "DataProcessorObject.События", "main": true },
|
{ "name": "Объект", "type": "DataProcessorObject.События", "main": true },
|
||||||
|
|||||||
@@ -15,13 +15,15 @@
|
|||||||
"validatePath": "DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml",
|
"validatePath": "DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml",
|
||||||
"input": {
|
"input": {
|
||||||
"title": "Группы",
|
"title": "Группы",
|
||||||
|
"properties": { "showCloseButton": false, "horizontalAlign": "Left", "childrenAlign": "ItemsLeftTitlesLeft", "childItemsWidth": "Equal", "verticalAlign": "Top", "horizontalSpacing": "Double" },
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "cmdBar": "КоманднаяПанель", "autofill": true },
|
{ "cmdBar": "КоманднаяПанель", "autofill": true },
|
||||||
{ "group": "horizontal", "name": "ГруппаШапка", "showTitle": true, "title": "Шапка", "children": [
|
{ "group": "horizontal", "name": "ГруппаШапка", "behavior": "usual", "showTitle": true, "title": "Шапка", "shortcut": "Ctrl+G", "childrenAlign": "ItemsRightTitlesLeft", "horizontalStretch": true, "groupHorizontalAlign": "Right", "throughAlign": "Use", "verticalAlign": "Top", "childItemsWidth": "Equal", "horizontalSpacing": "None", "children": [
|
||||||
{ "input": "Поле1", "path": "Поле1", "title": "Поле 1" },
|
{ "input": "Поле1", "path": "Поле1", "title": "Поле 1", "width": 20, "skipOnInput": true, "mask": "999-999" },
|
||||||
{ "input": "Поле2", "path": "Поле2", "title": "Поле 2" }
|
{ "input": "Поле2", "path": "Поле2", "title": "Поле 2" },
|
||||||
|
{ "labelField": "Метка", "path": "Поле1", "groupVerticalAlign": "Center" }
|
||||||
]},
|
]},
|
||||||
{ "group": "vertical", "name": "ГруппаПодвал", "children": [
|
{ "group": "vertical", "name": "ГруппаПодвал", "behavior": "collapsible", "collapsed": true, "title": { "ru": "Подвал", "en": "Footer" }, "collapsedTitle": "Развернуть подвал", "titleDataPath": "Изменено", "format": { "ru": "БЛ=; БИ=*", "en": "BF=; BT=*" }, "showLeftMargin": false, "enableContentChange": false, "verticalSpacing": "None", "displayImportance": "Low", "children": [
|
||||||
{ "input": "Поле3", "path": "Поле3", "title": "Поле 3" }
|
{ "input": "Поле3", "path": "Поле3", "title": "Поле 3" }
|
||||||
]}
|
]}
|
||||||
],
|
],
|
||||||
@@ -29,7 +31,8 @@
|
|||||||
{ "name": "Объект", "type": "DataProcessorObject.СГруппами", "main": true },
|
{ "name": "Объект", "type": "DataProcessorObject.СГруппами", "main": true },
|
||||||
{ "name": "Поле1", "type": "string" },
|
{ "name": "Поле1", "type": "string" },
|
||||||
{ "name": "Поле2", "type": "decimal(15,2)" },
|
{ "name": "Поле2", "type": "decimal(15,2)" },
|
||||||
{ "name": "Поле3", "type": "date" }
|
{ "name": "Поле3", "type": "date" },
|
||||||
|
{ "name": "Изменено", "type": "boolean" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,43 @@
|
|||||||
"input": {
|
"input": {
|
||||||
"title": "Поля ввода",
|
"title": "Поля ввода",
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "input": "ОбычноеПоле", "path": "ОбычноеПоле", "title": "Обычное поле" },
|
{ "input": "ОбычноеПоле", "path": "ОбычноеПоле", "title": "Обычное поле", "tooltip": "Введите значение поля", "tooltipRepresentation": "ShowBottom", "editMode": "EnterOnInput", "multiLine": false, "shortcut": "Ctrl+Shift+O", "horizontalStretch": false, "verticalStretch": false, "format": "ЧДЦ=2", "editFormat": "ЧДЦ=2; ЧН=", "extendedTooltip": { "width": 30, "autoMaxWidth": false, "hyperlink": true, "text": "Расширенная подсказка поля", "tooltip": { "ru": "Подсказка самой расширенной подсказки", "en": "Tooltip of the extended tooltip" }, "events": { "URLProcessing": "ОбычноеПолеРасширеннаяПодсказкаОбработкаНавигационнойСсылки" } } },
|
||||||
{ "input": "МногострочноеПоле", "path": "МногострочноеПоле", "multiLine": true, "height": 5, "title": "Комментарий" },
|
{ "labelField": "Ссылка", "path": "ОбычноеПоле", "titleLocation": "left", "hyperlink": true, "format": { "ru": "ДЛФ=D", "en": "DLF=D" }, "warningOnEdit": "Поле только для чтения" },
|
||||||
|
{ "input": "МногострочноеПоле", "path": "МногострочноеПоле", "multiLine": true, "height": 5, "title": "Комментарий", "wrap": false, "showInHeader": false, "showInFooter": false, "autoCellHeight": true, "footerHorizontalAlign": "Right", "openButton": false, "chooseType": false },
|
||||||
{ "input": "ПолеПароля", "path": "ПолеПароля", "passwordMode": true, "title": "Пароль" },
|
{ "input": "ПолеПароля", "path": "ПолеПароля", "passwordMode": true, "title": "Пароль" },
|
||||||
{ "input": "ПолеСКнопками", "path": "ПолеСКнопками", "choiceButton": true, "clearButton": true, "title": "Выбор" },
|
{ "input": "ЧисловоеПоле", "path": "ЧисловоеПоле", "title": "Число", "minValue": 1, "maxValue": 100, "displayImportance": "VeryHigh" },
|
||||||
{ "input": "ПолеПодсказка", "path": "ПолеПодсказка", "inputHint": "Введите значение...", "title": "Подсказка" },
|
{ "input": "ПолеСКнопками", "path": "ПолеСКнопками", "choiceButton": true, "clearButton": true, "dropListButton": false, "spinButton": true, "choiceListButton": true, "quickChoice": false, "autoChoiceIncomplete": true, "incompleteChoiceMode": "OnActivate", "choiceHistoryOnInput": "DontUse", "choiceForm": "DataProcessor.ПоляВвода.Form.Форма", "title": "Выбор" },
|
||||||
{ "check": "Флаг", "path": "Флаг", "title": "Включено" }
|
{ "input": "ПолеСписокВыбора", "path": "ПолеСписокВыбора", "title": "Список выбора", "choiceList": [
|
||||||
|
{ "value": "", "presentation": "Все" },
|
||||||
|
{ "value": "Первый" },
|
||||||
|
{ "value": "Второй", "presentation": "Второй вариант" }
|
||||||
|
]},
|
||||||
|
{ "input": "ПолеПодсказка", "path": "ПолеПодсказка", "inputHint": "Введите значение...", "warningOnEdit": "Изменение запрещено", "footerText": "итого", "extendedEdit": true, "editTextUpdate": "OnValueChange", "markIncomplete": false, "title": "Подсказка" },
|
||||||
|
{ "input": "ПолеСвязи", "path": "ПолеСвязи", "title": "Поле со связями",
|
||||||
|
"choiceParameters": [
|
||||||
|
{ "name": "Отбор.Активный", "value": true },
|
||||||
|
{ "name": "Отбор.Вид", "value": "Основной" },
|
||||||
|
{ "name": "Отбор.Дата", "value": "2020-01-01T00:00:00" },
|
||||||
|
{ "name": "Отбор.Список", "value": ["Один", "Два"] },
|
||||||
|
{ "name": "Отбор.Одно", "value": ["Единственный"] },
|
||||||
|
{ "name": "Отбор.БезЗначения" }
|
||||||
|
],
|
||||||
|
"choiceParameterLinks": [
|
||||||
|
{ "name": "Отбор.Организация", "dataPath": "ОбычноеПоле" },
|
||||||
|
{ "name": "Отбор.Тип", "dataPath": "ПолеСписокВыбора", "valueChange": "DontChange" }
|
||||||
|
],
|
||||||
|
"typeLink": { "dataPath": "ПолеПодсказка", "linkItem": 0 }
|
||||||
|
},
|
||||||
|
{ "input": "ПолеСвязиКратко", "path": "ПолеСвязиКратко", "title": "Связи (короткая форма)",
|
||||||
|
"choiceParameters": [ "Отбор.Активный=true", "Отбор.Вид=Основной", "Отбор.Дата=2020-01-01T00:00:00", "Отбор.Список=Один, Два" ],
|
||||||
|
"choiceParameterLinks": [ "Отбор.Организация=ОбычноеПоле", "Отбор.Тип=ПолеСписокВыбора:DontChange" ],
|
||||||
|
"typeLink": "ПолеПодсказка"
|
||||||
|
},
|
||||||
|
{ "check": "Флаг", "path": "Флаг", "title": "Включено", "warningOnEdit": { "ru": "Изменение флага требует подтверждения", "en": "Confirm flag change" }, "extendedTooltip": { "width": 45 } },
|
||||||
|
{ "check": "ФлагПлатформенный", "path": "ФлагПлатформенный", "title": "Слева", "titleLocation": "" },
|
||||||
|
{ "check": "ФлагЯвный", "path": "ФлагЯвный", "title": "Сверху", "titleLocation": "top" },
|
||||||
|
{ "check": "ФлагТумблер", "path": "ФлагТумблер", "title": "Тумблер", "checkBoxType": "switcher", "format": "БЛ=Нет; БИ=Да" },
|
||||||
|
{ "input": "ПолеСоставное", "path": "ПолеСоставное", "title": "Ограничение типов", "typeDomainEnabled": false, "availableTypes": "string | boolean" }
|
||||||
],
|
],
|
||||||
"attributes": [
|
"attributes": [
|
||||||
{ "name": "Объект", "type": "DataProcessorObject.ПоляВвода", "main": true },
|
{ "name": "Объект", "type": "DataProcessorObject.ПоляВвода", "main": true },
|
||||||
@@ -29,8 +60,28 @@
|
|||||||
{ "name": "МногострочноеПоле", "type": "string" },
|
{ "name": "МногострочноеПоле", "type": "string" },
|
||||||
{ "name": "ПолеПароля", "type": "string(50)" },
|
{ "name": "ПолеПароля", "type": "string(50)" },
|
||||||
{ "name": "ПолеСКнопками", "type": "string" },
|
{ "name": "ПолеСКнопками", "type": "string" },
|
||||||
|
{ "name": "ПолеСписокВыбора", "type": "string" },
|
||||||
{ "name": "ПолеПодсказка", "type": "string" },
|
{ "name": "ПолеПодсказка", "type": "string" },
|
||||||
{ "name": "Флаг", "type": "boolean" }
|
{ "name": "ПолеСвязи", "type": "string" },
|
||||||
|
{ "name": "ПолеСвязиКратко", "type": "string" },
|
||||||
|
{ "name": "Флаг", "type": "boolean" },
|
||||||
|
{ "name": "ФлагПлатформенный", "type": "boolean" },
|
||||||
|
{ "name": "ФлагЯвный", "type": "boolean" },
|
||||||
|
{ "name": "ФлагТумблер", "type": "boolean" },
|
||||||
|
{ "name": "ЧисловоеПоле", "type": "number(10,2)" },
|
||||||
|
{ "name": "ДатаПоля", "type": "dateTime" },
|
||||||
|
{ "name": "ПолеСоставное", "type": "string | boolean" }
|
||||||
|
],
|
||||||
|
"conditionalAppearance": [
|
||||||
|
{ "selection": ["ОбычноеПоле"], "filter": ["ЧисловоеПоле > 100"], "appearance": { "ЦветФона": "style:FormBackColor", "Текст": "Плоский текст" },
|
||||||
|
"presentation": { "ru": "Подсветка", "en": "Highlight" } },
|
||||||
|
{ "filter": ["ЧисловоеПоле = 0"], "appearance": { "Текст": { "ru": "Локализованный", "en": "Localized" } } },
|
||||||
|
{ "filter": ["ЧисловоеПоле < 0"], "appearance": { "Текст": "" } },
|
||||||
|
{ "filter": ["ЧисловоеПоле = 1"], "appearance": { "Текст": { "field": "ОбычноеПоле" } } },
|
||||||
|
{ "filter": [{ "field": "ДатаПоля", "op": "=", "value": "3999-12-31T23:59:59" }], "appearance": { "ЦветТекста": "web:Gray" } },
|
||||||
|
{ "filter": ["ДатаПоля > 2020-01-01T00:00:00"], "appearance": { "ЦветТекста": "web:Olive" } },
|
||||||
|
{ "filter": [{ "field": "ДатаПоля", "op": ">=", "value": "BeginningOfThisDay", "valueType": "v8:StandardBeginningDate" }], "appearance": { "ЦветТекста": "web:Silver" } },
|
||||||
|
{ "filter": [{ "field": "ОбычноеПоле", "op": "=", "value": "_", "valueType": "dcscor:Field" }], "appearance": { "ЦветТекста": "web:Maroon" } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "Имя реквизита == имя элемента — легально (раздельные неймспейсы)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "ТестНеймспейс" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/ТестНеймспейс.xml", "-FormName": "Форма" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": { "outputPath": "DataProcessors/ТестНеймспейс/Forms/Форма/Ext/Form.xml" },
|
||||||
|
"validatePath": "DataProcessors/ТестНеймспейс/Forms/Форма/Ext/Form.xml",
|
||||||
|
"input": {
|
||||||
|
"title": "Неймспейсы",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "Объект", "type": "DataProcessorObject.ТестНеймспейс", "main": true },
|
||||||
|
{ "name": "Сумма", "type": "number(15,2)" }
|
||||||
|
],
|
||||||
|
"elements": [
|
||||||
|
{ "input": "Сумма", "name": "Сумма", "path": "Сумма" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,15 +17,15 @@
|
|||||||
"title": "Мастер настройки",
|
"title": "Мастер настройки",
|
||||||
"properties": { "autoTitle": false },
|
"properties": { "autoTitle": false },
|
||||||
"elements": [
|
"elements": [
|
||||||
{ "pages": "СтраницыМастера", "pagesRepresentation": "None", "children": [
|
{ "pages": "СтраницыМастера", "pagesRepresentation": "None", "tooltip": "Страницы мастера настройки", "children": [
|
||||||
{ "page": "Шаг1", "title": "Параметры", "children": [
|
{ "page": "Шаг1", "title": "", "showTitle": false, "picture": "StdPicture.ExecuteTask", "children": [
|
||||||
{ "input": "Параметр1", "path": "Параметр1" }
|
{ "input": "Параметр1", "path": "Параметр1" }
|
||||||
]},
|
]},
|
||||||
{ "page": "Шаг2", "title": "Результат", "children": [
|
{ "page": "Шаг2", "title": "Результат", "titleDataPath": "Итог", "tooltip": "Шаг \"Результат\"", "group": "horizontalIfPossible", "picture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true, "transparentPixel": { "x": 2, "y": 4 } }, "backColor": "style:FormBackColor", "titleTextColor": "style:FormTextColor", "titleFont": "style:TextFont", "children": [
|
||||||
{ "input": "Итог", "path": "Итог", "readOnly": true }
|
{ "input": "Итог", "path": "Итог", "readOnly": true }
|
||||||
]}
|
]}
|
||||||
]},
|
]},
|
||||||
{ "group": "horizontal", "name": "Навигация", "children": [
|
{ "group": "horizontalIfPossible", "name": "Навигация", "children": [
|
||||||
{ "button": "Назад", "command": "Назад", "title": "< Назад" },
|
{ "button": "Назад", "command": "Назад", "title": "< Назад" },
|
||||||
{ "button": "Далее", "command": "Далее", "title": "Далее >" }
|
{ "button": "Далее", "command": "Далее", "title": "Далее >" }
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -20,8 +20,9 @@
|
|||||||
"on": ["Selection"], "handlers": { "Selection": "ТаблицаДанныхВыбор" },
|
"on": ["Selection"], "handlers": { "Selection": "ТаблицаДанныхВыбор" },
|
||||||
"columns": [
|
"columns": [
|
||||||
{ "input": "ТаблицаДанныхНоменклатура", "path": "ТаблицаДанных.Номенклатура" },
|
{ "input": "ТаблицаДанныхНоменклатура", "path": "ТаблицаДанных.Номенклатура" },
|
||||||
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "valuesPicture": "StdPicture.Favorites", "loadTransparent": true },
|
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "titleLocation": "none", "editMode": "EnterOnInput", "hyperlink": true, "shortcut": "Ctrl+S", "headerPicture": "StdPicture.ExecuteTask", "valuesPicture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true, "transparentPixel": { "x": 7, "y": 3 } } },
|
||||||
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг" }
|
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг", "headerPicture": { "src": "StdPicture.ClearFilter", "loadTransparent": true } },
|
||||||
|
{ "labelField": "ТаблицаДанныхИтог", "path": "ТаблицаДанных.Номенклатура", "editMode": "EnterOnInput", "footerDataPath": "ТаблицаДанных.Номенклатура", "footerText": "Итого" }
|
||||||
]}
|
]}
|
||||||
],
|
],
|
||||||
"attributes": [
|
"attributes": [
|
||||||
|
|||||||
@@ -35,9 +35,12 @@
|
|||||||
"title": "Способ курса",
|
"title": "Способ курса",
|
||||||
"radioButtonType": "Auto",
|
"radioButtonType": "Auto",
|
||||||
"columnsCount": 1,
|
"columnsCount": 1,
|
||||||
|
"itemTitleHeight": 1,
|
||||||
|
"equalItemsWidth": false,
|
||||||
"choiceList": [
|
"choiceList": [
|
||||||
{ "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": { "ru": "Автоматически", "en": "Automatic" } },
|
{ "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": { "ru": "Автоматически", "en": "Automatic" } },
|
||||||
{ "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" }
|
{ "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" },
|
||||||
|
{ "value": "Enum.СпособыКурса.EmptyRef", "presentation": "(не задан)" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -26,10 +26,22 @@
|
|||||||
"radio": "ОтборСтрок",
|
"radio": "ОтборСтрок",
|
||||||
"path": "ОтборСтрок",
|
"path": "ОтборСтрок",
|
||||||
"radioButtonType": "Tumbler",
|
"radioButtonType": "Tumbler",
|
||||||
|
"editMode": "EnterOnInput",
|
||||||
|
"warningOnEdit": "Смена отбора перезагрузит список",
|
||||||
"choiceList": [
|
"choiceList": [
|
||||||
{ "value": "Рекомендуемые" },
|
{ "value": "Рекомендуемые" },
|
||||||
{ "value": "Все" }
|
{ "value": "Все" }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"radio": "ВидСчета",
|
||||||
|
"equalColumnsWidth": true,
|
||||||
|
"columnsCount": 1,
|
||||||
|
"choiceList": [
|
||||||
|
{ "value": "Active", "valueType": "ent:AccountType", "presentation": "Активный" },
|
||||||
|
{ "value": "Passive", "valueType": "ent:AccountType", "presentation": "Пассивный" },
|
||||||
|
{ "value": "ActivePassive", "valueType": "ent:AccountType", "presentation": "Активный/Пассивный" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,252 @@
|
|||||||
|
<?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></Vendor>
|
||||||
|
<Version></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>
|
||||||
|
<DataProcessor>ДопКолонки</DataProcessor>
|
||||||
|
</ChildObjects>
|
||||||
|
</Configuration>
|
||||||
|
</MetaDataObject>
|
||||||
+222
@@ -0,0 +1,222 @@
|
|||||||
|
<?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">
|
||||||
|
<DataProcessor uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="DataProcessorObject.ДопКолонки" category="Object">
|
||||||
|
<xr:TypeId>UUID-002</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-003</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="DataProcessorManager.ДопКолонки" category="Manager">
|
||||||
|
<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 />
|
||||||
|
<UseStandardCommands>false</UseStandardCommands>
|
||||||
|
<DefaultForm>DataProcessor.ДопКолонки.Form.Форма</DefaultForm>
|
||||||
|
<AuxiliaryForm />
|
||||||
|
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||||
|
<ExtendedPresentation />
|
||||||
|
<Explanation />
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Form>Форма</Form>
|
||||||
|
<TabularSection uuid="UUID-006">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="DataProcessorTabularSection.ДопКолонки.Прочее" category="TabularSection">
|
||||||
|
<xr:TypeId>UUID-007</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-008</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="DataProcessorTabularSectionRow.ДопКолонки.Прочее" category="TabularSectionRow">
|
||||||
|
<xr:TypeId>UUID-009</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-010</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>Прочее</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Прочее</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment />
|
||||||
|
<ToolTip />
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<StandardAttributes>
|
||||||
|
<xr:StandardAttribute name="LineNumber">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
</StandardAttributes>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Attribute uuid="UUID-011">
|
||||||
|
<Properties>
|
||||||
|
<Name>Значение</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Значение</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment />
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>50</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format />
|
||||||
|
<EditFormat />
|
||||||
|
<ToolTip />
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask />
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true" />
|
||||||
|
<MaxValue xsi:nil="true" />
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:string" />
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<ChoiceParameterLinks />
|
||||||
|
<ChoiceParameters />
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceForm />
|
||||||
|
<LinkByType />
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
</Properties>
|
||||||
|
</Attribute>
|
||||||
|
</ChildObjects>
|
||||||
|
</TabularSection>
|
||||||
|
<TabularSection uuid="UUID-012">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="DataProcessorTabularSection.ДопКолонки.ЕщёТаблица" category="TabularSection">
|
||||||
|
<xr:TypeId>UUID-013</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-014</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="DataProcessorTabularSectionRow.ДопКолонки.ЕщёТаблица" category="TabularSectionRow">
|
||||||
|
<xr:TypeId>UUID-015</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-016</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>ЕщёТаблица</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Ещё таблица</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment />
|
||||||
|
<ToolTip />
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<StandardAttributes>
|
||||||
|
<xr:StandardAttribute name="LineNumber">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
</StandardAttributes>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Attribute uuid="UUID-017">
|
||||||
|
<Properties>
|
||||||
|
<Name>Поле</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Поле</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment />
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>10</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format />
|
||||||
|
<EditFormat />
|
||||||
|
<ToolTip />
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask />
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true" />
|
||||||
|
<MaxValue xsi:nil="true" />
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:string" />
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<ChoiceParameterLinks />
|
||||||
|
<ChoiceParameters />
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceForm />
|
||||||
|
<LinkByType />
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
</Properties>
|
||||||
|
</Attribute>
|
||||||
|
</ChildObjects>
|
||||||
|
</TabularSection>
|
||||||
|
</ChildObjects>
|
||||||
|
</DataProcessor>
|
||||||
|
</MetaDataObject>
|
||||||
+22
@@ -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.17">
|
||||||
|
<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>
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
<?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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Доп. колонки</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<AutoTitle>false</AutoTitle>
|
||||||
|
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1"/>
|
||||||
|
<ChildItems>
|
||||||
|
<LabelDecoration name="Подпись" id="1">
|
||||||
|
<Title formatted="false">
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Форма с доп. колонками табличной части</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<ContextMenu name="ПодписьКонтекстноеМеню" id="2"/>
|
||||||
|
<ExtendedTooltip name="ПодписьРасширеннаяПодсказка" id="3"/>
|
||||||
|
</LabelDecoration>
|
||||||
|
</ChildItems>
|
||||||
|
<Attributes>
|
||||||
|
<Attribute name="Объект" id="4">
|
||||||
|
<Type>
|
||||||
|
<v8:Type>cfg:DataProcessorObject.ДопКолонки</v8:Type>
|
||||||
|
</Type>
|
||||||
|
<MainAttribute>true</MainAttribute>
|
||||||
|
<Columns>
|
||||||
|
<AdditionalColumns table="Объект.Прочее">
|
||||||
|
<Column name="Доступность" id="5">
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:boolean</v8:Type>
|
||||||
|
</Type>
|
||||||
|
</Column>
|
||||||
|
<Column name="Служебная" id="6">
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>0</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
</Column>
|
||||||
|
</AdditionalColumns>
|
||||||
|
<AdditionalColumns table="Объект.ЕщёТаблица"/>
|
||||||
|
</Columns>
|
||||||
|
</Attribute>
|
||||||
|
</Attributes>
|
||||||
|
</Form>
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#Область ОбработчикиСобытийФормы
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ОбработчикиСобытийЭлементовФормы
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ОбработчикиКомандФормы
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ОбработчикиОповещений
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область СлужебныеПроцедурыИФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
+18
@@ -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>
|
||||||
+140
-6
@@ -16,6 +16,9 @@
|
|||||||
</InputField>
|
</InputField>
|
||||||
<InputField name="Число" id="4">
|
<InputField name="Число" id="4">
|
||||||
<DataPath>Число</DataPath>
|
<DataPath>Число</DataPath>
|
||||||
|
<UserVisible>
|
||||||
|
<xr:Common>false</xr:Common>
|
||||||
|
</UserVisible>
|
||||||
<ContextMenu name="ЧислоКонтекстноеМеню" id="5"/>
|
<ContextMenu name="ЧислоКонтекстноеМеню" id="5"/>
|
||||||
<ExtendedTooltip name="ЧислоРасширеннаяПодсказка" id="6"/>
|
<ExtendedTooltip name="ЧислоРасширеннаяПодсказка" id="6"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
@@ -51,6 +54,13 @@
|
|||||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
</v8:StringQualifiers>
|
</v8:StringQualifiers>
|
||||||
</Type>
|
</Type>
|
||||||
|
<View>
|
||||||
|
<xr:Common>false</xr:Common>
|
||||||
|
</View>
|
||||||
|
<Save>
|
||||||
|
<Field>Строка</Field>
|
||||||
|
</Save>
|
||||||
|
<FillCheck>ShowError</FillCheck>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
<Attribute name="Число" id="15">
|
<Attribute name="Число" id="15">
|
||||||
<Title>
|
<Title>
|
||||||
@@ -67,14 +77,12 @@
|
|||||||
<v8:AllowedSign>Nonnegative</v8:AllowedSign>
|
<v8:AllowedSign>Nonnegative</v8:AllowedSign>
|
||||||
</v8:NumberQualifiers>
|
</v8:NumberQualifiers>
|
||||||
</Type>
|
</Type>
|
||||||
|
<Edit>
|
||||||
|
<xr:Common>false</xr:Common>
|
||||||
|
<xr:Value name="UUID-001">true</xr:Value>
|
||||||
|
</Edit>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
<Attribute name="Дата" id="16">
|
<Attribute name="Дата" id="16">
|
||||||
<Title>
|
|
||||||
<v8:item>
|
|
||||||
<v8:lang>ru</v8:lang>
|
|
||||||
<v8:content>Дата</v8:content>
|
|
||||||
</v8:item>
|
|
||||||
</Title>
|
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>xs:dateTime</v8:Type>
|
<v8:Type>xs:dateTime</v8:Type>
|
||||||
<v8:DateQualifiers>
|
<v8:DateQualifiers>
|
||||||
@@ -93,5 +101,131 @@
|
|||||||
<v8:Type>xs:boolean</v8:Type>
|
<v8:Type>xs:boolean</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
|
<Attribute name="Период" id="18">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Период</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||||
|
</Type>
|
||||||
|
<Save>
|
||||||
|
<Field>Период</Field>
|
||||||
|
<Field>Период.EndDate</Field>
|
||||||
|
<Field>Период.StartDate</Field>
|
||||||
|
<Field>Период.Variant</Field>
|
||||||
|
</Save>
|
||||||
|
</Attribute>
|
||||||
|
<Attribute name="СписокЗначений" id="19">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Список значений</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>v8:ValueListType</v8:Type>
|
||||||
|
</Type>
|
||||||
|
<Settings xsi:type="v8:TypeDescription">
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>50</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
<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>
|
||||||
|
</Settings>
|
||||||
|
</Attribute>
|
||||||
|
<Attribute name="СписокЛюбой" id="20">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Список любой</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>v8:ValueListType</v8:Type>
|
||||||
|
</Type>
|
||||||
|
<Settings xsi:type="v8:TypeDescription"/>
|
||||||
|
</Attribute>
|
||||||
|
<Attribute name="Идентификатор" id="21">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Идентификатор</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>v8:UUID</v8:Type>
|
||||||
|
</Type>
|
||||||
|
</Attribute>
|
||||||
|
<Attribute name="НаборКонстант" id="22">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Набор констант</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>cfg:ConstantsSet</v8:Type>
|
||||||
|
</Type>
|
||||||
|
</Attribute>
|
||||||
|
<Attribute name="ОбъектОтчета" id="23">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Объект отчета</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>cfg:ReportObject</v8:Type>
|
||||||
|
</Type>
|
||||||
|
</Attribute>
|
||||||
|
<Attribute name="Таблица" id="24">
|
||||||
|
<Title>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Таблица</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Title>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>v8:ValueTable</v8:Type>
|
||||||
|
</Type>
|
||||||
|
<Columns>
|
||||||
|
<Column name="ИНН" id="25">
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>12</v8:Length>
|
||||||
|
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
</Column>
|
||||||
|
<Column name="Код" id="26">
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>9</v8:Length>
|
||||||
|
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
</Column>
|
||||||
|
<Column name="Имя" id="27">
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>100</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
</Column>
|
||||||
|
</Columns>
|
||||||
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
+61
-9
@@ -22,37 +22,89 @@
|
|||||||
<DataPath>Список</DataPath>
|
<DataPath>Список</DataPath>
|
||||||
<CommandBarLocation>None</CommandBarLocation>
|
<CommandBarLocation>None</CommandBarLocation>
|
||||||
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
|
||||||
|
<AutoRefresh>false</AutoRefresh>
|
||||||
|
<AutoRefreshPeriod>60</AutoRefreshPeriod>
|
||||||
|
<Period>
|
||||||
|
<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>
|
||||||
|
</Period>
|
||||||
|
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||||
|
<RestoreCurrentRow>false</RestoreCurrentRow>
|
||||||
|
<TopLevelParent xsi:nil="true"/>
|
||||||
|
<ShowRoot>true</ShowRoot>
|
||||||
|
<AllowRootChoice>false</AllowRootChoice>
|
||||||
|
<UpdateOnDataChange>Auto</UpdateOnDataChange>
|
||||||
|
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
|
||||||
<ContextMenu name="СписокКонтекстноеМеню" id="4"/>
|
<ContextMenu name="СписокКонтекстноеМеню" id="4"/>
|
||||||
<AutoCommandBar name="СписокКоманднаяПанель" id="5">
|
<AutoCommandBar name="СписокКоманднаяПанель" id="5">
|
||||||
<Autofill>false</Autofill>
|
<Autofill>false</Autofill>
|
||||||
</AutoCommandBar>
|
</AutoCommandBar>
|
||||||
<SearchStringAddition name="СписокСтрокаПоиска" id="6"/>
|
<ExtendedTooltip name="СписокРасширеннаяПодсказка" id="6"/>
|
||||||
<ViewStatusAddition name="СписокСостояниеПросмотра" id="7"/>
|
<SearchStringAddition name="СписокСтрокаПоиска" id="7">
|
||||||
<SearchControlAddition name="СписокУправлениеПоиском" id="8"/>
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchStringRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСтрокаПоискаКонтекстноеМеню" id="8"/>
|
||||||
|
<ExtendedTooltip name="СписокСтрокаПоискаРасширеннаяПодсказка" id="9"/>
|
||||||
|
</SearchStringAddition>
|
||||||
|
<ViewStatusAddition name="СписокСостояниеПросмотра" id="10">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>ViewStatusRepresentation</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокСостояниеПросмотраКонтекстноеМеню" id="11"/>
|
||||||
|
<ExtendedTooltip name="СписокСостояниеПросмотраРасширеннаяПодсказка" id="12"/>
|
||||||
|
</ViewStatusAddition>
|
||||||
|
<SearchControlAddition name="СписокУправлениеПоиском" id="13">
|
||||||
|
<AdditionSource>
|
||||||
|
<Item>Список</Item>
|
||||||
|
<Type>SearchControl</Type>
|
||||||
|
</AdditionSource>
|
||||||
|
<ContextMenu name="СписокУправлениеПоискомКонтекстноеМеню" id="14"/>
|
||||||
|
<ExtendedTooltip name="СписокУправлениеПоискомРасширеннаяПодсказка" id="15"/>
|
||||||
|
</SearchControlAddition>
|
||||||
<ChildItems>
|
<ChildItems>
|
||||||
<InputField name="Наименование" id="9">
|
<InputField name="Наименование" id="16">
|
||||||
<DataPath>Список.Description</DataPath>
|
<DataPath>Список.Description</DataPath>
|
||||||
<ContextMenu name="НаименованиеКонтекстноеМеню" id="10"/>
|
<ContextMenu name="НаименованиеКонтекстноеМеню" id="17"/>
|
||||||
<ExtendedTooltip name="НаименованиеРасширеннаяПодсказка" id="11"/>
|
<ExtendedTooltip name="НаименованиеРасширеннаяПодсказка" id="18"/>
|
||||||
</InputField>
|
</InputField>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
</Table>
|
</Table>
|
||||||
</ChildItems>
|
</ChildItems>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute name="Список" id="12">
|
<Attribute name="Список" id="19">
|
||||||
<Type>
|
<Type>
|
||||||
<v8:Type>cfg:DynamicList</v8:Type>
|
<v8:Type>cfg:DynamicList</v8:Type>
|
||||||
</Type>
|
</Type>
|
||||||
<MainAttribute>true</MainAttribute>
|
<MainAttribute>true</MainAttribute>
|
||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<MainTable>Catalog.Бригады</MainTable>
|
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<MainTable>Catalog.Бригады</MainTable>
|
||||||
|
<ListSettings>
|
||||||
|
<dcsset:filter>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||||
|
</dcsset:filter>
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:conditionalAppearance>
|
||||||
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
|
</dcsset:conditionalAppearance>
|
||||||
|
<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>
|
||||||
|
<dcsset:itemsUserSettingID>UUID-004</dcsset:itemsUserSettingID>
|
||||||
|
</ListSettings>
|
||||||
</Settings>
|
</Settings>
|
||||||
</Attribute>
|
</Attribute>
|
||||||
</Attributes>
|
</Attributes>
|
||||||
<Commands>
|
<Commands>
|
||||||
<Command name="ИзменитьВыделенные" id="13">
|
<Command name="ИзменитьВыделенные" id="20">
|
||||||
<Title>
|
<Title>
|
||||||
<v8:item>
|
<v8:item>
|
||||||
<v8:lang>ru</v8:lang>
|
<v8:lang>ru</v8:lang>
|
||||||
|
|||||||
@@ -0,0 +1,252 @@
|
|||||||
|
<?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></Vendor>
|
||||||
|
<Version></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>
|
||||||
|
<DataProcessor>ГруппыКнопок</DataProcessor>
|
||||||
|
</ChildObjects>
|
||||||
|
</Configuration>
|
||||||
|
</MetaDataObject>
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
<?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">
|
||||||
|
<DataProcessor uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="DataProcessorObject.ГруппыКнопок" category="Object">
|
||||||
|
<xr:TypeId>UUID-002</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-003</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="DataProcessorManager.ГруппыКнопок" category="Manager">
|
||||||
|
<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 />
|
||||||
|
<UseStandardCommands>false</UseStandardCommands>
|
||||||
|
<DefaultForm>DataProcessor.ГруппыКнопок.Form.Форма</DefaultForm>
|
||||||
|
<AuxiliaryForm />
|
||||||
|
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||||
|
<ExtendedPresentation />
|
||||||
|
<Explanation />
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Form>Форма</Form>
|
||||||
|
</ChildObjects>
|
||||||
|
</DataProcessor>
|
||||||
|
</MetaDataObject>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user