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)));
КонецЕсли;
КонецПроцедуры
В модуль приложения
Процедура ПриНачалеРаботыСистемы()
ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма");
// Если форма не рабочий стол - строчку ниже закомментировать
ф.Открыть();
Пример использования
(не забудьте ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма") в каждом модуле)
для формы-нерабочего_стола
// в общем модуле
Оповестить("$глТекущийПользователь", ,); // получаем глобальную переменную
Сообщить(ф.рез); //считываем полученное значение
Оповестить("=глТекущийПользователь", Неопределено,); // устанавливаем
Оповестить(".НекаяФункцияИлиПроцедура(параметр_глобальной_видимости)");
для формы, которая рабочий стол
//в общем модуле
//присвоение глоб. перем. значения
х = Новый СписокЗначений();
ф.Парам = х;
ф.Выражение_ = "=глоб_перем";
Сообщить(ф.рез);
// считывание глобальной переменной
ф.Выражение = "$глоб_перем" //считать глоб_перем в ф.рез
// Выполнить глобальную процедуру или функцию
ф.Выражение = ".НекаяФункцияИлиПроцедура(параметр_глобальной_видимости)";
Недостатки приведенного кода:
Рекомендации:
Старайтесь использовать форму-рабочий_стол, что бы не использовать метод Оповестить(). |