Получить реквизит формы в запросе 1с
gvk2009 подробно и доходчиво описал разницу методов, за что ему огромное спасибо:
В Синтаксис-Помощнике очень скупо написано о процедуре ДанныеФормыВЗначение(), чуть побольше - о РеквизитФормыВЗначение(). И совсем нет примеров использования. Попробуем с этим разобраться.
РеквизитФормыВЗначение()
Является методом управляемой формы, компилируется только &НаСервере, контекст формы является для него необходимым, поэтому компиляция &НаСервереБезКонтекста недоступна. На клиенте не работает, поскольку в результате получаем прикладной объект.
Где и когда его нужно использовать?
Метод РеквизитФормыВЗначение() необходим, если требуется из модуля формы вызвать стандартный метод объекта или метод (процедуру, функцию) из модуля объекта, из общего модуля.
Этот метод будет отрабатывать с данными, взятыми из формы, т.е. еще не записанными в базу.
Для того, чтобы измененные данные вернуть на форму, используется метод ЗначениеВРеквизитФормы().
Вторым параметром метода РеквизитФормыВЗначение является тип значения. Это необязательный параметр. Если обрабатываемый реквизит не является составным типом, то тип будет автоматически получен из реквизита формы. Иначе генерируется исключение времени выполнения.
В указанных выше случаях метод РеквизитФормыВЗначение() похож на метод ПолучитьОбъект(). Разница в том, что первый получает объект, заполненный данными формы, а второй - объект с данными из базы.
ДанныеФормыВзначение()
В отличие от метода управляемой формы РеквизитФормыВЗначение(), процедура глобального контекста ДанныеФормыВЗначение() может работать без контекста формы, но именно поэтому, в частности, ей необходимо указывать тип конвертируемых данных.
Обратной процедурой является ЗначениеВДанныеФормы().
В этом примере на форме отображен набор записей регистра бухгалтерии. При отработке процедуры, активность набора меняется только на форме, в базе при этом ничего не происходит. Активность у набора записей регистра в базе поменяется только после выполнения операции Записать.
В этом примере на клиент возвращается ОснРеквизит, содержащий измененные данные. Но его еще нужно "запихать" в отображаемую форму. Для этого используем процедуру глобального контекста КопироватьДанныеФормы().
В большинстве случаев процедуры ДанныеФормыВзначение() и РеквизитФормыВЗначение() взаимозаменяемы. При этом РеквизитФормыВЗначение проще в использовании. Но если требуется использование &НаСервереБезКонтекста - тогда только ДанныеФормыВЗначение.
Общий принцип оптимизации заключается в сокрашении количества обращений к базе данных. Для этого в линейном алгоритме анализируем, что за объект перед нами, если это ссылка, то описываем запрос, с помощью которого получаем все данные и в дальнейшем работаем с результатом запроса.
Задача: Описать функции позволяющие получить значения реквизитов различных объектов (независимо от типа объекта). Но ограничимся объектами метаданных конфигурации, которые могут иметь ссылочный тип данных: Справочники, Документы и т.п.
Описанные далее функции желательно располагать в общем серверном модуле без возможности вызова сервера. Если будет возможность вызывать данные функции с клиента, то злоумышленник сможет получить любые данные из базы без особого труда.
Определимся с параметрами:
- Объект - объект, данные которого необходимо получить;
- ИменаРеквизитов - Список имен реквизитов, данные которых необходимо получить. Если спиок не указан, то предполагаем, что нужно получить данные всех реквизитов;
- ДополнительныеРеквизиты - Структура, с помошью которой можно было бы описать дополнительные данные, которые нужно получить вместе с реквизитами объекта (без использования явных соединений с другими таблицами) или выполнение каких-то действий с полями выборки на языке запросов. В ключе элемента структуры описываем имя реквизита в общем списке реквизитов объекта, в значении - поле выборки или алгоритм обработки полей выборки на языке запросов.
Функция ДанныеРеквизитовОбъекта ( Объект , ИменаРеквизитов = Неопределено,
ДополнительныеРеквизиты = Неопределено) Экспорт
Разберем, значения каких реквизитов необходимо получить из базы и приведем список имен к типу данных Массив.
СтруктураОбъекта = Новый Структура ;
МетаданныеОбъекта = Объект . Метаданные ();
Если ИменаРеквизитов = Неопределено тогда
МассивИменРеквизитов = МассивИменРеквизитовОбъекта ( Объект );
иначе
Если ТипЗнч ( ИменаРеквизитов ) = Тип ( "Массив" ) тогда
МассивИменРеквизитов = ИменаРеквизитов ;
иначеЕсли ТипЗнч ( ИменаРеквизитов ) = Тип ( "Строка" ) тогда
МассивИменРеквизитов = МассивПодстрокИзСтроки ( ИменаРеквизитов );
КонецЕсли;
КонецЕсли;
Если список имен не задан, то с помощью функции МассивИменРеквизитовОбъекта () получим массив имен всех реквизитов объекта (алгоритм этой функции смотри ниже).
Если список имен задан в виде строки разделенной запятыми, то разложим ее на подстроки с помошью функции МассивПодстрокИзСтроки () . Это не сложная задача, алгоритм этой функции разбирать не будем.
Далее с помошью функции ЭтоСсылка () определим, является ли объект ссылочным типом. Для ссылочных типов значения необходимо получить из БД, в противном случае значения реквизитов хранятся в памяти.
ЭтоСсылка = ЭтоСсылка ( Объект );
СсылкаОбъекта = ?( ЭтоСсылка , Объект , Объект . Ссылка );
ПолучитьДанныеИзОбъекта = НЕ ЭтоСсылка ;
Если ЭтоСсылка И СсылкаОбъекта . Пустая () тогда
// это пустая ссылка (данных в базе нет)
ПолучитьДанныеИзОбъекта = Истина;
КонецЕсли;
Теперь, если данные объекта хранятся в памяти - мы можем их сразу получить, в противном случае необходио подготовиться для составления запроса к БД (переведем список имен реквизитов из типа данных Массив в тип Структура).
ОсновныеРеквизиты = Новый Структура ;
Для каждого ИмяРеквизита Из МассивИменРеквизитов Цикл
Если ПолучитьДанныеИзОбъекта тогда
СтруктураОбъекта . Вставить ( ИмяРеквизита , Объект [ ИмяРеквизита ]);
иначе
ОсновныеРеквизиты . Вставить ( ИмяРеквизита );
КонецЕсли;
КонецЦикла;
Все готово к составлению запроса чтобы получить значения реквизитов если перед нами объект ссылочного типа, а так же для получения дополнительных реквизитов, описанных в 3-ем параметре функции. Но смысл всех этих действий есть, только если данный объект существует в БД (на него есть ссылка).
Для начала составим текст запроса для полей выборки поочередно обходя структуры Основных и Дополнительных реквизитов
Если НЕ СсылкаОбъекта . Пустая () тогда
// сформируем текст выборки по реквизитам
ТекстВыборкиРеквизиты = "" ;
Для индекс = 0 по 1 Цикл
СтруктураРеквизитов = ?( индекс = 0 , ОсновныеРеквизиты , ДополнительныеРеквизиты );
Если СтруктураРеквизитов = Неопределено тогда
Продолжить;
КонецЕсли;
Для каждого ЭлементСтруктуры из СтруктураРеквизитов Цикл
Если НЕ МетаданныеОбъекта . ТабличныеЧасти . Найти ( ЭлементСтруктуры . Ключ ) = Неопределено тогда
// это имя табличной части
Продолжить;
КонецЕсли;
ТекстВыборкиРеквизиты = ТекстВыборкиРеквизиты
+ ?( ПустаяСтрока ( ТекстВыборкиРеквизиты ), "" , "," + Символы . ПС )
+ ?( ЗначениеЗаполнено ( ЭлементСтруктуры . Значение ), ЭлементСтруктуры . Значение , ЭлементСтруктуры . Ключ )
+ " КАК " + ЭлементСтруктуры . Ключ ;
КонецЦикла;
КонецЦикла;
Теперь соберем текст запроса и выполним его. Результат запроса добавим в общую структуру данных объекта
// получим реквизиты одним запросом
Если НЕ ПустаяСтрока ( ТекстВыборкиРеквизиты ) тогда
Запрос = Новый Запрос ;
Запрос . Текст = "ВЫБРАТЬ
|" + ТекстВыборкиРеквизиты + "
|ИЗ
| " + МетаданныеОбъекта . ПолноеИмя () + "
|ГДЕ
| Ссылка = &Ссылка" ;
Запрос . УстановитьПараметр ( "Ссылка" , СсылкаОбъекта );
РезультатЗапроса = Запрос . Выполнить ();
Выборка = РезультатЗапроса . Выбрать ();
Если Выборка . Следующий () тогда
Для каждого Колонка из РезультатЗапроса . Колонки Цикл
СтруктураОбъекта . Вставить ( Колонка . Имя , Выборка [ Колонка . Имя ]);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Все данные получены, можно завершать функцию
Достоинства алгоритма:
- Может работать с различными типами объектов конфигурации (которые могут иметь ссылки: Справочники, Документы, ПВХ и т.п.);
- Получение всех реквизитов за одно обращение к БД;
- Данные возвращаются в виде структуры, что позволяет их передать далее на клиент без преобразования;
- С помошью Дополнительных реквизитов можно получить вспомогательные данные (обращение к полям выборки через несколько точек) или на уровне запроса выполнить какие-то действия с данными.
- Наглядность кода, данные получаются одной функцией, без надобности каждый раз писать запрос к БД с обработкой результата.
Недостатки:
- Не реализована возможность получения табличных частей объектов
Дополнительные функции использованные в алгоритме:
// Возвращает массив имен всех реквизитов переданного объекта
//
Функция МассивИменРеквизитовОбъекта ( Объект ) Экспорт
МассивИменРеквизитов = Новый Массив ;
Если ТипЗнч ( Объект ) = Тип ( "ОбъектМетаданных" ) тогда
МетаданныеОбъекта = Объект ;
иначе
МетаданныеОбъекта = Метаданные . НайтиПоТипу ( ТипЗнч ( Объект ));
Если МетаданныеОбъекта = Неопределено тогда
Возврат МассивИменРеквизитов ;
КонецЕсли;
КонецЕсли;
Для индекс = 0 по 1 Цикл
КоллекцияРеквизитов = ?( индекс = 0 , МетаданныеОбъекта . СтандартныеРеквизиты , МетаданныеОбъекта . Реквизиты );
Для Каждого Реквизит Из КоллекцияРеквизитов Цикл
МассивИменРеквизитов . Добавить ( Реквизит . Имя );
КонецЦикла;
КонецЦикла;
Для каждого ОбщийРеквизит Из Метаданные . ОбщиеРеквизиты Цикл
Если ИспользуетсяОбщийРеквизит ( ОбщийРеквизит , МетаданныеОбъекта ) тогда
МассивИменРеквизитов . Добавить ( ОбщийРеквизит . Имя );
КонецЕсли;
КонецЦикла;
// Проверяет используется ли в Объекте указанный общий реквизит
//
Функция ИспользуетсяОбщийРеквизит ( ОбщийРеквизит , Объект ) Экспорт
Если ТипЗнч ( Объект ) = Тип ( "ОбъектМетаданных" ) тогда
МетаданныеОбъекта = Объект ;
иначе
МетаданныеОбъекта = Метаданные . НайтиПоТипу ( ТипЗнч ( Объект ));
Если МетаданныеОбъекта = Неопределено тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если ТипЗнч ( ОбщийРеквизит ) = Тип ( "ОбъектМетаданных" ) тогда
МетаданныеОбщегоРеквизита = ОбщийРеквизит ;
иначе
МетаданныеОбщегоРеквизита = Метаданные . ОбщиеРеквизиты . Найти ( ОбщийРеквизит );
Если МетаданныеОбщегоРеквизита = Неопределено тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ЭлементСостава = МетаданныеОбщегоРеквизита . Состав . Найти ( МетаданныеОбъекта );
Если ЭлементСостава = Неопределено тогда
Возврат Ложь;
КонецЕсли;
пИспользованиеОбщегоРеквизита = Метаданные . СвойстваОбъектов . ИспользованиеОбщегоРеквизита ;
Если ЭлементСостава . Использование = пИспользованиеОбщегоРеквизита . Использовать тогда
Возврат Истина;
иначеЕсли ЭлементСостава . Использование = пИспользованиеОбщегоРеквизита . НеИспользовать тогда
Возврат Ложь;
иначе
пАвтоИспользованиеОбщегоРеквизита = Метаданные . СвойстваОбъектов . АвтоИспользованиеОбщегоРеквизита ;
Если МетаданныеОбщегоРеквизита . АвтоИспользование = пАвтоИспользованиеОбщегоРеквизита . Использовать тогда
Возврат Истина;
иначе
Возврат Ложь;
КонецЕсли;
КонецЕсли;
В обычном приложении у элемента формы 1С 8.3 было свойство "Значение", доступное как для чтения, так и для записи. Какой аналог в управляемом приложении?
Элементы формы 1С 8.3 могут содержать реквизиты двух видов: реквизиты объекта 1С и реквизиты формы.
Красным помечен реквизит объекта 1С Контрагент, а зеленым – реквизит формы в 1С.
Интерактивно выберем эти элементы в пользовательском режиме 1С и попробуем прочитать их «программно» кнопкой «Прочитать».
Если читать значения реквизитов в клиентской процедуре, то код для 1С Предприятия будет следующий:
Все бы хорошо: мы получили на клиенте значения реквизитов объекта 1С и формы, но – не значения элементов формы 1С. На клиенте значение элементов формы 1С получить нельзя.
2. Как получить значения из элементов формы 1С
Чтобы получить значения из элементов формы 1С, нам потребуется серверный вызов:
Именно на сервере у элемента формы 1С 8.3 становится доступно свойство ПутьКДанным, по которому его можно извлечь либо из Объекта, который имеет тип ДанныеФормыСтруктура:
…либо из Формы, которая имеет тип ФормаКлиентскогоПриложения:
Форма и ее элементы не видны на сервере без контекста. То есть код для 1С:Предприятия выдаст множество ошибок.
Также Форму нельзя передать как параметр в процедуру и функцию на сервер или в общий модуль.
Еще хочется разобрать момент, когда нам возможно увидеть состояние различающихся значений в элементе форме 1С и в объекте. Это возможно в событии элемента ОбработкаВыбора.
Например, при значении поля Контрагент - Ассоль, мы выбрали контрагента Бакалея:
Нужно вывести на форму список значений со списком типов цен.
Реквизит должен быть не реквизитом объекта, а реквизитом формы.
Что бы получить значение элемента (реквизита) формы нужно написать следующее:
Код 1C v 8.2 УП
Через "ЭтаФорма" также можно достучаться и к элементам "Объект".
Код 1C v 8.2 УП
Похожие FAQ
Как заполнить табличную часть формы программно? 6Нужно по кнопке Заполнить - сформировать данные для заполнения табличных частей и заполнить их. Форма имеет вид: Рядом с кнопкой Записать и закрыть добавлена кнопка Заполнить документ , код ее команды: // Код заполнения ТЧ НаСервере П 17 правил для составления оптимального ЗАПРОСа к данным базы 1С 42
Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос . Создается этот объект вызовом конструкции Новый Запрос . Запрос удобно использовать, когда требуется получ 1C и Google Maps 20
была поставлена задача отображения на географической карте медицинских учреждений. После обзора предлагаемых решений был выбран сервис google. Но так же подобного рода подход будет работать и с картами сервиса yandex. Во время решения задачи было реш 1C: Enterprise Development Tools 50
И вот случилось долгожданное: Вышел 1C: Enterprise Development Tools - это среда для разработки конфигурации в IDE Eclipse. С сайта 1С: « 1C:Enterprise Development Tools » – это инструмент нового поколения для разработчиков бизнес-приложений систем 1С Предприятие что это? 11
Что такое 1С? 1С — это фирма , у которой одно из направлений деятельности — разработка программного обеспечения для автоматизации бизнес-процессов предприятий. « 1С:Предприятие » - конкретный продукт, который выпускает компания 1С . Что такое Посмотреть все результаты поиска похожих
Еще в этой же категории
Как обновить динамический список или реквизит на форме клиента? 19Если вы, открыв форму справочника или документа, выполнили некоторое действие, код который должен изменить состояние данных в динамических списках или значение реквизита. Данные изменены, но в открытой форме осталось все как было, можно конечно закр Динамический список
Как на управляемой форме разместить список регистра сведений с отбором? 18
Решение рассмотрено для элемента справочника (Контрагент и регистр КонтактнаяИнформация) 1. Создание реквизита: Добавляем новый реквизит формы (. не путать с реквизитом справочника . ) с типом " ДинамическийСписок" В поле " Основная табли Как установить параметр динамического списка? 14
Когда используете для вывода данных динамический список и произвольный запрос, то бывают ситуации когда надо указать параметр используемый в этом запросе. Ниже пример вывода данных регистра сведений в карточке клиента Для вывода используется исп Форма
Программное создание таблицы значений с условным оформлением 12
Как создать на форме таблицу и сделать для нее подсветку содержимого колонки в строке по условию? Итак для начала нам надо добавить реквизиты в форму. Для этого у нас есть метод: ИзменитьРеквизиты(). Перед тем как его использовать мы сформируем ма Поле выбора
Заполнение списка значений в элементе поле выбора на форме 10
//Заполнение списка перебором данных // Элемент формы МетаданныеВыбор имеет тип - Произвольный, Использование - Режим выбора из Списка, кнопка списка Для Каждого Метаданное из Метаданные.РегламентныеЗадания Цикл ЭлементыФормы.МетаданныеВыбор.Спи Посмотреть все в категории Работа с Формой (Диалог) и её элементами
Читайте также: