Модуль управляемой формы 1С. Используй когда нужно написать или отревьюить обработчики формы, расставить директивы компиляции, сократить серверные вызовы и трафик, разобраться с параметрами формы, подключаемыми через УстановитьДействие обработчиками или клиент-серверной границей в модуле формы.
Installs into .claude/skills of the current project.
Are you the author of Form Events?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ingvarconsulting-form-events)
---
name: form-events
description: "Модуль управляемой формы 1С. Используй когда нужно написать или отревьюить обработчики формы, расставить директивы компиляции, сократить серверные вызовы и трафик, разобраться с параметрами формы, подключаемыми через УстановитьДействие обработчиками или клиент-серверной границей в модуле формы."
---
# Form Module Events
## MCP routing
- Preferred path: use MCP `unica` tools `unica.view {}`, `unica.view` on the form node, `unica.view` on the object node, `unica.search`, `unica.apply`, `unica.check`, and `unica.run`.
- Runtime идёт через `unica.run`: вызов без `op` отдаёт словарь операций и
контракт каждой — `argsSchema`, `execution`, `previewRequired`,
`dryRunRequired`. Контракт вызова бери оттуда, а не из этого текста;
при `implemented: true` используй опубликованную `argsSchema`; при
`support.state: limited` разрешено только подмножество `support.supportedArgs`.
При `support.state: unavailable` остановись; не выдумывай аргументов при
`argsSchema: null`. Для плановой операции сначала проверь результат `dryRun: true`,
затем исполняй запрос с `dryRun: false`. Preview не фиксирует входы между
вызовами. Не обходи контракт прямым runner-ом.
- Use `unica.docs` with `source: "development-standard"` for the standards about form modules: 439, 455, 487, 492, 642, 724, 741, and diagnostics АПК:100, АПК:526, АПК:547, АПК:1410, АПК:1412, BSLLS:SeveralCompilerDirectives, BSLLS:ServerSideExportFormMethod. These are standards, not evidence of runtime behavior; confirm the wording before citing one.
- Do not call internal analyzer, runtime, standards, or package adapters directly. They are hidden behind MCP `unica`.
## References
- Read `../../references/platform/form-events.md` for the client/server split, directives, the server-call budget, form parameters, and attached handlers.
- Read `../../references/platform/object-events.md` when the logic belongs to the object being written rather than to the form.
- Read `../../references/specs/form-patterns.md` and use `form-patterns` for layout, archetypes, and UX; this skill owns the module, not the arrangement.
## Core model
A form module holds client and server code in one file, and the directive on each procedure decides which. Everything else follows:
- **Where it runs** — `&НаКлиенте`, `&НаСервере`, `&НаСервереБезКонтекста` belong in form and command modules; elsewhere use preprocessor instructions (std439). One directive per procedure, never zero and never two.
- **What it costs** — one user action must not produce extra server calls from configuration code, and a deviation needs a stated reason (std487).
- **What it receives** — form parameters are declared on the parameter tab, so `ПриСозданииНаСервере` reads them directly instead of probing with `Параметры.Свойство()` (std741).
- **How it is wired** — a handler assigned through `УстановитьДействие` carries the `Подключаемый_` prefix (std492).
## Workflow
1. Decide which side the logic belongs to before writing it: needs the database or the object → server; needs the user or the form's visual state → client.
2. Inspect the form with `unica.view` on the form node for the declared events, parameters, and items, and `unica.view` on the object node for the object behind it.
3. Read the existing module with `unica.view` on the module node (its `Method` branch lists the methods) before adding to it.
4. Count the server calls the change adds on the path of a single user action. If it adds one, name the reason.
5. Declare any new form parameter through `unica.apply` (`formAttribute.add`) before reading it in the module.
6. Apply module changes with `unica.apply`, one verifiable step at a time, giving every new procedure exactly one directive.
7. Verify statically with `unica.check` on the module node (test runs are outside the v0.13 surface), and require separate evidence for runtime behavior and opening the affected form.
## Command Availability
When a handler must disable, lock, or re-enable a form command in the UI, do not
write `Команды[ИмяКоманды].Доступность`: the form command object is not the UI
element whose availability is shown to the user. Inspect the form first with
`unica.view` using its qualified `at` address
(CTR.SOURCE.LOGICAL-NODE-VIEW-SHAPE). Example calls for the form and its item
collection:
```json
{"name": "unica.view", "arguments": {"at": "main:Catalog.Номенклатура.Form.ФормаЭлемента"}}
```
```json
{"name": "unica.view", "arguments": {"at": "main:Catalog.Номенклатура.Form.ФормаЭлемента.Item"}}
```
A node returns `props` and `branches`; a collection page returns `items` with
`at` addresses. Follow all nested `Item` branches using their returned addresses
and all pages using the returned `cursor`, keeping the address and read parameters.
The current view exposes only `tag`, `title`, `visible`, `enabled`, and `readOnly`
in an item's `props` (`title` is `null` when no distinct title is set).
To establish a link, the item's `CommandName` must match
`Form.Command.<ИмяКоманды>` or the relevant standard-command reference.
However, the current view does not expose `CommandName` or `binding`: the item
tree alone cannot prove command links or that every linked item has been found.
Do not guess links from names or titles. For the missing data, use the emergency
source bridge, which permits opening a file outside Unica:
```json
{"name": "unica.resolve", "arguments": {"at": "main:Catalog.Номенклатура.Form.ФормаЭлемента"}}
```
The returned `path` is relative to the selected source-set root, which need not
be the workspace root. Confirm the root and format in the project configuration.
In a Designer dump it may identify the descriptor
`Catalogs/Номенклатура/Forms/ФормаЭлемента.xml`; the item tree lives beside it
in `ФормаЭлемента/Ext/Form.xml`. Check that this file exists and has a `Form`
root in the `http://v8.1c.ru/8.3/xcf/logform` namespace. A `MetaDataObject`
descriptor does not contain the complete form tree. Do not assume this layout
for EDT or other formats without evidence.
Read the form content with `Read` and collect every element whose `CommandName`
exactly matches the command, accounting for the XML namespace. Traverse the whole XML, including `AutoCommandBar`,
`ContextMenu`, table command bars, and nested groups, rather than only the root
`ChildItems`: the `Item` projection does not expose all these containers.
Record the element names and bindings. This is read-only inspection; source
changes still go through `unica.apply`: plan with `at` and `ops`, then execute
with only `executionToken` from the successful plan's `data.executionToken`.
Also inspect command-bar autofill and element creation in the form module:
static XML does not prove the contents of a dynamic UI. If the file cannot be
read, its format is unconfirmed, or the complete set of links remains unknown,
name the specific limitation and candidates; do not generate BSL with unconfirmed
item names. Report missing MCP read support as an **Unica MCP contract gap**;
dynamic form contents require evidence from the code or the opened form.
A missing `binding` in `view` alone does not end the investigation.
Once links are confirmed, set availability on every related item:
```bsl
Элементы[ИмяЭлемента].Доступность = Ложь;
```
For example, after verifying that both `ЗаполнитьВПанели` and `ЗаполнитьВМеню`
are bound to `Form.Command.Заполнить` in this form, disable both:
```bsl
Для Каждого ИмяЭлемента Из СтрРазделить("ЗаполнитьВПанели,ЗаполнитьВМеню", ",") Цикл
Элементы[ИмяЭлемента].Доступность = Ложь;
КонецЦикла;
```
If the same command is rendered by a main command bar button, table command bar
button, context-menu item, group button, or submenu item, update all of them or
state that the form must be inspected further before code is generated. For table
part standard commands, check the table's `ТолькоПросмотр` property first
(`readOnly` in the table node's `props`):
read-only tables usually let the platform block add, copy, delete, and move-row
commands without duplicate manual code. Add manual blocking mainly for custom
buttons or menu items whose handlers can still change table rows, prices,
discounts, VAT, sorting, selection, loading, filling, or recalculation.
## Design rules
- Do not branch with `#Если Сервер` or `#Если Клиент` inside a `КлиентСервер` common module — the execution context cannot be determined reliably there (std439, АПК:547). Split into `Клиент` and `Сервер` modules with the same function name and keep the shared part in `КлиентСервер`.
- A directive in a server-only or client-only common module is noise; the context is already fixed.
- A server procedure called from the client marks its parameters `Знач` (АПК:1412), and a form must not expose a server export method (BSLLS:ServerSideExportFormMethod).
- Startup handlers should not reach the server. When unavoidable, pass every startup parameter in one call and cache repeats through a reusable-return module (std487, std724); with БСП use `ОбщегоНазначенияПереопределяемый`.
- Long work belongs in a background job (std642), not in a longer server call. Route it to `background-jobs`.
- A form that needs parameters and opens only from code must not be the object's main form. If it has to be main, check the parameters in `ПриСозданииНаСервере` and raise an exception that tells the user why it cannot open (std741).
- Do not call a form event handler programmatically. Extract the body into a named procedure and call that from both places.
## Review checklist
- Every procedure in the form module has exactly one compilation directive.
- No preprocessor branch on client versus server inside a `КлиентСервер` module.
- The change adds no server call to a per-action path without a stated reason.
- Every form parameter read in the module is declared on the parameter tab — no `Параметры.Свойство()` probing in `ПриСозданииНаСервере` (АПК:1410).
- Handlers attached with `УстановитьДействие` carry the `Подключаемый_` prefix (АПК:100).
- Form event handlers sit in the standard event-handler region, and non-handlers do not.
- Write-related form events are only present when the main attribute is a persistent object or record.
## Stop rules
- Do not put logic that belongs to the object's own write path into the form module; it will not run when the object is written from code.
- Do not read an undeclared form parameter.
- Do not grow a server call to avoid a background job.
## Contract gaps
If public MCP `unica` cannot inspect the form, its parameters, its module, or the diagnostics needed for the task, report a Unica MCP contract gap with the missing operation.