mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-10 16:14:54 +03:00
dc9e1fe3db
Collapsible groups, status banners, popup menus, custom command bars, hyperlink labels — with DSL examples for each pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
338 lines
18 KiB
Markdown
338 lines
18 KiB
Markdown
# Паттерны компоновки управляемых форм
|
||
|
||
Рекомендации по дизайну форм, извлечённые из типовых конфигураций 1С. Используйте при создании форм через `/form-compile`, когда требования пользователя не детализируют расположение элементов.
|
||
|
||
## Архетипы форм
|
||
|
||
### Форма документа
|
||
|
||
```
|
||
Шапка (horizontal, 2 колонки)
|
||
├─ Левая (vertical): НомерДата (H: Номер + Дата "от"), Контрагент, Договор
|
||
├─ Правая (vertical): Организация, Подразделение, ЦеныИВалюта (надпись-ссылка)
|
||
Страницы (pages)
|
||
├─ Товары: таблица Объект.Товары
|
||
├─ Услуги: таблица Объект.Услуги (опционально)
|
||
└─ Дополнительно: прочие реквизиты
|
||
Подвал (vertical)
|
||
├─ Итоги (horizontal): Всего, НДС, Скидка
|
||
└─ КомментарийОтветственный (horizontal): Комментарий + Ответственный
|
||
```
|
||
|
||
**Типичные события:** OnCreateAtServer, OnReadAtServer, OnOpen, BeforeWriteAtServer, AfterWriteAtServer, AfterWrite, NotificationProcessing
|
||
|
||
**Свойства:** autoTitle=false, командная панель со стандартными + глобальными командами
|
||
|
||
### Форма обработки (DataProcessor)
|
||
|
||
```
|
||
Параметры (vertical)
|
||
├─ Группа полей ввода (Организация, Период, режимы работы)
|
||
├─ Информационные надписи (label, hyperlink)
|
||
Рабочая область
|
||
├─ Таблица данных или Pages с вкладками
|
||
Кнопки действий
|
||
├─ Выполнить / Применить (defaultButton)
|
||
├─ Закрыть (stdCommand: Close)
|
||
```
|
||
|
||
**Типичные события:** OnCreateAtServer, OnOpen, NotificationProcessing
|
||
|
||
**Свойства:** windowOpeningMode=LockOwnerWindow (если диалог), autoTitle=false
|
||
|
||
### Форма списка
|
||
|
||
```
|
||
Отборы (group: alwaysHorizontal)
|
||
├─ ГруппаОтбор[Поле] (H): Флажок + Поле ввода (для каждого фильтра)
|
||
Список (table, DynamicList)
|
||
├─ Колонки: labelField (не input — данные только для чтения)
|
||
```
|
||
|
||
**Типичные события:** OnCreateAtServer, OnOpen, NotificationProcessing, OnLoadDataFromSettingsAtServer
|
||
|
||
**Свойства:** autoSaveDataInSettings=Use (запомнить отборы)
|
||
|
||
**Фильтры:** пара реквизитов на каждый фильтр — `Отбор[Поле]` (значение) + `Отбор[Поле]Использование` (boolean, флажок вкл/выкл)
|
||
|
||
### Форма элемента справочника
|
||
|
||
**Простая:**
|
||
```
|
||
ГруппаРеквизитов (horizontal)
|
||
├─ Наименование -> Объект.Description
|
||
└─ Код -> Объект.Code (если нужен)
|
||
```
|
||
|
||
**Сложная:**
|
||
```
|
||
Главное (vertical)
|
||
├─ Наименование -> Объект.Description
|
||
├─ Параметры (horizontal, 2 колонки)
|
||
│ ├─ Левая: основные реквизиты
|
||
│ └─ Правая: дополнительные реквизиты
|
||
└─ КонтактныеДанные / Дополнительно (vertical)
|
||
```
|
||
|
||
**Типичные события:** OnCreateAtServer, OnReadAtServer, BeforeWriteAtServer, NotificationProcessing
|
||
|
||
### Мастер (Wizard)
|
||
|
||
```
|
||
Страницы (pages, OnCurrentPageChange)
|
||
├─ Шаг1: описание + параметры
|
||
├─ Шаг2: основная работа
|
||
└─ Шаг3: результат
|
||
Кнопки (horizontal)
|
||
├─ Назад (command), Далее (command, defaultButton), Выполнить (command)
|
||
└─ Закрыть (stdCommand: Close)
|
||
```
|
||
|
||
**Свойства:** windowOpeningMode=LockOwnerWindow
|
||
|
||
## Конвенции именования
|
||
|
||
### Группы
|
||
|
||
| Назначение | Имя | Тип |
|
||
|-----------|-----|-----|
|
||
| Шапка | `ГруппаШапка` | horizontal |
|
||
| Левая колонка | `ГруппаШапкаЛевая` | vertical |
|
||
| Правая колонка | `ГруппаШапкаПравая` | vertical |
|
||
| Номер+Дата | `ГруппаНомерДата` | horizontal |
|
||
| Подвал | `ГруппаПодвал` | vertical |
|
||
| Итоги | `ГруппаИтоги` | horizontal |
|
||
| Кнопки | `ГруппаКнопок` | horizontal |
|
||
| Страницы | `ГруппаСтраницы` / `Страницы` | pages |
|
||
| Предупреждение | `ГруппаПредупреждение` | horizontal, visible:false |
|
||
| Доп. секция | `ГруппаДополнительно` / `ГруппаПрочее` | vertical, collapse |
|
||
|
||
### Элементы
|
||
|
||
| Назначение | Имя | Суффикс |
|
||
|-----------|-----|---------|
|
||
| Поле в таблице | `[Таблица][Поле]` | — |
|
||
| Итог | `Итоги[Поле]` | — |
|
||
| Надпись-ссылка | `[Поле]Надпись` | — |
|
||
| Фильтр | `Отбор[Поле]` | — |
|
||
| Флажок фильтра | `Отбор[Поле]Использование` | — |
|
||
| Кнопка команды | `[Команда]Кнопка` | — |
|
||
| Баннер-картинка | `[Баннер]Картинка` | — |
|
||
| Баннер-надпись | `[Баннер]Надпись` | — |
|
||
| Подменю | `Подменю[Действие]` | — |
|
||
|
||
### Обработчики событий
|
||
|
||
Имя обработчика = имя элемента + суффикс события на русском:
|
||
|
||
| Событие | Суффикс | Пример |
|
||
|---------|---------|--------|
|
||
| OnChange | ПриИзменении | `ОрганизацияПриИзменении` |
|
||
| StartChoice | НачалоВыбора | `КонтрагентНачалоВыбора` |
|
||
| Click | Нажатие | `ЦеныИВалютаНажатие` |
|
||
| OnEditEnd | ПриОкончанииРедактирования | `ТоварыПриОкончанииРедактирования` |
|
||
| OnStartEdit | ПриНачалеРедактирования | `ТоварыПриНачалеРедактирования` |
|
||
|
||
Обработчики формы — стандартные имена: `ПриСозданииНаСервере`, `ПриОткрытии`, `ПередЗакрытием`, `ОбработкаОповещения`.
|
||
|
||
## Принципы компоновки
|
||
|
||
1. **Порядок чтения.** Сверху вниз, слева направо. Самое важное — вверху.
|
||
2. **Двухколоночная шапка.** Основные реквизиты слева (контрагент, склад), организационные справа (организация, подразделение).
|
||
3. **Кнопки действий внизу.** Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя.
|
||
4. **Таблицы — основная область.** Табличные части занимают большую часть формы, обычно на Pages.
|
||
5. **Итоги рядом с таблицей.** В подвале, горизонтальная группа, все поля readOnly.
|
||
6. **Фильтры — отдельная зона.** Над списком, горизонтальная группа (alwaysHorizontal), пара "флажок + поле" на каждый фильтр.
|
||
7. **Скрытые элементы для состояний.** Баннеры, предупреждения — `visible: false` по умолчанию, показываются программно.
|
||
8. **Надписи-ссылки для диалогов.** `labelField` с `hyperlink: true` и событием Click — для открытия подформ (ЦеныИВалюта, УчётнаяПолитика).
|
||
|
||
## Продвинутые паттерны (ERP)
|
||
|
||
Извлечены из конфигурации «Управление предприятием» (ERP 8.3.24). Применяйте в сложных формах.
|
||
|
||
### Сворачиваемые группы (Collapsible)
|
||
|
||
Для необязательных секций — «Подписи», «Дополнительно», «Прочее». Сворачиваются по умолчанию, экономят место.
|
||
|
||
```
|
||
ГруппаПодписи (vertical, collapse, collapsed)
|
||
├─ Руководитель -> Объект.Руководитель
|
||
└─ ГлавныйБухгалтер -> Объект.ГлавныйБухгалтер
|
||
```
|
||
|
||
DSL:
|
||
```json
|
||
{ "group": "vertical", "name": "ГруппаПодписи", "title": "Подписи",
|
||
"behavior": "Collapsible", "collapsed": true, "children": [
|
||
{ "input": "Руководитель", "path": "Объект.Руководитель" },
|
||
{ "input": "ГлавныйБухгалтер", "path": "Объект.ГлавныйБухгалтер" }
|
||
]}
|
||
```
|
||
|
||
### Баннер-предупреждение (Status Banner)
|
||
|
||
Группа «картинка + надпись» без заголовка, скрыта по умолчанию. Показывается программно при определённых условиях (просрочка, блокировка, информация).
|
||
|
||
```
|
||
ГруппаПредупреждение (horizontal, showTitle:false, visible:false)
|
||
├─ [Picture] ПредупреждениеКартинка -> StdPicture.Information
|
||
└─ [Label] ПредупреждениеНадпись (maxWidth:76, textColor:style:ПоясняющийТекст)
|
||
```
|
||
|
||
DSL:
|
||
```json
|
||
{ "group": "horizontal", "name": "ГруппаПредупреждение", "showTitle": false,
|
||
"visible": false, "children": [
|
||
{ "picture": "ПредупреждениеКартинка" },
|
||
{ "label": "ПредупреждениеНадпись", "title": "Текст предупреждения",
|
||
"maxWidth": 76, "autoMaxWidth": false }
|
||
]}
|
||
```
|
||
|
||
### Выпадающее меню в командной панели (Popup)
|
||
|
||
Группировка связанных команд (печать, отправка, выгрузка) в одну кнопку-меню с иконкой.
|
||
|
||
```
|
||
[CmdBar] КоманднаяПанель
|
||
├─ [Popup] ПодменюПечать (picture: StdPicture.Print, representation: Picture)
|
||
│ ├─ [Button] ПечатьНакладная -> Печать [cmd]
|
||
│ └─ [Button] ПечатьСчёт -> ПечатьСчёт [cmd]
|
||
└─ [Popup] ПодменюОтправить (picture: StdPicture.SendByEmail)
|
||
└─ [Button] ОтправитьПоПочте -> Отправить [cmd]
|
||
```
|
||
|
||
DSL:
|
||
```json
|
||
{ "cmdBar": "КоманднаяПанель", "children": [
|
||
{ "popup": "ПодменюПечать", "title": "Печать",
|
||
"picture": "StdPicture.Print", "representation": "Picture", "children": [
|
||
{ "button": "ПечатьНакладная", "command": "Печать" },
|
||
{ "button": "ПечатьСчёт", "command": "ПечатьСчёт" }
|
||
]},
|
||
{ "popup": "ПодменюОтправить", "title": "Отправить",
|
||
"picture": "StdPicture.SendByEmail", "representation": "Picture", "children": [
|
||
{ "button": "ОтправитьПоПочте", "command": "Отправить" }
|
||
]}
|
||
]}
|
||
```
|
||
|
||
### Форма без стандартной командной панели
|
||
|
||
Для модальных диалогов и мастеров — отключение стандартной командной панели, полностью ручное управление кнопками.
|
||
|
||
```
|
||
properties: commandBarLocation=None, windowOpeningMode=LockWholeInterface
|
||
Содержимое (vertical)
|
||
├─ ... рабочая область ...
|
||
ГруппаКнопок (horizontal)
|
||
├─ Назад (command), Далее (command, defaultButton)
|
||
└─ Закрыть (stdCommand: Close)
|
||
```
|
||
|
||
DSL:
|
||
```json
|
||
{
|
||
"properties": { "commandBarLocation": "None", "windowOpeningMode": "LockWholeInterface" },
|
||
"elements": [
|
||
{ "group": "vertical", "name": "Содержимое", "children": [ "..." ] },
|
||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
||
{ "button": "Назад", "command": "Назад" },
|
||
{ "button": "Далее", "command": "Далее", "defaultButton": true },
|
||
{ "button": "Закрыть", "stdCommand": "Close" }
|
||
]}
|
||
]
|
||
}
|
||
```
|
||
|
||
### Надпись-гиперссылка для открытия подформ
|
||
|
||
`labelField` с `hyperlink: true` и событием Click — вместо кнопки. Типичный приём для «ЦеныИВалюта», «УчётнаяПолитика» и подобных.
|
||
|
||
```
|
||
[LabelField] ЦеныИВалютаНадпись -> ЦеныИВалюта (hyperlink) {Click}
|
||
```
|
||
|
||
DSL:
|
||
```json
|
||
{ "labelField": "ЦеныИВалютаНадпись", "path": "ЦеныИВалюта",
|
||
"hyperlink": true, "on": ["Click"] }
|
||
```
|
||
|
||
## Примеры DSL
|
||
|
||
### Типичная форма обработки
|
||
|
||
```json
|
||
{
|
||
"title": "Загрузка данных из CSV",
|
||
"properties": { "autoTitle": false, "windowOpeningMode": "LockOwnerWindow" },
|
||
"events": { "OnCreateAtServer": "ПриСозданииНаСервере" },
|
||
"elements": [
|
||
{ "group": "vertical", "name": "ГруппаПараметры", "children": [
|
||
{ "input": "ФайлЗагрузки", "path": "ФайлЗагрузки", "title": "Файл", "clearButton": true, "horizontalStretch": true, "on": ["StartChoice"] },
|
||
{ "input": "Кодировка", "path": "Кодировка", "title": "Кодировка" },
|
||
{ "input": "Разделитель", "path": "Разделитель", "title": "Разделитель колонок" }
|
||
]},
|
||
{ "table": "Данные", "path": "Объект.Данные", "on": ["OnStartEdit"], "columns": [
|
||
{ "input": "ДанныеНомерСтроки", "path": "Объект.Данные.LineNumber", "readOnly": true, "title": "№" },
|
||
{ "input": "ДанныеНаименование", "path": "Объект.Данные.Наименование" },
|
||
{ "input": "ДанныеКоличество", "path": "Объект.Данные.Количество", "on": ["OnChange"] },
|
||
{ "input": "ДанныеСумма", "path": "Объект.Данные.Сумма", "readOnly": true }
|
||
]},
|
||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
||
{ "button": "Загрузить", "command": "Загрузить", "title": "Загрузить из файла", "defaultButton": true },
|
||
{ "button": "Очистить", "command": "Очистить", "title": "Очистить таблицу" },
|
||
{ "button": "Закрыть", "stdCommand": "Close" }
|
||
]}
|
||
],
|
||
"attributes": [
|
||
{ "name": "Объект", "type": "ExternalDataProcessorObject.ЗагрузкаИзCSV", "main": true },
|
||
{ "name": "ФайлЗагрузки", "type": "string" },
|
||
{ "name": "Кодировка", "type": "string(20)" },
|
||
{ "name": "Разделитель", "type": "string(5)" }
|
||
],
|
||
"commands": [
|
||
{ "name": "Загрузить", "action": "ЗагрузитьОбработка" },
|
||
{ "name": "Очистить", "action": "ОчиститьОбработка" }
|
||
]
|
||
}
|
||
```
|
||
|
||
### Типичная форма со списком и фильтрами
|
||
|
||
```json
|
||
{
|
||
"properties": { "autoTitle": false, "autoSaveDataInSettings": "Use" },
|
||
"events": {
|
||
"OnCreateAtServer": "ПриСозданииНаСервере",
|
||
"NotificationProcessing": "ОбработкаОповещения"
|
||
},
|
||
"elements": [
|
||
{ "group": "alwaysHorizontal", "name": "ГруппаОтборы", "children": [
|
||
{ "group": "horizontal", "name": "ГруппаОтборОрганизация", "children": [
|
||
{ "check": "ОтборОрганизацияИспользование", "path": "ОтборОрганизацияИспользование", "titleLocation": "none", "on": ["OnChange"] },
|
||
{ "input": "ОтборОрганизация", "path": "ОтборОрганизация", "title": "Организация", "on": ["OnChange"] }
|
||
]},
|
||
{ "group": "horizontal", "name": "ГруппаОтборКонтрагент", "children": [
|
||
{ "check": "ОтборКонтрагентИспользование", "path": "ОтборКонтрагентИспользование", "titleLocation": "none", "on": ["OnChange"] },
|
||
{ "input": "ОтборКонтрагент", "path": "ОтборКонтрагент", "title": "Контрагент", "on": ["OnChange"] }
|
||
]}
|
||
]},
|
||
{ "table": "Список", "path": "Список", "on": ["Selection", "OnActivateRow"], "columns": [
|
||
{ "labelField": "СписокДата", "path": "Список.Дата", "title": "Дата" },
|
||
{ "labelField": "СписокНомер", "path": "Список.Номер", "title": "Номер" },
|
||
{ "labelField": "СписокКонтрагент", "path": "Список.Контрагент" },
|
||
{ "labelField": "СписокСумма", "path": "Список.Сумма" }
|
||
]}
|
||
],
|
||
"attributes": [
|
||
{ "name": "Список", "type": "DynamicList", "mainTable": "Document.РеализацияТоваров" },
|
||
{ "name": "ОтборОрганизация", "type": "CatalogRef.Организации" },
|
||
{ "name": "ОтборОрганизацияИспользование", "type": "boolean" },
|
||
{ "name": "ОтборКонтрагент", "type": "CatalogRef.Контрагенты" },
|
||
{ "name": "ОтборКонтрагентИспользование", "type": "boolean" }
|
||
]
|
||
}
|
||
```
|