Имя: Пароль:
1C
1С v8
Как на сервере получить объект созданной внешней обработки по уникальному ид
0 Crush
 
21.05.14
16:38
Тонкий клиент 8.3.4
Запускаю внешнюю обработку. Её объект остается на сервере, а клиенту передается форма.
У формы есть свойства:
ЭтаФорма.ИмяФормы = "ВнешняяОбработка.Тест.Форма.Форма"
и
ЭтаФорма.УникальныйИдентификатор = xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx

Хочу получить ИспользуемоеИмяФайла без передачи контекста. Ведь объект внешней обработки есть на сервере.

Подскажите как получить объект внешней обработки по уид или по имени формы?

ВнешниеОбработкиМенеджер имеет методы Создать(Имя) и Подключить(Имя). В обоих случаях сказано, что создается объект внешней обработки. А мне нужно получить ранее созданный.
1 fisher
 
21.05.14
17:02
"Её объект остается на сервере, а клиенту передается форма"
Новичок в УФ?
2 Crush
 
21.05.14
17:17
(1) Ага.
За последние 2 года сегодня первый раз взялся.

получилось так

#Область НеМобильноеПриложение
#Если НЕ (МобильноеПриложениеСервер или МобильноеПриложениеКлиент) Тогда
    &НаКлиенте
    Процедура ДействиеРезет(Команда)
        Резет(ЭтаФорма.ИмяФормы);
    КонецПроцедуры
    
    &НаКлиенте
    Процедура Резет(ПолноеИмяФормы)
        ИмяОбработки    = Сред(ПолноеИмяФормы,СтрДлина("ВнешняяОбработка.")+1);
        ИмяОбработки    = Лев(ИмяОбработки,Найти(ИмяОбработки,".")-1);
        РезетНаСервере(ИмяОбработки);
        ЭтаФорма.Закрыть();
        ОткрытьФорму(ПолноеИмяФормы);
    КонецПроцедуры
    
    &НаСервереБезКонтекста
    Процедура РезетНаСервере(ИмяОбработки)
        ВнешниеОбработки.Создать(ВнешниеОбработки.Создать(ИмяОбработки).ИспользуемоеИмяФайла,Ложь);
    КонецПроцедуры    
    
#КонецЕсли
#КонецОбласти

Теперь хочу это в общий модуль как то припаять, что бы из внешних обработок можно было одной строчкой вызывать
3 fisher
 
21.05.14
18:24
Получить "ранее созданный" объект обработки невозможно, потому что он самоликвидировался при завершении серверного вызова.
А смысл процедуры РезетНаСервере() остался за пределами моего понимания.
4 Crush
 
21.05.14
18:31
(3) Там как раз получается ранее созданный объект. Из него вытягивается ИмяФайла и создается новый объект на основании файла.
Потом на клиенте открывается его форма по имени..
Сейчас еще чуть допилю и выложу конечный результат. мож кому сгодиться, а может кто пинка правильного даст
5 fisher
 
21.05.14
18:35
Чтобы не сойти с ума, открою эту ветку завтра утром. Пока я что-то вообще не пойму ни смысла телодвижений, ни каким путем этот смысл достигается. Кто-то из нас двоих заработался.
6 H A D G E H O G s
 
21.05.14
18:37
&НаСервере
Процедуру ПриСозданииНаСервере()

ЭтотОбъект=РеквизитФормыВЗначение("Объект");
Сообщить(ЭтотОбъект.ИспользуемоеИмяФайла);
КонецПроцедуры
7 H A D G E H O G s
 
21.05.14
18:37
(5) Автор чето жжет и курит
8 H A D G E H O G s
 
21.05.14
18:39
(3) Он пытается "обнулить" уже созданный объект на сервере.
Бедолага.
9 H A D G E H O G s
 
21.05.14
18:42
При последующей контекстном вызове, с клиента поползут мигрируемые данные (Объект.Организация, Объект.НомерГТД) и он их увидит.
10 Crush
 
21.05.14
18:55
(6) Имя файла нужно в момент перезапуска обработки.
(8) Всё работает. Проверено!:)

(5) Цель была такая: быстро подключать в новые обработки возможность перезагрузки. Как помните в опенКонфе в 7.7 был шаблон на форму "Перезагрузить".

Вот как получилось и работает.
В модуле формы добавляем процедуру

&НаКлиенте
Процедура ДействиеРезет(Команда)
РаботаСФормамиНаКлиенте.ПерезагрузитьВнешнююОбработку(ЭтаФорма);
КонецПроцедуры

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

Общий модуль "РаботаСФормамиНаКлиенте": Только галка "Клиент (Управляемое приложение)".
&НаКлиенте
Процедура ПерезагрузитьВнешнююОбработку(Форма) Экспорт
    ПолноеИмяФормы    = Форма.ИмяФормы;
    ИмяОбработки    = Сред(ПолноеИмяФормы,Найти(ПолноеИмяФормы,".")+1);
    ИмяОбработки    = Лев(ИмяОбработки,Найти(ИмяОбработки,".")-1);
    РаботаСФормамиНаСервере.ПерезагрузитьВнешнююОбработку(ИмяОбработки);
    Форма.Закрыть();
    ОткрытьФорму(ПолноеИмяФормы);
КонецПроцедуры

Общий модуль "РаботаСФормамиНаСервере": Галки "Сервер" и "Вызов сервера".
&НаСервере
Процедура ПерезагрузитьВнешнююОбработку(ИмяОбработки) Экспорт
    #Если НЕ МобильноеПриложениеСервер Тогда
        ВнешниеОбработки.Создать(ВнешниеОбработки.Создать(ИмяОбработки).ИспользуемоеИмяФайла,Ложь);
    #КонецЕсли
КонецПроцедуры    

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

(5) не знаю как на счет "Заработался", но слезть с толстого клиента и столкнуться со стеной непонимания клиент-серверного программирования - это вынос мозга еще тот. Если кто знает правильный метод быстрого добавления кнопки "Перезагрузить" на управляемую форму внешней обработки, подскажите пожалуйста пока ко мне 03 не вызвали:)
11 Crush
 
21.05.14
18:59
(9) У меня получилось обратиться к контексту при вызове процедуры из общего модуля. Точнее я не знаю как это сделать.
12 Crush
 
21.05.14
19:03
(11) *НЕ получилось
13 H A D G E H O G s
 
21.05.14
20:15
(10) Чтобы не переоткрывать форму?
14 Лефмихалыч
 
21.05.14
21:11
(7) покрышки
15 H A D G E H O G s
 
21.05.14
21:18
(14) Да не, походу автор чето годное раскопал.
16 H A D G E H O G s
 
21.05.14
21:23
автор крут, че!
17 H A D G E H O G s
 
21.05.14
21:24
он автоматизировал перезапуск обработок при отладке вида

1. Закрыть.
2. Файл - Открыть - имя файла обработки.
18 Crush
 
21.05.14
21:31
А кто то кроме меня это протестил? Начал читать доки по УФ и там подтверждаются слова (3) " fisher
Получить "ранее созданный" объект обработки невозможно, потому что он самоликвидировался при завершении серверного вызова. "

А объект то получается, иначе ВнешниеОбработки.Создать(ИмяОбработки).ИспользуемоеИмяФайла возвращало бы какую-нибудь ерунду. Проверил сейчас на двух разных однвременно работающих обработках - полет нормальный.
19 fisher
 
22.05.14
10:52
Так. С утра я хотя бы понял, чего ты хочешь добиться.
А если в РаботаСФормамиНаКлиенте.ПерезагрузитьВнешнююОбработку() закомментировать строчку
РаботаСФормамиНаСервере.ПерезагрузитьВнешнююОбработку(ИмяОбработки);
То результат разве изменится? :)
20 Crush
 
22.05.14
13:41
Это будет удар ниже пояса:) *полез проверять*
21 Crush
 
22.05.14
13:47
(19) Изменится. Будет открываться тот экземпляр формы, который был открыт руками, а не тот, что в файле.
Короче не перезагружается внешняя обработка без этой строчки.
22 fisher
 
22.05.14
14:17
А давай сначала. А то я плохо нащупываю нить.
Смысл всех телодвижений, чтобы переоткрыть открытую внешнюю обработку кнопкой из этой самой обработки? Встроенных в конфу одноименных обработок нет?
23 Crush
 
22.05.14
14:44
(22) 1.Да.
2. Не важно есть или нет одноименные встроенные в конфу. Они уже не внешние обработки и не имеют свойства "ИспользуемоеИмяФайла".
24 H A D G E H O G s
 
22.05.14
14:56
Автор, ты - прекрасен.
Это - лучшее, что я видел на мисте за последнее время.
25 Crush
 
22.05.14
14:57
А если одновременно открыть 3 обработки и два раза жмакнуть на f5, то останется одна:)
26 Crush
 
22.05.14
15:01
(24)
Выбор Когда НЕ(ЯНачинающийУФник И НадоМнойСтебутся) Тогда
"Искренне "
Иначе ""
Конец + "благодарю!"
27 H A D G E H O G s
 
22.05.14
15:04
Я бы

&НаСервере
Процедура ПерезагрузитьВнешнююОбработку(ИмяОбработки) Экспорт
    #Если НЕ МобильноеПриложениеСервер Тогда

        ВнешниеОбработки.Создать(ВнешниеОбработки.Создать(ИмяОбработки).ИспользуемоеИмяФайла,Ложь);
    #КонецЕсли

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

заменил на

&НаСервере
Процедура ПерезагрузитьВнешнююОбработку(ИспользуемоеИмяФайла) Экспорт
    #Если НЕ МобильноеПриложениеСервер Тогда

        ВнешниеОбработки.Создать(ИспользуемоеИмяФайла,Ложь);
    #КонецЕсли

КонецПроцедуры
28 H A D G E H O G s
 
22.05.14
15:06
А ИспользуемоеИмяФайла - получал бы в

ПриСозданииНаСервере()

И еще смотрел - является ли обработка внешней

    ЭтоВнешняяОбработка=Метаданные.НайтиПоТипу(ТипЗнч(ОбработкаОбъект))=Неопределено;
29 H A D G E H O G s
 
22.05.14
15:06
СтруктураКлиентСерверныхДанных=Новый Структура;
            СтруктураКлиентСерверныхДанных.Вставить("ЭтоВнешнийОтчет",ЭтоВнешнийОтчет);
    СтруктураКлиентСерверныхДанных.Вставить("ИмяОтчета",МетаданныеОтчета.Имя);
    Если ЭтоВнешнийОтчет Тогда
        СтруктураКлиентСерверныхДанных.Вставить("ИспользуемоеИмяФайла",ОтчетОбъект.ИспользуемоеИмяФайла);
    Иначе
        СтруктураКлиентСерверныхДанных.Вставить("ИспользуемоеИмяФайла","");
    КонецЕсли;
30 H A D G E H O G s
 
22.05.14
15:06
СтруктураКлиентСерверныхДанных - реквизит формы, тип - Произвольный
31 H A D G E H O G s
 
22.05.14
15:09
Вообще, надо бы статью черкнуть, как правильно хранить данные в УФ, а то понапишуть дятлы, волосы на жопе дыбом встают.
32 Crush
 
23.05.14
09:43
(27) Основная цель - это минимизировать работу в новой внешней обработке по созданию кнопки "Перезагрузить". А если в "ПриСозданииНаСервере" получать имя файла, то это дополнительный текст модуля, что не совпадает с основной целью.

Кстати, сейчас идея возникла! "лампочка над затылком":)
Если бы найти событие, которое вызывается при открытии файла внешней обработки, то вообще было бы круто:)
33 Crush
 
23.05.14
11:59
Похоже цель достигнута: Ничего писать во внешней обработке не надо:)

Решается добавлением только одной общей команды с хоткеем.
У себя назвал глShiftF5
Модуль:

&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    текОкно    = АктивноеОкно();
    Если ТипЗнч(текОкно) = Тип("ОкноКлиентскогоПриложения") Тогда
        текФорма    = текОкно.ПолучитьСодержимое();
        Если ТипЗнч(текФорма) = Тип("УправляемаяФорма") Тогда
            ПолноеИмяФормы        = текФорма.ИмяФормы;
            позПервойТочки        = Найти(ПолноеИмяФормы,".");
            ТипОбъекта    = Лев(ПолноеИмяФормы,позПервойТочки-1);
            Если ТипОбъекта    = "ВнешняяОбработка" Тогда
                ИмяОбработки    = Сред(ПолноеИмяФормы,позПервойТочки+1);
                ИмяОбработки    = Лев(ИмяОбработки,Найти(ИмяОбработки,".")-1);
                ПерезагрузитьВнешнююОбработку(ИмяОбработки);
                текФорма.Закрыть();
                ОткрытьФорму(ПолноеИмяФормы);
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПерезагрузитьВнешнююОбработку(ИмяОбработки) Экспорт
    #Если НЕ МобильноеПриложениеСервер Тогда
        ВнешниеОбработки.Создать(ВнешниеОбработки.Создать(ИмяОбработки).ИспользуемоеИмяФайла,Ложь);
    #КонецЕсли
КонецПроцедуры    

Свойства команды:
        <Properties>
            <Name>глShiftF5</Name>
            <Synonym>
                <v8:item>
                    <v8:lang>ru</v8:lang>
                    <v8:content>Глобальный Shift+F5</v8:content>
                </v8:item>
            </Synonym>
            <Comment/>
            <Group>FormNavigationPanelImportant</Group>
            <Representation>Auto</Representation>
            <ToolTip/>
            <Picture/>
            <Shortcut>Shift+F5</Shortcut>
            <IncludeHelpInContents>false</IncludeHelpInContents>
            <CommandParameterType/>
            <ParameterUseMode>Single</ParameterUseMode>
            <ModifiesData>false</ModifiesData>
        </Properties>


При открытии нескольких экземпляров внешней обработки перезагружается только текущая активная.
34 fisher
 
23.05.14
16:10
Ты крут :) Я другого способа добраться до имени файла (имея только ссылку на форму), кроме твоего ВнешниеОбработки.Создать(ИмяОбработки) так и не нашел.
А сам бы этого мог и не додуматься.
35 fisher
 
23.05.14
16:35
Не. Всё равно фигня. В тонком клиенте не получится. Сервер ведь другой комп и там клиентский путь к обработке может не канать. А если передавать файл обработки на сервер - то нормально отладить, наверное, не получится...
36 H A D G E H O G s
 
23.05.14
16:43
(35) Обычно отлаживают на файловой
37 DmitriyDI
 
23.05.14
16:45
(17) да ладно, это работает?
38 fisher
 
23.05.14
16:47
(36) Я отлаживаю не тестовом сервере :)
Буду по-старинке. Два лишних клика :)
39 DmitriyDI
 
23.05.14
16:50
(37) если да то это очень круто, а при перезапуске реквизиты на форме остаются заполнены?
если да то просто добавить это в глобальник и постоянно использовать при отладке
40 H A D G E H O G s
 
23.05.14
16:54
(39) Я сделал это для себя.
41 DmitriyDI
 
23.05.14
17:09
(33) а куда добавлять эти Свойства команды:
42 DmitriyDI
 
23.05.14
17:14
(41) ааа это просто отчет по команде
43 Crush
 
26.05.14
11:44
(35) Да.. С серваком засада. Либо файл передавать, либо отлаживать на серваке, либо класть обработку на общий ресурс и обращаться к ней через сетевой интерфейс (\\МойКомп\Шара\Обработка.epf).

В 8.2(18.102) хреново работает метод АктивноеОкно() - всё время возвращает основное окно конфигурации. Может это от того, что в 8.2 окно обработки открывается отдельным окном, а в 8.3 открывается в рабочей области основного окна. Но при этом код на серваке отрабатывается если непосредственно из обработки вызывать.
44 Crush
 
26.05.14
12:49
Вариант для клиент-сервер и файл-сервер
Модуль команды:

&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    текОкно    = АктивноеОкно();
    Если ТипЗнч(текОкно) = Тип("ОкноКлиентскогоПриложения") Тогда
        текФорма    = текОкно.ПолучитьСодержимое();
        Если ТипЗнч(текФорма) = Тип("УправляемаяФорма") Тогда
            ПолноеИмяФормы        = текФорма.ИмяФормы;
            позПервойТочки        = Найти(ПолноеИмяФормы,".");
            ТипОбъекта    = Лев(ПолноеИмяФормы,позПервойТочки-1);
            Если ТипОбъекта    = "ВнешняяОбработка" Тогда
                ИмяОбработки    = Сред(ПолноеИмяФормы,позПервойТочки+1);
                ИмяОбработки    = Лев(ИмяОбработки,Найти(ИмяОбработки,".")-1);
                ПоместитьФайл(,ИмяФайлаВнешнейОбработки(ИмяОбработки),, Ложь);
                текФорма.Закрыть();
                ОткрытьФорму(ПолноеИмяФормы);
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция ИмяФайлаВнешнейОбработки(ИмяОбработки)
    #Если НЕ МобильноеПриложениеСервер Тогда
        Возврат ВнешниеОбработки.Создать(ИмяОбработки).ИспользуемоеИмяФайла;
    #КонецЕсли
КонецФункции
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой