|
Зависание 1С при возврате на клиента | ☑ | ||
---|---|---|---|---|
0
non1ka
10.02.15
✎
14:05
|
Добрый день.
Платформа 8.3.5.1443. Модуль собственной разработки. Ошибка в следующем, в определенной ситуации (не диагностируемой), после выполнения процедуры &НаСервереБезКонтекста, которая возвращает «массив структур» для дальнейшего заполнения табличной части справочника в момент когда производится отключение от сервера (КонецФункции) и возврат НаКлиента система «мифически» зависает и не передает управление Клиенту. Другими словами система зависает. В некоторых справочниках все отлично, в некоторых зависает. Что я предпринял: 1. Вынес все выводы сообщений из процедуры; 2. Вывел из контекста формы, перенес НаСерверБезКонтекста, ранее заполнял табличную часть в процедуре &НаСервере методом Загрузить(); 3. Установил привилегированный режим. Укажите куда копать? |
|||
1
mikecool
10.02.15
✎
14:06
|
замер производительности
|
|||
2
H A D G E H O G s
10.02.15
✎
14:07
|
(0) Циклическая ссылка?
|
|||
3
polosov
10.02.15
✎
14:09
|
(0) А в структуре значения каких типов?
|
|||
4
Жан Пердежон
10.02.15
✎
14:10
|
(0) но код нам все равно не покажешь?
|
|||
5
non1ka
10.02.15
✎
14:12
|
Обнаружил зависимость.
Зависит от размера массива. В диспетчере состояние процесса "Работает". Код простой: УстановитьПривилегированныйРежим(Истина); ТабличнаяЧастьСоставМеню = ПолучитьИзВременногоХранилища(АдресВоВременномХранилище); ТабличнаяЧастьСоставМенюДляРазузлования = ТабличнаяЧастьСоставМеню.Скопировать(); ТабличнаяЧастьСоставМенюДляРазузлования.Свернуть("Номенклатура, ЕдиницаИзмерения"); ТаблицаМатериалов = ИнициализироватьТаблицуМатериаловПоПродукции(); МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; // Сформируем таблицу материалов по продукции, для оперделения закупочной стоимости Запрос = Новый Запрос; Запрос.УстановитьПараметр("ТабличнаяЧастьСоставМеню", ТабличнаяЧастьСоставМеню); Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; Запрос.Текст = ПолучитьТекстЗапросаИнициированияВременныхТаблицОбновленияСтоимости(); Запрос.Выполнить(); // Выполним рекурсивное заполнение таблицы материалы по продукции Для каждого СтрокаТабличнойЧастиСоставМеню из ТабличнаяЧастьСоставМенюДляРазузлования Цикл Если СтрокаТабличнойЧастиСоставМеню.Номенклатура.Пустая() Тогда Продолжить; КонецЕсли; Запрос.Текст = ПолучитьТекстЗапросаОпределенияОсновнойСпецификацииПродукции(); Запрос.УстановитьПараметр("Номенклатура", СтрокаТабличнойЧастиСоставМеню.Номенклатура); РузельтатЗапросаПоискаОснонойСпецификации = Запрос.Выполнить(); Если РузельтатЗапросаПоискаОснонойСпецификации.Пустой() Тогда Продолжить; КонецЕсли; ВыборкаПоискаОснонойСпецификации = РузельтатЗапросаПоискаОснонойСпецификации.Выбрать(); ВыборкаПоискаОснонойСпецификации.Следующий(); Если СписокСпецификацийДляАнализа.НайтиПоЗначению(ВыборкаПоискаОснонойСпецификации.Спецификация) = Неопределено Тогда СписокСпецификацийДляАнализа.Добавить(ВыборкаПоискаОснонойСпецификации.Спецификация); КонецЕсли; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // UIK KAV ++ // PR_ДополнительныйМодуль.ПодпискаНаСобытиеПередЗаписьюСпецификацииНоменклатуры(ВыборкаПоискаОснонойСпецификации.Спецификация, Ложь); // UIK KAV -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ПараметрыПоиска = Новый Структура; ПараметрыПоиска.Вставить("Продукция", СтрокаТабличнойЧастиСоставМеню.Номенклатура); ПараметрыПоиска.Вставить("Спецификация", ВыборкаПоискаОснонойСпецификации.Спецификация); ПараметрыПоиска.Вставить("ЕдиницаИзмеренияПродукции", СтрокаТабличнойЧастиСоставМеню.ЕдиницаИзмерения); ПараметрыПоиска.Вставить("КоличествоПродукции", 1); ПараметрыЗаполнения = Новый Структура; ПараметрыЗаполнения.Вставить("Продукция", СтрокаТабличнойЧастиСоставМеню.Номенклатура); ПараметрыЗаполнения.Вставить("ЕдиницаИзмеренияПродукции", СтрокаТабличнойЧастиСоставМеню.ЕдиницаИзмерения); // Проверим, может быть мы уже расчитывали стоимость по номенклатуре ПараметрыПроверкиРасчетаПродукции = Новый Структура("Продукция, ЕдиницаИзмеренияПродукции"); ЗаполнитьЗначенияСвойств(ПараметрыПроверкиРасчетаПродукции, ПараметрыЗаполнения); Если ТаблицаМатериалов.НайтиСтроки(ПараметрыПроверкиРасчетаПродукции).Количество() Тогда Продолжить; КонецЕсли; ВыполнитьРекурсивноеЗаполнениеТаблицыМатериалов(ТаблицаМатериалов, ПараметрыПоиска, ПараметрыЗаполнения, МенеджерВременныхТаблиц, СписокСпецификацийДляАнализа); КонецЦикла; Запрос.УстановитьПараметр("ТаблицаМатериалов", ТаблицаМатериалов); Запрос.Текст = ПолучитьТекстЗапросаОбновленияСебестоимости(); ТабличнаяЧастьСоставМеню = Запрос.Выполнить().Выгрузить(); // Уничтожим менеджер временных таблиц МенеджерВременныхТаблиц = Неопределено; МассивСтрокРасчетаРозничнойСтоимости = ТабличнаяЧастьСоставМеню.НайтиСтроки(Новый Структура("МетодРасчетаСтоимости", "ФормулаРасчета")); Для каждого СтрокаМассиваРасчетаРозничнойСтоимости из МассивСтрокРасчетаРозничнойСтоимости Цикл Попытка ФормулаРасчетаСтоимости = СтрЗаменить(СтрокаМассиваРасчетаРозничнойСтоимости.ФормулаРасчетаСтоимости, "Себестоимость", СтрЗаменить(СтрокаМассиваРасчетаРозничнойСтоимости.Себестоимость, ",", ".")); ФормулаРасчетаСтоимости = "СтрокаМассиваРасчетаРозничнойСтоимости.Стоимость = " + ФормулаРасчетаСтоимости; Выполнить(ФормулаРасчетаСтоимости); Исключение КонецПопытки; КонецЦикла; КлючиСтруктурыИзКолонок = ""; Для каждого КолонкаТабличнойЧастиСоставМеню из ТабличнаяЧастьСоставМеню.Колонки Цикл КлючиСтруктурыИзКолонок = КлючиСтруктурыИзКолонок + ?(Не ТабличнаяЧастьСоставМеню.Колонки.Индекс(КолонкаТабличнойЧастиСоставМеню), "", ?(ТабличнаяЧастьСоставМеню.Колонки.Индекс(КолонкаТабличнойЧастиСоставМеню) = ТабличнаяЧастьСоставМеню.Колонки.Количество() - 1, "", ",")) + КолонкаТабличнойЧастиСоставМеню.Имя; КонецЦикла; МассивСтруктурСОбновленнойСебестоимостью = Новый Массив; Для каждого СтрокаТабличнойЧастиСоставМеню из ТабличнаяЧастьСоставМеню Цикл СтруктураВМассив = Новый Структура(КлючиСтруктурыИзКолонок); ЗаполнитьЗначенияСвойств(СтруктураВМассив, СтрокаТабличнойЧастиСоставМеню); МассивСтруктурСОбновленнойСебестоимостью.Добавить(СтруктураВМассив); КонецЦикла; УстановитьПривилегированныйРежим(Ложь); Возврат МассивСтруктурСОбновленнойСебестоимостью; |
|||
6
DmitrO
10.02.15
✎
14:21
|
Функция ВызватьПереполнениеСтека()
Массив = Новый Массив; Массив.Добавить(Массив); Возврат Массив; КонецФункции |
|||
7
non1ka
10.02.15
✎
14:55
|
Самое удивительное, что в тонком клиенте работает все отлично.
|
|||
8
НЕА123
10.02.15
✎
15:30
|
(5)
может мимо, но... попробовать присвоить >Запрос.Выполнить(); ПУСТО = Запрос.Выполнить(); |
|||
9
non1ka
10.02.15
✎
16:50
|
Сейчас в другой процедуре, такая же проблема.
Интересный факт. Я процедуру вынес на обработчик ожидания. Если в процессе отладки прохожу подключение обработчика ожидания, все отрабатывает отлично. Ставлю 10 сек, что бы увидеть задержку и результат. А если отключаю точки остановы, при подключении отладчика зависает. |
|||
10
non1ka
11.02.15
✎
08:09
|
Ап
|
|||
11
stonewolf
11.02.15
✎
11:19
|
Попробуй вернуть как строку через ЗначениеВСтрокуВнутр.
|
|||
12
non1ka
12.02.15
✎
13:27
|
Первоначально не было ни каких возвратов. С сервера, все равно зависало.
|
|||
13
non1ka
13.02.15
✎
19:00
|
Ап!
Коллеги подскажите куда еще можно обратиться? |
|||
14
Sol78
13.02.15
✎
19:32
|
(13) покажи как выглядит описание функции, а то ты только её код привел
|
|||
15
non1ka
15.02.15
✎
14:12
|
(14), Что значит описание функции?
1. Табличная часть предварительно выгружается в таблицу значений и помещается во временное хранилище. 2. Вызывается серверная вне контекстная процедура которая получает из хранилища эту таблицу значений и передает ее в запрос. 3. Инициализируются временные таблицы, в которые помещаются состав спецификаций, последняя закупочная стоимость материалов, цены номенклатуры и т.п.; 4. Затем в цикле рекурсивно производится разузлование продукции до материалов (что бы определить плановую себестоимость номенклатуры на текущий момент времени). 5. Затем таблица материалов соединяется с таблицей себестоимости, 6. Затем по произвольной формуле (которую задает пользователь) рассчитывается розничная стоимость продукции. 7. Затем итоговая таблица переводится в массив структур и возвращается на клиента. Ошибок в алгоритме нет, есть контрольные процедуры проверки рекурсии и зацикливания, все временные таблицы проиндексированы, при выполнении алгоритма зависаний нет. Всегда алгоритм завершается на КонецФункции. |
|||
16
hhhh
15.02.15
✎
14:40
|
так вроде нельзя писать
СтруктураВМассив = Новый Структура(КлючиСтруктурыИзКолонок); Во всех строках массива будет одна и та же структура. |
|||
17
alle68
15.02.15
✎
15:01
|
(0) Если заполнять ТЧ на сервере, какова реакция системы?
(16) Для каждой строки своя структура. |
|||
18
non1ka
15.02.15
✎
16:06
|
(17) Если заполнять ТЧ на сервере, какова реакция системы?
Все прекрасно выполняется, табличная часть загружается. Но при возврате на клиента система зависает. Иногда, система не зависает и передает управление клиенту :) Но потом вызывается процедура расчета итогов, и при возврате на клиента опять зависает :) |
|||
19
alle68
15.02.15
✎
16:13
|
(18) А итоги тут при чём, это же справочник?
А сразу всё рассчитать на сервере нельзя, а не гонять туда-сюда? И что значит "иногда", это зависит от настроения клиента или от положения звёзд? |
|||
20
non1ka
15.02.15
✎
16:21
|
В справочнике, табличная часть представлена в виде ДереваЗначений, заполнение дерева значений из табличной части и расчет итогов (по каждой строке группировки) производится в отдельной процедуре, которая вызывается, как при открытии формы, так и при обновлении себестоимости.
Вот так выглядит форма справочника https://www.dropbox.com/s/oac4277zr3geqmr/Скриншот%202015-02-15%2016.18.06.png?dl=0 Скорее всего от положения звезд :) Закономерность не выявлена, открываешь форму запускаешь - отрабатывает, запускаешь снова - зависает. Кстати, в Файловом режиме все работает стабильно. |
|||
21
alle68
15.02.15
✎
16:34
|
(20) Значит, итоги на клиенте считать надо.
На картинке их что-то не видно... |
|||
22
non1ka
15.02.15
✎
17:04
|
(21) Просто скриншот сделан из чистой базы данных без документов.
Администратор компании для которой реализуется подсистема, частенько выполнял динамическое обновление базы данных, и однажды это привело к тому, что полетела таблица конфигурации. И мы проводили работы по копированию таблицы конфигурации из бэкапов средствами SQL. Соответственно мы попытались исключить ошибки связанные с базой данных, сделали чистый cf файл, создали чистую базу данных и перенесли в нее справочники. (21) "Значит, итоги на клиенте считать надо" Процедура расчета итогов запускается так же при открытии формы, и в 100% случаев выполняется. Зависания начали происходить совершенно в разных ситуациях, к примеру сейчас зависает функция подбора номенклатуры, которая открывает специализированную форму подбора, которая заполняется по такому же принципу: 1. Запрос для определения номенклатуры; 2. Загрузка номенклатуры в дерево значений 3. Возврат на клиента. (Зависает при возврате на клиента) |
|||
23
Sol78
16.02.15
✎
01:53
|
(15)
Функция ЭтоМояЗависающаяФункция(параметр1, Знач Параметр2, Параметр3 = Ложь) и какие типы у параметров |
|||
24
GROOVY
16.02.15
✎
02:44
|
Да. Об этом собственно и рекомендация 1с, не стоит имитировать работу обычного приложения в управляемом. Данные либо порционно сериализуются и самой системой отправляются клиенту, либо используется (в разумных пределах) временное хранилище.
|
|||
25
H A D G E H O G s
16.02.15
✎
03:11
|
(20) Жесть, как она есть.
|
|||
26
H A D G E H O G s
16.02.15
✎
03:12
|
(20) Завтра стукни мне в аську, я тебе все растолкую.
|
|||
27
non1ka
17.02.15
✎
09:33
|
(24) Павел, добрый день.
Если Вы меня помните, на Вашем форуме обсуждали запрет использования Регистров накопления при решении расчетных задач к Специалисту 1С. :) В Моем случае, происходит имитирование управляемого приложения в обычном. Но проблема не в имитировании, так как процедура зависает и в управляемом приложении! (23) Один параметр АдресВоВременномХранилище - Адрес таблицы значений во временном хранилище. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |