Имя: Пароль:
1C
1С v8
Управляемые формы. Как программно выполнить процедуры и обработ. событий формы?
0 Mr_Best
 
18.01.12
10:06
Здравствуйте Уважаемые коллеги. Столкнулся с задачей выполнить процедуру управляемой формы, но что-то как-то не получается.
Коротко: в УТ11 создается программно элементы справочника вид цен. И все бы хорошо, только вот этот вид цен работать не будет до тех пор, пока элемент не откроешь в программе вручную, а затем нажмешь "Записать и закрыть".
Объекты создаются на сервере.
Проверял в отладчике, события формы элемента естественно не выполняются(при создании и записи).
Пробывал создовать объекты на сервере, затем по ссылке открывать формы на клиенте, все равно обработчики событий не срабатывают!

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

На сервере создаются так:

&НаСервере
Процедура СоздатьВидЦен(КоллекцияАтрибутов, БазовыйВидЦен = Неопределено)
   
   НовыйВидЦен = Справочники.ВидыЦен.СоздатьЭлемент();
   
   НовыйВидЦен.Заполнить(Неопределено);
   НовыйВидЦен.Наименование  = КоллекцияАтрибутов.ПолучитьИменованныйЭлемент("Наименование").Значение;
   
   // недопустимо пустое наименование
   Если Не ЗначениеЗаполнено(НовыйВидЦен.Наименование) Тогда
       НовыйВидЦен.Наименование = Новый УникальныйИдентификатор();
   КонецЕсли;
   
   НовыйВидЦен.Идентификатор = ОбщегоНазначенияУТКлиентСервер.ПолучитьИдентификатор(НовыйВидЦен.Наименование);
   
   // не допустимы не уникальные идентификаторо относительно всех видов цен
   Запрос = Новый Запрос;
   Запрос.УстановитьПараметр("Идентификатор", НовыйВидЦен.Идентификатор);
   Запрос.Текст = "ВЫБРАТЬ
                  |    ВидыЦен.Ссылка
                  |ИЗ
                  |    Справочник.ВидыЦен КАК ВидыЦен
                  |ГДЕ
                  |    ВидыЦен.Идентификатор = &Идентификатор";
   РезультатВыполнения = Запрос.Выполнить();
   
   Если Не РезультатВыполнения.Пустой() Тогда
       
       НовоеНаименование = НовыйВидЦен.Наименование + "_" + Новый УникальныйИдентификатор();
       
       НовыйВидЦен.Идентификатор = ОбщегоНазначенияУТКлиентСервер.ПолучитьИдентификатор(НовоеНаименование);
       
   КонецЕсли;
           
   НовыйВидЦен.ОР_ВходящийКод = КоллекцияАтрибутов.ПолучитьИменованныйЭлемент("Код").Значение;
   
   Если КоллекцияАтрибутов.ПолучитьИменованныйЭлемент("ЦенаВключаетНДС").Значение = "1" Тогда
       НовыйВидЦен.ЦенаВключаетНДС = Истина;
   КонецЕсли;
   
   НовыйВидЦен.ИспользоватьПриПродаже                        = Истина;
   НовыйВидЦен.ИспользоватьПриПередачеМеждуОрганизациями    = Истина;
   
   НовыйВидЦен.ВалютаЦены = НайтиВалюту(КоллекцияАтрибутов.ПолучитьИменованныйЭлемент("Валюта").Значение);
   
   // проверим, если валюту не нашли отменяем создание вида цены
   Если Не ЗначениеЗаполнено(НовыйВидЦен.ВалютаЦены) Тогда
       Сообщить ("Не удалось создать вид цен: " + НовыйВидЦен.Наименование + ". Причина: не найдена валюта цены с кодом: [" + КоллекцияАтрибутов.ПолучитьИменованныйЭлемент("Валюта").Значение + "]");
       Возврат;
   КонецЕсли;
   
   // Определимся, вдруг расчитывается на основании базовой цены
   Если ЗначениеЗаполнено(БазовыйВидЦен) Тогда
       НовыйВидЦен.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.РассчитыватьПоДругимВидамЦен;        
       ПроцентнаяСтавка = КоллекцияАтрибутов.ПолучитьИменованныйЭлемент("Процент").Значение;        
       Если Число(ПроцентнаяСтавка) >= 0 Тогда
           НовыйВидЦен.АлгоритмРасчетаЦены = "[" + БазовыйВидЦен.Идентификатор + "] * ((100 + " + Строка(ПроцентнаяСтавка) + ") / 100)";
       Иначе
           НовыйВидЦен.АлгоритмРасчетаЦены = "[" + БазовыйВидЦен.Идентификатор + "] * ((100 " + Строка(ПроцентнаяСтавка) + ") / 100)";
       КонецЕсли;
   Иначе
       НовыйВидЦен.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.Вручную;
   КонецЕсли;
   
   НовыйВидЦен.Записать();
       
КонецПроцедуры

Вообще это все пишется для обработки переноса данных из писаной-переписанной семерки в УТ11. Так сказать, одноразовая обработка, лишь бы перебросить данные ))))

Вопрос: как программно эмулировать открытие формы и нажатие кнопки "Записать и закрыть" в управляемом приложении, так что бы выполнились все стандартные обработчики соответствующих событий формы? Желательно, что бы пользователь не наблюдал открытия и закрытия формы, но необязательно.
1 vmv
 
18.01.12
10:09
Модуль Формы

Процедура ТраЛяЛяПриИзменении(Элемент)

Справочник.Контрагенты.МодульМенеждераТраЛяЛяПриИзменении(Неопределено);

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

надеюсь, пояснения не нужны
2 Mr_Best
 
18.01.12
10:21
(1) я был бы признателен, если бы Вы указали хотя бы директиву компиляции процедуры.
Будте любезны, немножко поподробнее.
3 vmv
 
18.01.12
10:25
(2) в модуле менеджера она смысла не имеет, пердавать данные объекта при загрузке в методы менеджера можно структурами.

посмотрите функционал модулей менеждеров объектов в новых конфах на УФ.

Конечно, можно еще придумать нечто что будет позволять использовать методы ФОРМЫ в условном "глобальном" контексте, но именно перенос общего функционала форм и загрузчиков в модуль менеджера считаю правильным. Все остальное от лукавого
4 KindLion
 
18.01.12
10:56
(0) Для начала - постарайтесь выяснить, отработки какой функции вы, все же, добиваетесь.
При нажатии кнопки формы "Записать и закрыть" отрабатывают не только функции модуля формы, но и ряд функций объекта.
Например "ПриЗаписи".
Если, все же, необходимые вам функции находятся именно в модуле формы, то у них должна быть приписка - ЭКСПОРТ.
И тогда в коде пишите что-то типа:

ФормаОбъекта = ПолучитьФорму(....);
ФормаОбъекта.ИмяНужнойПроцедуры(); - вызываете нужную вам процедуру.
5 toypaul
 
гуру
18.01.12
11:04
у меня есть какой-то перенос из ТиС в УТ
6 toypaul
 
гуру
18.01.12
11:05
перенос справочников.
в загрузке просто повторяешь весь код из формы справочника и все. делов-то.
7 Mr_Best
 
18.01.12
12:15
Очень жаль, что все не так как в обычном приложении (((
В обычном приложении можно было бы сделать так:

Форма = Объект.ПолучитьФорму("ФормаЭлемента");
Форма.Открыть();
Форма.Закрыть();

или к процедурам-событиям экспорт

Форма = Объект.ПолучитьФорму("ФормаЭлемента");
Форма.ПриОткрытии();
Форма.ПриЗакрыть();

и все. Делов то было бы на пару минут, все выполнилось по стандартным алгаритмам, причем кодом написаным во внешней обработке. И не че менять в форме не надо!

Вот как то так можно? Или без гемороя не обойтись?
8 Mr_Best
 
18.01.12
12:17
Без разницы где это делать, на клиенте или на сервере. Так же без разницы интерактивно или нет.
9 Mr_Best
 
18.01.12
12:57
вверх!
10 1с-кин
 
18.01.12
13:16
(7) вообще-то, именно открытие и закрытие формы вы будете наблюдать при выполнении такого кода...
11 Mr_Best
 
19.01.12
10:59
(10) совершенно верно! Только между таким программным способом открытия / закрытия и "ручным способом" есть весьма существенная разница! Выполняются не все обработчики, конкретно:
ПриСозданииНаСервере - выполняется как программно, так и вручную.
ПередЗаписьюНаСервере - выполняется только "вручную".

Т.е. я поставил в двух этих обработчиках точки останова. При программном открытии / закрытии срабатывает только точка останова в обработчике "ПриСозданииНаСервере".
А при "ручном" открытии / закрытии того же справочника "ВидЦен" точки останова срабатывают в обоих обработчиках событий, и в "ПриСозданииНаСервере", и в "ПередЗаписьюНаСервере"!

Почему?

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

Ну, что не кто не знает? Или я непонятно изложил вопрос?
12 Mr_Best
 
19.01.12
11:18
ну очень нужно ... вверх!
13 5 Элемент
 
19.01.12
11:20
Что-то сомневаюсь что для записи видов цен нужно открывать форму.
14 1с-кин
 
19.01.12
11:20
(11) а зачем именно события открытия-закрытия понадобились? вытащите оттуда нужное и запускайте отдельно.
15 Mr_Best
 
19.01.12
11:21
вытаскивать очень много надо!!!! Легче открыть и закрыть, делов то на две менуты.
16 Mr_Best
 
19.01.12
11:22
Ведь как то же можно!
17 Mr_Best
 
19.01.12
11:22
(13) - запись проходит успешно, но не расчитываюся влияющие и базовые типы цен в объекте!
18 Mr_Best
 
19.01.12
11:22
А если открыть и закрыть форму, то расчитываются!
19 Defender aka LINN
 
19.01.12
11:23
(11) Потому что ты записываешь объект. А его, между прочим, в управляемой форме даже нет.
Ну и получать форму при крограммной записи - это уже верх идиотизма
20 5 Элемент
 
19.01.12
11:23
(11) А как ты записываешь?
надо через Записать() формы

Расширение управляемой формы для справочника (Managed form extension for catalogs)
Записать (Write)
Синтаксис:
Записать(<ПараметрыЗаписи>)

Описание:
Записывает объект.
21 Mr_Best
 
19.01.12
11:24
(4) - этот способ не выдаст ошибку про интерактивные операции.
22 Mr_Best
 
19.01.12
11:24
(20) - это на клиенте?
23 5 Элемент
 
19.01.12
11:25
(22) открой СП наконец таки
Доступность:
Тонкий клиент, веб-клиент, сервер, толстый клиент.
24 5 Элемент
 
19.01.12
11:26
(17) а вот за это надо разработчикам руки оторвать
25 1с-кин
 
19.01.12
11:28
сделайте дубляж процедур-обработчиков событий, и вызывайте их принудителдьно.
26 5 Элемент
 
19.01.12
11:28
лучше перенеси код формы в свою обработку.
открытие формы все же неправильно.
27 Mr_Best
 
19.01.12
11:29
Ура!!! ЩА выложу правильный код.
28 Mr_Best
 
19.01.12
11:29
(24) - целиком и полностью согласен!
29 Mr_Best
 
19.01.12
11:32
Привык доверять контекстной подсказки через точку, а там почему то метода записать нету (((((

Вот и мучался, а делов то:


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

Вот и все!
(20) !!!!!!