Список содержит 22 учебные позиции и итоговую строку. Закрепляем первую и последнюю строки при прокрутке, отдельно разрешаем перестановку и восстанавливаем исходный профиль. Это обычное ТабличноеПоле толстого клиента, не ТаблицаФормы управляемой формы.
Где и как запускать
Модуль новой обычной формы внешней обработки. Только толстый клиент, обычные формы; не серверный модуль и не управляемая форма.
Подготовка
Для будущего ручного запуска создайте НОВУЮ пустую учебную базу 8.5.1.1343 с именем конфигурации УчебнаяФиксацияСтрок85, без бизнес-объектов, расширений, подписок и регламентных заданий. Используйте толстый клиент в режиме обычного приложения. Не применяйте код к формам рабочей УТ10.3, КА, УНФ или БП. Здесь ни база, ни форма не создавались, код не выполнялся.
Создайте общий модуль УчебныеСтроки85: Клиент (обычное приложение)=Да, Сервер=Нет, Глобальный=Нет, Вызов сервера=Нет. Полный отдельный модуль проверки стенда приведён ниже. Он проверяет собственную пустую конфигурацию до создания учебных строк.
Создайте свою внешнюю обработку с обычной формой, не управляемой. В её реквизитах добавьте Товары типа ТаблицаЗначений. В редакторе разместите табличное поле ТаблицаТоваров, свойство Данные=Товары. Состав колонок создаётся из кода только для этого нового поля.
Добавьте обычные кнопки Закрепить, РазрешитьПерестановку, УчебнаяКоманда. Назначьте одноимённые действия. Событие ПриОткрытии формы свяжите с процедурой ПриОткрытии. Полный основной код вставьте на верхний уровень модуля формы и проверьте F7.
Для будущего визуального опыта обеспечьте небольшую высоту поля и стандартные команды перемещения/упорядочивания строк этого собственного элемента. Не редактируйте данные до сверки. Для восстановления исходного набора заново откройте только свою учебную обработку; рабочие формы не трогайте.
Процедура ПриОткрытии()
УчебныеСтроки85.ПроверитьСвойПустойСтенд();
Товары = Новый ТаблицаЗначений;
Товары.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
Товары.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
Товары.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
Товары.Колонки.Добавить("Выбран", Новый ОписаниеТипов("Булево"));
Книга = Товары.Добавить();
Книга.Код = "A-01";
Книга.Наименование = "Книга";
Книга.Количество = 3;
Книга.Выбран = Ложь;
Ручка = Товары.Добавить();
Ручка.Код = "B-02";
Ручка.Наименование = "Ручка";
Ручка.Количество = 1;
Ручка.Выбран = Ложь;
Таблица = ЭтаФорма.ЭлементыФормы.ТаблицаТоваров;
Таблица.СоздатьКолонки();
Таблица.АвтоВводНовойСтроки = Ложь;
Если Товары.Количество() <> 2 Тогда
ВызватьИсключение "Ожидались два собственных учебных товара";
КонецЕсли;
Таблица.ТекущаяСтрока = Товары[0];
Для Номер = 1 По 20 Цикл
Позиция = Товары.Добавить();
Позиция.Код = "P-" + Строка(Номер);
Позиция.Наименование = "Учебная позиция " + Строка(Номер);
Позиция.Количество = Номер;
Позиция.Выбран = Ложь;
КонецЦикла;
СуммаДоИтога = Товары.Итог("Количество");
Если СуммаДоИтога <> 214 Тогда
ВызватьИсключение "Ожидался итог собственных количеств 214";
КонецЕсли;
Итого = Товары.Добавить();
Итого.Код = "TOTAL";
Итого.Наименование = "Итого";
Итого.Количество = СуммаДоИтога;
Итого.Выбран = Ложь;
Таблица.ТолькоПросмотр = Ложь;
Таблица.ИзменятьСоставСтрок = Ложь;
Таблица.Шапка = Истина;
ПрименитьПрофиль(Ложь, 1, 1);
ПроверитьПрофиль(Ложь, 1, 1);
КонецПроцедуры
Процедура УчебнаяКоманда(Кнопка)
Таблица = ЭтаФорма.ЭлементыФормы.ТаблицаТоваров;
ПроверитьСвоиДанные();
Снимок = Новый Структура("ИзменятьПорядокСтрок,ФиксацияСверху,ФиксацияСнизу",
Таблица.ИзменятьПорядокСтрок, Таблица.ФиксацияСверху, Таблица.ФиксацияСнизу);
Попытка
ПрименитьПрофиль(Ложь, 1, 1);
ПроверитьПрофиль(Ложь, 1, 1);
ПрименитьПрофиль(Истина, 0, 0);
ПроверитьПрофиль(Истина, 0, 0);
Исключение
ПрименитьПрофиль(Снимок.ИзменятьПорядокСтрок, Снимок.ФиксацияСверху, Снимок.ФиксацияСнизу);
ПроверитьПрофиль(Снимок.ИзменятьПорядокСтрок, Снимок.ФиксацияСверху, Снимок.ФиксацияСнизу);
ВызватьИсключение;
КонецПопытки;
ПрименитьПрофиль(Снимок.ИзменятьПорядокСтрок, Снимок.ФиксацияСверху, Снимок.ФиксацияСнизу);
ПроверитьПрофиль(Снимок.ИзменятьПорядокСтрок, Снимок.ФиксацияСверху, Снимок.ФиксацияСнизу);
Сообщить("Два профиля проверены; восстановлены три свойства своей таблицы");
КонецПроцедуры
Процедура Закрепить(Кнопка)
ПрименитьПрофиль(Ложь, 1, 1);
ПроверитьПрофиль(Ложь, 1, 1);
КонецПроцедуры
Процедура РазрешитьПерестановку(Кнопка)
ПрименитьПрофиль(Истина, 0, 0);
ПроверитьПрофиль(Истина, 0, 0);
КонецПроцедуры
Процедура ПроверитьСвоиДанные()
УчебныеСтроки85.ПроверитьСвойПустойСтенд();
Если ТипЗнч(Товары) <> Тип("ТаблицаЗначений") Или Товары.Количество() <> 23 Тогда
ВызватьИсключение "Нужны 23 строки собственного учебного набора";
КонецЕсли;
ПроверитьСтроку(Товары[0], "A-01", "Книга", 3);
ПроверитьСтроку(Товары[1], "B-02", "Ручка", 1);
Для Номер = 1 По 20 Цикл
ПроверитьСтроку(Товары[Номер + 1], "P-" + Строка(Номер), "Учебная позиция " + Строка(Номер), Номер);
КонецЦикла;
ПроверитьСтроку(Товары[22], "TOTAL", "Итого", 214);
КонецПроцедуры
Процедура ПроверитьСтроку(Строка, Код, Наименование, Количество)
Если Строка.Код <> Код Или Строка.Наименование <> Наименование
Или Строка.Количество <> Количество Или Строка.Выбран <> Ложь Тогда
ВызватьИсключение "Изменились данные или порядок собственных строк; заново откройте учебную обработку";
КонецЕсли;
КонецПроцедуры
Процедура ПрименитьПрофиль(Перестановка, Сверху, Снизу)
ПроверитьСвоиДанные();
Таблица = ЭтаФорма.ЭлементыФормы.ТаблицаТоваров;
Таблица.ИзменятьПорядокСтрок = Перестановка;
Таблица.ФиксацияСверху = Сверху;
Таблица.ФиксацияСнизу = Снизу;
КонецПроцедуры
Процедура ПроверитьПрофиль(Перестановка, Сверху, Снизу)
ПроверитьСвоиДанные();
Таблица = ЭтаФорма.ЭлементыФормы.ТаблицаТоваров;
Если ТипЗнч(Таблица.ИзменятьПорядокСтрок) <> Тип("Булево")
Или ТипЗнч(Таблица.ФиксацияСверху) <> Тип("Число") Или ТипЗнч(Таблица.ФиксацияСнизу) <> Тип("Число")
Или Таблица.ИзменятьПорядокСтрок <> Перестановка
Или Таблица.ФиксацияСверху <> Сверху Или Таблица.ФиксацияСнизу <> Снизу Тогда
ВызватьИсключение "Не совпал профиль закрепления собственных строк";
КонецЕсли;
КонецПроцедурыУчебныеСтроки85
Своя пустая конфигурация УчебнаяФиксацияСтрок85 → Общие → Общие модули → УчебныеСтроки85
Полный общий модуль: Клиент (обычное приложение)=Да, Сервер=Нет. Вызывается из обычной формы толстого клиента; не выполнялся.
Процедура ПроверитьСвойПустойСтенд() Экспорт
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыРазбор по шагам
ПриОткрытии создаёт собственную таблицу значений: Книга/3, Ручка/1 и 20 учебных позиций с количествами 1..20. Сумма 3+1+210=214 вычисляется до добавления строки Итого. После добавления итога в таблице ровно 23 строки.
Таблица связана с реквизитом Товары через свойство Данные в редакторе обычной формы. Расширение табличного поля появляется из типа этого источника; Новый Расширение не нужен.
ФиксацияСверху=1 закрепляет первую строку данных — Книгу, а не шапку с названиями колонок. ФиксацияСнизу=1 закрепляет последнюю строку Итого/214. При вертикальной прокрутке средние 21 строка должны прокручиваться отдельно; это ожидаемое поведение для будущего ручного теста.
ИзменятьПорядокСтрок=Ложь запрещает изменение упорядочивания своего источника. Кнопка РазрешитьПерестановку снимает оба закрепления и ставит Истина. Это не то же самое, что ИзменятьСоставСтрок: добавление и удаление интерактивно отключены отдельно.
УчебнаяКоманда снимает три текущих значения, применяет закреплённый и свободный профили, затем восстанавливает исходный. Восстановление предусмотрено и при исключении. Перед применением и сравнением проверяются все 23 собственные строки, а не только их количество.
Свойства относятся только к толстому клиенту и обычной форме. Ни директивы НаСервере, ни коллекция Элементы управляемой формы здесь не используются. СоздатьКолонки действует только на собственное поле этой новой обработки.
Как проверить результат
В будущем ручном запуске: 23 строки, первой идёт Книга/3, второй Ручка/1, затем позиции 1..20, последней Итого/214. Сначала нажмите Закрепить и уменьшите высоту поля, чтобы появилась вертикальная прокрутка; проверьте закрепление крайних строк визуально.
Нажмите РазрешитьПерестановку: свойства должны стать Истина/0/0. До ручной перестановки нажмите УчебнаяКоманда: после цикла остаётся Истина/0/0. Из закреплённого профиля цикл должен вернуть Ложь/1/1.
Разрешение изменения порядка проверяется отдельно от сортировки данных и внешнего вида кнопок. Для интерактивного опыта подготовьте стандартные команды перемещения/упорядочивания собственного поля. Если вы вручную изменили порядок, последующие команды сверки должны отказаться от работы; снова откройте только свою обработку, чтобы получить исходный набор.
Отрицательная проверка на копии модуля: после первой строки ПрименитьПрофиль(Ложь, 1, 1) в УчебнаяКоманда, до ПроверитьПрофиль, вставьте Таблица.ФиксацияСнизу = 0;. Должно возникнуть исключение сравнения, после которого восстанавливается исходный профиль. Не меняйте ожидание и код восстановления.
Не редактируйте количества и не воспринимайте сумму всех 23 строк как итог продаж: Товары.Итог("Количество") после добавления Итого даст 428, потому что итоговая строка тоже входит в источник. В уроке 214 вычисляется до её добавления.
Ожидаемый результат
Подготовлен полный модуль обычной формы с 23 собственными строками и двумя профилями закрепления. Ожидается сохранение данных и восстановление трёх свойств поля. Код, прокрутка и команды перемещения в 1С здесь не запускались: runtimeVerifiedScenarios=0.
На что обратить внимание
ФиксацияСверху и ФиксацияСнизу — количества строк, не объекты строк, не ссылки и не числа колонок. Здесь используются только 0 и 1, без перекрытия закреплённых областей.
Закрепление относится к позициям, а не к коду товара. При перестановке или сортировке первой и последней могут стать другие строки; поэтому учебная сверка фиксирует исходный порядок.
ТолькоПросмотр=Ложь нужно для отдельного опыта с изменением порядка. Это не разрешение писать бизнес-данные; всё находится в памяти собственной внешней обработки. Данные и порядок перед проверками не редактируйте.
Обычная и управляемая формы используют разные элементы и события. Нельзя перенести свойства расширения обычного ТабличноеПоле в ТаблицаФормы и считать интерфейс проверенным.
Сверка присвоенных значений не доказывает фактическое закрепление при прокрутке; оно требует отдельного ручного теста.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.