Имя: Пароль:
1C
1С v8
Рассчеты в строке
,
0 Ilqarupup
 
03.06.13
13:47
Добрый день! Есть Документ Табель в конфигурации УСФ. Там у меня каждая строка это день месяца, а всего их 31. Заказчик захотел, чтобы в отдельной колонке показывалось количество дней отработанных за месяц. Сейчас это реализовано в виде цикла из 31 итераций с какой то формулой (уже сам не помню) по часам в каждом дне, результатом которой является количество дней. Все бы хорошо, но это занимает около 5 секунд. Есть ли другие более быстрые варианты решения этой задачи?
1 zak555
 
03.06.13
13:49
что такое усф ?
2 mikecool
 
03.06.13
13:49
цикл по колонкам + суммирование
3 Ilqarupup
 
03.06.13
13:50
управление строительной фирмой
4 mikecool
 
03.06.13
13:50
(1) стройфирма наверное
5 Ненавижу 1С
 
гуру
03.06.13
13:50
"с какой то формулой (уже сам не помню)"

придется вспомнить
6 Рэйв
 
03.06.13
13:51
(0)Расчет идет только по данным строки или еще куда то смотрит?
7 zak555
 
03.06.13
13:51
(2) запром это можно реализовать ?
8 mikecool
 
03.06.13
13:52
(7) можно
9 Ilqarupup
 
03.06.13
13:52
(2) я так и делаю сейчас,
(5) не так важно, максимум 3 строчки кода, суть вопроса в том как обойтись без цикла
10 Рэйв
 
03.06.13
13:52
Если расчет только по данным строки, то можно сделать просто добавочной колонкой и расчитывать  в ПриПолученииДанных()
11 Ilqarupup
 
03.06.13
13:52
(6) только по данным строки
12 Рэйв
 
03.06.13
13:53
(11)Тогда см. (10)
13 Ilqarupup
 
03.06.13
13:53
это какое то событие ячейки?
14 Рэйв
 
03.06.13
13:53
(13)Это событие табличного поля
15 Рэйв
 
03.06.13
13:54
(13)При каждом выводе порции строк на экран они будут расчитываться.Но только те что на показаны экране
16 Ilqarupup
 
03.06.13
13:56
такого события нету
17 Рэйв
 
03.06.13
13:58
(16)Есть.  Хотя если у тебя УФ, то тогда не знаю.
18 Cyberhawk
 
03.06.13
13:58
(16) ты выдели все табличное поле, а не колонку/поле ввода
19 Ilqarupup
 
03.06.13
14:00
сейчас это работает через событие "ПриИзменении" табличного поля
20 Ilqarupup
 
03.06.13
14:00
вообще всей таблицы
21 Cyberhawk
 
03.06.13
14:01
(19) а вот у таб. поля нет такого события. Настоятельно рекомендую перечитывать (18) до просветления
22 Ненавижу 1С
 
гуру
03.06.13
14:02
(21) в УФ есть
23 Cyberhawk
 
03.06.13
14:02
(22) спс, ща курну
24 Рэйв
 
03.06.13
14:03
25 kosts
 
03.06.13
14:03
Покажи код своего цикла
26 Ilqarupup
 
03.06.13
14:03
(24) у меня 8.2
27 Рэйв
 
03.06.13
14:04
(26)Ты не поверишь...
28 Ilqarupup
 
03.06.13
14:04
(25)

&НаКлиенте
Процедура ОтработанноеВремяПоДнямПриИзменении(Элемент)
   ТекущаяСтрока = Элементы.ОтработанноеВремяПоДням.ТекущиеДанные;
   ПосчитатьСтроку(ТекущаяСтрока);
   //ТекущаяСтрока.КолДней=Колдней;
КонецПроцедуры




&НаКлиенте
Процедура ПосчитатьСтроку(Строка)
   строка.КолДней=0;
   Для й=1 по 31 цикл
       тип=ПолСправочник(Строка["ПервыйВидВремени"+й]);
       чс= Строка["ПервыйЧасы"+й];
       Если тип <> неопределено и чс> 0 тогда
           строка.КолДней=строка.КолДней+чс/8;    
       КонецЕсли;
   КонецЦикла;    
КонецПроцедуры
29 Ilqarupup
 
03.06.13
14:05
(27) во что?
30 kosts
 
03.06.13
14:05
вот эту процедуру суда выложи
ПолСправочник()
31 kosts
 
03.06.13
14:06
Скорее всего сервер на каждой итерации дергается...
32 Ilqarupup
 
03.06.13
14:07
(30) у меня нет такой процедуры, один раз отправляю на сервер
33 Cyberhawk
 
03.06.13
14:07
(22) курнул, благодарю еще раз
(27) реально, таб. поле в УФ называется "Таблица" и автор не врет :) https://dl.dropboxusercontent.com/u/4517049/106.png
34 kosts
 
03.06.13
14:08
(32) Посмотри в модуле объекта
35 Ilqarupup
 
03.06.13
14:09
(34) причем тут модуль объекта? изменения происходят на клиенте
36 Ilqarupup
 
03.06.13
14:10
какие еще идеи?
37 kosts
 
03.06.13
14:10
(35) Что там делается в ПолСправочник(), нам отсюда не видать...
38 Cyberhawk
 
03.06.13
14:10
(35) тебе (34) говорит, мол, поищи функцию "ПолСправочник" в модуле объекта
39 Ilqarupup
 
03.06.13
14:12
сорри, сейчас увидел

&НаКлиенте
Процедура ПосчитатьСтроку(Строка)
   строка.КолДней=0;
   Для й=1 по 31 цикл
       тип=ПолСправочник(Строка["ПервыйВидВремени"+й]);
       чс= Строка["ПервыйЧасы"+й];
       Если тип <> неопределено и чс> 0 тогда
           строка.КолДней=строка.КолДней+чс/8;    
       КонецЕсли;
   КонецЦикла;    
КонецПроцедуры
   

&НаСервере
Функция ПолСправочник(Справочник)
   Зпр=новый Запрос;
   зпр.текст="ВЫБРАТЬ
             |    ВидыРабочегоВремени.Код
             |ИЗ
             |    Справочник.ВидыРабочегоВремени КАК ВидыРабочегоВремени
             |ГДЕ
             |    ВидыРабочегоВремени.Ссылка = &Справочник";
             Зпр.УстановитьПараметр("Справочник",Справочник);
             рез=Зпр.Выполнить().Выбрать();
             тип=Неопределено;
             Пока рез.Следующий() цикл
                 Если рез.Код="20" или рез.Код="24" или рез.Код="28" тогда
                      тип=55;
                 КонецЕсли;
                    возврат тип;
             КонецЦикла;    
             
КонецФункции
40 kosts
 
03.06.13
14:12
Запусти для профилактики замер производительности в начале цикла, и останови после цикла.
41 kosts
 
03.06.13
14:13
(39) Переделывай, что бы один раз сервер вызывался.
42 Ilqarupup
 
03.06.13
14:14
я 31 раз обращаюсь на сервер
43 Ilqarupup
 
03.06.13
14:14
сейчас попробую
44 kosts
 
03.06.13
14:21
На будущее называй переменные и функции более корректно.
Функция ПолСправочник(Справочник)
Лучше было бы как-то так
Функция ВходитВОтработанныеЧасы(ВидВремени)
45 Ilqarupup
 
03.06.13
14:42
все, переписал, теперь не тормозит

&НаКлиенте
Процедура ПосчитатьСтроку(Строка)
   строка.КолДней=0;
   струк=новый Структура;
   Для й=1 по 31 цикл
   струк.Вставить("ПервыйВидВремени"+й,Строка["ПервыйВидВремени"+й])
   КонецЦикла;

   тп=ПолСправочник(струк);
   
   Для й=1 по 31 цикл
       тип=тп[Строка("ПервыйВидВремени"+й)];
       чс= Строка["ПервыйЧасы"+й];
       Если тип <> неопределено и чс> 0 тогда
           строка.КолДней=строка.КолДней+чс/8;    
       КонецЕсли;
   КонецЦикла;    
   
   
   
   //Для й=1 по 31 цикл
   //    тип=ПолСправочник(Строка["ПервыйВидВремени"+й]);
   //    чс= Строка["ПервыйЧасы"+й];
   //    Если тип <> неопределено и чс> 0 тогда
   //        строка.КолДней=строка.КолДней+чс/8;    
   //    КонецЕсли;
   //КонецЦикла;    

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

&НаСервере
Функция ПолСправочник(струк)
   тп=новый структура;
   Для й=1 по 31 цикл
   
   Зпр=новый Запрос;
   зпр.текст="ВЫБРАТЬ
             |    ВидыРабочегоВремени.Код
             |ИЗ
             |    Справочник.ВидыРабочегоВремени КАК ВидыРабочегоВремени
             |ГДЕ
             |    ВидыРабочегоВремени.Ссылка = &Справочник";
             Зпр.УстановитьПараметр("Справочник",струк[Строка("ПервыйВидВремени"+й)]);
             рез=Зпр.Выполнить().Выбрать();
             тип=Неопределено;
             Если рез.Следующий() тогда
                 Если рез.Код="20" или рез.Код="24" или рез.Код="28" тогда
                      тп.Вставить(Строка("ПервыйВидВремени"+й),55);
                  иначе
                     тп.Вставить(Строка("ПервыйВидВремени"+й),Неопределено);
                 КонецЕсли;
                 
                 //возврат тип;
                  иначе
                     тп.Вставить(Строка("ПервыйВидВремени"+й),Неопределено);
             КонецЕсли;
             
         КонецЦикла;
         
         Возврат тп;
КонецФункции
46 Ilqarupup
 
03.06.13
14:49
(44) учту
47 kosts
 
03.06.13
15:30
(45) Если будет предпраздничный день с семью часами, сколько получится отработанных дней?
48 Ilqarupup
 
03.06.13
15:36
на 1/8 дня меньше
49 kosts
 
04.06.13
06:36
(48) Первый раз, встретил, когда дни дробными считают.
Программист всегда исправляет последнюю ошибку.