.. Автор: Александр Орефков
.. Автор: Александр Клабуков

.. include:: commonchm.txt

*****************************************************
TurboBL
*****************************************************

..	<chminfo>
		<insert nodes="//common/maininfo/*"/>
		<alinks>_1cpp_TurboBL_</alinks>
	</chminfo>

.. contents:: Содержание
	:backlinks: none

Назначение
==========
..	<chminfo split="0">
	</chminfo>

- Ускорение вызова методов и обращения к свойствам объектов 1С-Предприятия 7.7
- Обращение к методам и переменным модулей через Контекст 

Краткий экскурс в механизм вызова методов
==========================================
..	<chminfo splitchild="0">
	</chminfo>

Для всех
--------

Что происходит внутри 1С, когда мы пишем спр.ТекущийЭлемент()?

1С преобразует имя метода ТекущийЭлемент в соответствующий ему номер, и вызывает метод объекта
по номеру. НО, клинические исследования показали, что для ЛЮБОГО объекта 1С используется один
алгоритм такого преобразования, реализованный "В ЛОБ", и котрый заключатся в простом
последовательном переборе всех имен методов объекта и сравнении их с искомым. Соответственно,
чем больше номер метода, тем большее время занимает такой поиск. Например, для того же
"ТекущийЭлемент" перед реальным вызовом функции происходит перебор 88 названий методов.

Аналогично и для свойств объектов. 

Для знакомых с "Rainbow"
------------------------

Как известно, для поиска номера метода применяется
::

	virtual int CBLContext::FindMethod(const char* name);

Как оказалось, НИ В ОДНОМ из объектов 1С данный метод не переопределен. Перехват вызова
функций различных объектов показал лень и мягко говоря, не вполне компетентность людей,
писавших этот код.

Вобщем, когда вызывается ``FindMethod``, из него вызываются: ``GetNMethods(),
GetMethodName(i,0), GetMethodName(i,1)`` т.е. ``FindMethod`` работает примерно так:: 

	 for(int i=0;i<GetNMethods();i++)
	 {
	     if(!stricmp(name,GetMethodName(i,0))
	         return i;
	     if(!stricmp(name,GetMethodName(i,1))
	         return i;
	 }
	 return -1;
		
Понятно, хотелось добиться универсальности и простоты, что и достигнуто. Но при этом:
- Некомпетентность: GetNMethods можно вынести из цикла.
- Лень: не зря же FindMethod виртуальная, почему же она не переопределена ни в одном из наследуемых классов для более оптимального поиска?

Аналогичная ситуация и с FindProp. 

Цель компоненты
===============
..	<chminfo splitchild="0">
	</chminfo>

Дабы устранить досадную оплошность разработчиков 1С в отношении поиска методов и свойств
была создана ВК **TurboBL**, которая включена в 1С++. Суть ее работы в следующем: оптимизация 
алгоритма преобразования имен методов/свойств в их номера.

Попутно сделана возможность обращаться к методам и переменным модулей ГрупповыхКонтекстов. 

Как использовать
----------------
::

	ЗагрузитьВнешнююКомпоненту("1cpp.dll");

Вот практически и все.

Более никаких изменений в существующем коде конфигурации не требуется. При загрузке компонента берет на себя всю работу по поиску номеров методов и свойств объектов 1С. 

Вызов методов модулей групповых контекстов
==========================================
..	<chminfo splitchild="0">
	</chminfo>

**Да!!! Свершилось!!!**

Теперь можно через контекст обратится к методам и переменным модуля контекста.

Например::

	конт=0;
	ОткрытьФорму("Справочник.Товары",конт);
	конт.Печать();
	//где Печать() - процедура в модуле	ФормыСписка справочника.
	
	или например:
	// в модуле проведения дока
	Процедура ЭтоДокСТоваром()
	    возврат 1;
	КонецПроцедуры;
	Процедура ОбработкаПроведения(парам)
	    глНекаяГлобФункция(Контекст);
	    ....
		
	// В ГМ:
	Процедура глНекаяГлобФункция(Конт)
	    Если Конт.ЭтоДокСТоваром()=1
	    .......

Дополнительные методы контекстов
--------------------------------

__ВызыватьМетодыКакСобытия / __CallMethodsAsEvents
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
..	<chminfo split="1">
	</chminfo>
..

	:Синтаксис:
		__ВызыватьМетодыКакСобытия(<Флаг>)

	:Параметр:
		Флаг - необязательный параметр. Число: 0 - отключает, 1 - включает вызов методов как событий.

	:Возвращает:
		Предыдущее установленное значение.

	:Описание:
		Вызов методов как событий влияет на установку номера строки для таблиц, расположенных
		на форме контекста, а также на подключение таблиц-шаблонов для объектов типа
		"**Таблица**", используемых в этом контексте (метод ``Таблица.ИсходнаяТаблица()``).	

		Вызов метода влияет только на тот контекст, для которого он вызван. До вызова этого
		метода соответствующий ему флаг установлен в <**1**>.

Вызов метода (процедуры или функции) контекста может иметь разный результат
в зависимости от того, был ли этот метод вызван из другого метода контекста,
либо этот же метод вызван извне, например, по нажатию кнопки на форме.
Например, для метода ``СообщитьНомерСтроки()``::

	Процедура СообщитьНомерСтроки()
		Сообщить(тзНаФорме.НомерСтроки());
	КонецПроцедуры

	Процедура СменитьИСообщить()
		тзНаФорме.ПолучитьСтрокуПоНомеру(1);
		СообщитьНомерСтроки();
	КонецПроцедуры

Вызов же того же метода контекста извне может иметь даже более непредсказуемый результат::

	Процедура СменитьИСообщитьДляКонтекста(Конт)
		Конт.тзНаФорме.ТекущаяСтрока(2);
		Конт.тзНаФорме.ПолучитьСтрокуПоНомеру(1);
		Конт.СообщитьНомерСтроки();
	КонецПроцедуры

В результате вызова данной процедуры может вывестись как **1**, так и **2**. В зависимости
от версии **TurboBL** (или **1С++**), которую вы используете.

Для устранения данной неоднозначности и был добавлен метод групповых контекстов
``__ВызыватьМетодыКакСобытия()``. Результатом вызова
::

	Конт.__ВызыватьМетодыКакСобытия(0);
	СменитьИСообщитьДляКонтекста(Конт);
	Конт.__ВызыватьМетодыКакСобытия(1);
	СменитьИСообщитьДляКонтекста(Конт);

будет
::

	1
	2

