Имя: Пароль:
1C
1С v8
УФ. Как заполнить ТЧ оброботки на сервере без контекста вызванного из клиента?
0 simol
 
13.03.13
15:42
Есть обработка с двумя табличными частями.
На УФ формы две таблицы отображающие эти ТЧ.
Одна заполняется при открытии по данным базы. Она большая. Пользователь в УФ может ее редактировать.
При активации строке строки в этой таблице (исходя из данных строки) заполняется вторая таблица.
Все по функционалу работает. При активации строки вызывается серверная процедура с контекстом, которая заполняет вторую таблицу.

НО! При вызове серверной процедуры с контекстом, по причине большой первой таблицы, происходит задержка на передачу контекста.

Как можно исторгнутся с серверной процедурой без контекста, чтобы передать ей данные текущей строки первой таблицы и она заполнила вторую таблицу?
1 simol
 
13.03.13
15:43
исторгнутся  = изгольнуться
2 НЕА123
 
13.03.13
15:45
передать через параметры
?
3 Жан Пердежон
 
13.03.13
15:46
ответ же в (0) уже есть, передавай только нужные параметры
4 simol
 
13.03.13
15:51
Я не могу в параметры вызова функции вставить Объкт.ТЧ, так как тип "ДанныеФормыКоллекция" не передается с клиента на сервер. А с сервера Таблица значения на клиент не возвращается.
5 НЕА123
 
13.03.13
15:53
(4)
зачем Объкт.ТЧ?
достаточно ведь данные строки.
возвращай через структуру.
6 simol
 
13.03.13
15:57
(5)Вариант возвращаемую таблицу на сервере преобразовывать в массив структур и на клиенте структуры из массива добавлять по построчно в таблицу рассматриваю, но это кажется мне костылем.
7 НЕА123
 
13.03.13
15:59
(6)
согласен. но на ум больше ничего не приходит...
8 MSII
 
13.03.13
16:07
(6) Чтобы не казалось костылем, надо написать серверную и клиентскую функции, которые будут, соответственно, упаковывать переданные данные в массив структур и распаковывать этот массив, создавая строки табличной части. Дальше во всех аналогичных случаях пользоваться этими функциями.
9 simol
 
13.03.13
16:22
(8)Очень надеюсь, что кто-то обрадует что уже можно на клиенте тип ТаблицаЗначений :)
10 MSII
 
13.03.13
16:35
(9) Давно ли? Я где-то с УФ с 14-й платформы не работаю, не в курсе. А на 14-й вернуть ТЗ, как она есть, с сервера на клиент не представлялось возможным.
11 simol
 
13.03.13
16:49
(10)ТЗ есть только в в толстом клиенте. А загрузить ТЗ в ТЧ можно только на сервере, на клиенте доступно построчное добавление.
12 simol
 
14.03.13
00:35
(7)(8)Общий модуль так и назвал "КостылиДляУФ"
Задержку удалось победить таким способом.
13 Команданте
 
14.03.13
00:38
у тебя активизация строки не отлажена
14 Команданте
 
14.03.13
00:41
нельзя вызывать при активизации строки серверную процедуру с контекстом
15 Команданте
 
14.03.13
00:43
попробуй так

&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
   
   Если Элементы.Список.ТекущиеДанные = Неопределено Тогда
       Возврат;
   КонецЕсли;    
       
   ПодключитьОбработчикОжидания("ОбработчикОжиданияСписокПриАктивизацииСтроки", 0.2, Истина);        
   
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикОжиданияСписокПриАктивизацииСтроки()
   
   СервернаяПроцедураСКонтекстом();
   
КонецПроцедуры
16 Команданте
 
14.03.13
00:45
в худшем случае, елси это не прокатит

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

&НаКлиенте
Процедура ОбработчикОжиданияСписокПриАктивизацииСтроки()
   
   ТекНоменклатураПриИзмененииСервер();
   
КонецПроцедуры

где ТекНоменклатуры реквизит формы
заменить на нужный реквизит ДС
17 Команданте
 
14.03.13
00:48
скинь код, товарищ массив структур
18 Aleksey
 
14.03.13
00:53
(17) ты про
// Преобразовывает таблицу значений в массив структур
&НаКлиенте
Функция ПреобразоватьТаблицуВМассив(ТаблицаЗначений)

   Перем РезультатМассив;
   Перем СтруктураСтрока;

   // Сформируем массив структур

   РезультатМассив = Новый Массив;
   Для Каждого Строка Из ТаблицаЗначений Цикл
       // Сформируем структуру-строку

       СтруктураСтрока = Новый Структура;
       Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
           СтруктураСтрока.Вставить(Колонка.Имя, Строка[Колонка.Имя]);
       КонецЦикла;
       РезультатМассив.Добавить(СтруктураСтрока);
   КонецЦикла;

   Возврат РезультатМассив;

КонецФункции
19 Команданте
 
14.03.13
00:55
(18) откуда на клиенте ТЗ
20 Aleksey
 
14.03.13
00:58
(19) Да пофиг ТЗ это или ТЧ
21 Команданте
 
14.03.13
01:00
у тебя путаница с клиентом-сервером. не обязательно делать массив структур (хотя ут 11 этим пользуется часто)
всё дело в стиле вызова
22 Команданте
 
14.03.13
01:01
ты скинь код, а не огрызок
23 simol
 
14.03.13
02:19
(13)В активации у меня идет проверка на повторный вызов, потому зацикливания нет.
(22)

&НаКлиенте
Процедура ТЧРаспределяемоеПриАктивизацииСтроки(Элемент)
   
   Если ПредыдущаяСтрока = Элементы.ТЧРаспределяемое.ТекущаяСтрока Тогда
       Возврат;
   КонецЕсли;    
   
   Если ЭтаФорма.Модифицированность Тогда
       //Сохраним изменения
       СохранитьИзмененияСервер();
   КонецЕсли;    
   
   //Так сложно сделано, чтобы сделать заполнение таблиц на сервере без контекста. С контекстом гонять ТЧРаспределяемое медленно.
   //А нормальног оспособа обмена ТЧ между клиентом и Серверными не контекстными функциями не нашел. В тонком клиенте нет Таблицы Значений
   //Сохраним текущий как предыдущий
   ПредыдущаяСтрока = Элементы.ТЧРаспределяемое.ТекущаяСтрока;
   
   ТекущийДокумент = Элементы.ТЧРаспределяемое.ТекущиеДанные.ДокументРаспределения;
   НеУдалосьЗаблокировать = Ложь;
   
   ТекущиеДанныеВСтруктуре = _КостылиДляУФ.ПолучитьТекущиеДанныеВСтруктуре(Элементы.ТЧРаспределяемое.ТекущиеДанные, СписокКолонокТЧРаспределяемое);
   
   СтруктураВозврата = ТЧРаспределяемоеПриАктивизацииСтрокиНаСервере(ПредыдущийДокумент, ЭтаФорма.УникальныйИдентификатор, НеУдалосьЗаблокировать, ТекущиеДанныеВСтруктуре);
   _КостылиДляУФ.ЗаполнитьТЧПоСтруктуре(Объект, СтруктураВозврата);
   
   //ТекущиеДанные могли в ТЧРаспределяемоеПриАктивизацииСтрокиНаСервере измениться
   _КостылиДляУФ.ЗаполнитьТЧПоСтруктуре(Элементы.ТЧРаспределяемое.ТекущиеДанные, ТекущиеДанныеВСтруктуре);
   
   Если НеУдалосьЗаблокировать Тогда
       Элементы.СтатьиОборотовБазаРаспределения.ТолькоПросмотр = Истина;
       Элементы.ЦФОБазаРаспределения.ТолькоПросмотр = Истина;
       Элементы.ТаблицаПодменЗадачПроектов.ТолькоПросмотр = Истина;
   КонецЕсли;    
   
КонецПроцедуры
24 simol
 
14.03.13
02:22
Модуль _КостылиУФ

//В Тонком клиенте и в Веб клиенте нет типа Таблица значений.
//Потмоу чтобы УФ работали и в этих клинетах для передачи Табличных частей с клиентткой процедуры УФ в серверную без контекста использую эти костыли.

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

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

//Клиент
Функция ПолучитьТекущиеДанныеВСтруктуре(ТекущиеДанные, СписокКолонокТЧ) Экспорт
   
   Если ТекущиеДанные = Неопределено Тогда
       Возврат Неопределено;
   Иначе    
       СтруктураВозврата = ПолучитьСтруктуруПоСпискуКолонокТЧ(СписокКолонокТЧ);
       ЗаполнитьЗначенияСвойств(СтруктураВозврата, ТекущиеДанные);
       Возврат СтруктураВозврата;
   КонецЕсли;    
   
КонецФункции    

Функция ВыгрузитьКолонкуТЧВМассивБезПустых(ТабличкаяЧасть, ИмяКолонки) Экспорт
   
   Массив = Новый Массив;
   
   Для Каждого СтрокаТЧ Из ТабличкаяЧасть Цикл
       Если ЗначениеЗаполнено(СтрокаТЧ[ИмяКолонки]) Тогда
           Массив.Добавить(СтрокаТЧ[ИмяКолонки]);
       КонецЕсли;
   КонецЦикла;    
       
КонецФункции    
#КонецЕсли

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

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

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

25 simol
 
14.03.13
02:23
ТЧРаспределяемоеПриАктивизацииСтрокиНаСервере

&НаСервереБезКонтекста
Функция ТЧРаспределяемоеПриАктивизацииСтрокиНаСервере(ПредыдущийДокумент, УникальныйИдентификатор, НеУдалосьЗаблокировать, ТекущиеДанныеВСтруктуре);
   
   СтруктураВозврата = Новый Структура;
   
   //Разблокируем предыдущий, если заблокирован
   Если ЗначениеЗаполнено(ПредыдущийДокумент) Тогда
       РазблокироватьДанныеДляРедактирования(ПредыдущийДокумент, УникальныйИдентификатор);
   КонецЕсли;
   
   //Проверим, может уже создано в другой сессии
   Если Не ЗначениеЗаполнено(ТекущиеДанныеВСтруктуре.ДокументРаспределения) Тогда
       Запрос = Новый Запрос;
       Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
                      |    _НастройкаРаспределенияЗатратПоПроектам.Ссылка,
                      |    _НастройкаРаспределенияЗатратПоПроектам.Дата
                      |ИЗ
                      |    Документ._НастройкаРаспределенияЗатратПоПроектам КАК _НастройкаРаспределенияЗатратПоПроектам
                      |ГДЕ
                      |    _НастройкаРаспределенияЗатратПоПроектам.СтатьяОборотовРаспределяемое = &СтатьяОборотовРаспределяемое
                      |    И _НастройкаРаспределенияЗатратПоПроектам.ЦФОРаспределяемое = &ЦФОРаспределяемое
                      |    И _НастройкаРаспределенияЗатратПоПроектам.Сценарий = &Сценарий
                      |    И _НастройкаРаспределенияЗатратПоПроектам.ПериодПланирования = &ПериодПланирования
                      |    И НЕ _НастройкаРаспределенияЗатратПоПроектам.ПометкаУдаления";
       Запрос.УстановитьПараметр("СтатьяОборотовРаспределяемое", ТекущиеДанныеВСтруктуре.СтатьяОборотовРаспределяемое);              
       Запрос.УстановитьПараметр("ЦФОРаспределяемое", ТекущиеДанныеВСтруктуре.ЦФОРаспределяемое);              
       Запрос.УстановитьПараметр("Сценарий", ТекущиеДанныеВСтруктуре.Сценарий);              
       Запрос.УстановитьПараметр("ПериодПланирования", ТекущиеДанныеВСтруктуре.ПериодПланирования);              
       РезультатЗапроса = Запрос.Выполнить().Выбрать();
       Если РезультатЗапроса.Следующий() Тогда
           ТекущиеДанныеВСтруктуре.ДокументРаспределения = РезультатЗапроса.Ссылка;    
           ТекущиеДанныеВСтруктуре.ДатаИзменения = РезультатЗапроса.Дата;    
       КонецЕсли;    
       
   КонецЕсли;    
   
   //Заблокируем текущий
   ПредыдущийДокумент = ТекущиеДанныеВСтруктуре.ДокументРаспределения;
   Если ЗначениеЗаполнено(ПредыдущийДокумент) Тогда
       Попытка
           ЗаблокироватьДанныеДляРедактирования(ПредыдущийДокумент, ,УникальныйИдентификатор);
       Исключение
           
           ТекстСообщения = ОписаниеОшибки();
           ТекстСообщения = Сред(ТекстСообщения, Найти(ТекстСообщения, "пользователь:"));
           ПоложениеЗапятой = Найти(ТекстСообщения, ",");
           ТекстСообщения = Лев(ТекстСообщения, ПоложениеЗапятой - 1);
           
           ОбщегоНазначения.СообщитьОбОшибке("Объект уже заблокирован, " + ТекстСообщения);
           
           НеУдалосьЗаблокировать = Истина;
           
       КонецПопытки;
       //ЗаполнимТаблицы
       ТекущиеДанныеВСтруктуре.ДатаИзменения = ПредыдущийДокумент.Дата;
       СтруктураВозврата.Вставить("СтатьиОборотовБазаРаспределения", _КостылиДляУФ.ПреобразоватьТЧВМассивСтруктур(ПредыдущийДокумент.СтатьиОборотовБазаРаспределения));
       СтруктураВозврата.Вставить("ЦФОБазаРаспределения", _КостылиДляУФ.ПреобразоватьТЧВМассивСтруктур(ПредыдущийДокумент.ЦФОБазаРаспределения));
       СтруктураВозврата.Вставить("ТаблицаПодменЗадачПроектов", _КостылиДляУФ.ПреобразоватьТЧВМассивСтруктур(ПредыдущийДокумент.ТаблицаПодменЗадачПроектов));
       СтруктураВозврата.Вставить("ТаблицаРезультат", _КостылиДляУФ.ПреобразоватьТЧВМассивСтруктур(ПолучитьТаблицуРезультатСервер(ТекущиеДанныеВСтруктуре, ПредыдущийДокумент.СтатьиОборотовБазаРаспределения.ВыгрузитьКолонку("СтатьяОборотовБазаРаспределения"), ПредыдущийДокумент.ЦФОБазаРаспределения.ВыгрузитьКолонку("ЦФОБазаРаспределения"))));
   Иначе
       СтруктураВозврата.Вставить("СтатьиОборотовБазаРаспределения", Новый Массив);
       СтруктураВозврата.Вставить("ЦФОБазаРаспределения", Новый Массив);
       СтруктураВозврата.Вставить("ТаблицаПодменЗадачПроектов", Новый Массив);
       СтруктураВозврата.Вставить("ТаблицаРезультат", Новый Массив);
   КонецЕсли;
   
   Возврат СтруктураВозврата;
   
КонецФункции
26 simol
 
14.03.13
02:25
(20)Совсем не пофиг. Оказалось и ".Колонки" даже нет.
27 simol
 
14.03.13
02:59
(21) Мне в в током клиенте с клиентской процедуры УФ в серверную процедуру без контекста нужно передать ДанныеФормыКолекция.
28 simol
 
14.03.13
13:07
Вылезла бяка - неявный вызов сервера с контекстом после обработчика Активация строки.
Буду искать причину.
29 simol
 
11.04.13
11:08
(28)Наше, устранил. Серверные функции с контекстом это зло!!!