Жил-был начинающий разработчик Вася. И было у него три «пунктика»:
-
Писать по стандартам
-
Делать универсально
-
Перепроверять, что все соответствует п.1 и п.2
И в зависимости от расположения звёзд на небе, у Василия активизировались те или иные пункты. Например.
Есть на форме обработки таблица с колонками. Разработчик столкнулся с, на первый взгляд, примитивной задачей — сделать кнопку, которая будет открывать значение в текущей колонке. Пользователь становится курсором на валюту «Руб.» и нажимает кнопку. Карточка валюты «руб.» открывается. Пользователь становится на другую ячейку и нажимает на кнопку — открывается значение из этой ячейки.
И вот программист Вася, вдохновившись тем, что сможет моментально решить задачу, добавляет команду.
- А вдруг пользователь нажмёт кнопку в тот момент, когда в таблице вообще не будет строк?
И прилежный программист сразу же (как учили) в процедуре делает стандартную проверку.
ТаблицаФормы = Элементы.Валюты; Если ТаблицаФормы.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли;
- Ну вот! Уже лучше. Начинаем эксперименты
И вот Василий берётся за определение текущей колонки. А так как наш разработчик любит сначала всё проверять, то выводит её сообщением.
ТекущаяКолонка = ТаблицаФормы.ТекущийЭлемент; Сообщить("Имя текущего поля: " + ТекущаяКолонка.Имя);
Открывает свой любимый тонкий клиент и проверяет:
- Но ведь сама колонка в таблице называется «Валюта», а не «ВалютыВалюта».
Взмахнув мышкой, Василий открывает редактор формы и видит, что на самом деле происходит.
«Валюты» - это имя таблицы, в которой хранятся данные.
«Валюта» - имя колонки этой таблицы.
А «ВалютыВалюта» - это имя поля на форме. Оно не хранит данные, а лишь выводит их. На самом деле данные хранятся в строке таблицы «Валюты» в колонке «Валюта».
Так происходит, когда имя поля было сгенерировано автоматически. Например, разработчик вынес его «вручную» на форму обработки. Имя автоматически присвоелось по формуле:
имя таблицы + имя колонки.
- И как же мне определить реальное имя колонки у текущего элемента?
Чему зачастую учат программистов в этих ваших интернетах? Прежде чем создавать свой велосипед, нужно поискать чужие. Естественно, в интернете.
Недолго думая гугля, Вася находит несколько примеров.
- А где-то я уже это видел...
Флэшбеки вспышками имен методов и переменных пролетают в сознании разработчика 1С и, погрузившись в океан жёлтых воспоминаний, он хватает за хвост имя обработки, в которой видел нечто подобное.
- Точно, я уже такое видел!
И действительно, в одной из завалявшихся в конфигурации обработок есть это:
ТаблицаФормы.ТекущиеДанные[Сред(ТаблицаФормы.ТекущийЭлемент.Имя, СтрДлина(ТаблицаФормы.Имя) + 1)]
Всё просто. Автор этого кода полагает, что имена элементов в его инструменте всегда будут строиться по приведенной ранее формуле: имя таблицы + имя колонки. И вроде бы ничего страшного, ведь так чаще всего и бывает, но:
- Я хочу универсальное решение!
Звёзды сошлись. Сегодня Василий решается на серьёзный поступок — не денег ради, но во имя высокой цели, сделать кнопку не «как можно быстрее», а «как можно круче». Естественно, степень крутости определяется им самим.
Нужно решение, которое можно будет скопировать в другой инструмент, не заботясь о том, чтобы имена элементов соответствовали какому-то там шаблону.
Порывшись в гугле синтаксис помощнике, Василий находит свойство у поля: ПутьКДанным
ПолеФормы (FormField)
ПутьКДанным (DataPath)
Использование:
Чтение и запись.
Описание:
Тип: Строка.
Содержит путь к реквизиту, с которым связан объект.
Доступность:
Сервер, мобильное приложение(сервер).
И вроде бы вот оно решение, однако:
Доступность:
Сервер, мобильное приложение(сервер).
Есть загвоздка — свойство доступно только на сервере.
Можно, конечно, написать серверную функцию, которая будет возвращать путь к данным формы:
&НаКлиенте Процедура ОткрытьЗначениеЯчейки(Команда) ТаблицаФормы = Элементы.Валюты; Если ТаблицаФормы.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли; ТекущаяКолонка = ТаблицаФормы.ТекущийЭлемент; Сообщить("Имя текущего поля: " + ТекущаяКолонка.Имя); Сообщить("Путь к данным текущего поля: " + ПутьКДаннымЭлементаФормы(ТекущаяКолонка.Имя)); КонецПроцедуры &НаСервере Функция ПутьКДаннымЭлементаФормы(ИмяЭлемента) ПутьКДаннымЭлемента = Неопределено; НайденныйЭлемент = Элементы.Найти(ИмяЭлемента); Если НЕ НайденныйЭлемент = Неопределено Тогда ПутьКДаннымЭлемента = НайденныйЭлемент.ПутьКДанным; КонецЕсли; Возврат ПутьКДаннымЭлемента; КонецФункции
Но...
- Так не пойдёт!
Вспомнив, что каждое излишнее обращение к серверу — это зло, за которое его ругали в Великой Школе Одинэсников Имени Желтого Чайника, разработчик Вася решает попробовать не плодить серверные вызовы. Тем более с передачей всей формы.
Программист добавляет на форму обработки реквизит произвольного типа «ПутиКДаннымЭлементовФормы»
А при создании формы заполняем эту структуру именами полей и адресами их значений, хранящихся в свойстве «ПутьКДанным»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ПутиКДаннымЭлементовФормы = Новый Структура; Для Каждого ЭлементФормы Из ЭтаФорма.Элементы Цикл Если ТипЗнч(ЭлементФормы) = Тип("ПолеФормы") ИЛИ ТипЗнч(ЭлементФормы) = Тип("ТаблицаФормы") Тогда ПутиКДаннымЭлементовФормы.Вставить(ЭлементФормы.Имя, ЭлементФормы.ПутьКДанным); КонецЕсли; КонецЦикла; КонецПроцедуры
Теперь остаётся лишь сделать клиентский метод, который будет возвращать соответствующее значение свойства «ПутьКДанным»
&НаКлиенте Функция ПутьКДаннымЭлементаФормы(ИмяЭлемента) ПутьКДаннымЭлемента = Неопределено; ПутиКДаннымЭлементовФормы.Свойство(ИмяЭлемента, ПутьКДаннымЭлемента); Возврат ПутьКДаннымЭлемента; КонецФункции
Разработчик оглядывает код и радуется проделанной работе. А заодно и проверяет насколько правильно всё работает:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ПутиКДаннымЭлементовФормы = Новый Структура; Для Каждого ЭлементФормы Из ЭтаФорма.Элементы Цикл Если ТипЗнч(ЭлементФормы) = Тип("ПолеФормы") ИЛИ ТипЗнч(ЭлементФормы) = Тип("ТаблицаФормы") Тогда ПутиКДаннымЭлементовФормы.Вставить(ЭлементФормы.Имя, ЭлементФормы.ПутьКДанным); КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиенте Процедура ОткрытьЗначениеЯчейки(Команда) ТаблицаФормы = Элементы.Валюты; Если ТаблицаФормы.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли; ТекущаяКолонка = ТаблицаФормы.ТекущийЭлемент; Сообщить("Имя текущего поля: " + ТекущаяКолонка.Имя); Сообщить("Путь к данным текущего поля: " + ПутьКДаннымЭлементаФормы(ТекущаяКолонка.Имя)); КонецПроцедуры &НаКлиенте Функция ПутьКДаннымЭлементаФормы(ИмяЭлемента) ПутьКДаннымЭлемента = Неопределено; ПутиКДаннымЭлементовФормы.Свойство(ИмяЭлемента, ПутьКДаннымЭлемента); Возврат ПутьКДаннымЭлемента; КонецФункции
Вернувшись в тонкий клиент, Василий смотрит на результат:
Уже лучше. Теперь мы можем на клиенте узнать путь к данным формы. Для проверки, что всё на самом деле так, как планировалось, разработчик Вася переименовал элемент формы на «КолонкаСВалютой». Теперь путь к данным и имя элемента непохожи между собой, что поможет понять разницу. Вася любит всё перепроверять.
Ну вот. Всё хорошо. Но что теперь делать с этим? Нужно же определить имя колонки из полного пути к данным формы. Василий берёт самый прямой способ - расщепить полный путь на массив и взять его последний элемент:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ПутиКДаннымЭлементовФормы = Новый Структура; Для Каждого ЭлементФормы Из ЭтаФорма.Элементы Цикл Если ТипЗнч(ЭлементФормы) = Тип("ПолеФормы") ИЛИ ТипЗнч(ЭлементФормы) = Тип("ТаблицаФормы") Тогда ПутиКДаннымЭлементовФормы.Вставить(ЭлементФормы.Имя, ЭлементФормы.ПутьКДанным); КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиенте Функция ПутьКДаннымЭлементаФормы(ИмяЭлемента) ПутьКДаннымЭлемента = Неопределено; ПутиКДаннымЭлементовФормы.Свойство(ИмяЭлемента, ПутьКДаннымЭлемента); Возврат ПутьКДаннымЭлемента; КонецФункции &НаКлиенте Процедура ОткрытьЗначениеЯчейки(Команда) ТаблицаФормы = Элементы.Валюты; Если ТаблицаФормы.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли; ИмяПоляКолонки = ТаблицаФормы.ТекущийЭлемент.Имя; //КолонкаСВалютой ПутьКДаннымКолонки = ПутьКДаннымЭлементаФормы(ИмяПоляКолонки); //Валюты.Валюта СоставПутиКДанным = СтрРазделить(ПутьКДаннымКолонки, ".", Ложь); //Валюты; Валюта ИмяКолонкиТаблицы = СоставПутиКДанным[СоставПутиКДанным.ВГраница()]; //Валюта Сообщить("Имя колонки таблицы: " + ИмяКолонкиТаблицы); КонецПроцедуры
- Сейчас проверим
Осталось немного — просто взять значение из колонки и открыть его:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ПутиКДаннымЭлементовФормы = Новый Структура; Для Каждого ЭлементФормы Из ЭтаФорма.Элементы Цикл Если ТипЗнч(ЭлементФормы) = Тип("ПолеФормы") ИЛИ ТипЗнч(ЭлементФормы) = Тип("ТаблицаФормы") Тогда ПутиКДаннымЭлементовФормы.Вставить(ЭлементФормы.Имя, ЭлементФормы.ПутьКДанным); КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиенте Функция ПутьКДаннымЭлементаФормы(ИмяЭлемента) ПутьКДаннымЭлемента = Неопределено; ПутиКДаннымЭлементовФормы.Свойство(ИмяЭлемента, ПутьКДаннымЭлемента); Возврат ПутьКДаннымЭлемента; КонецФункции &НаКлиенте Процедура ОткрытьЗначениеЯчейки(Команда) ТаблицаФормы = Элементы.Валюты; Если ТаблицаФормы.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли; ИмяПоляКолонки = ТаблицаФормы.ТекущийЭлемент.Имя; ПутьКДаннымКолонки = ПутьКДаннымЭлементаФормы(ИмяПоляКолонки); СоставПутиКДанным = СтрРазделить(ПутьКДаннымКолонки, ".", Ложь); ИмяКолонкиТаблицы = СоставПутиКДанным[СоставПутиКДанным.ВГраница()]; ЗначениеЯчейки = Неопределено; ТаблицаФормы.ТекущиеДанные.Свойство(ИмяКолонкиТаблицы, ЗначениеЯчейки); ПоказатьЗначение(Новый ОписаниеОповещения, ЗначениеЯчейки); КонецПроцедуры
Замечательно! Инструмент заработал. И теперь уже значение будет открываться независимо от того, как называется наш элемент формы.
Василий уже прикинул в голове способы применения этого кода. Например, у нас есть табличная часть документа, которую нельзя редактировать. Наш разработчик ставит на таблицу ТолькоПросмотр, а так же подвязывает событие «Выбор», в котором открывает текущее значение.
И как только наш начинающий программист подумал об этом, в голову пришла мысль.
- Недостаточно удобно!
Да, этого мало. Василий хочет сделать ещё круче! Он решает переспать с этой мыслью, чтобы уже позже продолжить свой путь от простой задачи к универсальному механизму...
Понравилась статья?
Дамы и господа 1Сники. Не будьте равнодушными. Каждая ваша "звёздочка" порадует и автора и программиста Васю. Ведь это показатель того, что кому-то текст зашёл, а значит и время было потрачено не зря.
Ну а после переходите к другим работам.
"Меньше копипаста!", или как Вася универсальную процедуру писал
Сортируем ДанныеФормыДерево на клиенте
Не провоцируйте СКД, или пример "как не надо"