Книга знаний

1С:Предприятие / Приемы программирования

Видимость переменных - неклассический подход

Как-то все программисты уже привыкли, что переменные бывают только локальными или глобальными. Мы расширим понятие видимости переменных и покажем, как смоделировать такую видимость во встроенном языке, а затем покажем, где такое можно применять.Автор статьи: Гений 1С | Редакторы:
Последняя редакция №3 от 18.07.06 | История
URL: http://kb.mista.ru/article.php?id=299

Ключевые слова: видимость


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

Посмотрите на пример, как выглядел бы код. В функции Ф4 видны все переменные, объявленные в предыдущих вызовах (при этом переменные с одинаковым именем замещаются):


Функция Ф1(А,Б,В)
  Сообщить(А, Б, В); //1,2,0
  Ф2(В=3, Г=4); //В замещается на 3
  Ф3(Г=6); //Должно передаться исходное В=0
КонецФункции

Функция Ф2(В, Г)
  Сообщить(А, Б, В, Г); //1,2,3,4
КонецФункции

Функция Ф3(В, Г)
  Сообщить(А, Б, В, Г); //1,2,5,6
КонецФункции

Ф1(А=1, Б=2, В=0);


В 1С это можно смоделировать так:

Функция обПрм(Родитель, Ребенок) Экспорт
    Ребенок.Вставить("Родитель", Родитель);
    Возврат Ребенок;
КонецФункции

Функция обСвойство(П, Параметр, Зн) 
    Перем Родитель;
    Если НЕ П.Свойство(Параметр, Зн) Тогда
        Если НЕ П.Свойство("Родитель", Родитель) Тогда
            Возврат ложь;
        Иначе
            Возврат обДоступСвойство(Родитель, Параметр, Зн);
        КонецЕсли;
    Иначе
        Возврат истина;
    КонецЕсли;
КонецФункции

Функция обЗначение(П, Параметр, ЗнН=Неопределено) 
    Перем Зн;

    Если обСвойство(П, Параметр, Зн) Тогда
        Возврат Зн;
    Иначе
        Возврат ЗнН;
    КонецЕсли;
КонецФункции


Тогда наш код будет выглядеть так:

Функция Ф1(П)
  Сообщить(обЗначение(П,"А"), обЗначение(П,"Б")); //1,2
  Ф2(обПрм(П, Новый Структура("В, Г", 3, 4)));
  Ф3(обПрм(П, Новый Структура("Г", 6)));
  Ф3(В=5, Г=6);
КонецФункции

Функция Ф2(П)
  Сообщить(обЗначение(П,"А"), обЗначение(П,"Б"), обЗначение(П,"В"), обЗначение(П,"Г")); //1,2,3,4
КонецФункции

Функция Ф3(П)
  Сообщить(обЗначение(П,"А"), обЗначение(П,"Б"), обЗначение(П,"В"), обЗначение(П,"Г")); //1,2,0,6
КонецФункции

Ф1(Новый Структура("А,Б,В", 1,2,0);


О практическом применении - расмотрим пример проверки правильности (валидности) объекта.
Часто нужно проверять правильность объекта. Но для проверки правильности объекта нужно знать не только сам объект, но и в каком контексте рассматривается проверка. Например, для проведения документ должен быть полностью заполнен, а для записи допускается частичная незаполненность. В то же время при проверке реквизита нужно не допускать неправильных значений у реквизита.

Пусть у нас есть функция Валидность(Объект, ПолнаяПроверка, ЧтоПроверять, Ошибки) которая возвращает Истину, если объект правильный и ложь, если неправильный. В случае, если есть ошибки, они накапливаются в массиве Ошибки.

При записи объекта определяем, нужна ли полная проверка (зависит от режима записи - если проведение, тогда нужна, если просто запись, тогда не нужна) и вызываем функцию с параметрами:
Валидность({Объект, ПолнаяПроверка, ЧтоПроверять="Объект"})


После выбора нового значения реквизита в форме объекта мы вызываем ту же функцию с параметрами:
Валидность({Объект, ПолнаяПроверка=ложь, ЧтоПроверять="Реквизит", Реквизит=[Имя реквизита], Значение=[Новое значение реквизита]})


Но по сути полная проверка объекта заключается в проверке валидности его строк и реквизитов этих строк.

Т.е. валидность при проверке объекта вызывает сама же себя с проверкой строк табличных частей и реквизитов. Но при этом значения ПолнаяПроверка и Объект не меняются.

Т.е. из вызова проверки валидности для объекта делаются примерно такие вызовы:

Валидность(обПрм(П, {ЧтоПроверять="Реквизит", Реквизит=[Имя реквизита], Значение=[Значение реквизита]})

Валидность(обПрм(П, {ЧтоПроверять="Строка", Строка=[Строка табличной части]})


В конце смотрим, есть ли ошибки и если они есть, возвращаем ложь - объект не валиден, содержит ошибки.

Вот здесь мы и видим, что удобно применение нашей схемы, иначе бы переменная ЧтоПроверять затиралась и нам приходилось бы ее восстанавливать.

Данный метод удобен и в других случаях, когда нужно передавать рекурсивно какие-нибудь структуры и списки.




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

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