Полный тест своей текстовой R2C1: ввод Учебная книга принимается, ввод Не сохранять отменяется, затем своя таблица полностью восстанавливается кнопкой сброса.
Где и как запускать
Полный отдельный модуль формы менеджера тестирования собственного тонкого клиента и два полных supporting-модуля для создания/открытия своей таблицы. В1С не запускался.
Подготовка
НОВАЯ пустая отдельная конфигурация УчебнаяПравкаТаблицы85 на8.5.1.1343, совместимость Не использовать, Русский, интерфейс Такси. Нет рабочих справочников, документов, регистров, общих реквизитов, расширений, подписок и заданий. Только свои формы/команда этого урока; модули вручную пустые до вставки приведённого кода.
Конфигуратор → Общие формы → УчебнаяТаблицаТест85: реквизит МеткаСеанса Строка100, одиночное поле ввода МеткаСеанса с тем же путём и ТолькоПросмотр=Да; реквизит УчебныйДокумент типа ТабличныйДокумент, поле УчебнаяТаблица85 вида ПолеТабличногоДокумента с ПутьКДанным=УчебныйДокумент. Вставьте весь модуль fixture ниже; событие ПриСозданииНаСервере назначьте одноимённой процедуре.
Общая команда ОткрытьУчебнуюТаблицу85: модуль ниже полностью открывает ОбщаяФорма.УчебнаяТаблицаТест85. Включите команду в интерфейс своей подсистемы УчебныеТесты85. Не создавайте похожую команду для рабочего отчёта. Будущая ручная подготовка: сохранить конфигурацию, обновить базу F7.
Будущий ручной запуск ТОЛЬКО собственного стенда: первый отдельный тонкий клиент /TESTCLIENT -TPort15384, второй /TESTMANAGER. Собственный localhost-порт15384 заранее свободен и выделен только этому уроку; если выбран другой собственный порт, одинаково измените ручной ключ и конструктор. Здесь клиенты, порт и сетевое соединение не запускались.
В своём /TESTCLIENT откройте ровно одну собственную форму общей командой. Скопируйте реально показанный МеткаСеанса UUID. В таблице обычным щелчком выберите только R2C1, ячейку Книга; не выделяйте диапазон или объединённый заголовок.
Своя внешняя обработка УчебныйМенеджерТаблицы85 → новая управляемая Форма в /TESTMANAGER: реквизиты Согласие Булево, МеткаСеанса Строка100, Итог Строка1000. Видимые поля с этими путями, Итог ТолькоПросмотр=Да. Команда/кнопка ВыполнитьСвойТест, действие ВыполнитьСвойТест; ПриОткрытии назначьте одноимённой процедуре. Вставьте весь основной модуль, вставьте настоящую скопированную метку и подтвердите Согласие только своему тесту.
Для этого урока используйте ТОЛЬКО полный fixture ниже: он делает Документ.ТолькоПросмотр=Ложь и Редактирование=Истина, но Вывод остаётся Запретить. Не переносите запрет редактирования из предыдущего урока.
В общей форме УчебнаяТаблицаТест85 создайте собственную команду СброситьСвоиДанные85, действие СброситьСвоиДанные85, кнопку с внутренним именем СброситьСвоиДанные85 вне табличного поля. Весь обработчик и серверный сброс приведены в fixture; UUID при сбросе не меняется.
В менеджере остаются Согласие/МеткаСеанса/Итог и команда ВыполнитьСвойТест. Здесь Согласие разрешает только правку текста в памяти собственной таблицы и её восстановление; не запись базы, файла или печать. До запуска вручную выберите одиночную R2C1.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Согласие = Ложь;
МеткаСеанса = "";
Итог = "Сначала подготовьте свою таблицу и выберите только R2C1";
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвойСтенд()
Если Не Согласие Тогда
ВызватьИсключение "Разрешите только правку собственной таблицы в памяти и её сброс без файлов, печати и записи базы";
КонецЕсли;
UUIDМетки = Новый УникальныйИдентификатор(МеткаСеанса);
Если Строка(UUIDМетки) <> МеткаСеанса Тогда
ВызватьИсключение "Скопируйте фактическую метку своего открытого клиента тестирования";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция НайтиСвоюТаблицу(Приложение)
Заголовок = "Учебная таблица85 " + МеткаСеанса;
Формы = Приложение.НайтиОбъекты(Тип("ТестируемаяФорма"), Заголовок, , 10);
Если ТипЗнч(Формы) <> Тип("ФиксированныйМассив") Или Формы.Количество() <> 1 Тогда
ВызватьИсключение "Должна быть одна фактически открытая собственная форма";
КонецЕсли;
Форма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), Заголовок, , 10);
Метка = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , "МеткаСеанса", 10);
Если Метка.ПолучитьПредставлениеДанных() <> МеткаСеанса Тогда
ВызватьИсключение "Не подтверждена настоящая метка собственной таблицы";
КонецЕсли;
Поле = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , "УчебнаяТаблица85", 10);
Если ТипЗнч(Поле) <> Тип("ТестируемоеПолеФормы") Или Поле.Имя <> "УчебнаяТаблица85"
Или Поле.Вид <> ВидПоляФормы.ПолеТабличногоДокумента Тогда
ВызватьИсключение "Нужно своё поле именно вида ПолеТабличногоДокумента";
КонецЕсли;
Если Не Поле.ТекущаяВидимость() Или Не Поле.ТекущаяДоступность() Тогда
ВызватьИсключение "Собственное поле должно быть видимым и доступным для выбора ячейки";
КонецЕсли;
Возврат Поле;
КонецФункции
&НаКлиенте
Процедура ПроверитьСвоюМатрицу(Поле, ИмяКниги = "Книга")
Если Поле.ПолучитьРазмерОбластиДанныхДокументаПоВертикали() <> 3
Или Поле.ПолучитьРазмерОбластиДанныхДокументаПоГоризонтали() <> 2 Тогда
ВызватьИсключение "Свой документ должен иметь последние данные в строке3 и колонке2";
КонецЕсли;
Если Поле.ПолучитьТекстОбласти("R1C1") <> "Учебная таблица85"
Или Поле.ПолучитьТекстОбласти("R2C1") <> ИмяКниги
Или Поле.ПолучитьТекстОбласти("R2C2") <> "3"
Или Поле.ПолучитьТекстОбласти("R3C1") <> "Ручка"
Или Поле.ПолучитьТекстОбласти("R3C2") <> "1" Тогда
ВызватьИсключение "Все пять текстов собственной таблицы должны совпасть полностью";
КонецЕсли;
Объединение = Поле.ВходитВОбъединеннуюОбласть("R1C1");
Если ТипЗнч(Объединение) <> Тип("Строка") Или Объединение <> "R1C1:R1C2" Тогда
ВызватьИсключение "Заголовок должен входить именно в собственную объединённую область";
КонецЕсли;
Если Поле.ВходитВОбъединеннуюОбласть("R2C1") <> Неопределено Тогда
ВызватьИсключение "Ячейка Книга не должна быть объединена";
КонецЕсли;
Если Поле.ТекущийРежимРедактирование() Тогда
ВызватьИсключение "Не начинайте редактировать собственную таблицу этого урока";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьСвойТест(Команда)
ПроверитьСвойСтенд();
Приложение = Новый ТестируемоеПриложение("127.0.0.1", 15384);
Поле = Неопределено;
ИсходныйЛимит = Неопределено;
СвояОбластьПодтверждена = Ложь;
Сброс = Неопределено;
Ошибка = "";
Итог = "Проверка ещё не завершена";
Попытка
Приложение.УстановитьСоединение();
ИсходныйЛимит = Приложение.ПолучитьМаксимальноеВремяВыполненияДействия();
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(10);
Поле = НайтиСвоюТаблицу(Приложение);
ПроверитьСвоюМатрицу(Поле);
Если Поле.ПолучитьАдресТекущейОбласти() <> "R2C1" Тогда
ВызватьИсключение "До старта вручную выберите одну собственную ячейку Книга, R2C1";
КонецЕсли;
СвояОбластьПодтверждена = Истина;
СвояФорма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), "Учебная таблица85 " + МеткаСеанса, , 10);
Сброс = СвояФорма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "СброситьСвоиДанные85", 10);
Если ТипЗнч(Сброс) <> Тип("ТестируемаяКнопкаФормы") Или Сброс.Имя <> "СброситьСвоиДанные85"
Или Не Сброс.ТекущаяДоступность() Тогда
ВызватьИсключение "Нужна своя заранее подготовленная кнопка сброса";
КонецЕсли;
Поле.НачатьРедактированиеТекущейОбласти();
Если Не Поле.ТекущийРежимРедактирование() Тогда
ВызватьИсключение "Не началось редактирование только своей R2C1";
КонецЕсли;
Редактор = Поле.ПолучитьПолеТекущейОбласти();
Если ТипЗнч(Редактор) <> Тип("ТестируемоеПолеФормы")
Или Редактор.Вид <> ВидПоляФормы.ПолеВвода
Или Не Редактор.ТекущаяВидимость() Или Не Редактор.ТекущаяДоступность() Тогда
ВызватьИсключение "Нужен настоящий редактор своей текущей текстовой ячейки";
КонецЕсли;
Редактор.ВвестиТекст("Учебная книга");
Поле.ЗакончитьРедактированиеТекущейОбласти(Ложь);
Если Поле.ТекущийРежимРедактирование() Тогда
ВызватьИсключение "Приём изменений должен завершить режим редактирования";
КонецЕсли;
ПроверитьСвоюМатрицу(Поле, "Учебная книга");
Поле.НачатьРедактированиеТекущейОбласти();
РедакторОтмены = Поле.ПолучитьПолеТекущейОбласти();
Если ТипЗнч(РедакторОтмены) <> Тип("ТестируемоеПолеФормы") Или РедакторОтмены.Вид <> ВидПоляФормы.ПолеВвода Тогда
ВызватьИсключение "Второе изменение должно идти через настоящий редактор той же собственной ячейки";
КонецЕсли;
РедакторОтмены.ВвестиТекст("Не сохранять");
Поле.ЗакончитьРедактированиеТекущейОбласти(Истина);
Если Поле.ТекущийРежимРедактирование() Тогда
ВызватьИсключение "Отмена должна завершить режим редактирования";
КонецЕсли;
ПроверитьСвоюМатрицу(Поле, "Учебная книга");
Исключение
Ошибка = ОписаниеОшибки();
КонецПопытки;
Если СвояОбластьПодтверждена Тогда
Попытка
Если Поле.ТекущийРежимРедактирование() Тогда
Поле.ЗакончитьРедактированиеТекущейОбласти(Истина);
КонецЕсли;
Если Сброс <> Неопределено Тогда
Сброс.Нажать();
КонецЕсли;
Поле.УстановитьТекущуюОбласть("R2C1");
Если Поле.ПолучитьАдресТекущейОбласти() <> "R2C1" Тогда
ВызватьИсключение "Не восстановлена подтверждённая исходная ячейка";
КонецЕсли;
ПроверитьСвоюМатрицу(Поле);
Исключение
Ошибка = Ошибка + " Восстановление собственной области: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ТипЗнч(ИсходныйЛимит) = Тип("Число") Тогда
Попытка
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(ИсходныйЛимит);
Исключение
Ошибка = Ошибка + " Восстановление фактического лимита: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Попытка
Приложение.РазорватьСоединение();
Исключение
Ошибка = Ошибка + " Разрыв собственного соединения: " + ОписаниеОшибки();
КонецПопытки;
Если Ошибка <> "" Тогда
Итог = "Свой тест не завершён: " + Ошибка;
ВызватьИсключение Итог;
КонецЕсли;
Итог = "Приём и отмена своей правки проверены; исходная таблица, R2C1 и фактический лимит восстановлены; своё соединение разорвано";
КонецПроцедурыУчебнаяТаблицаТест85
Конфигуратор → Общие формы → УчебнаяТаблицаТест85 → Модуль
Полный самостоятельный модуль управляемой общей формы: создание собственной таблицы на сервере; не выполнялся.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПроверитьСвойПустойСтенд();
МеткаСеанса = Строка(Новый УникальныйИдентификатор);
ЭтотОбъект.АвтоЗаголовок = Ложь;
ЭтотОбъект.Заголовок = "Учебная таблица85 " + МеткаСеанса;
СоздатьСвоюТаблицуНаСервере();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СоздатьСвоюТаблицуНаСервере()
ПроверитьСвойПустойСтенд();
Документ = Новый ТабличныйДокумент;
Заголовок = Документ.Область(1, 1, 1, 2);
Заголовок.Объединить();
Заголовок.Текст = "Учебная таблица85";
Документ.Область(2, 1).Текст = "Книга";
Документ.Область(2, 2).Текст = "3";
Документ.Область(3, 1).Текст = "Ручка";
Документ.Область(3, 2).Текст = "1";
Документ.Область(1, 1, 3, 2).ШиринаКолонки = 30;
Документ.ТолькоПросмотр = Ложь;
УчебныйДокумент = Документ;
Элементы.УчебнаяТаблица85.Редактирование = Истина;
Элементы.УчебнаяТаблица85.Вывод = ИспользованиеВывода.Запретить;
Элементы.УчебнаяТаблица85.РазрешитьНачалоПеретаскивания = Ложь;
Элементы.УчебнаяТаблица85.РазрешитьПеретаскивание = Ложь;
КонецПроцедуры
&НаКлиенте
Процедура СброситьСвоиДанные85(Команда)
СоздатьСвоюТаблицуНаСервере();
КонецПроцедурыОткрытьУчебнуюТаблицу85
Конфигуратор → Общие команды → ОткрытьУчебнуюТаблицу85 → Модуль
Полный модуль собственной общей команды с ОбработкаКоманды; не выполнялся.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ОткрытьФорму("ОбщаяФорма.УчебнаяТаблицаТест85");
КонецПроцедурыРазбор по шагам
Источник — реальная собственная таблица3×2 с подтверждённым UUID и всеми пятью исходными текстами. При неподготовленной матрице изменения не начинаются.
НачатьРедактированиеТекущейОбласти работает над выбранной R2C1. ТекущийРежимРедактирование подтверждает настоящий режим, после чего ПолучитьПолеТекущейОбласти отдаёт отдельный ТестируемоеПолеФормы — редактор ячейки, не сам табличный документ.
У редактора проверяются реальный тип, вид ПолеВвода, видимость и доступность. ВвестиТекст вводит Учебная книга; ЗакончитьРедактированиеТекущейОбласти(Ложь) принимает изменение. Полная матрица проверяется с новой Книгой и прежними остальными четырьмя текстами.
Во второй попытке вводится Не сохранять, но ЗакончитьРедактированиеТекущейОбласти(Истина) отменяет только эту правку. В матрице остаётся ранее принятая Учебная книга, не исходная Книга и не Не сохранять.
На завершении при необходимости отменяется незаконченная правка, затем собственная кнопка заново строит исходную таблицу в памяти. Проверяются исходная R2C1 и все пять первоначальных текстов; фактический лимит и своё соединение восстанавливаются отдельно.
Как проверить результат
Будущий результат: после приёма R2C1=Учебная книга, после отмены второго ввода R2C1 по-прежнему Учебная книга. После собственного сброса R2C1=Книга и остальные данные/объединение восстановлены.
Будущий отрицательный контроль: в fixture временно установите Редактирование=Ложь и откройте новый собственный клиент/форму с новым UUID. Код не должен заявить успешный ввод. Верните полный fixture после опыта.
Проверьте сообщения ошибки, если свой редактор не появился. Не подменяйте его случайным полем формы или колонкой другой таблицы ради продолжения.
Ожидаемый результат
Приём и отмена своей правки проверены; исходная таблица, R2C1 и фактический лимит восстановлены; своё соединение разорвано
На что обратить внимание
runtimeVerifiedScenarios=0: BSL, UI, клиенты тестирования, соединения, файлы и печать здесь не запускались. Это полные исходники для будущего ручного опыта только на своём стенде.
Нужен новый отдельный /TESTCLIENT только этого урока, не рабочая конфигурация и не общий тестовый клиент. Настоящий UUID копируется из своей формы; ни похожие имена, ни новый выдуманный UUID не заменяют подтверждение источника.
У разных уроков одинаковые имена модулей/форм/процедур, но разные точные имена конфигураций. Каждый урок готовится отдельно; модули не склеивать.
Имя встроенного редактора может генерироваться платформой. Здесь не выдумывается его внутреннее имя: объект получается исключительно из своего текущего поля и проверяется по реальному типу/виду.
Отмена текущей правки не откатывает ранее принятое изменение. Собственный полный сброс — отдельное действие, не транзакция базы.
Таблица содержит текст, а не ссылки/числовые ячейки. Для числовых типов, формата, редактирования многострочных областей и рабочих печатных форм нужны отдельные условия.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.