Значение реквизита объекта не реквизита формы в базе данных

Преобразование данных прикладных объектов в данные формы и обратно

Для конвертирования прикладных объектов в данные формы и обратно существует набор глобальных методов:

  • ЗначениеВДанныеФормы(),
  • ДанныеФормыВЗначение(),
  • КопироватьДанныеФормы().

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

Во время конвертирования данных формы в прикладной объект нужно учитывать их совместимость.

  • ЗначениеВДанныеФормы() ‑ преобразует объект прикладного типа в данные формы.
  • ДанныеФормыВЗначение() ‑ преобразует данные формы в объект прикладного типа.
  • КопироватьДанныеФормы() ‑ производит копирование данных формы, обладающих совместимой структурой. Возвращает значение Истина, если копирование произведено, или Ложь, если структура объектов несовместима.

При преобразовании данных формы в прикладные объекты и обратно используется кеширование объектов, но при этом выполняется проверка актуальности версии объекта в кеше.

ПРИМЕЧАНИЕ. При выполнении стандартных действий (открытие формы, выполнение стандартной команды Записать и т. д.) в форме с основным реквизитом преобразование выполняется автоматически.

Приведем пример, как использовать преобразование данных в собственных алгоритмах.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ОбъектТовар = Товары.НайтиПоНаименованию("Кофейник").ПолучитьОбъект(); ЗначениеВДанныеФормы(ОбъектТовар, Объект);
КонецПроцедуры
&НаКлиенте
Процедура Записать()
ЗаписатьНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаписатьНаСервере()
ОбъектТовар = ДанныеФормыВЗначение(Объект,Тип("СправочникОбъект.Товары"));
ОбъектТовар.Записать();
КонецПроцедуры

Также у объекта ФормаКлиентскогоПриложения существуют методы, доступные на сервере:

  • ЗначениеВРеквизитФормы() ‑ выполняет преобразование объекта прикладного типа в заданный реквизит формы.
  • РеквизитФормыВЗначение() ‑ преобразует реквизит данных формы в объект прикладного типа.

Использование данных методов обычно удобнее, так как они имеют, например, информацию о типе реквизита формы. Кроме того, метод РеквизитФормыВЗначение() выполняет установку соответствия данных формы и объекта, которая используется при формировании сообщений .

Также следует помнить, что при преобразовании в данные формы (как с помощью метода ЗначениеВДанныеФормы(), так и с помощью метода ЗначениеВРеквизитФормы()) объектов типа ТаблицаЗначений или ДеревоЗначений нужно учитывать следующую особенность: в преобразуемом объекте должны существовать все колонки, которые существуют в данных формы.

ВНИМАНИЕ! Колонки реквизитов, не связанные с данными , не участвуют в преобразовании значений между данными формы и объектами информационной базы и обратно. Колонки, отсутствующие в данных объекта, очищаются при преобразовании в данные формы.

При переносе объекта в данные формы платформой, или при вызове методов ЗначениеВДанныеФормы(), ЗначениеВРеквизитФормы(), переносятся только данные объекта. Внутренние состояние объекта в данные формы не переносится. Например, значение ссылки нового, которая установлена в объект методом УстановитьСсылкуНового(), будет утеряна в процессе преобразования объекта в данные формы и обратно.

В качестве первого параметра методов РеквизитФормыВЗначение() и ДанныеФормыВЗначение() могут выступать только реквизиты формы следующих типов:

  •  ДанныеФормыСтруктура, 
  • ДанныеФормыКоллекция,
  •  ДанныеФормыСтруктураСКоллекцией, 
  • ДанныеФормыДерево.

Приведем пример использования этих методов.

&НаСервере
Процедура ПересчитатьНаСервере()
// Преобразует реквизит Объект в прикладной объект. Документ = РеквизитФормыВЗначение("Объект");
// Выполняет пересчет методом, определенным в модуле документа. Документ.Пересчитать();
// Преобразует прикладной объект обратно в реквизит. ЗначениеВРеквизитФормы(Документ, "Объект");
КонецПроцедуры

Содержание:

1.    Реквизиты объекта и реквизиты формы в 1С

2.    Как получить значения из элементов формы 1С  

1.    Реквизиты объекта и реквизиты формы в 1С

В обычном приложении у элемента формы 1С 8.3 было свойство «Значение», доступное как для чтения, так и для записи. Какой аналог в управляемом приложении?

Элементы формы 1С 8.3 могут содержать реквизиты двух видов: реквизиты объекта 1С и реквизиты формы.

Красным помечен реквизит объекта 1С Контрагент, а зеленым – реквизит формы в 1С.

Интерактивно выберем эти элементы в пользовательском режиме 1С и попробуем прочитать их «программно» кнопкой «Прочитать».

Если читать значения реквизитов в клиентской процедуре, то код для 1С Предприятия будет следующий:


Все бы хорошо: мы получили на клиенте значения реквизитов объекта 1С и формы, но – не значения элементов формы 1С. На клиенте значение элементов формы 1С получить нельзя. 

2.    Как получить значения из элементов формы 1С

Чтобы получить значения из элементов формы 1С, нам потребуется серверный вызов:

Именно на сервере у элемента формы 1С 8.3 становится доступно свойство ПутьКДанным, по которому его можно извлечь либо из Объекта, который имеет тип ДанныеФормыСтруктура:

…либо из Формы, которая имеет тип ФормаКлиентскогоПриложения:


Форма и ее элементы не видны на сервере без контекста. То есть код для 1С:Предприятия выдаст множество ошибок.

Также Форму нельзя передать как параметр в процедуру и функцию на сервер или в общий модуль.


            Еще хочется разобрать момент, когда нам возможно увидеть состояние различающихся значений в элементе форме 1С и в объекте. Это возможно в событии элемента ОбработкаВыбора.
Например, при значении поля Контрагент — Ассоль, мы выбрали контрагента Бакалея:


Новое значение доступно как параметр процедуры ВыбранноеЗначение.


Система дает шанс что-то сделать в этой ситуации.

Специалист компании ООО «Кодерлайн»

Добрыгин Михаил

Не основная форма обработки и содержимое реквизитов объекта

Я
   LisaAlisa

06.05.16 — 12:18

Подскажите. пожалуйста, почему при обращении к процедурам и функциям объекта из модуля неосновной формы обработки не видны значения реквизитов объекта, в частности табличных частей?

«МояТабличнаяЧасть» — реквизит объекта, в отладчике Тип и значение имеет ВнешняяОбработкаТабличнаяЧасть.ВнешняяОбработка1.МояТабличнаяЧасть

  

Партнерская программа EFSOL Oblako

   LisaAlisa

1 — 06.05.16 — 12:23

Форма2 вызывается из основной формы Форма через ОткрытьФорму()

   lubitelxml

2 — 06.05.16 — 12:31

я так понимаю вы про управляемые формы. В процедуре с директивой &НаКлиенте так отображается, попробуйте в процедуре с директивой &НаСервере

   LisaAlisa

3 — 06.05.16 — 13:04

(2) Да, формы управляемые.

В форме2

&НаСервере

Процедура СоздатьНоменклатуруНаСервере()

    ОбработкаОбъект = РеквизитФормыВЗначение(«Объект»);    

    Номенклатура = ОбработкаОбъект.СоздатьНоменклатуру();

КонецПроцедуры

В модуле объекта в процедуре СоздатьНоменклатуру() не видно значения реквизитов объекта

   lubitelxml

4 — 06.05.16 — 13:06

покажите весь код

   LisaAlisa

5 — 06.05.16 — 13:08

(4) чего именно? процедур в модуле формы или модуле объекта?

может, значения реквизитов вообще не видны в экспортных процедурах? СоздатьНоменклатуру() экспортная

   lubitelxml

6 — 06.05.16 — 13:09

СоздатьНоменклатуру() покажи. Это процедура модуля объекта или модуля менеджера?

   LisaAlisa

7 — 06.05.16 — 13:10

Это функция в модуле объекта

Функция СоздатьНоменклатуру(Строка) Экспорт

    
    НоменклатураСсылка = Справочники.Номенклатура.НайтиПоРеквизиту(«Артикул»,Строка.Артикул);

    
    Если НоменклатураСсылка = Справочники.Номенклатура.ПустаяСсылка() Тогда

        
        НоменклатураНовый = Справочники.Номенклатура.СоздатьЭлемент();

        НоменклатураНовый.АлкогольнаяПродукция                        = Истина;

        НоменклатураНовый.Артикул                                        = Строка.Артикул;

        НоменклатураНовый.Наименование                                    = Строка.Наименование;

        НоменклатураНовый.НаименованиеПолное                        = Строка.ПолноеНаименование;

        НоменклатураНовый.ВидНоменклатуры                              = Справочники.ВидыНоменклатуры.НайтиПоНаименованию(«Товар-алкоголь»);

        НоменклатураНовый.ТипНоменклатуры                              = Перечисления.ТипыНоменклатуры.Товар;

        НоменклатураНовый.СтавкаНДС                                 = ПолучитьСтавкуНДС(Строка.СтавкаНДС);

        НоменклатураНовый.ЕдиницаИзмерения                             = Справочники.БазовыеЕдиницыИзмерения.НайтиПоНаименованию(«шт»);

        НоменклатураНовый.Родитель                                    = Справочники.Номенклатура.НайтиПоНаименованию(Строка.ВидНоменклатуры);

        Попытка

            НоменклатураНовый.Записать();

            НоменклатураСсылка = НоменклатураНовый.Ссылка;

            Сообщить(«Записан артикул: » + НоменклатураНовый.Артикул + » » + НоменклатураНовый.Наименование);

            Успех = Истина;

        Исключение

            Сообщить(«Артикул «+НоменклатураНовый.Артикул + «. » + ОписаниеОшибки());

            Успех = Ложь;

        КонецПопытки;

        
        Если Не Успех Тогда

            Возврат Справочники.Номенклатура.ПустаяСсылка();

        КонецЕсли;

        
    КонецЕсли;

        
    Возврат НоменклатураСсылка;

КонецФункции

   LisaAlisa

8 — 06.05.16 — 13:11

в (3) я привела максимально упрощенный код

   lubitelxml

9 — 06.05.16 — 13:15

Переменную с именем «Строка» переименуйте

   lubitelxml

10 — 06.05.16 — 13:18

а вообще — код выкинуть и переписать все по нормальному. Почитайте для начала про управляемые формы

   LisaAlisa

11 — 06.05.16 — 13:19

(9) не думаю, что дело в имени переменной, потому что в других процедурах так же недоступны значения объекта

   rozer76

12 — 06.05.16 — 13:59

(3) в «Объект» точно тот объект экспортные функции которого которые хотите вызвать?

   rozer76

13 — 06.05.16 — 14:02

(12) + тип посмотрите его

   LisaAlisa

14 — 11.05.16 — 10:05

(13) объект имеет тип ДанныеФормыСтруктура,

ОбработкаОбъект — ВнешняяОбработкаОбъект.ВнешняяОбработка1

   LisaAlisa

15 — 11.05.16 — 10:16

Вот та же проблема с еще одной формой этой обработки. Это процедуры описаны в НЕосновной форме объекта. В процедуре СоздатьКонтрагентов() я могу увидеть значения реквизитов только через ЭтаФорма.ВладелецФормы.Объект, но в СоздатьКонтрагентовНаСервере() это уже недоступно.

Там же переходя в ОбработкаОбъект.СоздатьПартнеровКонтрагентов(ТаблицаНесопоставленныхКонтрагентов); выполнение переходит в процедуру модуля объекта СоздатьПартнеровКонтрагентов(), но при этом все реквизиты объекта имеют значения неопределено

&НаСервере

Процедура СоздатьКонтрагентовНаСервере()

    ОбработкаОбъект = РеквизитФормыВЗначение(«Объект»);

    ОбработкаОбъект.СоздатьПартнеровКонтрагентов(ТаблицаНесопоставленныхКонтрагентов);

    ЗначениеВРеквизитФормы(ОбработкаОбъект, «Объект»);

КонецПроцедуры

&НаКлиенте

Процедура СоздатьКонтрагентов(Команда)

    СоздатьКонтрагентовНаСервере();

    ЭтаФорма.Закрыть();

КонецПроцедуры

   RomanYS

16 — 11.05.16 — 10:19

(7) ээээ… А где там обращение к «реквизитам объекта»?

   LisaAlisa

17 — 11.05.16 — 10:23

(16) обращение идет в процедуре, описанной в модуле объекта.

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

   RomanYS

18 — 11.05.16 — 10:30

(17) ближе к делу. Ты приводишь куски кода, а потом говоришь что не работает где-то «там» в другом месте. Где и что у тебя не получается.

   LisaAlisa

19 — 11.05.16 — 10:42

(18) ок.

Из формы (не основной) я обращаюсь к функции модуля объекта. Из одной формы я обращаюсь к функции создания номенклатуры, из другой — к процедуре создания контрагентов. В (7) я описала, как создаю номенклатуру, она записывается успешно. После этого я должна в «МояТабличнаяЧасть» — реквизит объекта — записать эту новую номенклатуру, а так же записать её в таблицу-реквизит формы. но «МояТабличнаяЧасть» имеет тип неопределено и в процедуре модуля объекта, и в процедуре формы. поэтому не могу это сделать. Функция СоздатьНоменклатуру() имеет Возврат НоменклатураСсылка; — но это значение не возвращается в форму, поэтому не могу заполнить и таблицу формы.

Получается, элемент создала, но не могу его записать ни в объект, ни в реквизит формы.

Форму открываю так

        ОткрытьФорму(

            ДополнительныеПараметры.ИмяФормы,

            Новый Структура(«ТаблицаНесоответствий», ДополнительныеПараметры.Таблица),

            ЭтотОбъект,,,,

            Новый ОписаниеОповещения(«СопоставлениеЗавершение», ЭтотОбъект, ДополнительныеПараметры));

   LisaAlisa

20 — 11.05.16 — 10:45

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

   RomanYS

21 — 11.05.16 — 10:49

(19) МояТабличнаяЧасть — это реквизит (не табличная часть?) обработки? Какого она типа (по метаданным обработки)? Что ты в неё пытаешься засунуть(присвоить)?

   LisaAlisa

22 — 11.05.16 — 10:53

МояТабличнаяЧасть — реквизит объекта, табличная часть. Я пытаюсь перебрать строки этой ТЧ и некоторые из них заполнить ссылкой на созданную номенклатуру. НО она недоступна,пустая в момент создания номенклатуры, хотя на самом деле строки есть

   RomanYS

23 — 11.05.16 — 11:18

(22) «реквизит объекта, табличная часть» = ТЧ обработки?

«недоступна» это как?

«пустая» — всё таки это ТЧ, в (19) утверждалось, что неопределено.

(20) опять тоже самое, ты приводишь код, который работает. А спрашиваешь почему не работал код, который ты убрала.

Покажи ошибку и тебе (может быть) объяснят почему она возникает.

   LisaAlisa

24 — 11.05.16 — 11:40

Функция СоздатьНоменклатуру(Строка) Экспорт

    
        НоменклатураНовый = Справочники.Номенклатура.СоздатьЭлемент();

        НоменклатураНовый.АлкогольнаяПродукция                        = Истина;

        НоменклатураНовый.Артикул                                        = Строка.Артикул;

        НоменклатураНовый.Наименование                                    = Строка.Наименование;

        НоменклатураНовый.НаименованиеПолное                        = Строка.ПолноеНаименование;

        
        Попытка

            НоменклатураНовый.Записать();

            НоменклатураСсылка = НоменклатураНовый.Ссылка;

        Исключение

            Сообщить(«Артикул «+НоменклатураНовый.Артикул + «. » + ОписаниеОшибки());

        КонецПопытки;

        
        Если Не Успех Тогда

            Возврат Справочники.Номенклатура.ПустаяСсылка();

        КонецЕсли;

        Отбор = Новый Структура(«Артикул»,Строка.Артикул);

        МассивСтрок = МояТабличнаяЧасть.НайтиСтроки(Отбор);

        Для каждого СтрокаМассива Из МассивСтрок Цикл

            СтрокаМассива.НоменкалтураСсылка = НоменклатураСсылка;

        КонецЦикла;

            
    Возврат НоменклатураСсылка;

КонецФункции

Не записывается ничего в «МояТабличнаяЧасть», если эту функцию вызываю из неосновной формы. В этом случае МояТабличнаяЧасть имеет значение ВнешняяОбработкаТабличнаяЧасть.ВнешняяОбработка1.МояТабличнаяЧасть, тип такой же ВнешняяОбработкаТабличнаяЧасть.ВнешняяОбработка1.МояТабличнаяЧасть

   LisaAlisa

25 — 11.05.16 — 11:52

в отладчике не видно ни колонок ТЧ, ни значений

   RomanYS

26 — 11.05.16 — 12:17

(24) Если ТЧ пустая, то твой код её не изменит.

Покажи результат:

&НаСервере

Процедура СоздатьКонтрагентовНаСервере()

Сообщить(«на форме: «+ Объект.МояТабличнаяЧасть.Количество());

    ОбработкаОбъект = РеквизитФормыВЗначение(«Объект»);

Сообщить(«у обработки: «+ ОбработкаОбъект.МояТабличнаяЧасть.Количество());

    ОбработкаОбъект.СоздатьПартнеровКонтрагентов(ТаблицаНесопоставленныхКонтрагентов);

    ЗначениеВРеквизитФормы(ОбработкаОбъект, «Объект»);

КонецПроцедуры

   LisaAlisa

27 — 11.05.16 — 12:36

результат

На форме: 0

У обработки: 0

Хотя ТЧ совершенно точно заполнена, она заполняется в основной форме, откуда и вызывается форма сопоставления контрагентов

   BlackBytes

28 — 11.05.16 — 13:07

а где и когда заполнялась МояТабличнаяЧасть?

Отбор = Новый Структура(«Артикул»,Строка.Артикул);

        МассивСтрок = МояТабличнаяЧасть.НайтиСтроки(Отбор);

        Для каждого СтрокаМассива Из МассивСтрок Цикл

        СтрокаМассива.НоменкалтураСсылка = НоменклатураСсылка;

        КонецЦикла;

тут отладчиком и смотри есть или нету

   RomanYS

29 — 11.05.16 — 13:11

(27) ну вот ты и добралась до правильного вопроса «Как в УФ передать контекст из одной формы (обработки) в другую форму (при её открытии)?»

   LisaAlisa

30 — 11.05.16 — 13:39

(29) т.е. в дополнительные параметры надо передать объект?

   LisaAlisa

31 — 12.05.16 — 08:39

(28) ТЧ заполнялась в основной форме обработки, из которой вызывается форма сопоставления контрагентов

   RomanYS

32 — 12.05.16 — 09:08

+(29) общего контекста/объекта у форм нет, поэтому контекст этот надо передавать явно, например

КопироватьДанныеФормы(ЭтаФорма.ВладелецФормы.Объект, Объект);

И не забыть потом вернуть данные обратно.

Если на допформе ТЧ не отображается, то проще редактировать ТЧ основной формы:

ТЧ = ЭтаФорма.ВладелецФормы.Объект.МояТабличнаяЧасть;

МассивСтрок = ТЧ.НайтиСтроки(Отбор);

  

LisaAlisa

33 — 12.05.16 — 10:13

RomanYS , огромное спасибо!!! Вы мне очень помогли!!!

  1. подскажите, как получить значение реквизита формы(но не объекта) из другого места, что бы его можно было передать в ячейку отчёта, при этом не открывая саму форму искомого объекта?


  2. lazy

    Offline

    lazy
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 сен 2007
    Сообщения:
    2.127
    Симпатии:
    4
    Баллы:
    29

    Форма — это объект. Его можно создать, но не открывать (метод Открыть()). Реквизиты формы можно условно разделить на два типа — связанные с данными в конфигурации, и реквизиты самой формы. Про данные конфигурации все понятно. Проблема в том, что при создании формы — ее реквизиты ничем не заполнены. Их заполняет пользователь ручками, или код (например запускающийся из процедуры ПриОткрытии() ) Т.е. создать то форму не открывая можно, а данные в нее кто внесет?

  3. суть проблемы не в записи данных при создании новой формы, а наоборот, в извлечении из формы уже созданного документа, необходимо извлеч из формы данные реквизитов формы…..
    но как?


  4. lazy

    Offline

    lazy
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 сен 2007
    Сообщения:
    2.127
    Симпатии:
    4
    Баллы:
    29

    Понятно, хотите получить данные из формы открытого в данный момент документа. Посмотрите на метод ПолучитьФорму() в частности на третий параметр «КлючУникальности». Вот выдержка из Синтаксис помошника:И вот, что пишут про сам КлючУникальности:
    Сам я с данной штукой не работал, но по всей видимости рыть нужно в данном направлении — пробовать присвоить форме Ключ, а затем по этому ключу получить форму. И соответственно ее реквизиты…

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


  6. soltik

    Offline

    soltik

    Регистрация:
    26 ноя 2007
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1

    насколько я понимаю, пока форма не открыта ее данных просто нет, они формируются во время открытия на основе данных объекта формы или других данных в соответствии с логикой процедуры ПриОткрытии()

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


  8. lazy

    Offline

    lazy
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 сен 2007
    Сообщения:
    2.127
    Симпатии:
    4
    Баллы:
    29

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

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

    P.S. Почитайте на досуге про формы, реквизиты формы и чем они отличаются от реквизитов прочих объектов(справочников, документов), предопределенные процедуры формы…

  9. вообщем решид проблему сам.
    предлагаю простой вариант ответа на свой вопрос, вдруг кому понадобиться.

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

    для того чтобы получить данные реквизитов формы(!), необходимо проделать следующее:
    выбрать элемент,обратиться к форме этого документа, открыть её и обратиться к реквизиту формы как к обычному реквизиту документа, затем следует закрыть форму.


  10. OksM

    Offline

    OksM
    Опытный в 1С

    Регистрация:
    15 окт 2007
    Сообщения:
    76
    Симпатии:
    0
    Баллы:
    26

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


  11. lazy

    Offline

    lazy
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 сен 2007
    Сообщения:
    2.127
    Симпатии:
    4
    Баллы:
    29

    OksM тссс, изобретение велосипедов — важный этап в становлении любого 1Сника :)


  12. AlexFF

    Offline

    AlexFF
    Разбирающийся

    Регистрация:
    6 мар 2007
    Сообщения:
    565
    Симпатии:
    1
    Баллы:
    26


1C-pro.ru - форум по 1С:Предприятию 7.7, 8.0, 8.1, 8.2, 8.3

Первые проблемы

Во времена толстого клиента вызов процедуры модуля объекта из модуля формы был прост. Достаточно было определить процедуру модуля как экспортируемую и вызвать её в модуле формы.

Вызов процедуры модуля в толстом клиенте обычное приложение

Времена меняются, платформу 1С оптимизируют и совершенствуют, толстый клиент забывают, всем подавай тонкий или web-клиент. Разработчики начинают переводить обычные формы на управляемые, но не все так просто, появляются некоторые сложности в связи с разделением выполнения программного кода на два контекста: сервер и клиент. Поэтому выше приведенный пример кода работать не будет в тонком клиенте.

Новые типы данных

Так же из-за управляемых форм появились новые типы данных. Имеется форма:

Управляемая форма

Запоминаем типы реквизитов и смотрим какие типы в отладке для этих реквизитов:

Новые типы данных формы

Делаем вывод, для отображения данных самого объекта используется тип ДанныеФормыСтруктура, для отображения дерева значений — ДанныеФормыДерево, для табличной части — ДанныеФормыКоллекция и т.д. То есть  в модуле формы на клиенте мы работаем не с самим объектом а с его представлением! Поэтому, методы, которые доступны, например, для табличной части в модуле объекта НЕ ДОСТУПНЫ в модуле формы.

Борьба с новыми типами

Разработчики платформы 1С предоставили две функции:

  1. РеквизитФормыВЗначение — преобразует указанный реквизит формы в объект прикладного типа.
  2. ДанныеФормыВЗначение — преобразует данные формы в объект прикладного типа.

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

СпрОбъект1 = РеквизитФормыВЗначение("Объект");
СпрОбъект1.ВывестиСообщение(Объект.Реквизит1);

СпрОбъект2 = ДанныеФормыВЗначение(Объект, Тип("СправочникОбъект.Справочник1"));
СпрОбъект2.ВывестиСообщение(Объект.Реквизит1);

КонецПроцедуры

Работает и с помощью одной функции и с помощью другой О_о. Напишем код по преобразованию ДанныеФормыДерево в объект прикладного типа:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ДеревоЗначений1 = РеквизитФормыВЗначение("Реквизит1");
ДеревоЗначений2 = ДанныеФормыВЗначение(ЭтаФорма.Реквизит1, Тип("ДеревоЗначений"));

КонецПроцедуры

ДеревоЗначений1 и ДеревоЗначений2 имеют одинаковый тип — ДеревоЗначений. Так в чем же разница этих функций???

ДанныеФормыВЗначение — функция глобального контекста. Производит преобразование типа объекта поддерживаемого формой в тип объекта базы данных: ДанныеФормыСтруктура —> СправочникОбъект.Справочник1.

РеквизитФормыВЗначение — функция модуля формы, то есть вызывается на сервере в контексте формы (&НаСервере). Если вы попытаетесь вызвать данную функцию вне контексте формы, то платформа сгенерирует исключительную ошибку:

&НаСервереБезКонтекста
Процедура ПреобразованиеТипа()

// Этот код неправильный, контекст формы не доступен, будет ошибка!
СпрОбъект2 = РеквизитФормыВЗначение(Объект, Тип("СправочникОбъект.Справочник1"));
СпрОбъект2.ВывестиСообщение(Объект.Реквизит1);

КонецПроцедуры

Вот и все отличия.

Содержание

  • 1 Реквизиты формы
    • 1.1 Типы данных, доступные в управляемой форме
    • 1.2 Преобразование прикладных объектов в данные формы
    • 1.3 Передача данных между клиентской и серверной частями управляемой формы
    • 1.4 Методы для преобразования данных прикладных объектов в данные формы
  • 2 Программный интерфейс
    • 2.1 ДанныеФормыДерево (FormDataTree)
      • 2.1.1 ПолучитьЭлементы (GetItems)
      • 2.1.2 НайтиПоИдентификатору (FindById)
    • 2.2 ДанныеФормыЭлементДерева (FormDataTreeItem)
    • 2.3 ДанныеФормыКоллекцияЭлементовДерева (FormDataTreeItemCollection)
  • 3 Особенности работы с деревом значений
    • 3.1 Обновление дерева

Реквизиты формы

Набор реквизитов формы описывает состав данных, которые отображаются, редактируются или хранятся в форме. При этом реквизиты формы сами по себе не обеспечивают возможности отображения и редактирования данных. Для отображения и редактирования служат элементы формы (смотрите раздел «Элементы формы» данной главы), связанные с реквизитами формы. Совокупность всех реквизитов формы будем называть данными формы.

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

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

Расширение формы – это дополнительные свойства, методы и параметры формы объекта УправляемаяФорма, характерные для объекта, являющегося основным элементом формы.

В процессе разработки формы можно явно задать возможность просмотра и редактирования конкретных реквизитов формы, в разрезе ролей, с помощью свойств Просмотр и Редактирование (подробнее смотрите раздел «Ролевая настройка формы» главы «Редакторы»). Кроме того, доступность того или иного реквизита в самой форме можно настраивать с помощью функциональных опций (подробнее о функциональных опциях можно посмотреть в главе «Управление интерфейсом конфигурации»).

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

Типы данных, доступные в управляемой форме

Управляемая форма отличается от обычной формы также и типами данных, с которыми она работает. Если обычная форма работает с большинством типов, которые предоставляет 1С:Предприятие (в том числе и вида СправочникОбъект, ДокументОбъект и т. д.), то в управляемой форме можно выделить следующие категории типов:

  • типы, которые непосредственно используются в форме – это те типы, которые существуют на стороне тонкого и Веб-клиента (например, Число, СправочникСсылка.Товары, ГрафическаяСхема, ТабличныйДокумент);
  • типы, которые будут преобразованы в специальные типы данных – типы данных управляемой формы. Такие типы отображаются в списке реквизитов формы в круглых скобках, например (СправочникОбъект.Товары);
  • динамический список (подробнее см. раздел «Динамический список» данной главы).

Преобразование прикладных объектов в данные формы

Некоторые прикладные типы (такие как СправочникОбъект и т. д.) не существуют на стороне тонкого и Веб-клиентов (подробнее см. главу «Концепция управляемого приложения»). Поэтому для представления в форме таких прикладных типов в платформе введены специальные типы данных, предназначенные для работы в управляемых формах. Эта особенность управляемого приложения обуславливает необходимость выполнять преобразование прикладных объектов в данные формы (и обратно).

Используются следующие типы данных:

  • ДанныеФормыСтруктура – содержит набор свойств произвольного типа. Свойствами могут быть другие структуры, коллекции или структуры с коллекциями. Таким типом представляется, например, в форме СправочникОбъект.
  • ДанныеФормыКоллекция – это список типизированных значений, похожий на массив. Доступ к элементу коллекции осуществляется по индексу или по идентификатору. Доступ по идентификатору может отсутствовать в некоторых случаях. Это обусловлено типом прикладного объекта, который представлен этой коллекцией. Идентификатором может быть любое целое число. Таким типом представляется, например, в форме табличная часть.
  • ДанныеФормыСтруктураСКоллекцией – это объект, который представлен в виде структуры и коллекции одновременно. С ним можно обращаться как с любой из этих сущностей. Таким типом представляется, например, в форме набор записей.
  • ДанныеФормыДерево – объект предназначен для хранения иерархических данных.

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

Например, документ, содержащий табличную часть, будет представлен объектом типа ДанныеФормыСтруктура (собственно документ), которому подчинен объект типа ДанныеФормыКоллекция (табличная часть документа).

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

Передача данных между клиентской и серверной частями управляемой формы

Фактически можно сказать, что данные формы – это унифицированное представление данных различных прикладных объектов, с которыми форма работает единообразно и которые присутствуют и на сервере, и на клиенте. То есть форма содержит некоторую «проекцию» данных прикладных объектов в виде своих собственных типов данных и выполняет преобразование между ними при необходимости. Однако в случае если разработчик конфигурации реализует свой алгоритм обработки данных, то преобразование данных (из специализированных типов в прикладные и обратно) он должен выполнять самостоятельно.

При редактировании реквизитов формы в специализированном редакторе (подробнее см. раздел «Реквизиты формы» главы «Редакторы») имеется возможность влиять на передачу данных между клиентом и сервером во время работы формы. Для этого служит колонка редактора реквизитов Использовать всегда. Действие этого свойства различается для трех типов реквизитов:

  • Для реквизита, подчиненного динамическому списку (колонке динамического списка):
    • свойство включено – реквизит всегда считывается из базы данных и включается в данные формы;
    • свойство выключено – реквизит считывается из базы данных и включается в данные формы только тогда, когда есть видимый в данный момент элемент формы, связанный с реквизитом или его подчиненным реквизитом.
  • Для реквизита, подчиненного коллекции движений:
    • свойство включено – движения документа считываются из базы данных и будут присутствовать в данных формы;
    • свойство выключено – движения документа не будут считываться из базы данных и не попадут в данные формы (если нет элемента формы, ссылающегося на движения документа).
  • Остальные реквизиты формы:
    • свойство включено – реквизит будет присутствовать в данных формы вне зависимости от того, есть или нет хоть один элемент формы, который связан с реквизитом или его подчиненным реквизитом;
    • свойство выключено – реквизит будет присутствовать в данных формы только в том случае, если есть элемент формы, связанный с реквизитом или его подчиненным реквизитом. В отличие от реквизитов динамического списка, здесь не играет роли видимость элемента, связанного с реквизитом.

Примечание. Следует помнить, что свойство, установленное у родительского реквизита, действует на все подчиненные реквизиты. Например, если свойство Использовать всегда снято у табличной части документа, то система считает, что это свойство снято и у всех подчиненных реквизитов (несмотря на фактическое состояние свойства).

Методы для преобразования данных прикладных объектов в данные формы

Для конвертирования прикладных объектов в данные формы и обратно существует набор глобальных методов:

  • ЗначениеВДанныеФормы(),
  • ДанныеФормыВЗначение(),
  • КопироватьДанныеФормы().

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

Во время конвертирования данных формы в прикладной объект нужно учитывать их совместимость.

  • ЗначениеВДанныеФормы() – преобразует объект прикладного типа в данные формы;
  • ДанныеФормыВЗначение() – преобразует данные формы в объект прикладного типа;
  • КопироватьДанныеФормы() – производит копирование данных формы, обладающих совместимой структурой. Возвращает значение Истина, если копирование произведено, или Ложь, если структура объектов несовместима.

Примечание. При выполнении стандартных действий (открытие формы, выполнение стандартной команды Записать и т. д.) формы с основным реквизитом, преобразование выполняется автоматически.

Приведем пример, как использовать преобразование данных в собственных алгоритмах.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
  ОбъектТовар = Справочники.Товары.НайтиПоНаименованию(«Кофейник»).ПолучитьОбъект();
  ЗначениеВДанныеФормы(ОбъектТовар, Объект);
КонецПроцедуры
 
&НаКлиенте
Процедура Записать()
  ЗаписатьНаСервере();
КонецПроцедуры
 
&НаСервере
Процедура ЗаписатьНаСервере()
  ОбъектТовар = ДанныеФормыВЗначение(Объект, Тип(«СправочникОбъект.Товары»));
  ОбъектТовар.Записать();
КонецПроцедуры

Также у объекта УправляемаяФорма существуют методы, доступные на сервере:

  • ЗначениеВРеквизитФормы() – выполняет преобразование объекта прикладного типа в заданный реквизит формы.
  • РеквизитФормыВЗначение() – преобразует реквизит данных формы в объект прикладного типа.

Использование данных методов обычно удобнее, так как они, имеют, например, информацию о типе реквизита формы. Кроме того, метод РеквизитФормыВЗначение() выполняет установку соответствия данных формы и объекта, которая используется при формировании сообщений. Подробнее об этом можно прочитать в главе «Сервисные возможности навигации».

Приведем пример использования этих методов.

&НаСервере
Процедура ПересчитатьНаСервере()
 
  // Преобразует реквизит Объект в прикладной объект.
  Документ = РеквизитФормыВЗначение(«Объект»);
 
  // Выполняет пересчет методом, определенным в модуле документа.
  Документ.Пересчитать();
 
  // Преобразует прикладной объект обратно в реквизит.
  ЗначениеВРеквизитФормы(Документ, «Объект»);
КонецПроцедуры

Программный интерфейс

ДанныеФормыДерево (FormDataTree)

Методы:

  • НайтиПоИдентификатору (FindById)
  • ПолучитьЭлементы (GetItems)

Описание:

Предназначен для моделирования дерева в данных управляемой формы.

Доступность: клиент, сервер, тонкий клиент, веб-клиент. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту определяется в пространстве имен . Имя типа XDTO:

ПолучитьЭлементы (GetItems)

Синтаксис:

ПолучитьЭлементы()

Возвращаемое значение:

Тип: ДанныеФормыКоллекцияЭлементовДерева.

Описание:

Получает коллекцию элементов дерева верхнего уровня.

Доступность: клиент, сервер, тонкий клиент, веб-клиент.

НайтиПоИдентификатору (FindById)

Синтаксис:

НайтиПоИдентификатору(<Идентификатор>)

Параметры:

<Идентификатор> (обязательный)

Тип: Число. Идентификатор элемента дерева.

Возвращаемое значение:

Тип: ДанныеФормыЭлементДерева.

Описание:

Получает элемент коллекции по идентификатору.

Доступность: клиент, сервер, тонкий клиент, веб-клиент.

ДанныеФормыЭлементДерева (FormDataTreeItem)

Свойства:

<Имя свойства> (<Имя свойства>)

Методы:

  • ПолучитьИдентификатор (GetId)
  • ПолучитьРодителя (GetParent)
  • ПолучитьЭлементы (GetItems)
  • Свойство (Property)

Описание:

Элемент дерева данных формы.

Доступность: клиент, сервер, тонкий клиент, веб-клиент. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту определяется в пространстве имен . Имя типа XDTO:

ДанныеФормыКоллекцияЭлементовДерева (FormDataTreeItemCollection)

Элементы коллекции:
ДанныеФормыЭлементДерева

Для объекта доступен обход коллекции посредством оператора Для каждого … Из … Цикл. При обходе выбираются элементы коллекции.
Возможно обращение к элементу коллекции посредством оператора […]. В качестве аргумента передается индекс элемента.

Методы:

  • Вставить (Insert)
  • Добавить (Add)
  • Индекс (IndexOf)
  • Количество (Count)
  • Очистить (Clear)
  • Получить (Get)
  • Сдвинуть (Move)
  • Удалить (Delete)

Описание:

Коллекция элементов дерева.

Доступность: клиент, сервер, тонкий клиент, веб-клиент.

См. также:

  • ДанныеФормыЭлементДерева, метод ПолучитьЭлементы
  • ДанныеФормыДерево, метод ПолучитьЭлементы

Особенности работы с деревом значений

Обновление дерева

Существует проблема падения платформы при обновлении дерева.

Если в дереве был развернут какой-либо узел и выбран подчиненный узел, то при обновлении дерева функцией ЗначениеВДанныеФормы
происходит падение платформы.

Решение: перед обновлением нужно очищать дерево.

Например:

&НаСервере
Процедура ОчиститьДерево(элементы)
	Для каждого элемент из элементы Цикл
		ОчиститьДерево(элемент.ПолучитьЭлементы());
	КонецЦикла;
	элементы.Очистить();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДеревоПонятий()
	дзПонятия = срСвойства.ПостроитьДеревоПонятий(НаДату, Мета.ТекущаяИБ());
	ОчиститьДерево(ДеревоПонятий.ПолучитьЭлементы());
	ЗначениеВДанныеФормы(дзПонятия, ДеревоПонятий);
КонецПроцедуры

&НаКлиенте
Процедура НаДатуПриИзменении(Элемент)
	ЗаполнитьДеревоПонятий();
КонецПроцедуры

Чтобы обратиться к экспортной процедуре созданного объекта который еще не сохранен в базе — нужно воспользоваться методом «РеквизитФормыВЗначение«

Данные метод преобразует указанный реквизит формы в объект прикладного типа:

Даже при пустой ссылке (то есть объект еще не создан в базе) мы можем получить экспортные процедуры и переменные текущего объекта метаданных. 

Метод используется только «&НаСервере»

Чтобы изменить текущий объект после выполнения экспортных процедур из модуля объекта используют метод «ЗначениеВРеквизитФормы»

Понравилась статья? Поделить с друзьями:

Другие крутые статьи на нашем сайте:

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии