|
Ускорение проведения | ☑ | ||
---|---|---|---|---|
0
romaku
16.08.11
✎
20:24
|
Есть куча ручных операций. Там нужно заменить один счет на другой.
Цикл по операциям: Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей(); Набор.Отбор.Регистратор.Установить(Объект.Ссылка); Набор.Прочитать(); Для каждого Запись из Набор Цикл Если Запись.СчетКт = "800" тогда Запись.СчетКт = "900" (условно) КонецЕсли; КонецЦикла; Набор.Записать(); КонецЦикла по операциям. Все это дело работает очень медленно, операций и проводок очень много. можно как-то ускорить процесс? |
|||
1
МихаилМ
16.08.11
✎
20:27
|
про транзакцию почитайте
про не явные преобразоваеия типов |
|||
2
romaku
16.08.11
✎
20:28
|
НачатьТРанзакцию() в начале, и ЗафиксироватьТранзакцию() в конце вставил. Все равно долго. Или я что-то не понял как необходимо с ней работать.
А что с преобразованием типов? |
|||
3
asady
16.08.11
✎
20:29
|
(0) отключи итоги по РБ
потом выполни все изменения потом включи итоги |
|||
4
KRV
16.08.11
✎
20:29
|
Провести.Быстро.Мля!()
|
|||
5
romaku
16.08.11
✎
20:30
|
Зада кстати не только замены счета одного на другой, но и одного значения субконто на другое. счет - это для примера.
Можно как-то сделать запрос на обновление данных? |
|||
6
Stim213
16.08.11
✎
20:36
|
Для каждого Запись из Набор Цикл - это для новичков.
Тру-программеры обрабатывают в запросе такие вещи и загружают ТЗ в движения. Примерно так: Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ХозрасчетныйДвиженияССубконто.Период, | ХозрасчетныйДвиженияССубконто.НомерСтроки, | ХозрасчетныйДвиженияССубконто.Активность, | ВЫБОР | КОГДА ХозрасчетныйДвиженияССубконто.СчетДт = &Счет | ТОГДА &СчетЗаменить | ИНАЧЕ ХозрасчетныйДвиженияССубконто.СчетДт | КОНЕЦ КАК СчетДт бла-бла а потом ТЗЗаписей = Запрос.Выполнить().Выгрузить(); МояОперация.Движения.Хозрасчетный.Загрузить(ТЗЗаписей); |
|||
7
Господин ПЖ
16.08.11
✎
20:38
|
>Тру-программеры обрабатывают в запросе
1Ц за запросы в цикле ставит тру-двойки на сертификации... |
|||
8
romaku
16.08.11
✎
20:42
|
(6) я новичок.
что такое МояОперация? Это, я так понял, делается не в цикле, а просто подмена счета или субконто в итоговой таблице запроса происходит? или не так понял? |
|||
9
GROOVY
16.08.11
✎
20:43
|
(7) СовсемТруПрограммеры делают запрос, который находит все что надо переделать, и на его основе в цикле по результату запроса в транзакции формируют движения.
|
|||
10
GROOVY
16.08.11
✎
20:44
|
За (6) можо поставить ну не 2, а 3...
|
|||
11
romaku
16.08.11
✎
20:45
|
я сделал запрос, который выбирает все что нужно переделать.
выгрузил итог запроса в таблицу. а дальше по таблице в цикле: Набор.Отбор.Регистратор.Установить(тз.Объект.Ссылка); Набор.Прочитать(); Проводка = НаборЗаписей.Получить(тз.НомерСтроки-1); Если проводка.СчетКт = "800" тогда проводка.СчетКт = "900" (условно) КонецЕсли; КонецЦикла; Набор.Записать(); КонецЦикла; |
|||
12
Stim213
16.08.11
✎
20:46
|
(7)Если бы можно было загружать выборку по итогам в ТЗ, было бы еще здоровее.
А по поводу запросов в цикле - иногда это полезно. Полезнее, например, чем в делать вложенные циклы, как в (0). Да и авторы типовых совсем не брезгуют запросами в цикле |
|||
13
GROOVY
16.08.11
✎
20:47
|
(12) Как в (0) делать вообще никогда не надо и это не оправдание запросу в цикле.
|
|||
14
Stim213
16.08.11
✎
20:48
|
когда операции созданы программно и имеют более 1к строк - то лучше загружать через выборку запроса(ТЗ)
|
|||
15
GROOVY
16.08.11
✎
20:48
|
(11) Ты чето не понял. Зачем тебе идиотские циклы и условия по результату запроса? Там уже все отобрано должно быть.
|
|||
16
Stim213
16.08.11
✎
20:48
|
(13)а как по-другому? Имхо - это самый быстрый вариант.
|
|||
17
romaku
16.08.11
✎
20:48
|
так как надо сделать?
запроса в цикле нет. сперва запрос, потом итог запроса в таблицу, затем обработка таблицу. затык на том что НаборЗаписей,Записать() очень долго времени занимает. |
|||
18
GROOVY
16.08.11
✎
20:53
|
Запрос формирует выборку с полями "Регистратор, номерСтроки, Счета и другие данные о проводке". Выборку попадает только отобранные по условиям проводки. В запросе используются итоги по регистратору.
На основе иерархической выборки запроса формируется 2 цикла. Первый цикл Выбирает регистратор, второй ищет в наборе записей с отбором по регистратору нужную строку и заменяет значение. По результату внутри цикла по Регистратору происходит запись набора записей. Над обоими цикла разумно использовать транзакцию со счетчиком фиксирования. Размер записей в транзакции разумно подобрать экспериментально, например за начальное значение может сойти 10000. |
|||
19
GROOVY
16.08.11
✎
20:55
|
(16) Иди учиться.
(14) Какая разница как созданы записи в регистре? Обрабатывать ВСЕ строки - бред. Загрузка данных из результата запроса в набор записей не всегда быстрее обработки данных в выборке. Как раз в регистре бухгалтерии это будет медленнее, из-за составного типа субконто. |
|||
20
Aleksey
16.08.11
✎
20:57
|
(11) Итоги отключил?
|
|||
21
Stim213
16.08.11
✎
21:00
|
"Запрос формирует выборку с полями "Регистратор, номерСтроки, Счета и другие данные о проводке". Выборку попадает только отобранные по условиям проводки"
"По результату внутри цикла по Регистратору происходит запись набора записей." Ловко, однако. Из 100 записей одного регистратора будет отобрано запросом только 2(к примеру) и эти две будут обходиться во втором цикле. И эти две в итоге запишутся в регистр, перезаписывая или добавляясь к предыдущим записям. (РегистрБухгалтерииНаборЗаписей.<Имя регистра бухгалтерии> (AccountingRegisterRecordSet.<Имя регистра бухгалтерии>) Записать (Write) Синтаксис: Записать(<Замещать>) Параметры: <Замещать> (необязательный) Тип: Булево. Определяет режим замещения существующих записей в соответствии с текущими установками отбора. Истина - перед записью существующие записи будут удалены. Ложь - записи будут дописаны к уже существующим в информационной базе записям. ) |
|||
22
Stim213
16.08.11
✎
21:01
|
+ это я СП скопировал, если что
|
|||
23
GROOVY
16.08.11
✎
21:02
|
(21) Прочитав набор записей и заменив в нем 2 строки Ты предлагаешь ДОПИСАТЬ чтоли второй раз данные в базу?
|
|||
24
Stim213
16.08.11
✎
21:06
|
(23) выложи плз код, а то я тебя не пойму. Ты хочешь обойти иерархическую выборку запроса и в то же время читать набор записей РБ.
|
|||
25
artbear
16.08.11
✎
21:08
|
(23) Нафига внутри второго цикла еще раз выполнять поиск?
ИМХО это как раз медленно! Пояснишь? ЗЫ у нас уже почти ночь, возможно, я что-то не понял. |
|||
26
GROOVY
16.08.11
✎
21:11
|
(24) Код не выложу, нет 1С, писать в блокноте лень.
(25) Поиск по номеру строки в наборе записей очень быстро. |
|||
27
Stim213
16.08.11
✎
21:13
|
Набор записей все равно придется записывать полностью. Не важно, что из 100 записей регистратора только одна проводка исправлена - записывать приходится весь набор регистратора, разве нет?
|
|||
28
GROOVY
16.08.11
✎
21:15
|
(27) Естественно.
|
|||
29
Stim213
16.08.11
✎
21:20
|
(28)тогда твой метод получается медленнее.
Что быстрее: 1. Получаем итоговую выборку запроса цикл - обходим регистраторы вложенный цикл - обходим записи,заменяем счет. конецЦикла ЗаписываемНаборЗаписей 2. Получаем выборку регистраторов, где есть проводки с нужным счетом Цикл - обходим регистраторы Вложенный цикл - получаем исправленную ТЗ, без обхода проводок КонецЦикла ЗаписываемНаборЗаписей В то время, пока ты будешь обходить записи - я получу исправленную ТЗ и загружу её в набор. В вилларибо еще моют посуду, а в вилабаджио поют и танцуют. |
|||
30
artbear
16.08.11
✎
21:20
|
(28) ИМХО на повторном чтении набора по регистратору ты упустишь весь выигрыш от запроса :(
|
|||
31
artbear
16.08.11
✎
21:20
|
(29) ты также не прав :(
|
|||
32
artbear
16.08.11
✎
21:21
|
(29) Опиши, как во вложенном цикле ты получишь ТЗ ?
через повторный запрос чтоли? |
|||
33
vde69
16.08.11
✎
21:26
|
пишу на память (ошибок наверно много), конечно это тоже не оптимально но будет сильно быстрее
начатьтранзакцию() Набор.Отбор.Регистратор.Установить(тз.Объект.Ссылка); Набор.Прочитать(); тз=Набор.Выгрузить(); отбор = новый соответствие; отбор.вставить("СчетКт", 800); ст = тз.найтистроки(отбор); для каждого эл из ст цикл эл.СчетКт = "900" (условно) КонецЦикла; Набор.загрузить(ТЗ); Набор.Записать(); КонецЦикла; зафиксироватьтранзакцию() |
|||
34
Stim213
16.08.11
✎
21:27
|
(32)да.
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | ХозрасчетныйДвиженияССубконто.Регистратор |ИЗ | РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(, , Счет = &Счет И ХозрасчетныйДвиженияССубконто.Регистратор ССЫЛКА Документ.ОперацияБух, , ) КАК ХозрасчетныйДвиженияССубконто"; Запрос.УстановитьПараметр("Счет",счетИскать); ВыборкаДокументов = Запрос.Выполнить().Выбрать(); Пока ВыборкаДокументов.Следующий() Цикл ТЗЗаписей = ПолучитьИсправленныйНаборЗаписей(ВыборкаДокументов.Регистратор); Операция = ВыборкаДокументов.Регистратор.ПолучитьОбъект(); Операция.Движения.Хозрасчетный.Загрузить(ТЗЗаписей); Операция.Записать(); КонецЦикла |
|||
35
GROOVY
16.08.11
✎
21:27
|
(29) Возьми 1с и затести. Незабудь отписаться о результатах.
(30) Согласен. |
|||
36
GROOVY
16.08.11
✎
21:28
|
(34) А нафига тебе ДОКУМЕНТ то читать?
|
|||
37
artbear
16.08.11
✎
21:30
|
(29) Заново прочитал твое (6)
Да, ты говоришь о запросах внутри цикла. Совсем не гуд. Лично я сделал так: фактически компоную ваши подходы все исправления делаю сразу в запросе (выбор если счетДт = ХХ ТОГДА &СчетЗаменить Иначе СчетДТ), в нем собираю всю таблицу и в запросе ставлю итоги по регистратору внешний цикл по регистратору, внутренний - создаю набор записей из выборки (через простые и быстрые Добавить, ЗаполнитьЗначенияСвойств), после выхода из внутреннего цикла идет запись созданного набора. |
|||
38
Stim213
16.08.11
✎
21:30
|
+
Функция ПолучитьИсправленныйНаборЗаписей(Регистратор) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ХозрасчетныйДвиженияССубконто.Период, | ХозрасчетныйДвиженияССубконто.НомерСтроки, | ХозрасчетныйДвиженияССубконто.Активность, | ВЫБОР | КОГДА ХозрасчетныйДвиженияССубконто.СчетДт = &Счет | ТОГДА &СчетДобавить | ИНАЧЕ ХозрасчетныйДвиженияССубконто.СчетДт | КОНЕЦ КАК СчетДт, | ХозрасчетныйДвиженияССубконто.СубконтоДт1 | ВЫБОР | КОГДА ХозрасчетныйДвиженияССубконто.СчетКт = &Счет | ТОГДА &СчетДобавить | ИНАЧЕ ХозрасчетныйДвиженияССубконто.СчетКт | КОНЕЦ КАК СчетКт, | ХозрасчетныйДвиженияССубконто.СубконтоКт1, бла-бла Запрос.УстановитьПараметр("Счет",счетИскать); Запрос.установитьПараметр("Регистратор", Регистратор); Возврат Запрос.Выполнить().Выгрузить(); КонецФункции |
|||
39
artbear
16.08.11
✎
21:32
|
(33) Тз.Объект.Ссылка сильно выглядит :(
Незачет :) (36) Прав, нафига документ-то читать, ссылки достаточно. У тебя и без этого будут потери на запросах :( Что скажете о моем варианте (37) |
|||
40
Stim213
16.08.11
✎
21:32
|
(37) а что гуд - внутри цикла создавать еще один цикл по отобранным проводкам? Запрос быстрее вернет ТЗ, имхо.
|
|||
41
Stim213
16.08.11
✎
21:33
|
(36) чтобы обратиться к его движениям
|
|||
42
Stim213
16.08.11
✎
21:33
|
+40 а записывать все равно весь набор записей
|
|||
43
artbear
16.08.11
✎
21:34
|
Ты попробуй на реальной базе для документов более 200, ИМХО даже на столь малом количестве увидишь потери
Вложенный цикл для такой задачи с потенциально большим количество документов ЗЛО. |
|||
44
GROOVY
16.08.11
✎
21:34
|
(39) Да на чтении набора сильно съэкономим, но есть проблема "огромных" движений, хотя это исключение скорее.
(41) Посмотри в (0) как движения редактировать. |
|||
45
milan
16.08.11
✎
21:34
|
Правильный ответ был в (3)
|
|||
46
GROOVY
16.08.11
✎
21:35
|
(40) не прав.
|
|||
47
Stim213
16.08.11
✎
21:36
|
(46) почему? Выборкой я получаю срез внутренней таблицы, а цикл обходит всяко дольше
|
|||
48
artbear
16.08.11
✎
21:36
|
(3) Недостаточно
|
|||
49
GROOVY
16.08.11
✎
21:36
|
(40) Ты учти что сначала ты результат запроса конвертируешь в ТЗ, а потом ТЗ конвертируешь в набор записей. Метод "Загрузить" это не просто встасить ТЗ в ТЗ, а конвертация типов, сопоставление по идентификаторам.
|
|||
50
artbear
16.08.11
✎
21:37
|
(45) Предложения из (3) Недостаточно
|
|||
51
GROOVY
16.08.11
✎
21:38
|
Да еще Запрос это такая штука которая требует трянсляции к скулю и пост обработки того что скуль вернул.
|
|||
52
Stim213
16.08.11
✎
21:39
|
(49)ну.. не вопрос. замерю производительность и отпишусь. Ты только код свой оставь, чтобы было по-честному
|
|||
53
GROOVY
16.08.11
✎
21:40
|
(52) Мне лень. Начинай ты, потом я свой код выложу. Пишу с нетбука, 1С нет, ставить ради такой ерунды нет желания. Я в командировке, доступа к рабочему компу не будет до конца месяца.
|
|||
54
milan
16.08.11
✎
21:41
|
(50) зависит, кончено отого, как часто встречается замена счетов. По идее если набор не изменился, в базу писаться он не будет. Автор описал что записать() делается дольше всего?
|
|||
55
artbear
16.08.11
✎
21:44
|
(53) А как же облачные вычисления ? неужели у тебя доступа к ним нету? ну или банальный терминальный доступ :)
ЗЫ шучу, конечно, задача на самом деле простая. Но для ваших курсов вполне годная. У разработчик встречается не так уж и редко :) |
|||
56
artbear
16.08.11
✎
21:46
|
(54) Набор изменится в любом случае, мы же работаем только с теми регистраторами и наборам, где нужно поменять счета.
|
|||
57
Fragster
гуру
16.08.11
✎
21:46
|
(0) перед выполнением выключить итоги (рассчитать на дату перед первой заменой, если не весь период заменяется), после выполнения включить обратно.
|
|||
58
milan
16.08.11
✎
21:49
|
(56) ну и какой смысл тогда выгадывать копейки, если записать () съедает большую часть времени работы?
|
|||
59
artbear
16.08.11
✎
21:51
|
(53) Меня с момента появления Снеговика мучает вопрос:
почему 1С не сделала возможность получения таблицы значений из выборки? Почему РезультатЗапроса.Выгрузить(), а Выборка.Выгрузить() нет ? ведь очень часто, сабж это только подтверждает, можно было бы быстро получить нужную ТЗ и дальше работать с ней, например, загрузить в набор и т.п. Т.е. 1С можно было бы продублировать с оптимизацией все действия, которые все равно делает разработчик/пользователь выборки. ИМХО за счет оптимизации внутри кода 1С подобная задача решалась бы быстрее :) |
|||
60
artbear
16.08.11
✎
21:54
|
(58) 1. Автор об этом не писал :)
2. Записать не обязательно очень долго будет! на "плохих" запросах Записать как раз не так сильно будет влиять :) 3. На Записать повлиять можно с трудом, а вот на запросы вполне в наших силах. |
|||
61
Stim213
16.08.11
✎
21:55
|
(59)да. да-да. Это косяк(
|
|||
62
milan
16.08.11
✎
22:01
|
(60) в (17) писал
в снеговике здорово ускорили исполнение кода. Сам всегда формирую таблицу движений в запросе, но на скорость проведения на 90% влияет чтение и запись данных, так что выигрыш от таких манипуляций никакой. |
|||
63
artbear
16.08.11
✎
22:08
|
(62) Конечно, нужно смотреть замеры производительности.
Но учитываем все сказанное всеми нами + тот факт, что автор еще неопытный, так что слишком большого доверия его словам нельзя придавать :( Тем более, что интересная и не столь уж редкая задача :) |
|||
64
Dmitrii
гуру
16.08.11
✎
22:22
|
Ускорение при выполнении записи набора будет только при отключении итогов и актуальных итогов регистра.
Заполнение набора из ТЗ для регистра бухгалтерии будет медленнее, чем, например, для регистра накопления, из-за того, что для него не соблюдается порядок следования субконто на счете, а так же из-за того, что субкнто имеют составной тип данных. ИМХО, самый оптимальный алгоритм предложен Пашей GROOVY. |
|||
65
milan
17.08.11
✎
08:32
|
Ждем результата замеров от ТС
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |