На том же A/B/C отделим источник списка от его UI: интерактивные настройки, автообновление, способ редактирования и проверка новой строки без записи.
Где и как запускать
Полный модуль собственной обычной формы УчебныеМенеджерыРасчетов85 → Обработки → УчебныеВидыСписок85 → Формы → Список. Полный общий модуль и Пульт ниже; не выполнялся.
Подготовка
Создайте НОВУЮ отдельную файловую базу 8.5.1.1343: имя конфигурации УчебныеМенеджерыРасчетов85, совместимость НеИспользовать, обычное приложение и толстый клиент. Не используйте рабочие ЗУП/КА/УТ/УНФ/БП. Здесь код, стенд и формы не выполнялись: runtimeVerifiedScenarios=0.
План видов расчёта Уч85Начисления: Код Строка(10), переменная длина, наименование 100, уникальность кода включена. ИспользованиеПериодаДействия=Да, ЗависимостьОтВидовРасчета=ПоПериодуДействия, в базовых планах только сам Уч85Начисления. Собственный реквизит Уч85Ключ Строка(8), Индексировать. Нет предопределённых элементов, общих реквизитов, разделителей, регистров расчёта или расчётных алгоритмов. Модули пустые.
В стандартном списке своего плана вручную создайте ровно три обычных вида: A — код 10, имя Учебный оклад, ключ A, ПериодДействияБазовый=Истина; B — код 20, имя Учебная премия, ключ B, ПериодДействияБазовый=Ложь; C — код 30, имя Учебное отсутствие, ключ C, ПериодДействияБазовый=Ложь. Все без пометки удаления и не предопределённые.
У B вручную заполните три стандартные таблицы: БазовыеВидыРасчета содержит только ссылку A; ВедущиеВидыРасчета только A; ВытесняющиеВидыРасчета только C. У A/C все три таблицы пустые. Сохраните только эту собственную подготовку. Это технический граф связей, не утверждённая методика начисления зарплаты.
Общий модуль УчебныеВиды85: неглобальный, Клиент (обычное приложение)=Да, Сервер=Нет, Привилегированный=Нет. Вставьте отдельный полный общий модуль ниже. Основной блок этого урока — модуль обычной формы Список, не общий модуль.
Создайте собственную обработку УчебныеВиды85 с обычной основной формой Пульт. Кнопка Выполнить, действие ВыполнитьНажатие; отдельный полный модуль формы приведён ниже. F7 и обновление только своего стенда, запуск Пульта в толстом клиенте.
Для основных опытов используется одна сессия, никаких фоновых обменов, расширений, сторонних обработчиков или других пользователей, меняющих записи. Код читает собственные виды и изменяет полученный объект только в памяти. Записать, удаление, проведение, расчёт регистров, файлы и сеть не вызываются.
Создайте обработку УчебныеВидыСписок85 с обычной основной формой Список. Реквизит СписокРасчетов типа ПланВидовРасчетаСписок.Уч85Начисления. Табличное поле Виды связано именно с СписокРасчетов; колонки Код/Наименование/Уч85Ключ связаны с одноимёнными полями источника. ТолькоПросмотр=Да, стандартных команд создания/записи/удаления нет.
В этой форме кнопки ТолькоПремия, ВсеПоУбыванию, Восстановить, Закрыть; назначьте соответствующие действия *Нажатие и событие ПриОткрытии. Полный модуль списка вставьте отдельно, общий УчебныеВиды85 оставьте обычным клиентским модулем по общей подготовке.
В собственной Список добавьте кнопки Фиксированный, Настраиваемый, АвтоОбновление с соответствующими действиями *Нажатие. В контекстном меню поля сохраните стандартный диалог настройки списка. Начальные значения задаёт полный модуль формы до открытия; другие уроки одновременно не вставляйте.
Перем Подготовлено;
Процедура ПодготовитьДоОткрытия() Экспорт
Подготовлено = Ложь;
Свои = УчебныеВиды85.ПолучитьСвоиВиды();
Если ЭтаФорма.Открыта() Или ТипЗнч(СписокРасчетов) <> Тип("ПланВидовРасчетаСписок.Уч85Начисления") Тогда
ВызватьИсключение "Нужен настоящий реквизит списка своей закрытой обычной формы";
КонецЕсли;
Колонки = СписокРасчетов.Колонки;
Если ТипЗнч(Колонки) <> Тип("КолонкиСписка") Тогда
ВызватьИсключение "Колонки списка не равны визуальным колонкам поля";
КонецЕсли;
Для Каждого Имя Из СтрРазделить("Код,Наименование,Уч85Ключ", ",") Цикл
Если Колонки.Найти(Имя) = Неопределено Тогда
Колонки.Добавить(Имя);
КонецЕсли;
КонецЦикла;
Если ТипЗнч(СписокРасчетов.Отбор) <> Тип("Отбор") Или ТипЗнч(СписокРасчетов.Порядок) <> Тип("Порядок") Тогда
ВызватьИсключение "Нужны реальные коллекции отбора и порядка";
КонецЕсли;
СписокРасчетов.Отбор.Сбросить();
СписокРасчетов.Порядок.Установить("Код Возр");
ЭлементыФормы.Виды.ТолькоПросмотр = Истина;
НастроитьПоле(Ложь);
Подготовлено = Истина;
КонецПроцедуры
Процедура ПриОткрытии()
Если Подготовлено <> Истина Тогда
ВызватьИсключение "Открывайте этот список через собственный Пульт после подготовки";
КонецЕсли;
СписокРасчетов.Обновить();
Сообщить("Проверьте три строки: 10/A, 20/B, 30/C. Порядок задан источнику, не массиву строк.");
КонецПроцедуры
Процедура ПроверитьСвойОткрытыйСписок()
Свои = УчебныеВиды85.ПолучитьСвоиВиды();
Если Подготовлено <> Истина Или Не ЭтаФорма.Открыта() Тогда
ВызватьИсключение "Нужен свой подготовленный открытый список";
КонецЕсли;
КонецПроцедуры
Процедура ТолькоПремияНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
СписокРасчетов.Отбор.Сбросить();
СписокРасчетов.Отбор.Уч85Ключ.Установить("B", Истина);
СписокРасчетов.Обновить();
Сообщить("Проверьте одну строку: код 20, Учебная премия, ключ B. A и C скрыты, но не удалены.");
КонецПроцедуры
Процедура ВсеПоУбываниюНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
СписокРасчетов.Отбор.Сбросить();
СписокРасчетов.Порядок.Установить("Код Убыв");
СписокРасчетов.Обновить();
Сообщить("Проверьте порядок трёх строк: 30/C, 20/B, 10/A. В базе те же записи.");
КонецПроцедуры
Процедура ВосстановитьНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
СписокРасчетов.Отбор.Сбросить();
СписокРасчетов.Порядок.Установить("Код Возр");
СписокРасчетов.Обновить();
Сообщить("Проверьте исходные 10/A, 20/B, 30/C. Обновить перечитал базу, не записывал её.");
КонецПроцедуры
Процедура ЗакрытьНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
ЭлементыФормы.Виды.АвтоОбновление = Ложь;
ЭтаФорма.Закрыть();
КонецПроцедуры
Процедура НастроитьПоле(Интерактивно)
Поле = ЭлементыФормы.Виды;
УправлениеОтбором = Поле.НастройкаОтбора.Найти("Уч85Ключ");
УправлениеПорядком = Поле.НастройкаПорядка.Найти("Код");
Если УправлениеОтбором = Неопределено Или УправлениеПорядком = Неопределено Тогда
ВызватьИсключение "Нет собственных элементов управления отбором ключа и порядком кода";
КонецЕсли;
Поле.АвтоОбновление = Ложь;
Поле.ПериодАвтоОбновления = 10;
Поле.ВосстанавливатьТекущуюСтроку = Ложь;
Поле.ИзменятьАвтоОбновление = Интерактивно;
Поле.ИзменятьСпособРедактирования = Интерактивно;
Если Интерактивно Тогда
Поле.СпособРедактирования = СпособРедактированияСписка.ВСписке;
Поле.ПроверкаОтображенияНовойСтроки = ВариантПроверкиОтображенияНовойСтроки.НеПроверять;
Иначе
Поле.СпособРедактирования = СпособРедактированияСписка.ВДиалоге;
Поле.ПроверкаОтображенияНовойСтроки = ВариантПроверкиОтображенияНовойСтроки.СообщатьОНесоответствииОтбору;
КонецЕсли;
УправлениеОтбором.Доступность = Интерактивно;
УправлениеПорядком.Доступность = Интерактивно;
Поле.ТолькоПросмотр = Истина;
ПроверитьПрофиль(Интерактивно);
КонецПроцедуры
Процедура ПроверитьПрофиль(Интерактивно)
Поле = ЭлементыФормы.Виды;
Если Поле.АвтоОбновление Или Поле.ПериодАвтоОбновления <> 10 Или Поле.ВосстанавливатьТекущуюСтроку
Или Поле.ИзменятьАвтоОбновление <> Интерактивно Или Поле.ИзменятьСпособРедактирования <> Интерактивно
Или Не Поле.ТолькоПросмотр Тогда
ВызватьИсключение "Флаги своего профиля не совпали";
КонецЕсли;
Если Поле.НастройкаОтбора.Найти("Уч85Ключ").Доступность <> Интерактивно
Или Поле.НастройкаПорядка.Найти("Код").Доступность <> Интерактивно Тогда
ВызватьИсключение "Интерактивная доступность отбора/порядка не совпала";
КонецЕсли;
Если Интерактивно Тогда
Если Поле.СпособРедактирования <> СпособРедактированияСписка.ВСписке
Или Поле.ПроверкаОтображенияНовойСтроки <> ВариантПроверкиОтображенияНовойСтроки.НеПроверять Тогда
ВызватьИсключение "Не совпали режим и проверка настраиваемого профиля";
КонецЕсли;
Иначе
Если Поле.СпособРедактирования <> СпособРедактированияСписка.ВДиалоге
Или Поле.ПроверкаОтображенияНовойСтроки <> ВариантПроверкиОтображенияНовойСтроки.СообщатьОНесоответствииОтбору Тогда
ВызватьИсключение "Не совпали режим и проверка фиксированного профиля";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура НастраиваемыйНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
НастроитьПоле(Истина);
Сообщить("Откройте стандартный диалог настройки списка: отбор по ключу, порядок кода и настройки автообновления доступны. Запись строк по-прежнему запрещена настройкой ТолькоПросмотр.");
КонецПроцедуры
Процедура ФиксированныйНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
НастроитьПоле(Ложь);
ВосстановитьНажатие(Неопределено);
Сообщить("Фиксированный профиль восстановлен. Программный отбор кнопкой ТолькоПремия работает независимо от запрета его интерактивного изменения.");
КонецПроцедуры
Процедура АвтоОбновлениеНажатие(Кнопка)
ПроверитьСвойОткрытыйСписок();
Поле = ЭлементыФормы.Виды;
Поле.ИзменятьАвтоОбновление = Ложь;
Поле.ПериодАвтоОбновления = 10;
Поле.АвтоОбновление = Не Поле.АвтоОбновление;
Сообщить(СтрШаблон("АвтоОбновление=%1, период=%2 секунд, интерактивное изменение=%3",
Поле.АвтоОбновление, Поле.ПериодАвтоОбновления, Поле.ИзменятьАвтоОбновление));
КонецПроцедурыУчебныеВиды85.Пульт
УчебныеМенеджерыРасчетов85 → Обработки → УчебныеВиды85 → Формы → Пульт → Модуль
Полный модуль собственной обычной формы, не выполнялся.
Процедура ВыполнитьНажатие(Кнопка)
УчебныеВиды85.ВыполнитьПример();
КонецПроцедурыУчебныеВиды85.ОбщийМодуль
УчебныеМенеджерыРасчетов85 → Общие модули → УчебныеВиды85
Полный обычный клиентский общий модуль запуска и проверки собственной подготовки. Не выполнялся.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойСтенд();
Свои = ПолучитьСвоиВиды();
Ключ = Новый УникальныйИдентификатор;
Окно = Обработки.УчебныеВидыСписок85.ПолучитьФорму("Список", , Ключ);
Если Окно = Неопределено Тогда
ВызватьИсключение "Создайте собственную обычную форму Список";
КонецЕсли;
Если ТипЗнч(Окно) <> Тип("Форма") Тогда
ВызватьИсключение "Нужна обычная форма толстого клиента";
КонецЕсли;
Если Окно.Открыта() Или Окно.КлючУникальности <> Ключ Тогда
ВызватьИсключение "Не перенастраиваем чужую или ранее открытую форму";
КонецЕсли;
Окно.КлючСохраненияПоложенияОкна = "Уч85.СписокРасчетов." + Строка(Ключ);
Окно.ПодготовитьДоОткрытия();
Окно.Открыть();
КонецПроцедуры
Процедура ПроверитьСвойКонтекст()
Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
ВызватьИсключение "Нужен собственный стенд УчебныеМенеджерыРасчетов85 платформы 8.5.1.1343";
КонецЕсли;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Учебный вывод не должен выполняться внутри чужой транзакции";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойОсновнойПлан()
Описание = Метаданные.ПланыВидовРасчета.Найти("Уч85Начисления");
Если Описание = Неопределено Тогда
ВызватьИсключение "Создайте собственный план Уч85Начисления";
КонецЕсли;
Если Описание.ТипКода <> Метаданные.СвойстваОбъектов.ТипКодаПланаВидовРасчета.Строка
Или Описание.ДлинаКода <> 10 Или Описание.ДлинаНаименования <> 100
Или Не Описание.ИспользованиеПериодаДействия
Или Описание.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.ПоПериодуДействия Тогда
ВызватьИсключение "Настройки учебного плана не соответствуют подготовке";
КонецЕсли;
Если Описание.БазовыеВидыРасчета.Количество() <> 1
Или Не Описание.БазовыеВидыРасчета.Содержит(Описание) Тогда
ВызватьИсключение "Выберите только собственный план как базовый";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСвоиВиды() Экспорт
ПроверитьСвойОсновнойПлан();
Менеджер = ПланыВидовРасчета.Уч85Начисления;
A = Менеджер.НайтиПоРеквизиту("Уч85Ключ", "A");
B = Менеджер.НайтиПоРеквизиту("Уч85Ключ", "B");
C = Менеджер.НайтиПоРеквизиту("Уч85Ключ", "C");
Если A.Пустая() Или B.Пустая() Или C.Пустая() Или A = B Или A = C Или B = C Тогда
ВызватьИсключение "Подготовьте три разные реальные ссылки своего основного плана";
КонецЕсли;
Коды = Новый Структура("A,B,C", "10", "20", "30");
Имена = Новый Структура("A,B,C", "Учебный оклад", "Учебная премия", "Учебное отсутствие");
Свои = Новый Структура("Менеджер,A,B,C,Коды,Имена", Менеджер, A, B, C, Коды, Имена);
Ключи = Новый Массив;
Выборка = Менеджер.Выбрать(, "Код Возр");
Пока Выборка.Следующий() Цикл
Ключ = Выборка.Уч85Ключ;
ОжидаемыйКод = Неопределено;
ОжидаемоеИмя = Неопределено;
Если Не Коды.Свойство(Ключ, ОжидаемыйКод) Или Не Имена.Свойство(Ключ, ОжидаемоеИмя) Тогда
ВызватьИсключение "В основной выборке есть лишний учебный вид";
КонецЕсли;
Если Выборка.Код <> ОжидаемыйКод Или Выборка.Наименование <> ОжидаемоеИмя
Или Выборка.ПометкаУдаления Или Выборка.Предопределенный Или Выборка.ИмяПредопределенныхДанных <> ""
Или Выборка.Ссылка <> Свои[Ключ] Тогда
ВызватьИсключение "Поля собственного вида не совпали с подготовкой";
КонецЕсли;
ПроверитьСвоиСвязи(Выборка, Ключ, Свои);
Ключи.Добавить(Ключ);
КонецЦикла;
Если СтрСоединить(Ключи, ",") <> "A,B,C" Тогда
ВызватьИсключение "Основной план должен содержать ровно A,B,C в порядке кода";
КонецЕсли;
Возврат Свои;
КонецФункции
Процедура ПроверитьСвоиСвязи(Выборка, Ключ, Свои)
Если ТипЗнч(Выборка.ПериодДействияБазовый) <> Тип("Булево") Или Выборка.ПериодДействияБазовый <> (Ключ = "A") Тогда
ВызватьИсключение "Только собственный A имеет подготовленный признак базового периода";
КонецЕсли;
Если Ключ = "B" Тогда
Если Выборка.БазовыеВидыРасчета.Количество() <> 1 Или Выборка.ВедущиеВидыРасчета.Количество() <> 1
Или Выборка.ВытесняющиеВидыРасчета.Количество() <> 1 Тогда
ВызватьИсключение "У B нужны три реальные подготовленные строки зависимостей";
КонецЕсли;
Если Выборка.БазовыеВидыРасчета.Получить(0).ВидРасчета <> Свои.A
Или Выборка.ВедущиеВидыРасчета.Получить(0).ВидРасчета <> Свои.A
Или Выборка.ВытесняющиеВидыРасчета.Получить(0).ВидРасчета <> Свои.C Тогда
ВызватьИсключение "У B базовый/ведущий A и вытесняющий C, не плановые случайные ссылки";
КонецЕсли;
Иначе
Если Выборка.БазовыеВидыРасчета.Количество() <> 0 Или Выборка.ВедущиеВидыРасчета.Количество() <> 0
Или Выборка.ВытесняющиеВидыРасчета.Количество() <> 0 Тогда
ВызватьИсключение "У A/C таблицы зависимостей должны быть пустыми";
КонецЕсли;
КонецЕсли;
КонецПроцедурыРазбор по шагам
Используем настоящие сохранённые записи собственного стенда. Источник списка — реквизит обычной формы, Виды — визуальное поле. Само расширение появляется из типа связанного источника, его не создают через Новый.
Перед открытием общий модуль проверяет свою конфигурацию/записи, получает новую форму по уникальному ключу и вызывает ПодготовитьДоОткрытия. Код списка, общего модуля и Пульта представлен отдельными полными блоками.
Фиксированный профиль устанавливает ТолькоПросмотр, выключает автообновление, задаёт 10 секунд, ВосстанавливатьТекущуюСтроку=Ложь. Последний флаг относится к позиции при открытии формы, не выполняет поиск строки и не является восстановлением данных базы.
НастройкаОтбора и НастройкаПорядка — readonly коллекции управления UI. Найти может вернуть Неопределено: проверяем собственные Уч85Ключ и Код. Меняем их Доступность, а не заменяем коллекции и не изменяем через них значение фильтра.
При фиксированном профиле интерактивная настройка этих двух полей запрещена, но программная кнопка отбора продолжает работать: СписокРасчетов.Отбор — другой объект. Это демонстрирует отличие политики интерфейса от данных фильтра.
ИзменятьАвтоОбновление и ИзменятьСпособРедактирования управляют доступностью настройки пользователю. Они не запрещают программное присваивание соответствующих свойств и не являются правами на запись.
Настраиваемый профиль включает интерактивные настройки. СпособРедактирования переключается ВДиалоге/ВСписке, но ТолькоПросмотр сохраняется: реальное редактирование/запись в этом опыте не выполняется.
ПроверкаОтображенияНовойСтроки переключается между двумя действительными значениями перечисления. СообщатьОНесоответствииОтбору применяется после ввода новой строки; здесь ввод выключен, поэтому подтверждаем настройку, но не выдаём опыт за тест такого сообщения.
Кнопка АвтоОбновление программно включает/выключает перечитывание каждые 10 секунд даже при ИзменятьАвтоОбновление=Ложь. Минимум по справке 5 секунд. При отключённом АвтоОбновление сам по себе период не запускает таймер.
Фиксированный возвращает учебный профиль, отключает таймер и восстанавливает исходный фильтр/порядок источника. Закрыть тоже выключает таймер. Опыт касается только собственного нового окна, не чужих форм или системных пользовательских настроек.
Как проверить результат
Будущий тест: вставить три полных блока в указанные разные модули, назначить события/действия, F7, открыть через Пульт. Сверить реальные строки, не только сообщения.
Нажать Фиксированный и открыть стандартный диалог настройки списка: Уч85Ключ и Код недоступны для интерактивного изменения. Программная кнопка отбора показывает одну собственную B.
Нажать Настраиваемый: доступность этих полей и настроек автообновления/режима меняется. Сам список остаётся ТолькоПросмотр; не сохранять и не добавлять строки.
Кнопка АвтоОбновление: проверять выведенные фактические свойства Истина/Ложь и период 10. Ожидание нескольких обновлений — будущий ручной тест; неизменные строки не доказывают работу таймера.
Фиксированный возвращает исходные строки и режим, выключает таймер. Закрыть закрывает только свой список. Данные и связи учебного набора прежние.
Ожидаемый результат
Два профиля своего поля переключаются и проверяются кодом; программный отбор независим от интерактивной доступности. Исходный набор A/B/C не записывается.
На что обратить внимание
Это обычная форма толстого клиента, не расширение конфигурации и не ДинамическийСписок управляемой формы.
Доступность интерактивного управления не блокирует программные операции. ТолькоПросмотр — политика поля, не система прав доступа к базе.
Не заменяйте readonly НастройкаОтбора/НастройкаПорядка. Их элементы Доступность относятся к UI, а фактический фильтр хранится у источника списка.
ВосстанавливатьТекущуюСтроку здесь осознанно выключен для нового независимого опыта. Урок не доказывает восстановление позиции после повторного открытия.
При ТолькоПросмотр режимы редактирования и проверка новой строки показаны как настройки, не как выполненное редактирование и не как проверенные сообщения платформы.
Автообновление перечитывает базу и создаёт нагрузку, но не делает обмен и не отправляет сообщения. Для настоящего обмена нужны другие API.
Стенд/UI/таймер здесь не выполнялись: runtimeVerifiedScenarios=0. Сообщения ожидаемых строк не заменяют ручную проверку поля.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.