Книга знаний

1С:Предприятие / v8 / Приемы программирования / Встроенный язык

v8: Доступ к глобальным переменным, процедурам и функциям из общих модулей

Не секрет, что в общих модулях 8.0 не видны экспортируемые переменные, процедуры и функции модуля приложения. Ниже предлагается некоторое решение этой проблемы.Автор статьи: Волшебник | Редакторы: Rovan, Гений 1С, nop
Последняя редакция №13 от 06.12.07 | История
URL: http://kb.mista.ru/article.php?id=37

Ключевые слова: глобальных, экспорт, переменные, видимость, общих, модулей


Небольшим заместителем глобальных переменных могут служить параметры сеанса, которые доступны в общих модулях. Но параметры сеанса могут сохранять не все типы значений, например, не получится так сохранить коллекцию значений (массив, структуру, список значений, таблицу значений и т.д.) Без преобразования в строку эти значения нельзя сохранить в параметре сеанса.


Кроме того, в параметрах сеанса не получается хранить сложные объекты, типа 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)));
    КонецЕсли;
КонецПроцедуры

В модуль приложения
Процедура ПриНачалеРаботыСистемы()
    
    ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма");
    // Если форма не рабочий стол - строчку ниже закомментировать
    ф.Открыть();

Пример использования
(не забудьте ф = ПолучитьОбщуюФорму("ТестоваяФорма", ,"ТестоваяФорма") в каждом модуле)


для формы-нерабочего_стола
// в общем модуле
Оповестить("$глТекущийПользователь", ,); // получаем глобальную переменную
Сообщить(ф.рез); //считываем полученное значение
Оповестить("=глТекущийПользователь", Неопределено,); // устанавливаем
Оповестить(".НекаяФункцияИлиПроцедура(параметр_глобальной_видимости)");

для формы, которая рабочий стол
//в общем модуле
//присвоение глоб. перем. значения
х = Новый СписокЗначений();
ф.Парам = х;
ф.Выражение_ = "=глоб_перем";
Сообщить(ф.рез);
// считывание глобальной переменной
ф.Выражение = "$глоб_перем" //считать глоб_перем в ф.рез
// Выполнить глобальную процедуру или функцию
ф.Выражение = ".НекаяФункцияИлиПроцедура(параметр_глобальной_видимости)";


Недостатки приведенного кода:
  • дополнение к статье писалось быстро - ошибки не исключены. Позже пересмотрю

  • Код не поддерживает получение результата глоб.функций, точнее он не различает что выполняет - функцию или переменную. Позже перепишу что бы понимал
  • При выполнении функций, процедур не поддерживается параметр локального контекста, например
     х = "бла_бла";
     ф.Выражение = ".НекаяФункцияИлиПроцедура(х)"; //будет ошибка

    Исправлю позже, сделав передаче через "парам"


Рекомендации:
Старайтесь использовать форму-рабочий_стол, что бы не использовать метод Оповестить().

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика