Универсальная замена метода Свойство()

09 марта 2013

О чем собственно речь

Возможно у многих из вас возникала задача проверять наличие определенного элемента на форме, или имеется ли на области макета нужный параметр. К сожалению, стандартных методов, позволяющих выполнить эту задачу, платформа не предоставляет.

Для значений типа "Структура" доступен метод "Свойство()":

ТестСтруктура = Новый Структура;
ТестСтруктура.Вставить("ТестКлюч", "ТестЗначение");

ЕстьЗначениеТестКлюч = ТестСтруктура("ТестКлюч");
// В итоге переменная "ЕстьЗначениеТестКлюч" 
// будет содержать значение ИСТИНА  

Если же мы попытаемся таким же образом узнать о существовании какого-либо элемента формы или параметра на области макета (как пример), то это вызовет следующую ошибку:

Метод "Свойство()" не обнаружен для данного типа

По подробной информации об ошибке видно, что коллекция элементов управляемой формы (переменная "Элементы") не имеет метода "Свойство()". Тоже самое относится к абсолютному большинству коллекций, которые поддерживает платформа.

Для некоторых коллекций, таких как "КолонкиТабличногоПоля", "КоллекцияЭлементовМетаданных" для использования доступен метод "Найти()", в качестве первого параметра которому передается имя элемента для поиска. Методы возвращают найденный элемент или "Неопределено", если значение не найдено. Таким образом, с помощью метода найти можно узнать наличие того или иного свойства для тех коллекций, которые поддерживают работу с ним.

Но что делать, если коллекция не поддерживает работу с подобными методами, описанными выше. В таких случая нужен совсем иной способ работы с этими типами данных.

Сегодня в статье будет идти речь об универсальном подходе, позволяющим определить наличие свойства у значения любого типа данных 1С:Предприятие 8.x.

Как это реализовать

Предлагаю написать универсальную функцию для определения наличия свойства у любого типа значения и затем перейти к использованию ее на небольшом примере.

Работа предлагаемого подхода основывается на использовании метода "ЗаполнитьЗначенияСвойств()" и переменной с типом "Структура". На следующем листинге приведен программный код данной функции:

// Универсальная функция для проверки наличия свойств 
// у значения любого типа данных
// Переменные:
// 1. Переменная - переменная любого типа, 
// для которой необходимо проверить наличие свойства
// 2. ИмяСвойства - переменная типа "Строка", 
// содержащая имя искомое свойство
//
Функция ПеременнаяСодержитСвойство(Переменная, ИмяСвойства)
     // Инициализируем структуру для теста 
     // с ключом (значение переменной "ИмяСвойства") 
     // и значением NULL
     СтруктураПроверка = Новый Структура;
     СтруктураПроверка.Вставить(ИмяСвойства, NULL);
     // Заполняем созданную структуру из
     // переданного значения переменной
     ЗаполнитьЗначенияСвойств(СтруктураПроверка, Переменная);
     // Если значение для свойства структуры 
     // осталось NULL, то искомое свойство не найдено, 
     // и наоборот.
     Если СтруктураПроверка[ИмяСвойства]= NULL Тогда
          Возврат Ложь;
     Иначе
          Возврат Истина;
     КонецЕсли;
КонецФункции

В принципе все понятно из комментариев в листинге. Единственным моментом, на что следует обратить внимание, является то, что если свойство будет найдено, а его значение при этом равно NULL, то функция все равно скажет, что такого свойства нет. В таких случаях нужно создавать дополнительную проверку.

Практический пример

В качестве примера в тестовой конфигурации добавим документ "ТестовыйДокумент" с несколькими реквизитами. На его форму добавлены соответствующие элементы формы.

Форма обработки для поиска элемента на форме

В поле "Имя элемента" вводится имя элемента формы. По кнопке найти отрабатывает созданная нами ранее функция. После выполнения команды, программа уведомляет пользователя об успешности поиска. На следующем листинге приведен программный код обработчика команды и вызываемая процедура поиска свойств.

&НаКлиенте
Процедура НайтиКоманда(Команда)
 
     Если ПеременнаяСодержитСвойство(Элементы, ИмяЭлемента) Тогда
          Предупреждение("Элемент """ + 
                          ИмяЭлемента + """ найден!"); 
     Иначе
          Предупреждение("Элемент """ + 
                          ИмяЭлемента + """ НЕ найден!");
     КонецЕсли;
 
КонецПроцедуры

// Универсальная функция для проверки наличия 
// свойств у значения любого типа данных
// Переменные:
// 1. Переменная - переменная любого типа, 
// для которой необходимо проверить наличие свойства
// 2. ИмяСвойства - переменная типа "Строка", 
// содержащая искомого свойства
// 
&НаКлиенте
Функция ПеременнаяСодержитСвойство(Переменная, ИмяСвойства)
     // Инициализируем структуру для теста с ключом 
     // (значение переменной "ИмяСвойства") и значением NULL
     СтруктураПроверка = Новый Структура;
     СтруктураПроверка.Вставить(ИмяСвойства, NULL);
     // Заполняем созданную структуру из переданного 
     // значения переменной
     ЗаполнитьЗначенияСвойств(СтруктураПроверка, Переменная);
     // Если значение для свойства структуры осталось 
     // NULL, то искомое свойство не найдено, 
     // и наоборот.
     Если СтруктураПроверка[ИмяСвойства] = NULL Тогда
          Возврат Ложь;
     Иначе
          Возврат Истина;
     КонецЕсли;
КонецФункции

Тестовую конфигурация Вы можете скачать по ссылке

Подведем итог

Описанный в статье подход позволяет проверять наличия свойств в коллекциях любого типа. Элементы формы, коллекция метаданных, параметры макета и много другое. Отрицательного влияния на производительность не имеет. Работает на любой версии платформы.

P.S. По замечанию alcom привожу программный код с использованием GUID'а:

// Универсальная функция для проверки наличия 
// свойств у значения любого типа данных
// Переменные:
// 1. Переменная - переменная любого типа, 
// для которой необходимо проверить наличие свойства
// 2. ИмяСвойства - переменная типа "Строка", 
// содержащая искомое свойства
// 
&НаКлиенте
Функция ПеременнаяСодержитСвойство(Переменная, ИмяСвойства)
     // Инициализируем структуру для теста 
     // с ключом (значение переменной "ИмяСвойства") 
     // и значением произвольного GUID'а
     GUIDПроверка = Новый УникальныйИдентификатор;
     СтруктураПроверка = Новый Структура;
     СтруктураПроверка.Вставить(ИмяСвойства, GUIDПроверка);
     // Заполняем созданную структуру из переданного 
     // значения переменной
     ЗаполнитьЗначенияСвойств(СтруктураПроверка, Переменная);
     // Если значение для свойства структуры осталось 
     // NULL, то искомое свойство не найдено, 
     // и наоборот.
     Если СтруктураПроверка[ИмяСвойства] = GUIDПроверка Тогда
          Возврат Ложь;
     Иначе
          Возврат Истина;
     КонецЕсли;
КонецФункции

comments powered by Disqus