Тип: Булево. Содержит признак того, что табличный документ открыт в режиме просмотра. В режиме просмотра в таблице не доступны для редактирования ячейки и рисунки, у которых установлено свойство Защита. Истина - режим просмотра.
Полное описание, параметры и ограничения
ТабличныйДокумент.ТолькоПросмотр (SpreadsheetDocument.ReadOnly)
ТабличныйДокумент (SpreadsheetDocument)
ТолькоПросмотр (ReadOnly)
Доступен, начиная с версии 8.0.
Использование:
Чтение и запись.
Описание:
Тип: Булево.
Содержит признак того, что табличный документ открыт в режиме просмотра. В режиме просмотра в таблице не доступны для редактирования ячейки и рисунки, у которых установлено свойство Защита.
Истина - режим просмотра.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
Примечание:
Если табличный документ расположен на форме, то у него могут возникать события Выбор и ОбработкаРасшифровки только в режиме просмотра.
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
Свой ordinary просмотрщик120×8: прокрутка, защищенные960 чисел, выбор ячейки, блокировка и точное восстановление оформления
Реальный own spreadsheet-field из подготовленной ordinary формы, а не getter wrapper/managed alias. Самостоятельная рассчитанная матрица читается и проверяется целиком; восемь actual исходных свойств сохраняются typed copies, режимы меняются только при exact expected-own-state и восстанавливаются без blind rollback после ошибок.
Где и как запускать
MAIN FORM только модуль own ordinary общей формы Просмотр85 новой пустой CF УчебныйПросмотрТабДок85. Windows thick ОбычноеПриложение/FileIB/currentownuser. Native actual ПолеТабличногоДокумента catalog56 from Form.Controls, не managedalias. APPLICATION отдельно ordinary application module.
Подготовка
Только отдельная собственная Windows VM, платформа8.5.1.1343, толстый клиент в режиме ОбычноеПриложение. Native ПолеТабличногоДокумента catalog56 является visual ТабличныйДокумент со свойствами/методами последнего. Managed ПолеФормы/форма клиента не подменяют этот native type.
Вручную создайте canonical nonzero UUID-marker и новую пустую FileIB C:\1c-labs\Уч85Просмотр_<UUID>\ИБ\; connection строго File="C:\1c-labs\Уч85Просмотр_<UUID>\ИБ\";. Конфигурация УчебныйПросмотрТабДок85, один actual IBUser Уч85Просмотр_<UUID> с собственными правами/чтением списка пользователей, без privileged mode.
Marker каталога/actualuser имени не UUID ИБ или UUID реального пользователя. Native currentuser UUID сверяется с единственным actual пользователем; реальный UUID самой базы не измеряется. Не рабочая/типовая база, другой пользователь или чужой просмотрщик.
Собственная CF пуста: нет справочников/документов/регистров/общих реквизитов/разделителей/ботов/констант/подписок/заданий/внешних данных/расширений. Создайте только ordinary общую форму Просмотр85. Runtime работает только с новым собственным TabDoc в памяти, без DBread/write.
Конфигуратор → Общие → Общие формы → Просмотр85: Обычная форма. Реквизиты: МеткаОпыта Строка36; Согласен85 Булево; Результат85 ТабличныйДокумент; Состояние85 Строка500. Флажок связан с Согласен85, readonly текстовое поле/надпись статуса — с Состояние85. Marker/False consent назначаются own app перед открытием.
Разместите собственное ПолеТабличногоДокумента Уч85Просмотр, Данные=Результат85. Окно/поле должно быть меньше полного содержимого121строка×8колонок для ручной проверки вертикальной/горизонтальной прокрутки; остальные кнопки/согласие/статус размещайте ВНЕ этого поля, чтобы блокировка не отключила их.
Три ordinary кнопки: Подготовить85, Блокировка85, Восстановить85. В свойствах → События → Нажатие явно назначьте соответственно ПодготовитьПросмотр85, ПереключитьДоступность85, ВосстановитьОформление85. Native Button.Нажатие() плюс ordinary form extension firstЭлемент дают handler(Элемент), не managed Команда и не zeroarg handler.
У Уч85Просмотр в свойствах → События → Выбор назначьте Уч85ПросмотрВыбор. Base native Выбор(Область,СтандартнаяОбработка) плюс ordinary form extension firstЭлемент дают ровно3args. Событие вызывается двойным щелчком/Enter; не вручную для имитации UI proof. Область от native события связана с actual initiating своим field.
Вставьте FORM целиком исключительно в модуль этой own ordinary общей формы. Readonly ЭтаФорма.ЭлементыФормы.Найти дает actual own field; проверяется native type/точный Data. Нет Новый ПолеТабличногоДокумента/неизвестного входного объекта или присваивания readonly коллекции.
В обычный модуль приложения своей CF вставьте APPLICATION полностью: real native OnStart0 получает marker из имени настоящего currentuser, выполняет полный guard и native GetCommonForm fresh UUIDkey, назначает own marker/False consent и открывает. Button/Selection события вручную не вызываются.
Вручную проверьте исходники конфигуратором и запустите только эту собственную ИБ actual пользователем. Автор не создавал/компилировал CF/формы и не запускал1С/UI/файлы/БД/сеть/печать. Подтвердите Согласен85 и нажмите Подготовить85 один раз. После ошибки закрывайте только этот свой экземпляр вручную, не делайте blind recovery.
Своя numeric матрица содержит header row1 и data rows2..121, колонки1..8, значения(row-1)*column. Есть960 числовых cells. Все header/data области защищены Защита=True и ТабДок.ТолькоПросмотр=True. OnlyView само по себе не абсолютный запрет: native документация ограничивает редактирование именно защищенных cells/рисунков. Это UI protection, не security boundary.
Перед каждым viewer setter процесс заново проверяет same actual field/data binding, обе shape121×8 и OnlyView, все8header/protection и все960actual field/object numeric/protected cells. Сумма читается из фактических cells:261360=120*121/2 *8*9/2. Формула проверяет, но не подставляет источник вместо испорченного cell.
Baseline восьми native getter values снимается после своего создания/проверки данных, но ДО изменения viewer props. Scrollbars/Enabled/DND — Boolean, ShowSelection — ТипОтображенияВыделенияТабличногоДокумента, Border/Color — реальные типы Рамка/Цвет. Значения по умолчанию/стиля не угадываются.
Frame/Color baseline копируются native XDTO через string-only writer/reader с explicit type, exact typed roundtrip и signature сравнение. Это только свои два допустимых UI value types из getter/own constructor; не user XML/файл/schema/объект данных. Style/auto сохранены, не превращены в guessed RGB. Deprecated ValueToStringInternal не используется.
Подготовленный desired plan строится ДО setters: обе scrollbar=True, enabled=True, selection Всегда, оба DND=False, double рамка толщиной2logicalunits и абсолютный RGB30/72/102. Цвет рамки native игнорируется у Выпуклая/Вдавленная, поэтому здесь Двойная. Border thickness logical units не миллиметры previous overlay урока.
State gating сравнивает все8current props с последним exact ожидаемым своим состоянием. НеЗавершено=True ставится до первого setter; только full desired readback и повторная data проверка позволяют записать новый expected state/снять флаг. Если setter/roundtrip/readback неудачен, flag остается, дальнейшие команды/rollback запрещены; нельзя объявить любой current afterstate своим.
Прокрутите только свой бланк по обеим осям. Двойной щелчок одной numeric cell, например row121/col8, должен показать actual960 в Состояние85; row2/col1 —1. Header/multi-cell/вне диапазона не считают numeric selection; проверки firstElement/area bounds/ContainsValue/Number/ownfield readback не заменяются подписью.
Блокировка85 переключает только own desired Enabled, при fullsamefield/fullgrid/currentstate guard. False запрещает доступ к полю и его controls по native контракту, а buttons вне поля остаются доступны. Повторная команда вернетTrue. Данные/checksum/Frame/Color/scroll/selection/DND сохраняются exact desired state.
Восстановить85 возвращает именно реальные baseline8props, включая исходные style/auto/Boolean/enum, только после exact expected-own-state. Не reset-to-known-defaults и не автоматический rollback по Exception. Если свой current state изменен извне, данные испорчены или flagfailed — отказ, никакого blind overwrite.
После successful restoration новые setters этого экземпляра запрещены; закрывайте свою форму вручную. Baseline DND/Enabled могут иметь другие значения: они возвращены как параметры, но protected свой data остаются. DND flags/UI protection не абсолютная sandbox/data security и не подтвержденная печать/экспорт/визуальная pixel correctness.
Ручные negative проверки только на отдельном новом собственном экземпляре: без согласия — отказ; повторная подготовка — отказ; изменение header/numeric cell/protection или viewer prop вне известного состояния — отказ до новых setters. Partialfailure не чинится принудительным restore, неизвестные поля/формы/состояния не используются.
Перем НачатаПодготовка85;
Перем Подготовлено85;
Перем НеЗавершено85;
Перем Восстановлено85;
Перем СвоеПоле85;
Перем ИсходноеСостояние85;
Перем ОжидаемоеСостояние85;
Процедура ПодготовитьПросмотр85(Элемент)
ПроверитьСвоюКнопку85(Элемент, "Подготовить85");
Если НачатаПодготовка85 = Истина Тогда
ВызватьИсключение "Подготовка одноразовая. Ошибка/частичный setter не разрешают повторную подготовку или автоматический rollback";
КонецЕсли;
СвоеПоле85 = ЭтаФорма.ЭлементыФормы.Найти("Уч85Просмотр");
Если СвоеПоле85 = Неопределено Или ТипЗнч(СвоеПоле85) <> Тип("ПолеТабличногоДокумента") Или СвоеПоле85.Данные <> "Результат85" Тогда
ВызватьИсключение "Нужно actual own prepared spreadsheet field с Data=Результат85, не managed alias";
КонецЕсли;
НачатаПодготовка85 = Истина;
НеЗавершено85 = Истина;
Результат85 = Новый ТабличныйДокумент;
Для Колонка = 1 По 8 Цикл
Результат85.Область(1, Колонка).Текст = "Колонка" + Строка(Колонка);
Для СтрокаДанных = 1 По 120 Цикл
Ячейка = Результат85.Область(СтрокаДанных + 1, Колонка);
Ячейка.СодержитЗначение = Истина;
Ячейка.ТипЗначения = Новый ОписаниеТипов("Число");
Ячейка.Значение = СтрокаДанных * Колонка;
КонецЦикла;
КонецЦикла;
Результат85.Область(1, 1, 121, 8).Защита = Истина;
Результат85.ТолькоПросмотр = Истина;
ПроверитьСвоеПолеИВсюМатрицу85();
ИсходноеСостояние85 = СнятьActualПаспортСвоегоПоля85();
ОжидаемоеСостояние85 = ИсходноеСостояние85;
План = Новый Структура(ИсходноеСостояние85);
План.ВертикальнаяПолосаПрокрутки = Истина;
План.ГоризонтальнаяПолосаПрокрутки = Истина;
План.Доступность = Истина;
План.ОтображатьВыделение = ТипОтображенияВыделенияТабличногоДокумента.Всегда;
План.РазрешитьНачалоПеретаскивания = Ложь;
План.РазрешитьПеретаскивание = Ложь;
КопияРамки = КопияСвоегоОформления85(Новый Рамка(ТипРамкиЭлементаУправления.Двойная, 2));
КопияЦвета = КопияСвоегоОформления85(Новый Цвет(30, 72, 102));
План.Рамка = КопияРамки.Значение;
План.XMLРамки = КопияРамки.XML;
План.ЦветРамки = КопияЦвета.Значение;
План.XMLЦвета = КопияЦвета.XML;
Если План.Рамка.ТипРамки <> ТипРамкиЭлементаУправления.Двойная Или План.Рамка.Толщина <> 2
Или План.ЦветРамки.Красный <> 30 Или План.ЦветРамки.Зеленый <> 72 Или План.ЦветРамки.Синий <> 102 Тогда
ВызватьИсключение "Typed own absolute рамка/RGB план не подтвердился до setters";
КонецЕсли;
ПрименитьТочныйСвойПлан85(Новый ФиксированнаяСтруктура(План));
Подготовлено85 = Истина;
Восстановлено85 = Ложь;
Состояние85 = "Матрица120×8 проверена:960 чисел, сумма261360. Прокрутите, затем дважды щелкните одну числовую ячейку.";
КонецПроцедуры
Процедура ПереключитьДоступность85(Элемент)
ПроверитьСвоюКнопку85(Элемент, "Блокировка85");
ПроверитьГотовностьСвоегоПросмотра85();
План = Новый Структура(ОжидаемоеСостояние85);
План.Доступность = Не План.Доступность;
ПрименитьТочныйСвойПлан85(Новый ФиксированнаяСтруктура(План));
Состояние85 = "Доступность actual поля=" + Строка(ОжидаемоеСостояние85.Доступность) + "; own960cells/сумма сохранены. Кнопки вне поля доступны.";
КонецПроцедуры
Процедура ВосстановитьОформление85(Элемент)
ПроверитьСвоюКнопку85(Элемент, "Восстановить85");
ПроверитьГотовностьСвоегоПросмотра85();
ПрименитьТочныйСвойПлан85(ИсходноеСостояние85);
Восстановлено85 = Истина;
Состояние85 = "Все8 actual исходных свойств возвращены своей форме после expected-own-state проверки. Матрица осталась собственной/защищенной. Закройте этот учебный экземпляр вручную.";
КонецПроцедуры
Процедура Уч85ПросмотрВыбор(Элемент, Область, СтандартнаяОбработка)
ПроверитьСвойOrdinaryПросмотр85(МеткаОпыта);
СтандартнаяОбработка = Ложь;
Если Подготовлено85 <> Истина Или НеЗавершено85 = Истина Тогда
ВызватьИсключение "Частичный/неподготовленный viewer не подтверждает UI выбор";
КонецЕсли;
Если Элемент <> СвоеПоле85 Или ЭтаФорма.ЭлементыФормы.Найти("Уч85Просмотр") <> Элемент
Или ТипЗнч(Элемент) <> Тип("ПолеТабличногоДокумента") Тогда
ВызватьИсключение "Нужно actual native Selection своего field, не foreign инициатор/вручную вызванное событие";
КонецЕсли;
ПроверитьСвоеПолеИВсюМатрицу85();
ПроверитьСовпадениеСвоихСостояний85(СнятьActualПаспортСвоегоПоля85(), ОжидаемоеСостояние85);
Если ТипЗнч(Область) <> Тип("ОбластьЯчеекТабличногоДокумента") Тогда
ВызватьИсключение "Native Selection должна передать actual область, связанную с собственным событием";
КонецЕсли;
Если Область.Верх <> Область.Низ Или Область.Лево <> Область.Право
Или Область.Верх < 2 Или Область.Верх > 121 Или Область.Лево < 1 Или Область.Лево > 8 Тогда
Состояние85 = "Выберите двойным щелчком одну свою числовую ячейку: строки2..121, колонки1..8, не заголовок/область.";
Возврат;
КонецЕсли;
СвояЯчейка = СвоеПоле85.Область(Область.Верх, Область.Лево);
Если Не Область.СодержитЗначение Или Не СвояЯчейка.СодержитЗначение
Или ТипЗнч(Область.Значение) <> Тип("Число") Или ТипЗнч(СвояЯчейка.Значение) <> Тип("Число")
Или Область.Значение <> СвояЯчейка.Значение
Или СвояЯчейка.Значение <> (Область.Верх - 1) * Область.Лево Тогда
ВызватьИсключение "Actual native event area/current ownfield cell numeric readback не совпал";
КонецЕсли;
Состояние85 = "Собственный actual Selection: строка=" + Строка(Область.Верх) + "; колонка=" + Строка(Область.Лево) + "; число=" + Строка(СвояЯчейка.Значение);
КонецПроцедуры
Процедура ПрименитьТочныйСвойПлан85(План)
ПроверитьСвоеПолеИВсюМатрицу85();
ПроверитьСовпадениеСвоихСостояний85(СнятьActualПаспортСвоегоПоля85(), ОжидаемоеСостояние85);
НеЗавершено85 = Истина;
СвоеПоле85.ВертикальнаяПолосаПрокрутки = План.ВертикальнаяПолосаПрокрутки;
СвоеПоле85.ГоризонтальнаяПолосаПрокрутки = План.ГоризонтальнаяПолосаПрокрутки;
СвоеПоле85.Доступность = План.Доступность;
СвоеПоле85.ОтображатьВыделение = План.ОтображатьВыделение;
СвоеПоле85.РазрешитьНачалоПеретаскивания = План.РазрешитьНачалоПеретаскивания;
СвоеПоле85.РазрешитьПеретаскивание = План.РазрешитьПеретаскивание;
СвоеПоле85.Рамка = План.Рамка;
СвоеПоле85.ЦветРамки = План.ЦветРамки;
ПроверитьСовпадениеСвоихСостояний85(СнятьActualПаспортСвоегоПоля85(), План);
ПроверитьСвоеПолеИВсюМатрицу85();
ОжидаемоеСостояние85 = План;
НеЗавершено85 = Ложь;
КонецПроцедуры
Функция СнятьActualПаспортСвоегоПоля85()
Паспорт = Новый Структура;
Паспорт.Вставить("ВертикальнаяПолосаПрокрутки", СвоеПоле85.ВертикальнаяПолосаПрокрутки);
Паспорт.Вставить("ГоризонтальнаяПолосаПрокрутки", СвоеПоле85.ГоризонтальнаяПолосаПрокрутки);
Паспорт.Вставить("Доступность", СвоеПоле85.Доступность);
Паспорт.Вставить("ОтображатьВыделение", СвоеПоле85.ОтображатьВыделение);
Паспорт.Вставить("РазрешитьНачалоПеретаскивания", СвоеПоле85.РазрешитьНачалоПеретаскивания);
Паспорт.Вставить("РазрешитьПеретаскивание", СвоеПоле85.РазрешитьПеретаскивание);
КопияРамки = КопияСвоегоОформления85(СвоеПоле85.Рамка);
КопияЦвета = КопияСвоегоОформления85(СвоеПоле85.ЦветРамки);
Паспорт.Вставить("Рамка", КопияРамки.Значение);
Паспорт.Вставить("ЦветРамки", КопияЦвета.Значение);
Паспорт.Вставить("XMLРамки", КопияРамки.XML);
Паспорт.Вставить("XMLЦвета", КопияЦвета.XML);
Если ТипЗнч(Паспорт.ВертикальнаяПолосаПрокрутки) <> Тип("Булево") Или ТипЗнч(Паспорт.ГоризонтальнаяПолосаПрокрутки) <> Тип("Булево")
Или ТипЗнч(Паспорт.Доступность) <> Тип("Булево") Или ТипЗнч(Паспорт.РазрешитьНачалоПеретаскивания) <> Тип("Булево")
Или ТипЗнч(Паспорт.РазрешитьПеретаскивание) <> Тип("Булево")
Или ТипЗнч(Паспорт.ОтображатьВыделение) <> Тип("ТипОтображенияВыделенияТабличногоДокумента") Тогда
ВызватьИсключение "Actual8 typed getter values не соответствуют native field контрактам";
КонецЕсли;
Возврат Новый ФиксированнаяСтруктура(Паспорт);
КонецФункции
Процедура ПроверитьСовпадениеСвоихСостояний85(Actual, Ожидаемое)
Если Actual.ВертикальнаяПолосаПрокрутки <> Ожидаемое.ВертикальнаяПолосаПрокрутки
Или Actual.ГоризонтальнаяПолосаПрокрутки <> Ожидаемое.ГоризонтальнаяПолосаПрокрутки
Или Actual.Доступность <> Ожидаемое.Доступность Или Actual.ОтображатьВыделение <> Ожидаемое.ОтображатьВыделение
Или Actual.РазрешитьНачалоПеретаскивания <> Ожидаемое.РазрешитьНачалоПеретаскивания
Или Actual.РазрешитьПеретаскивание <> Ожидаемое.РазрешитьПеретаскивание
Или Actual.XMLРамки <> Ожидаемое.XMLРамки Или Actual.XMLЦвета <> Ожидаемое.XMLЦвета Тогда
ВызватьИсключение "Current exact8 ownstate не совпал с подготовленным планом. Нет blind restore/легализации partial/foreign state";
КонецЕсли;
КонецПроцедуры
Функция КопияСвоегоОформления85(Значение)
ТребуемыйТип = ТипЗнч(Значение);
Если ТребуемыйТип <> Тип("Рамка") И ТребуемыйТип <> Тип("Цвет") Тогда
ВызватьИсключение "In-memory XDTO копирование разрешено только своему actual native Frame/Color value, не объектам данных/клиентскому XML";
КонецЕсли;
XML = ЗаписатьСвойТипОформленияВСтроку85(Значение);
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XML);
Если Не Чтение.Прочитать() Или Чтение.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
Чтение.Закрыть();
ВызватьИсключение "Own generated XDTO root element отсутствует";
КонецЕсли;
Копия = СериализаторXDTO.ПрочитатьXML(Чтение, ТребуемыйТип);
Чтение.Закрыть();
Если ТипЗнч(Копия) <> ТребуемыйТип Или ЗаписатьСвойТипОформленияВСтроку85(Копия) <> XML Тогда
ВызватьИсключение "Typed own Frame/Color XDTO roundtrip не сохранил exact value/style/default. UI setters не продолжаются";
КонецЕсли;
Возврат Новый ФиксированнаяСтруктура("Значение,XML", Копия, XML);
КонецФункции
Функция ЗаписатьСвойТипОформленияВСтроку85(Значение)
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, Значение, НазначениеТипаXML.Явное);
Возврат Запись.Закрыть();
КонецФункции
Процедура ПроверитьСвоеПолеИВсюМатрицу85()
ПроверитьСвойOrdinaryПросмотр85(МеткаОпыта);
Если СвоеПоле85 = Неопределено Или ЭтаФорма.ЭлементыФормы.Найти("Уч85Просмотр") <> СвоеПоле85
Или ТипЗнч(СвоеПоле85) <> Тип("ПолеТабличногоДокумента") Или СвоеПоле85.Данные <> "Результат85"
Или ТипЗнч(Результат85) <> Тип("ТабличныйДокумент") Тогда
ВызватьИсключение "Source identity собственного real field/bound document изменена";
КонецЕсли;
Если Результат85.ВысотаТаблицы <> 121 Или Результат85.ШиринаТаблицы <> 8 Или Не Результат85.ТолькоПросмотр
Или СвоеПоле85.ВысотаТаблицы <> 121 Или СвоеПоле85.ШиринаТаблицы <> 8 Или Не СвоеПоле85.ТолькоПросмотр Тогда
ВызватьИсключение "Own bound native field/document shape/viewmode не совпали";
КонецЕсли;
Сумма = 0;
Для Колонка = 1 По 8 Цикл
Заголовок = СвоеПоле85.Область(1, Колонка);
Если Заголовок.Текст <> "Колонка" + Строка(Колонка) Или Не Заголовок.Защита Тогда
ВызватьИсключение "Own bound header/protection изменены";
КонецЕсли;
Для СтрокаДанных = 1 По 120 Цикл
Ячейка = СвоеПоле85.Область(СтрокаДанных + 1, Колонка);
ЯчейкаОбъекта = Результат85.Область(СтрокаДанных + 1, Колонка);
Если Не Ячейка.СодержитЗначение Или Не ЯчейкаОбъекта.СодержитЗначение Или Не Ячейка.Защита Или Не ЯчейкаОбъекта.Защита
Или ТипЗнч(Ячейка.Значение) <> Тип("Число") Или ТипЗнч(ЯчейкаОбъекта.Значение) <> Тип("Число")
Или Ячейка.Значение <> СтрокаДанных * Колонка Или ЯчейкаОбъекта.Значение <> Ячейка.Значение Тогда
ВызватьИсключение "Одна из own960 actual field/object numeric/protected cells изменена. Формула не используется как fallback";
КонецЕсли;
Сумма = Сумма + Ячейка.Значение;
КонецЦикла;
КонецЦикла;
Если Сумма <> 261360 Или Сумма <> 120 * 121 / 2 * 8 * 9 / 2 Тогда
ВызватьИсключение "Actual960 numeric cell checksum не равна261360";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьГотовностьСвоегоПросмотра85()
Если Подготовлено85 <> Истина Или НеЗавершено85 = Истина Или Восстановлено85 = Истина Тогда
ВызватьИсключение "Не подготовлено/failedsetter/уже восстановлено: новые setters/rollback не разрешены. Закройте только свой экземпляр вручную";
КонецЕсли;
ПроверитьСвоеПолеИВсюМатрицу85();
ПроверитьСовпадениеСвоихСостояний85(СнятьActualПаспортСвоегоПоля85(), ОжидаемоеСостояние85);
КонецПроцедуры
Процедура ПроверитьСвоюКнопку85(Элемент, Имя)
ПроверитьСвойOrdinaryПросмотр85(МеткаОпыта);
Если Согласен85 <> Истина Или ТипЗнч(Элемент) <> Тип("Кнопка") Или ЭтаФорма.ЭлементыФормы.Найти(Имя) <> Элемент Тогда
ВызватьИсключение "Нужны согласие и actual инициатор собственной ordinary кнопки, не ручной вызов/foreign event";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойOrdinaryПросмотр85(МеткаОпыта)
#Если ТолстыйКлиентОбычноеПриложение Тогда
ПроверитьСвойПустойСтенд();
UUIDМетки = Новый УникальныйИдентификатор(МеткаОпыта);
Если МеткаОпыта <> Строка(UUIDМетки) Или UUIDМетки = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
ВызватьИсключение "Нужен canonical nonzero marker собственного каталога, не UUID базы/настоящего пользователя ИБ";
КонецЕсли;
Соединение = "File=""C:\1c-labs\Уч85Просмотр_" + МеткаОпыта + "\ИБ\"";";
Если СтрокаСоединенияИнформационнойБазы() <> Соединение Или ПривилегированныйРежим() Тогда
ВызватьИсключение "Только собственная новая FileIB и свой непривилегированный сеанс; connection не печатается";
КонецЕсли;
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
ВызватьИсключение "Нужен один настоящий собственный пользователь ИБ";
КонецЕсли;
Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
Или Текущий.Имя <> "Уч85Просмотр_" + МеткаОпыта Или Метаданные.ОбщиеФормы.Количество() <> 1
Или Метаданные.ОбщиеФормы.Просмотр85.Имя <> "Просмотр85" Или Метаданные.Боты.Количество() <> 0
Или Метаданные.Константы.Количество() <> 0 Тогда
ВызватьИсключение "Паспорт своей ordinary формы/реального пользователя не совпал";
КонецЕсли;
#Иначе
ВызватьИсключение "Только thick ordinary ПолеТабличногоДокумента, не одноименный managed element";
#КонецЕсли
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыПолный обычный модуль приложения: actual ownuser marker/guard/native fresh common form
Собственная CF → Открыть обычный модуль приложения.
Обычный модуль приложения своей CF, native OnStart0; только guarded WindowsThickOrdinary ownform factory, no fake UIevents.
Процедура ПриНачалеРаботыСистемы()
#Если ТолстыйКлиентОбычноеПриложение Тогда
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Пользователь = Неопределено Или Не СтрНачинаетсяС(Пользователь.Имя, "Уч85Просмотр_") Тогда
ВызватьИсключение "Запустите только собственную новую FileIB настоящим единственным учебным пользователем";
КонецЕсли;
Метка = Сред(Пользователь.Имя, СтрДлина("Уч85Просмотр_") + 1);
ПроверитьСвойOrdinaryПросмотр85(Метка);
СвояФорма = ПолучитьОбщуюФорму("Просмотр85", , Строка(Новый УникальныйИдентификатор));
Если ТипЗнч(СвояФорма) <> Тип("Форма") Тогда
ВызватьИсключение "Native GetCommonForm не создал собственную ordinary форму";
КонецЕсли;
СвояФорма.МеткаОпыта = Метка;
СвояФорма.Согласен85 = Ложь;
СвояФорма.Открыть();
Если Не СвояФорма.Открыта() Тогда
ВызватьИсключение "Открытие только своей формы не подтверждено native IsOpen";
КонецЕсли;
#Иначе
ВызватьИсключение "Источник field только Windows thick ordinary, не managed form element";
#КонецЕсли
КонецПроцедуры
Процедура ПроверитьСвойOrdinaryПросмотр85(МеткаОпыта)
#Если ТолстыйКлиентОбычноеПриложение Тогда
ПроверитьСвойПустойСтенд();
UUIDМетки = Новый УникальныйИдентификатор(МеткаОпыта);
Если МеткаОпыта <> Строка(UUIDМетки) Или UUIDМетки = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
ВызватьИсключение "Нужен canonical nonzero marker собственного каталога, не UUID базы/настоящего пользователя ИБ";
КонецЕсли;
Соединение = "File=""C:\1c-labs\Уч85Просмотр_" + МеткаОпыта + "\ИБ\"";";
Если СтрокаСоединенияИнформационнойБазы() <> Соединение Или ПривилегированныйРежим() Тогда
ВызватьИсключение "Только собственная новая FileIB и свой непривилегированный сеанс; connection не печатается";
КонецЕсли;
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
ВызватьИсключение "Нужен один настоящий собственный пользователь ИБ";
КонецЕсли;
Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
Или Текущий.Имя <> "Уч85Просмотр_" + МеткаОпыта Или Метаданные.ОбщиеФормы.Количество() <> 1
Или Метаданные.ОбщиеФормы.Просмотр85.Имя <> "Просмотр85" Или Метаданные.Боты.Количество() <> 0
Или Метаданные.Константы.Количество() <> 0 Тогда
ВызватьИсключение "Паспорт своей ordinary формы/реального пользователя не совпал";
КонецЕсли;
#Иначе
ВызватьИсключение "Только thick ordinary ПолеТабличногоДокумента, не одноименный managed element";
#КонецЕсли
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыРазбор по шагам
Own Windows thick ordinary/FileIB/actual user/empty CF guard выполняется перед native fresh common form и событиями. Source field получен из readonly own Form.Controls и real Data=Результат85.
Generate121×8 own memory TabDoc, protect headers/data and use OnlyView. Fullboundfield/object numeric960cells checksum261360 проверен, не DBsource или getter wrapper.
Восемь реальных исходных getter values сохранены typed immutable snapshot; Frame/Color copies имеют собственный in-memory XDTO exact roundtrip без файлов/user XML и сохраняют style/default semantics.
Planned viewer state строится до изменения: Bool scrollbars/Enabled/DND, ShowSelection enum, actual Double2/RGB. Current state должен совпасть со своим last expected, а не arbitrary afterstate.
Setter transaction здесь не симулируется: failflag до первого setter, запись expected только после fullplan readback и wholegrid. Ошибка означает stop this instance, никакого automatic rollback.
Manualscroll/native Selection3args показывают actual own numeric cell через first-control/bounds/ContainsValue/Number/source equality. UI события не вызываются программно.
Отключение/включение поля выполняет новый полный план на том же known ownfield, сохраняет матрицу и остальные настройки. Внешние buttons сохраняют доступность.
Restoration применяет только original8 actual values при exact-own-state guard. По успешному readback экземпляр больше не меняет viewer props; закрывается вручную владельцем.
Как проверить результат
Native field type/catalog56 source proof, связь Data и whole121×8actualfield/object matrix совпали. Все960numbers/protection/header checked, checksum261360 из actual values.
Bool scrollbars не ScrollBarUse enum; ShowSelection genuine enum; Frame/Color native constructors/typed copy. RGB не объявлен работающим на ignored convex/concave frame.
Baseline capturedbeforemode, style/auto preserved via own in-memory XDTO. All8current fieldprops match exact expected state before/after setters; foreign/partial state не легализуется.
Native Selection firstЭлемент+2baseparams wired explicitly; actualrow121/col8=960, row2/col1=1. Нет прямого вызова события или неизвестного input object.
Enabled toggle не меняет own960cells; successful restore вернул actualbaseline8, failed setters не инициируют blindrollback.
Authoredsource/static/rawnative проверки — не actual1С/UI/компиляция/печать/DB/files/network. Runtime verified0.
Ожидаемый результат
При ручной успешной компиляции/подготовке своего ordinary стенда protected viewer показывает120×8actualnumeric values/checksum261360, дает ownscroll/native selectedcell, guardedEnabled toggle и возврат actual baseline8. Здесь только authoredsource/native/static verification: actual1С/UI/DB/files/network/COM/print/compile0.
На что обратить внимание
ПолеТабличногоДокумента ordinary/catalog56 не managed ПолеФормы. Native visual ТабДок наследует его свойства/методы, но source/type/Data проверяется реальным own form, не именем переменной.
Обе scrollbar свойства native Boolean. ТипОтображенияВыделенияТабличногоДокумента имеет Всегда/ПриАктивности, не guessed cell/row selection mode.
ТолькоПросмотр блокирует редактирование защищенных cells, не всей произвольной таблицы и не безопасность внешних действий. Поэтому own headers/data protected и проверяются повторно.
У convex/concave BorderColor ignored; double absolute frame дает осмысленный цвет. Толщина рамки logical units, не mm spreadsheet overlay coordinates.
Native Frame/Color maystyle/auto; baseline не заменяется current RGB/newDouble defaults. XDTO copies source только own values и их типы, не userprovided XML/objectdata.
Copy XML signatures сравнивают same-version own serialized parameter values, не физическое rendering/pixels/cryptographic integrity. Roundtrip mismatch честно останавливает работу до setters.
Failflag/expected snapshot не создают atomic UI transaction. После partialfailed setters нет blindrollback/auto retry/захвата any currentstate как нового correctexpected.
Selection callback parameters связаны с native initiating field. FirstЭлемент добавлен ordinary extension; base событие2params. Manualcalls/bounds alone не являются доказательством UI event.
Numeric selection читает ownactualfield/callbackrange; header/многоклеточная/внешняя область отклоняется. Источник/формула не превращаются в fake actual result.
Data gate проверяет все960cells +8headers/protection и обе shapes перед каждымsetter. Один corrupted cell не скрывается coincidentally correct total.
Enabled=False отключает весь spreadsheet field и его contained controls, поэтому buttons находятся вне него. Hidden/readonly/disabled не взаимозаменяемые API.
Restoration только ownbaseline при known expectedstate. После успеха новые изменения запрещены; при ошибке владелец вручную закрывает только свое окно без force/foreign cleanup.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Очистить выделение пустым массивом в интерфейсе 8.5
Сначала устанавливаем собственную область, затем явно передаём пустой массив. Это не очистка документа и не удаление строк.
Где и как запускать
Модуль новой управляемой формы учебной внешней обработки. Код содержит готовые процедуры с директивами; вставляйте на уровне модуля, не внутрь другого обработчика. Каждую задачу запускайте в отдельной копии формы.
Подготовка
Создайте отдельную внешнюю обработку с новой пустой управляемой основной формой в учебной базе. ПриСозданииНаСервере назначьте одноимённой процедуре.
Вставьте полный модуль на уровне модуля формы. УчебныйДокумент, УчебноеПолеТаблицы и кнопку вручную не создавайте: их добавляет код.
Каждый урок — отдельная копия формы. Таблица содержит только собственную Книгу (3) и Ручку (1); это не печатная форма рабочего документа.
Настольный тонкий/толстый или веб-клиент. Для урока очистки выделения выберите интерфейс Версия 8.5: его поведение выделения отдельно отмечено в справке.
Код не вызывает печать, сохранение файла, сетевой обмен или запись базы. Внешняя кнопка остаётся вне табличного поля и его состояния.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Новые = Новый Массив;
Новые.Добавить(Новый РеквизитФормы("УчебныйДокумент", Новый ОписаниеТипов("ТабличныйДокумент")));
ЭтаФорма.ИзменитьРеквизиты(Новые);
Документ = Новый ТабличныйДокумент;
Документ.Область(1, 1).Текст = "Товар";
Документ.Область(1, 2).Текст = "Количество";
Документ.Область(2, 1).Текст = "Книга";
Документ.Область(3, 1).Текст = "Ручка";
Для НомерСтроки = 2 По 3 Цикл
Ячейка = Документ.Область(НомерСтроки, 2);
Ячейка.СодержитЗначение = Истина;
Ячейка.ТипЗначения = Новый ОписаниеТипов("Число");
Если НомерСтроки = 2 Тогда
Ячейка.Значение = 3;
Иначе
Ячейка.Значение = 1;
КонецЕсли;
КонецЦикла;
Документ.Область(, 1, , 1).ШиринаКолонки = 25;
Документ.Область(, 2, , 2).ШиринаКолонки = 12;
Документ.Область(2, 1, 3, 2).Имя = "УчебныеТовары";
Документ.ТолькоПросмотр = Истина;
ЭтаФорма.УчебныйДокумент = Документ;
Поле = Элементы.Добавить("УчебноеПолеТаблицы", Тип("ПолеФормы"));
Поле.Вид = ВидПоляФормы.ПолеТабличногоДокумента;
Поле.ПутьКДанным = "УчебныйДокумент";
Поле.Редактирование = Ложь;
Поле.РазрешитьНачалоПеретаскивания = Ложь;
Поле.РазрешитьПеретаскивание = Ложь;
КомандаДействия = ЭтаФорма.Команды.Добавить("УчебноеДействие");
КомандаДействия.Действие = "УчебноеДействие";
КомандаДействия.Заголовок = "Проверить свою таблицу";
КомандаДействия.Подсказка = "Действие только над данными учебной формы";
КомандаДействия.ИзменяетСохраняемыеДанные = Ложь;
Кнопка = Элементы.Добавить("КнопкаУчебноеДействие", Тип("КнопкаФормы"));
Кнопка.ИмяКоманды = КомандаДействия.Имя;
Кнопка.Заголовок = КомандаДействия.Заголовок;
КонецПроцедуры
&НаКлиенте
Процедура УчебноеДействие(Команда)
Поле = Элементы.УчебноеПолеТаблицы;
Области = Новый Массив;
Области.Добавить(ЭтаФорма.УчебныйДокумент.Область(2, 1, 3, 2));
Поле.УстановитьВыделенныеОбласти(Области);
ДоОчистки = Поле.ПолучитьВыделенныеОбласти();
Сообщить(ДоОчистки.Количество() > 0);
Поле.УстановитьВыделенныеОбласти(Новый Массив);
ПослеОчистки = Поле.ПолучитьВыделенныеОбласти();
Сообщить(ПослеОчистки.Количество() = 0);
Сообщить(ЭтаФорма.УчебныйДокумент.ВысотаТаблицы = 3);
Сообщить(ЭтаФорма.УчебныйДокумент.Область(2, 2).Значение = 3);
Сообщить(ЭтаФорма.УчебныйДокумент.Область(3, 2).Значение = 1);
КонецПроцедурыРазбор по шагам
Сначала создаётся непустое выделение одной своей области, чтобы очистка имела проверяемый эффект.
Пустой массив передаётся явно, аргумент не опускается. Справка отдельно обещает пустое текущее выделение в интерфейсе Версия8_5.
Массив повторно считывается после изменения. Документ не получает вызов Очистить.
В другом интерфейсе не выдавайте второе сравнение за универсальную гарантию: этот урок требует Версия 8.5.
Как проверить результат
В интерфейсе Версия 8.5: пять Истина. Документ всё ещё содержит три строки и количества 3/1.
Повторное нажатие опять сначала создаёт, потом убирает своё выделение.
Ожидаемый результат
Показана очистка состояния выбора, не данных.
На что обратить внимание
Это интерфейсное отличие 8.5, не общий контракт для всех старых клиентов.
Нет обращения к [0] после получения пустого массива.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.