| v8: Доступ к глобальным переменным, процедурам и функциям из общих модулейКлючевые слова: глобальных, экспорт, переменные, видимость, общих, модулей
 
 
 Небольшим заместителем глобальных переменных могут служить параметры сеанса, которые доступны в общих модулях. Но параметры сеанса могут сохранять не все типы значений, например, не получится так сохранить коллекцию значений (массив, структуру, список значений, таблицу значений и т.д.) Без преобразования в строку эти значения нельзя сохранить в параметре сеанса.
 
 Кроме того, в параметрах сеанса не получается хранить сложные объекты, типа COM-объектов (в том числе из внешних компонент), обработок и др.
 
 В некоторых случаях будет полезным следующий трюк:
 
 В конфигурации создается обработка, которая обеспечивает доступ к модулю приложения из общего модуля.
 
 В модуле обработки (не путать с модулем формы) размещаются следующие процедуры и функции:
 
 
 //------------------------- 
Функция Получить(Выражение) Экспорт 
    Возврат Вычислить(Выражение); 
КонецФункции 
//------------------------- 
Процедура Установить(Имя, Значение) Экспорт 
   Выполнить(Имя +" = Значение"); 
КонецПроцедуры 
//------------------------- 
Процедура ВыполнитьПрограмму(Текст) Экспорт 
   Выполнить(Текст); 
КонецПроцедуры 
//-------------------------
 Теперь в процедурах и функциях общих модулей можно делать следующие вещи:
 
 
 Процедура Тест() Экспорт 
//создаем объект типа ОбработкаОбъект.XXX 
гл = Обработки.гл.Создать(); 
//получение значения переменной 
а = гл.Получить("а"); 
//коллекции значений передаются "по ссылке", т.е. 
//ниже можно изменять ее элементы и они будут изменяться 
//в глобальной переменной 
//установить значение глобальной переменной 
гл.Установить("а",10); 
//вызвать экспортную процедуру модуля приложения 
гл.ВыполнитьПрограмму("проц()"); 
//вызвать функцию и получить ее возвращаемое значение 
а = гл.Вычислить("функ()");
КонецПроцедуры 
-----------------
 Я думаю, вы выясните самостоятельно, как передавать параметры в процедуры и функции.
 
 Еще хочу заметить, что такая обработка представляет собой ДЫРУ В БЕЗОПАСНОСТИ, потому что позволяет выполнить произвольный программный код и вызвать любую процедуру или функцию модуля приложения и общих модулей.
 
 Еще хочу заметить, что этот трюк не соответствует идеологии платформы и возможно, что такая конфигурация не пройдет "1С:Совместимо", станет запутаннее и сложнее.
 
 Кроме того, обращение к глобальным переменным будет довольно накладным (требуется создание объекта ОбработкаОбъект), но целью данной статьи является демонстрация технологических возможностей платформы на принципах "AS-IS". Вся ответственность за ваши программы лежит на вас.
 
 Рекомендуется по возможности:
 1. Обходиться вообще без глобальных переменных
 2. Передавать информацию через параметры процедур и функций
 3. Использовать параметры сеанса
 4. Не допускать выполнения чужого программного кода
 5. Комментировать сложные участки программы
 
 
 
 Альтернативное решение, посредством общей формы вместо обработки(с) nop
 Недостаток вышеприведенного метода - в каждой функции общего модуля нужно создавать экземпляр обработки.
 Реализация::
 Если есть общая-рабочий стол, то используем её, иначе создаем новую "ТестоваяФорма". На форму кладем ПолеВвода "рез" составного типа данных, и если форма-рабочий_стол,- то ещё два поляВвода "выражение_" и "парам".
 В модуль формы кладем код
 
 
 
// если форма - не рабочий стол
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если Лев(ИмяСобытия, 1) = "$" Тогда
        Выполнить("рез = " + Строка (Прав(ИмяСобытия, СтрДлина(ИмяСобытия)-1))); 
    ИначеЕсли Лев(ИмяСобытия, 1) = "=" Тогда
        Выполнить((Прав(ИмяСобытия, СтрДлина(ИмяСобытия)-1)) + "=Параметр" ); 
        Выполнить("рез = " + Строка (Прав(ИмяСобытия, СтрДлина(ИмяСобытия)-1))); 
    ИначеЕсли Лев(ИмяСобытия, 1) = "." Тогда
        Выполнить((Прав(ИмяСобытия, СтрДлина(ИмяСобытия)-1)));
    КонецЕсли;
КонецПроцедуры
 
 
// если форма - рабочий стол
Процедура ОбновлениеОтображения()
    Если Лев(выражение_, 1) = "$" Тогда
        Выполнить("рез = " + Строка (Прав(выражение_, СтрДлина(выражение_)-1))); 
    ИначеЕсли Лев(выражение_, 1) = "=" Тогда
        Если парам <> неопределено Тогда
            Выполнить((Прав(выражение_, СтрДлина(выражение_)-1)) + "=парам" ); 
            Выполнить("рез = " + Строка (Прав(выражение_, СтрДлина(выражение_)-1))); 
        КонецЕсли;
        парам = Неопределено;
    ИначеЕсли Лев(выражение_, 1) = "." Тогда
        Выполнить((Прав(выражение_, СтрДлина(выражение_)-1)));
    КонецЕсли;
КонецПроцедурыВ модуль приложения
 
 
Процедура ПриНачалеРаботыСистемы()
    
    ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма");
    // Если форма не рабочий стол - строчку ниже закомментировать
    ф.Открыть();Пример использования
 (не забудьте ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма") в каждом модуле)
 
 для формы-нерабочего_стола
 
 
// в общем модуле
Оповестить("$глТекущийПользователь", ,); // получаем глобальную переменную
Сообщить(ф.рез); //считываем полученное значение
Оповестить("=глТекущийПользователь", Неопределено,); // устанавливаем
Оповестить(".НекаяФункцияИлиПроцедура(параметр_глобальной_видимости)");
для формы, которая рабочий стол
 
 
//в общем модуле
//присвоение глоб. перем. значения
х = Новый СписокЗначений();
ф.Парам = х;
ф.Выражение_ = "=глоб_перем";
Сообщить(ф.рез);
// считывание глобальной переменной
ф.Выражение = "$глоб_перем" //считать глоб_перем в ф.рез
// Выполнить глобальную процедуру или функцию
ф.Выражение = ".НекаяФункцияИлиПроцедура(параметр_глобальной_видимости)";
 
 Недостатки приведенного кода:
 
 
 Рекомендации:
 Старайтесь использовать форму-рабочий_стол, что бы не использовать метод Оповестить().
 |