Объект УправляемаяФорма. Как получить все реквизиты?

1. kentavr27 97 08.08.14 21:23 Сейчас в теме
1С:Предприятие 8.3 (8.3.4.437) в режиме управляемого приложения
Возникла следующая проблема...

Задача: получить все табличные документы из некой формы.
Решение: для этого нужно получить все реквизиты этой формы (метод ПолучитьРеквизиты()), отсеять ненужное и все...

На первый взгляд все просто, если бы не одно "но".
Инициатором действий является ОбщаяКоманда. т.е. к форме в этом случае можно достучаться только через ПараметрыВыполненияКоманды.Источник (коим как раз является нужная УправляемаяФорма)
Из клиента на сервер эту самую форму можно передать через ВременноеХранилище, потом на сервере и делать все что нужно.
Примерно такой код:
&НаСервере
Функция ПолучитьРеквизитыФормы(Массив,Адрес)
	УправляемаяФорма=ПолучитьИзВременногоХранилища(Адрес);
	ВсеРеквизиты=УправляемаяФорма.ПолучитьРеквизиты();
	Для Каждого РеквизитИсточника Из ВсеРеквизиты Цикл 
		Если ТипЗнч(РеквизитИсточника)=Тип("ТабличныйДокумент") Тогда 
			Массив.Добавить(РеквизитИсточника);
		КонецЕсли;
	КонецЦикла;
        Возврат Массив;
КонецФункции
Показать

А вот здесь возникает это самое "НО"... если форму получать из временного хранилища, то при выполнении УправляемаяФорма.ПолучитьРеквизиты() платформа ругается
Ошибка при вызове метода контекста (ПолучитьРеквизиты)
ВсеРеквизиты=УправляемаяФорма.ПолучитьРеквизиты();
по причине:
Метод недоступен на клиенте

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

Народ, как можно побороть это "несчастье"?
Ну негде в моем случае взять контекст формы на сервере...
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
7. AlX0id 09.08.14 12:30 Сейчас в теме
(1) kentavr27,
Из клиента на сервер эту самую форму можно передать через ВременноеХранилище

Ну вот и запихните список табдоков там же - какие проблемы?
8. kentavr27 97 09.08.14 19:49 Сейчас в теме
(7) AlX0id, спасибо, но как раз с этим проблем никаких нет. Но это называется "костыль". И этот список табдоков в таком случае нужно пихать в каждую форму, где есть несколько табдоков. Вот я и пытаюсь выяснить, как можно без забивания костылей обойтись, когда эти табдоки уже есть в форме, есть сама форма в качестве источника, есть метод, с помощью которого (теоретически) можно отловить все табдоки. Дело за небольшим... осталось заставить этот метод отработать... :)
И ваще... ну как можно ругаться на клиента, если метод отрабатывается на сервере... просто бред какой-то, блин...
10. AlX0id 09.08.14 21:13 Сейчас в теме
(8) kentavr27,
Ну я как бы полагал, что там, где вы помещаете во временное хранилище форму, там и обработать реквизиты. Вы же не полагали помещать формы в хранилище в разных местах? Вот там бы и обработали. Кстати, попробовал запихать форму в 8.3 в хранилище - нэ лэзэ..
{ОбщаяКоманда.ОбщаяКоманда1.МодульКоманды(5)}: Ошибка при вызове метода контекста (ПоместитьВоВременноеХранилище)
УникальныйИдентификатор = ПоместитьВоВременноеХранилище(ПараметрыВыполненияКоманды.Источник);
по причине:
Ошибка помещения значения во временное хранилище
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
Запись значения свойства 'request':
форма: Элемент
имя: {http://v8.1c.ru/8.2/mngsrv/ws}request
по причине:
Ошибка отображения типов:
Отсутствует отображение для типа 'УправляемаяФорма'
Показать
11. kentavr27 97 09.08.14 23:43 Сейчас в теме
(10) AlX0id,
Ну я как бы полагал, что там, где вы помещаете во временное хранилище форму, там и обработать реквизиты. Вы же не полагали помещать формы в хранилище в разных местах? Вот там бы и обработали.

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

&НаСервере
Функция ПолучитьРеквизитыФормы(Адрес)
        Массив=Новый Массив;
	УправляемаяФорма=ПолучитьИзВременногоХранилища(Адрес);
	ВсеРеквизиты=УправляемаяФорма.ПолучитьРеквизиты(); //именно здесь грабли. Ругается что метод недоступен на клиенте
	Для Каждого РеквизитИсточника Из ВсеРеквизиты Цикл 
		Если ТипЗнч(РеквизитИсточника)=Тип("ТабличныйДокумент") Тогда 
			Массив.Добавить(Строка(РеквизитИсточника));
		КонецЕсли;
	КонецЦикла;
        Возврат Массив;
КонецФункции
Показать


ПараметрыВыполненияКоманды.Источник доступен только на клиенте. Метод ПолучитьРеквизиты() доступен на сервере. Напрямую на сервер объект УправляемаяФорма (ПараметрыВыполненияКоманды.Источник)передать нельзя, только через временное хранилище. Как объект, УправляемаяФорма помещается во ВХ без проблем.
А вот когда уже получил на сервере и применил к нему метод ПолучитьРеквизиты() -- вот здесь вылазят грабли...

Да, если на форме создать реквизит типа СписокТабДоков (СписокЗначений) и засунуть туда все ТабДоки -- то без проблем получаю прямо на клиенте по имени этот реквизит и отправляю его в общую форму. Но такой реквизит нужно создавать на всех формах и пихать туда табДоки во время их заполнения прямо в той форме. Ладно если таких форм может быть только 1-2. А если их 15-20 а через месяц к ним еще десяток форм добавиться например...

Ежели выполнить ВсеРеквизиты=ЭтаФорма.ПолучитьРеквизиты() на сервере прямо в контексте формы, то все отрабатывается нормально
Похоже что 1С что-то намудрило, и для системы ПараметрыВыполненияКоманды.Источник и ЭтаФорма (в контексте формы) несколько разные объекты, хотя и визуально и их тип абсолютно совпадают. А вот объехать этот баг без создания дополнительного реквизита в форме пока не получается...
12. Vovan58 65 11.08.14 11:53 Сейчас в теме
(11) kentavr27, Что хотел сказать - получение реквизитов формы, через Элементы, почему не устраивает?
13. FreeArcher 161 11.08.14 12:45 Сейчас в теме
(12)Это видимо для лохов...

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

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

Задача то вроде как решаема, если её правильно решать.
От привычки, как в обычных формах все тащить на сервер надо уже отучаться.
IvanBoychuk123; +1 Ответить
14. AlX0id 11.08.14 14:02 Сейчас в теме
(13) FreeArcher, (12) Vovan58,
Так как бы не факт, что все реквизиты формы размещены в элементах..
15. FreeArcher 161 11.08.14 14:12 Сейчас в теме
(14) Какая разница, они все доступны на клиенте.
16. kentavr27 97 11.08.14 16:32 Сейчас в теме
(15) FreeArcher, ну вроде как общее понятие о задаче я озвучил. Да, реквизиты формы доступны на клиенте. Обращаться, передавать -- не проблема. Но все это хорошо, когда известно имя_реквизита.
В моем случае ни имени реквизита заранее неизвестно, ни количество нужных реквизитов. Те реквизиты, которые мне нужны создаются на форме программно.
А поэтому мне нужно перебрать все реквизиты и выбрать меня интересующие по типу реквизита. А сделать это можно только на сервере. Вот и приходится серверу показывать объект УФ.
В клиент серверной реализации логики работы от 1С такая, что Форма может существовать только на клиенте

В контексте формы с сервера можно можно пречудесно обращаться к реквизитам формы (не элементам) через ЭтотОбъект (Тип("УправляемаяФорма")). И, как я уже говорил, в контексте формы метод ПолучитьРеквизиты() работает.
Через ПараметрыВыполненияКоманды.Источник обработчика команды тож можно обращаться, но возникают проблемы после передачи объекта УФ на сервер, причем эти проблемы возникают только с методом ПолучитьРеквизиты()

PS
Некоторые самолеты/вертолеты еще умеют взлетать и садиться с воды/на_воду, далеко не для всех нужна вертолетная площадка и ВПП протяженностью 2500м :)
PPS
И привычки "все тащить на сервер" как в обычных формах у меня нет, т.к. я с 77 переехал на управляемые, ну не работал я с "обычными" :)
17. AlX0id 12.08.14 18:03 Сейчас в теме
(15) FreeArcher,
Эм? Есть например табдок в реквизитах, но не присутствует в элементах. Если вы знаете его имя - понятно, можете обратиться типа Форма.ИмяРеквизита.. Ну а если не знаете?
Доступны-то они на клиенте доступны.. а вот информация о том, какова коллекция реквизитов формы - на клиенте не доступна.
19. kentavr27 97 12.08.14 19:22 Сейчас в теме
(17) AlX0id,
Есть например табдок в реквизитах, но не присутствует в элементах. Если вы знаете его имя - понятно, можете обратиться типа Форма.ИмяРеквизита.. Ну а если не знаете?

Так вот за этим то и загвоздка. В элементах формы у меня нет ничего. Имени реквизита не знаю, но знаю что мне нужны все реквизиты формы тип("ТабличныйДокумент"). Вот я и хотел узнать все имена таковых реквизитов с помощью метода ПолучитьРеквизиты(), а потом уже обращаться к эти реквизитам по имени...
о том, какова коллекция реквизитов формы - на клиенте не доступна.

Именно так. Это только на сервере, куда я пытался передать объект УФ и узнать на сервере про все реквизиты этой самой УФ
22. AlX0id 12.08.14 20:06 Сейчас в теме
(19) kentavr27,
Ну я тоже уже в этом убедился - просто попробовав )
На самом деле - аккуратнее в такого рода решении - как я писал, в 8.3 вы даже форму во временное хранилище не положите уже..
2. sssss_aaaaa_2011 08.08.14 21:50 Сейчас в теме
А теперь расскажи задачу, для решения которой ты выбрал такой способ. Только не пиши, что уже указал задачу. Раз работаешь с формой и нужны реквизиты формы, то их как особенно получать и не надо, они и так доступны.
3. kentavr27 97 08.08.14 22:00 Сейчас в теме
(2) sssss_aaaaa_2011, да по-большому счету конкретика задачи то не важна... да и "затык" в общем то на ровном месте.
просто нужно получить табличные документы из формы для передачи их в другую форму. Табличные документы (как реквизиты формы) формируются программно.
т.е. об их наличии или отсутствии, количестве, равно как и об имени реквизитов формы, я заранее не знаю.
Вот поэтому и требуется перебрать все реквизиты формы, что бы найти все табличные документы.
Ну и инициируется это все, как я уже говорил, общей командой.
Можно, конечно же, насовать костылей... только зачем, когда решение можно оформить универсальным методом
4. sssss_aaaaa_2011 08.08.14 23:23 Сейчас в теме
нужно получить табличные документы из формы для передачи их в другую форму
Для управляемых форм уже большой косяк. И для чего нужен такой косяк?
5. kentavr27 97 08.08.14 23:42 Сейчас в теме
(4) sssss_aaaaa_2011, ну что значит "косяк" "для управляемых форм". Неужели жить можно только в обычных формах? У меня вся конфа только для управляемых. Так что, теперь пойти и повеситься, что ль? :) Или отказаться от требуемого функционала?
Тем более задача по сути элементарна.
Есть форма, в которой работает пользователь. Есть некая общая форма, в которую нужно передать данные для их дальнейшей обработки. И что в этом такого военного?
6. sssss_aaaaa_2011 09.08.14 09:21 Сейчас в теме
что значит "косяк" "для управляемых форм".
То и значит, не рассчитаны управляемые формы на такие ивращения.
Неужели жить можно только в обычных формах?
А кто-то где-то что-то подобное написал?
У меня вся конфа только для управляемых.
Какая неожиданность! Кто бы мог подумать!
Или отказаться от требуемого функционала?
Еще раз: а кто-то где-то предлагал такое? Или изменить способ реализации функционала есть отказ от этого функционала? Думать над просчитанным не пробовал?
9. kentavr27 97 09.08.14 20:06 Сейчас в теме
(6) sssss_aaaaa_2011,
Или изменить способ реализации функционала

Допустим изменяем способ реализации...
Повторяюсь... Основные исходные условия:
1. Форма, в которой сейчас работает пользователь.
2. Общая команда, инициирующая действие (кнопка на форме, в которой сейчас работает пользователь).
3. Общая форма, которой передается управление с помощью общей команды и которая дальше должна производить действия с данными той формы, в которой работал пользователь. Из требуемых для передачи данных известен только Тип("ТабличныйДокумент")

Какие есть варианты?
Варианты типа "все процедуры общей команды, перенести в каждую форму (сделать командой формы)" или "общую форму 'слить' с формами отчетов/документов" -- не предлагать.
18. sssss_aaaaa_2011 12.08.14 18:11 Сейчас в теме
(9) Вы опять не изменили способ реализации, вы продолжаете долбить все тот же -
1. Форма, в которой сейчас работает пользователь.
2. Общая команда, инициирующая действие (кнопка на форме, в которой сейчас работает пользователь).
3. Общая форма, которой передается управление с помощью общей команды и которая дальше должна производить действия с данными той формы, в которой работал пользователь. Из требуемых для передачи данных известен только Тип("ТабличныйДокумент")

Но так и не написали ЗАЧЕМ все эти пляски с бубном? Вот это и будет задача, а не выбранный и приведший в тупик способ решения.
20. kentavr27 97 12.08.14 19:40 Сейчас в теме
(18) sssss_aaaaa_2011,
Но так и не написали ЗАЧЕМ все эти пляски с бубном? Вот это и будет задача, а не выбранный и приведший в тупик способ решения.

Бубна здесь нет. Простая задача, с прямым решением.
Зачем? Повторюсь. Взять все ТабДоки из одной формы, и передать в другую, которая отвечает за массу различных действий (интерактивных, выбираемых пользователем), которые можно или нужно производить с этимИ самымИ табДоком(и). Как можно еще описать слово "зачем"?
Между "одной" формой (ЛЮБОЙ) и общей формой в качестве "посредника" прописана Общая_Команда
В каком месте здесь "Бубен"? Простейший и логичный алгоритм без всяческих извратов.
Бубен нужен только для того, что бы обойти косяк самой платформы, что на текущий момент не представляется возможным даже с бубном, песнями и плясками. Только методом проб на старших релизах, которые наверное еще не выпущены (в стабильном варианте работы).
23. sssss_aaaaa_2011 12.08.14 20:51 Сейчас в теме
(20)А не надо повторяться. Уже давно понятно, что хочется перекидывать ТабДоки между формами. ЗАЧЕМ их перекидывать? Конечная цель какая? Работать с чем-то совершенно неизвестным и при этом еще тоннами гонять между формами? Нарисовать что-то абсолютно универсальное? Так этим только новички страдают по незнанию.
Взять все ТабДоки из одной формы, и передать в другую
Это и есть способ. Для решения какой задачи он выбран?
26. kentavr27 97 13.08.14 00:50 Сейчас в теме
(23) sssss_aaaaa_2011,
Для решения какой задачи он выбран?
Например: отправить в архив все ПФ одной кнопкой, какое-нить пакетное сохранение, отправка по почте, редактирование не стандартными средствами (которые для 90% пользователей недостижимы в понимании), а с помощью подготовленного удобного пользовательского интерфейса, пакетная отправка на печать. Да мало ли какие еще практические примеры можно привести...
...Работать с чем-то совершенно неизвестным...

Далеко не все и всегда известно заранее. Как и сейчас, ПФ, которые строятся динамически в зависимости от флажков, которые наставит пользователь.
21. kentavr27 97 12.08.14 19:45 Сейчас в теме
В общем, всем спасибо. На сколько я понял, на текущий момент единственное решение до исправления "фитчи" платформы с методом ПолучитьРеквизиты() -- это костыль в виде реквизита формы типа список документов, куда будут пихаться все табДоки формы.
24. Vovan58 65 12.08.14 22:58 Сейчас в теме
(21) kentavr27, Вопрос конкретный - эти реквизиты (Табличные документы) видимы? Если видимы, то что мешает обойти Элементы формы? А если не видимы - то зачем они создаются?
25. kentavr27 97 13.08.14 00:41 Сейчас в теме
(24) Vovan58, Просто дело это не благодарное :) Элементов на форме может быть в 5 - 50 раз больше чем самих реквизитов.
Такой вариант может прокатить только если имя реквизита и имя элемента формы одинаковые (через элемент не получишь имя реквизита).
К тому же, чаще могут видимы, но могут быть и невидимы (даже просто теоретически).
Еще табДок можно выплюнуть просто методом Показать() Тогда он как бы и есть, но к форме не привязан.
Теоретически попробовать можно (не пробовал), но грабли вылезут по-любому :)
А вообще просто не имею такой привычки работать с элементами (получать какие-нить значения из них), если это не событие этого элемента.
Гриффин; +1 Ответить
27. fixin 4253 01.03.23 13:27 Сейчас в теме
Использовал на форме внешней обработки. Там у Объекта не было реквизитов, все у формы, вернее была одна таблица, но она заполнялась при работе.
И мне больше понравилось сохранение настроек в строку.

Поэтому вышел такой код:
&НаСервере
Функция ЭкспортНастроекВСтрокуНаСервере() 
	//https://infostart.ru/public/378879/
    
    Настройки = Новый Структура;
    //Для Каждого Реквизит Из ЭтаФорма.ПолучитьРеквизиты("Объект") Цикл
    Для Каждого Реквизит Из ЭтаФорма.ПолучитьРеквизиты() Цикл
      
        ЗначениеРеквизита = ЭтаФорма[Реквизит.Имя];
		Если Реквизит.Имя = "Объект" Тогда
			Продолжить;
		КонецЕсли;
        Если ТипЗнч(ЗначениеРеквизита) = Тип("ДанныеФормыКоллекция") Тогда
            Настройки.Вставить(Реквизит.Имя, ЗначениеРеквизита.Выгрузить());
            Продолжить;
        КонецЕсли;
    
        Настройки.Вставить(Реквизит.Имя, ЗначениеРеквизита);
    
	КонецЦикла;                          
	
    
    Возврат ЗначениеВСтрокуВнутр(Настройки);
    
КонецФункции   

// Заполняет значения всех реквизитов формы из временого хранилища, адрес которого указан в АдресВременногоХранилища
Процедура ИмпортНастроекИзСтроки(Строка)
    
    Попытка
        Настройки = ЗначениеИзСтрокиВнутр(Строка);
    Исключение
        Сообщить("Ошибка при загрузке настроек на сервере: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
  
    Для Каждого ЭлементНастройки Из Настройки Цикл
      
        Попытка
            Если ТипЗнч(ЭтаФорма[ЭлементНастройки.Ключ]) = Тип("ДанныеФормыКоллекция") Тогда
                ЭтаФорма[ЭлементНастройки.Ключ].Загрузить(ЭлементНастройки.Значение);
                Продолжить;
            КонецЕсли;
            ЭтаФорма[ЭлементНастройки.Ключ] = ЭлементНастройки.Значение;
        Исключение
            Сообщить("Ошибка при импорте настроек: " + ОписаниеОшибки());
        КонецПопытки;
    
      КонецЦикла;                          
  
КонецПроцедуры

Показать


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

&НаКлиенте
Процедура СохранитьНастройки(Команда)
	Т = Новый ТекстовыйДокумент();
	Т.УстановитьТекст(ЭкспортНастроекВСтрокуНаСервере());
	Т.Записать(ВыбИмяФайлаНастроек);
КонецПроцедуры


Показать
Прикрепленные файлы:
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот