Обработки в 1С
Вот хорошая инфа по работе с доками helpme1s_ru
https://helpme1s.ru/dokumenty-v-yazyke-1s-8-v-primerax
Раскрыты вопросы:
Как открыть для редактирования, проверить, не заблокирован ли другим пользователем
Как заблокировать документ перед редактированием и разблокировать после
Как изменить неважный реквизит и записать без перепроведения по регистрам — это можно сделать, если в доке есть вариант записи без перепроведения по регистрам. Тогда перед записью значение того параметра документа устанавливается и док записывается без перепроведения по регистрам!
Вопрос по закрытию доков, полученных методом "ПолучитьОбъект", без записи (перепроведения).
Если документ был "открыт" для правки "вот так вот"
ОКСДляПравки=Строка.Ссылка.ПолучитьОбъект(); // Строка — выборка из таблицы значений в цикле
как его закрыть без записи и перепроведения?
Увидел — его можно записать в режиме записи, проведения, отмены проведения.
А как просто закрыть открытую ссылку? Нигде такое не нашел! Может, переменной ОКСДляПравки нужно присвоить пустое строковое значение?
В ходе отладки хотел было в цикле так пополучать документы, почитать и вывести сообщения, без правки и перезаписи документов. И от такой идеи отказался.
Получить документ для (чтения), изменения, добавления, удаления
ДокументСсылка.<Имя документа>.ПолучитьОбъект (GetObject)
Возвращаемое значение:
Тип: ДокументОбъект.<Имя документа>, или Неопределено.
Неопределено - объекта в базе нет (например, при обмене данными или после непосредственного удаления объекта, на который есть ссылки).
Описание: Получает по ссылке объект для чтения, изменения, добавления и удаления документа.
Записать документ
ДокументОбъект.Записать(<РежимЗаписи>, <РежимПроведения>)
РежимыЗаписи
- Запись (Write)
- ОтменаПроведения (UndoPosting)
- Проведение (Posting)
РежимПроведения
- Неоперативный
- Оперативный
Скопировать документ программно
ДокументСсылка.Скопировать () - возвращает ДокументОбъект. (из синтакс-помощника)
Создает новый документ копированием существующего.
Использование метода не приводит к записи созданного объекта в базу данных.
РСА Имеем ссылку на вновь созданный объект (документ). Можно исправить реквизиты, записать документ с проведением или без.
СсылкаНаРКО = Документы.РасходныйКассовыйОрдер.НайтиПоНомеру("00001", '20211231' ); // поиск среди документов 2021 года
// нам вернули не сам документ, а ссылку (указатель) на него // проверим - нашёлся ли вообще документ Если СсылкаНаРКО.Пустая() Тогда Сообщить("Документ не найден."); КонецЕсли; // Делаем копирование найденного документа
КопияРКО = СсылкаНаРКО.Скопировать();
КопияРКО.Дата = ДатаИзФайла(); // Ставим дату из файла КопияРКО.Сумма = СуммаИзФайла; // Ставим сумму из файла КопияРКО.Комментарий = "Создан обработкой"; // запишем и проведём документ КопияРКО.Записать(РежимЗаписиДокумента.Проведение);
ДокументОбъект.Скопировать() - возвращает ДокументОбъект.Имя, не записывая его в базу. Работает аналогично ДокументСсылка.Скопировать().
Важно понимать разницу в исходных данных: ссылка или сам объект
Пометка документов на удаление
// Получаем объект - док Затраты по ссылке из запроса, ставим пометку на удаление, записываем с отменой проведения ЗатратыОбъект=Стр.ЗатратыСсылка.ПолучитьОбъект(); ЗатратыОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения); // Отменить проведение ЗатратыОбъект.ПометкаУдаления=Истина; // Пометить на удаление ЗатратыОбъект.Записать(РежимЗаписиДокумента.Запись); // Записать
1) Отменяем проведение
2) После ставим пометку на удаление и записываем документ.
Если операцию №1 пропустить, то в базе в регистрах у помеченного на удаление документа остаются проводки?
В обработках объявление переменных
Если в модуле обработки переменная создается в одной процедуре, без объявления в начале модуля в другой процедуре данная переменная не будет будет доступна! Будет выдаваться сообщение об ошибке!
Если таблица значений получена из запроса в одной процедуре, так:
ТЗ_ОКС=Запрос.Выполнить().Выгрузить()
то без объявления переменной ТЗ_ОКС в начале модуля данная таблица значения не будет доступна в других процедурах. При сохранении модуля сразу же выводится ошибка, что ссылка на необъявленную переменную.
Вывод сообщений, предупреждений, вопросов пользователю
Вывод переносов строк в сообщениях
"+ Символы.ПС" - перевод строк
Преобразование типов числовых в строковые.
Если в параметре "Сообщить(Параметр)" первым идет число, то "число"+"строка" даст ошибку. А наоборот — пожалуйста.
Преобразование форматов смотри — при выводе сообщений, для вычислений.
Для вывода сообщений в коде обработчиков конфигурации "Конвертация данных 2.1. есть специальная команда! Я нашел на форумах. А хочется видеть нормально техническое описание....
Вывод вопросов пользователю
Вот образец кода для обычных форм, чтобы вывести вопрос пользователю и обработать ответ
Режим = РежимДиалогаВопрос.ДаНетОтмена;
Ответ = Вопрос("Выполнить?", Режим, 0); Если Ответ =КодВозвратаДиалога.Да Тогда Сообщить("Выполнено"); ИначеЕсли Ответ = КодВозвратаДиалога.Нет Тогда Сообщить("Не выполнено"); КонецЕсли;
Параметры — все есть в синтакс-помощнике!
Кнопка по умолчанию — не нужна, если работа в основном мышкой!
Таймаут — это время в секундах, после чего вопрос исчезнет!
Если вопрос закрылся по таймауту, то возвратное значение — именно "Таймаут", а не кнопка по умолчанию!
Форматирование выходных значений в 1С. Форматы чисел для макетов табличных доков — в свойствах ячеек макета; в отчетах на СКД форматы задавались в настройках условного форматирования для конкретных полей!
Для отчета "Прайс-лист" было надо:
- код товара без разделения на тройки цифр.
- цена и вес без дополнительных нулей в дробной части, но с граммами и копейками, если они есть!
Чтобы это сделать, нужны только такие настройки:
ЧГ=0; ЧФ=Ч (группировка — 0; числовой формат — "Ч").
Есть еще опция "представление нуля":
- Если не задать значение параметра (ЧН=;), тогда 0 будет отображаться как ноль.
- Если эту опцию не указать вообще, тогда ноль будет отображаться пустым значением.
Так (ЧН=;ЧГ=0; ЧФ=Ч) задается формат чисел:
- без лишних нулей в дробной части;
- без пробелов;
- нуль отображается как нуль, а не пусто.
Смотри картинку!

Все просто! А вот ветка по теме, где люди мучились в 2019 году https://forum.infostart.ru/forum9/topic225093/
Вывод сообщений, когда в аргументе есть выражения строкового и числового типа
Была ошибка при выводе "Сообщить(Аргумент1+Аргумент2+...АргументN). При плюсовске надо на первое место ставить строковой аргумент; если он не строковой, его надо преобразовывать в строку. А все последующие тогда будут преобразованы к строкам автоматом! Я так понял!
Вот все пробы:
Для Каждого Стр из ТЗ Цикл Сообщить(Формат(Стр.ДатаСдачи_В_Банк,"ДФ=""дд.ММ.гггг""")+" сумма: " + Строка(Стр.СуммаПринято)); // Выводит: 12.06.2023 сумма: 16 000 // Тут все приведено к строкам, по дате указан формат Сообщить(Строка(Стр.ДатаСдачи_В_Банк)+" сумма: " + Стр.СуммаПринято); // Выводит: 12.06.2023 0:00:00 сумма: 16 000 // Тут первая дата приведена к строке, + строка, + число - работает. Ведь "Стр.СуммаПринято" не может быть строкой? // Сообщить(Стр.ДатаСдачи_В_Банк+" сумма: " + Строка(Стр.СуммаПринято)); // Не работает: Преобразование значения к типу Число не может быть выполнено. Т.е. к дате не может прибавить строку далее // Тут плюсуется "Дата+строка+число"), и выводится ошибка. // Если на первое место поставить строковое значение? Сообщить("Дата " + Стр.ДатаСдачи_В_Банк+" сумма: " + Строка(Стр.СуммаПринято)); // Выводит: Дата 12.06.2023 0:00:00 сумма: 16 000 // Результат: если первое значение строковое, то "плюс" сразу все значения воспринимает как строки? // Проверяю: Сообщить("Дата " + Стр.ДатаСдачи_В_Банк+" сумма: " + Стр.СуммаПринято); // Выводит: Дата 12.06.2023 0:00:00 сумма: 16 000 // Видимо, так и есть. Если первое значение - строка, то все последующие аргументы "плюс" воспринимает как строки КонецЦикла;
Вывести таблицу значений в табличный документ. "Построитель отчетов".
Ответ 1
https://codernote.ru/1c/vyvod-tablicy-znachenij-v-tablichnyj-dokument/
// Возвращает табличный документ на основании таблицы значений
//
// Параметры:
// ДанныеВТабличныйДокумент - ТаблицаЗначений
//
&НаСервереБезКонтекста
Функция ДанныеТаблицыЗначенийВТабличныйДокумент(ДанныеВТабличныйДокумент)
ТабличныйДокумент = Новый ТабличныйДокумент;
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ДанныеВТабличныйДокумент);
Построитель.Вывести(ТабличныйДокумент);
Возврат ТабличныйДокумент;
КонецФункции // ДанныеТаблицыЗначенийВТабличныйДокумент()
После того, как табличный документ был получен, мы можем показать его пользователю:
ТабличныйДокумент = ДанныеТаблицыЗначенийВТабличныйДокумент(ТаблицаЗначенийДляВывода);
ТабличныйДокумент.Показать("Содержимое таблицы значений");
Ответ 2
https://helpf.pro/faq/view/1373.html
Как быстро вывести таблицу значений в табличный документ?
Код 1C v 8.х
ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Пользователи"; ЗапросаДанных = Новый Запрос(ТекстЗапроса); РезЗапроса = ЗапросаДанных.Выполнить().Выгрузить(); ТабДокумент = Новый ТабличныйДокумент; Построитель = Новый ПостроительОтчета; Построитель.ИсточникДанных=Новый ОписаниеИсточникаДанных(РезЗапроса); Построитель.Вывести(ТабДокумент); ТабДокумент.Показать("Название отчета в заголовке окошка");
Разместил: E_Migachev Версии: | 8.x | Дата: 01.04.2013 Прочитано: 162749
СинтаксПомощник — ТабДокумент.Показать
ТабличныйДокумент(SpreadsheetDocument).Показать (Show)
Синтаксис: Показать(<Заголовок>, <ИмяФайла>, <Активизация>)
Параметры: <Заголовок> (необязательный)
Тип: Строка. Заголовок окна табличного документа.
<ИмяФайла> (необязательный) Тип: Строка. Имя файла для сохранения табличного документа. Если значение не пустое, то при закрытии окна, если документ был изменен, будет предложено сохранить табличный документ в указанный файл.
<Активизация> (необязательный) Тип: Булево. Определяет активизацию открываемого окна табличного документа.
Истина - активизировать окно; Ложь - открывать окно без активизации.
Значение по умолчанию: Истина.
Описание:
Открывает окно для показа и редактирования табличного документа.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
Примечание:
Если табличный документ является реквизитом управляемой формы, то вызов метода приводит к возникновению исключения.
Пример:
ТабДок.Показать("Заявки от покупателей", "Заявки.mxl");
См. также:
ТабличныйДокумент, метод Скрыть
Использование в версии:
Доступен, начиная с версии 8.1.
Сохранение таблиц значений (структур) в файлы, в хранилище значений и обратное чтение
Сохранить таблицу значений в файл
https://1cguide.ru/programmirovanie-1s/soxranit-tablicu-znachenij-v-fajl.html
Сохранить таблицу значений в файл
28 июня, 2015 admin Комментировать
Для сохранения Таблицы значений в файл используется встроенная функция ЗначениеВФайл(<Путь>,<Значение>), она возвращает значение Истина, если выгрузка завершена успешно и Ложь, если она не удалась. В параметр Путь передается имя файла (в который будет сохраняться таблица) вместе с путем к нему. В параметр Значение передается таблица значений, либо массив одним из элементом которого является таблица значений (массив необходим в том случае, если в файл сохраняется много значений разных типов).
Пример (Пусть у нас есть таблица значений Таблица):
Путь = "E:\1с\Таблица.txt"; Массив = Новый Массив; Массив.Добавить(Таблица); Попытка Если ЗначениеВФайл(Путь, Массив) Тогда Предупреждение("Выгрузка успешно завершена!"); Иначе Предупреждение("Возникли проблемы при выгрузке!"); КонецЕсли; Исключение Предупреждение("Возникли проблемы при выгрузке! " + ОписаниеОшибки()); КонецПопытки;
Следует отметить, что функцию ЗначениеВФайл можно использовать и в режиме отладки используя механизм Вычислить выражение.
Функции сохранения таблицы значений в файл и чтения из файла (2016 год)
https://helpf.pro/faq/view/1837.html
Функции сохранения таблицы значений в файл и чтения из файла
В данном примере хочу привести несколько универсальных функций по выгрузке таблицы значений в файл и дальнейшего чтения из файла:
Порядок программных действий при выгрузке в файл выглядит так:
- Подготавливаем таблицу значений (выгружаем из табличной части, выбираем к олонки);
- Конвертируем таблицу значений в табличный документ;
- Сохраняем табличный документ в MXL.
При загрузке таблицы порядок действий такой:
- Читаем из файла табличный документ;
- Конвертируем табличный документ в таблицу значений;
- Используем эту таблицу значений в своих целях (загружаем в табличную часть).
Соответственно файл для хранения данных таблицы имеет расширение *.mxl.
Основные функции для реализации поставленной задачи следующие:
ПреобразоватьТДвТЗ – Функция преобразования табличного документа в таблицу значений.
ПреобразоватьТЗвТД – Функция обратного преобразования таблицы значений в табличный документ.
ПрочитатьТЗИзMXL – Читает из файла данные, определяет колонки таблицы и преобразует эти данные в таблицу значений.
ЗаписатьТЗВMXL – Преобразует таблицу значений в табличный документ и записывает его в файл.
РСА Детальный код смотри в статье.
"Простой способ сохранения таблицы значений в файл"
https://start1c.blogspot.com/2013/03/blog-post_29.html
29 мар. 2013 г.
Простой способ сохранения таблицы значений в файл
Для использования данных таблицы значений в сторонних программах необходимо выгружать их в текстовый файл, dbf, XML, Excel, либо другие. Но если данные таблицы планируется использовать только в 1С, то можно использовать такие методы, как XMLСтрока/XMLЗначение, либо ЗначениеВФайл/ЗначениеИзФайла. Мне, например, это пригодилось, когда пришлось формировать большой объем различных по виду документов с последующей правкой процедур проведения. Поэтому, чтобы можно было быстро восстановить перечень обрабатываемых документов после применения исправлений, я как раз и использовал эти способы.
Разберем на примере обработки для УТ 11 методы XMLСтрока/XMLЗначение. В этом случае таблицу значений необходимо предварительно поместить в ХранилищеЗначения.
"Хранилище значений" в 1С
https://koder.by/hranilishhe_znachenij.php
"Хранилище значений в 1С 8.3 это объект, который позволяет хранить в сериализованном виде почти любые типы данных (включая двоичные). Хранение происходит в самой базе данных (файле 1Cv8.1CD или на SQL-сервере в таблицах). Соответственно при выгрузки конфигурации, данные используемые хранилищем значений будут включены в архив базы (резервную копию). С помощью этого объекта можно хранить такие данные как: файлы, картинки (фотографии), внешние обработки, таблицы значений, структуры...
Важно понимать, что хранение данных в таком виде будет существенно замедлять работу базы данных.
Поэтому данную технологию хранения рекомендуется использовать в крайних случаях, если отсутствует альтернатива решения для имеющейся задачи."
Примеры кода смотри в статье.
Когда использование хранилища значений замедляет работу базы?
Еще информация про хранилища значений
http://howknow1c.ru/jazyk-1s/hranilishhe-znachenij-1s.html
Вывод таблицы значений в форму диалога в качестве реквизита
Контекст:
После поломки SSD кассового компа нужно было загрузить в Далион продажи из файла, полученного от ОФД.
Вот тут взял обработку:
https://programmist1s.ru/zagruzka-iz-csv-v-1s/
...После того как данные загружены в табличку, их можно использовать как Вам угодно — загрузить прайс, загрузить номенклатуру, загрузить контрагентов, загрузить остатки.
Скачать: обработка для загрузки данных из CSV в 1С 8.2."
Эта обработка была нужна как шаблон, чтобы обработать данные ОФД для последующего импорта в Далион.
Нужно было заменить полные наименования (из ОФД) на краткие наименования в Далионе, т.к. универсальная обработка загрузки из таблиц воспринимает стандартно делает сопоставления по кратким наименования. Надо было добавить единицу измерения и коэффициент.
Главное:
В обработке есть реквизит обработки типа "таблица значений"
В форме обработки есть реквизит формы типа "табличное поле", которое связано с таблицей значений (реквизитом обработки).
При программном изменении таблицы значений (добавление колонок, изменение данных в строках) автоматом данные в форме не изменяются!
Чтобы данные в форме диалога обновились, к табличному полю формы нужнол применить метод ТабличноеПоле.СоздатьКолонки / TableBox.CreateColumns
Чтобы в ОФ обновить таблицу значений в форме (это реквизит формы), связанную в таблицей значений, которая есть реквизит обработки, нужна команда "ТабличноеПоле (TableBox).СоздатьКолонки (CreateColumns)".
Инфа взята отсюда https://forum.infostart.ru/forum9/topic83334/
Пишут, как обновить в обычных формах таблицу на форме, которая была программно изменена
В СП пишут так:
ТабличноеПоле (TableBox).СоздатьКолонки (CreateColumns)
Синтаксис: СоздатьКолонки()
Описание: Удаляет старые колонки и загружает новые колонки из источника данных.
Доступность: Толстый клиент.
Пример:
ЭлементыФормы.ТабличноеПоле1.Значение = ТаблицаДанных;
ЭлементыФормы.ТабличноеПоле1.СоздатьКолонки();
Использование в версии: Доступен, начиная с версии 8.0.
Вот текст обработки в самом начале правки
Процедура ПрочитатьНажатие(Элемент) //очищаем таблицу и удаляем колонки Таблица.Очистить(); Таблица.Колонки.Очистить(); ЭлементыФормы.Таблица.Колонки.Очистить(); // чтение файла ЗагружаемыйФайл = Новый ТекстовыйДокумент; ЗагружаемыйФайл.Прочитать(ИмяФайла); //шапка по умолчанию 1 строка, из первой строки делаем колонки таблицы Шапка = ЗагружаемыйФайл.ПолучитьСтроку(1); //раскладываем строку в массив МассивКолонок = РазложитьСтрокуВМассивПодстрок(Шапка,Разделитель); //генерируем колонки Для Каждого ИмяКолонки Из МассивКолонок Цикл ИмяБезПробелов = СтрЗаменить(ИмяКолонки," ",""); // убираем из имени колонок пробелы ИмяБезПробелов = СтрЗаменить(ИмяКолонки,".",""); // убираем из имени колонок точки РСА ИмяБезПробелов = СтрЗаменить(ИмяКолонки,"-",""); // убираем из имени колонок тире РСА Таблица.Колонки.Добавить(ИмяБезПробелов,,ИмяКолонки); НоваяКолонка = ЭлементыФормы.Таблица.Колонки.Добавить(ИмяБезПробелов, ИмяКолонки); НоваяКолонка.Данные = ИмяБезПробелов; КонецЦикла; Для НомерСтроки=2 по ЗагружаемыйФайл.КоличествоСтрок() Цикл Состояние("Обрабатывается "+Строка(Формат(?(ЗагружаемыйФайл.КоличествоСтрок()=0,0,((100*НомерСтроки)/ЗагружаемыйФайл.КоличествоСтрок())),"ЧЦ=3; ЧДЦ=0"))+" %"); ОбработкаПрерыванияПользователя(); //указав данный оператор, цикл можно прервать в любой момент нажатие ctrl+break // получить строку файла с указанным номером и преобразуем её в массив Строка = ЗагружаемыйФайл.ПолучитьСтроку(НомерСтроки); МассивКолонок = РазложитьСтрокуВМассивПодстрок(Строка,Разделитель); НоваяСтрока = Таблица.Добавить(); Если МассивКолонок.Количество() <> Таблица.Колонки.Количество() Тогда Сообщить("Ошибка со строкой " + Строка); Продолжить; // скорее всего в тексте содержит разделитель КонецЕсли; Для НомерКолонки = 1 по МассивКолонок.Количество() Цикл //заполняем строку значениями ТекущееЗначение = МассивКолонок[НомерКолонки-1]; ИмяКолонки = Таблица.Колонки[НомерКолонки-1].Имя; НоваяСтрока[ИмяКолонки] = ТекущееЗначение; КонецЦикла; КонецЦикла; // Добавляем колонки для загрузки из табличного документа в расходную накладную // Если Таблица.Количество()>0 Тогда // Сообщить("В таблице ТЗ_ИтогВывод всего элементов: "+Таблица.Количество()); // КонецЕсли; // Сообщить("Колво колонок до добавки колонок" + Таблица.Колонки.Количество()); Таблица.Колонки.Вставить(1,"КраткоеНаименование",Новый ОписаниеТипов("Строка"),"КраткоеНаименование",30); // Ширину колонок установил, но они все равно не отобр. ПОчему? Таблица.Колонки.Вставить(2,"ЕдИзм",Новый ОписаниеТипов("Строка"),"ЕдИзм",10); // Сообщить("Колво колонок после добавки" + Таблица.Колонки.Количество()); ЭлементыФормы.Таблица.Колонки.Вставить(1,"КраткоеНаименование"); ЭлементыФормы.Таблица.Колонки.Вставить(2,"ЕдИзм"); Если Таблица.Количество()>0 Тогда // Заполняем доп колонки Для Каждого Строка Из Таблица Цикл // Сообщить(Строка[0]); // Наименования товаров выводятся Строка[1]="Краткое наимен"; // Данные добавляются, но в форме эти колонки не отображаются Строка[2]="шт"; // Сообщить(Строка[1]); // Наименования товаров выводятся КонецЦикла; КонецЕсли; // В цикле читаем полученную таблицу, и добавляем значения в строки // ЭтаФорма.Обновить(); // Это ничего не дало ЭлементыФормы.Таблица.СоздатьКолонки(); // РСА Вот эта команда действительно обновляет таблицу в форме!!! 140424 КонецПроцедуры
Видим:
1. Данные добавляются как в реквизит обработки (таблица значений):
Таблица.Колонки.Вставить(1,"КраткоеНаименование",Новый ОписаниеТипов("Строка"),"КраткоеНаименование",30);
так и табличное поле открытой формы:
ЭлементыФормы.Таблица.Колонки.Вставить(1,"КраткоеНаименование");
2. В исходной обработке не было кода
ЭлементыФормы.Таблица.СоздатьКолонки(); // РСА Вот эта команда действительно обновляет таблицу в форме!!! 140424
В исходной обработке таблица значений, считанная из CSV, не изменялась (не было такой задачи).
В цикле чтения строк из файла CSV добавлялась новая строка в таблицу значений. НоваяСтрока = Таблица.Добавить();
Добавлялись значения в строки ТАБЛИЦЫ ЗНАЧЕНИЙ (реквизита самой обработки). НоваяСтрока[ИмяКолонки] = ТекущееЗначение;
Как срабатывало обновление данных в форме - непонятно!
Можно подумать, что в исходной обработке в цикле читались данные из таблицы значений и непосредственно добавлялись строки табличного поля в форме. Но вроде бы это так не работало!
Читать по теме! Вернуться позже, просмотреть код исходной обработки.
Книга "Разработка интерфейса прикладных решений на платформе "1С:Предприятие 8" Часть 3. Программирование форм и интерфейса Глава 3.17. Работа с таблицей в форме" (на ИТС доступна по подписке https://its.1c.ru/db/pubv8devui/content/244/hdoc).
В.А. Ажеронок, А.В. Островерх, М.Г. Радченко, Е.Ю. Хрусталева "Разработка интерфейса прикладных решений на платформе "1С:Предприятие 8". Издание 2, стереотипное"
--
Прочитал эту главу в книге 2010 года по управляемому интерфейсу - мне не помогло. Смотри более новые изданий книги.