![]() |
|
1С:Предприятие
:: 1С:Предприятие 7.7 и ранее
|
|
| ||
Cyr 15.03.21 - 12:03 | Есть у нас самописная конфигурация с документами: Договор на аренду места(на несколько месяцев) и "График оплаты" (на месяц по дням).
В табличной части "графика оплаты" десятки мест. Чтобы получить задолженность по договору приходится в цикле перебирать всю табличную часть и каждый день документа "График оплаты". Для 200 договоров это занимает минуту. Можно как-то оптимизировать этот процесс? Может регистр оборотов помочь? Или календарь? | ||
HawkEye 1 - 15.03.21 - 12:04 | (0) а документ ничего не двигает чтоли? | ||
Cyr 2 - 15.03.21 - 12:05 | (1) Нет. | ||
HawkEye 3 - 15.03.21 - 12:06 | (2) а как по твоему, зачем в 1С сделаны регистры? )) | ||
Strogg 4 - 15.03.21 - 12:09 | Вообще, поможет остаточный регистр. график оплаты делает плюс, факт оплаты - минус. Там уже сам по датам разберешь как двигать факт оплаты. Ну и потом просто получаешь остатки по регистру :) | ||
Cyr 5 - 15.03.21 - 12:09 | (3) Конфигурация писалась давно. И программист видимо с регистрами не очень знаком был...
Так сильно ли поможет регистр в плане ускорения работы? Если на порядок, то будем заморачиваться. А если чуть-чуть, то и не стоит... | ||
Cyr 6 - 15.03.21 - 12:10 | (4) У нас факт оплаты по сути просто "галочка" в документе "График оплаты" за нужный день по нужному месту. | ||
Strogg 7 - 15.03.21 - 12:14 | (6) не. так не пойдет. В любом случае документ такого типа должен проводиться, а информация для аналитики должна находиться в остаточном регистре. причем, факт отражения задолженности и оплаты должны отражаться разными документами. А то Вася седня поставил галку, а Петя завтра ее снял. вот тебе и все :) | ||
HawkEye 8 - 15.03.21 - 12:16 | |||
Cyr 9 - 15.03.21 - 12:16 | (7) Ну пользователи и редактируют этот документ по много раз, когда им приносят чеки с оплатой.
Этот документ выглядит как календарь. | ||
Strogg 10 - 15.03.21 - 12:22 | |||
Cyr 11 - 15.03.21 - 12:40 | (10) Это программа не для бухгалтеров, поэтому так и сделана была. Чтоб побыстрее работало, ткнул мышкой - галка нарисовалась. За 3 минуты сотню мест отметил. | ||
Cyr 12 - 15.03.21 - 13:17 | (7)А почему регистр остатков, а не обороты? Ведь при печати "счётов" нужно указывать и за какие дни не оплачено.... | ||
HawkEye 13 - 15.03.21 - 13:28 | (11) программу "не для бухгалтеров" надо делать на порядок тщательнее ))) | ||
hhhh 14 - 15.03.21 - 13:33 | (12) у регистра остатков тоже можно получать обороты, прикинь. | ||
Cyr 15 - 15.03.21 - 14:34 | (7) А что помешает Пете изменить документ Васи и перепровести его? | ||
Arbuz 16 - 15.03.21 - 15:10 | (15) Правильно настроенные права | ||
Злопчинский 17 - 15.03.21 - 15:10 | Ускорение примерно на порядок м.б. получено и на текущей конфигурации за счет использования прямых запросов (если вы погромист 1С). скорее всего в рамках и существующей архитектуры конфигурации можно ускорить, просто надо вниматочно посмотреть как отчет строится и оптимизировать его штатными средствами просто тупо переписав получше.
. Если не справитесь сами - стукайтесь месяца через два (контакты в личке), к тому времени осовобожусь, посмотрим если надо будет | ||
Arbuz 18 - 15.03.21 - 15:14 | (17) Кстати тоже такая мысль появилась. Прямые запросы к таблицам журнала и документов, ускорят даже больше, чем на порядок, а возни может быть меньше, чем дорабатывать логику на регистры. | ||
Gucci76 19 - 15.03.21 - 15:19 | Для ускорения 7.7 еще полезно использовать 1СРР.dll | ||
Cyr 20 - 15.03.21 - 15:21 | |||
Gucci76 21 - 15.03.21 - 15:21 | В 7.7 долго отрабатывает ПолучитьСтрокуПоНомеру (или что то типа того - уже забыл) | ||
Arbuz 22 - 15.03.21 - 15:22 | (19) Конечно | ||
Arbuz 23 - 15.03.21 - 15:22 | |||
Cyr 24 - 15.03.21 - 15:36 | (23) Ну номер строку табличной части мы нашли:
"//{{ЗАПРОС(Сформировать2) |С (Договор.СрокС) по (Договор.СрокПО); |ОбрабатыватьДокументы все; |Обрабатывать НеПомеченныеНаУдаление; |Без итогов; |ДокументОплата = Документ.ГрафикОплаты.ТекущийДокумент; |НомерСтроки = Документ.ГрафикОплаты.НомерСтроки; |Место = Документ.ГрафикОплаты.Место; |Группировка ДокументОплата; |Группировка НомерСтроки; |Условие(Место в Договор.Место); |"//}}ЗАПРОС А вот как перебрать все столбцы табличной части документа "ГрафикОплаты"? У них Идентификатор "Д1"..."Д31" | ||
Злопчинский 25 - 15.03.21 - 15:50 | (24)
СтрокаДокумента - ПРЕДОПРЕДЕЛЕННАЯ ГРУППИРОВКА поэтому |НомерСтроки = Документ.ГрафикОплаты.НомерСтроки; - выкниут написать Группировка СтрокаДокумента | ||
Злопчинский 26 - 15.03.21 - 15:56 | "А вот как перебрать все столбцы табличной части документа "ГрафикОплаты"? У них Идентификатор "Д1"..."Д31" - для чего?
. |ДокументОплата = Документ.ГрафикОплаты.ТекущийДокумент;
|%ВЫБОРДНЕЙ%
|Место = Документ.ГрафикОплаты.Место;
ВыборДней = ""; Для ы=1 по 31 Цикл ВыборДней = ВыборДней+"д"+ы+";" КонецЦикла;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"%ВЫБОРДНЕЙ%",ВыборДней); | ||
Злопчинский 27 - 15.03.21 - 15:58 | и какой ч(м)удак реквизиты которые однотипные и потом стопудово придется перебирать иобрабатывать программно, в т.ч. вырезая из "дТУТХРЕНПОЛНЯ" номер дня именует криво?!
правильно архитекутрно если так сделано назвать д01,д02..д10.... тогда даже тупая сортировка по номеру дня "дХХ" будет работать правильно, а не так криво как при текущей нумерации. . "как дети, чесслово" | ||
Djelf 28 - 15.03.21 - 16:12 | (0) Забей, или нет... Это тебе решать! Это странная база, там все видимо "сделано на коленке" в стиле "сколько заплатили, то и получили".
Но могу предложить оптимизацию в стиле - "сделано на коленке"! Мне отсюда не видно, но предполагаю - выборка документов с 99% вероятностью перебирает вообще ВСЕ документы. Добавь в шапку документа Флаг - оплата закрыта (и его заполни!!!) и будет ну... возможно даже на порядок быстрее! | ||
Lazy Stranger 29 - 15.03.21 - 16:49 | Сделать регистр остатков с измерениями "договор" и "дата", может быть ещё "место". Проведение договора аренды вешает по отдельности долг на каждый день действия договора, а график оплаты двигает его в минус. Задолженность будет выниматься из остатков регистра за доли секунды. | ||
Злопчинский 30 - 15.03.21 - 17:29 | (29) затрахаются. ибо стопудово график оплаты вовремя не соблюдается арендаторами. и тогда ЕСЛИ ТАМ ХОТЬ КТОТО ВМЕНЯЕМЫй есть - то оплату регистрируют по факту в день когда была внесена с учетом за неоплаченные предыдущие дни - и тогда сумму оплаты 10 числа надо будет разносить на предыдущие неоплаченные дни. с квалификацией ТС затрахаютсяч возможно (хоть все и просто).
если же просто ставят галочку что "день оплачен" в соответсвующий день и пофиг когда было оплачено (скорее всего это сделано именно так в этом решении "на коленке") - то да, такой регистр простейший, проведение простйешее и данные будут вытягиваться очень быстро. Рекламное место пустует | ||
Lazy Stranger 31 - 15.03.21 - 17:31 | (30) судя по описанию, мне кажется что у них именно галочка "день оплачен", хотя чтобы что-то советовать надо их базу смотреть | ||
Злопчинский 32 - 15.03.21 - 17:31 | (21) "ПолучитьСтрокуПоНомеру" долго отрабатывает - это вряд ли. особой разницы не заметил по сравнению с последовательным ПолучитьСтроку(). Может быть только если колонки нетипизированные есть | ||
Злопчинский 33 - 15.03.21 - 17:33 | (26) тьфу, блин, надеюсь принцип понял ВыборДней = ""; Для ы=1 по 31 Цикл ВыборДней = ВыборДней+"д"+ы+"= Документ.ГрфикОплаты.д"+ы+";" КонецЦикла; ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"%ВЫБОРДНЕЙ%",ВыборДней); | ||
Злопчинский 34 - 15.03.21 - 17:34 | (31) тоже так думаю что просто галочкой. вполне норм решение. | ||
Cyr 35 - 15.03.21 - 18:36 | (31) Там наоборот ведется учёт долгов. Если день не оплатили, ставится буква "Н".
Вот проверка договора: Функция ПроверитьДоговор(Договор) ДолгиЗа=""; Оплата=СоздатьОбъект("Документ.ГрафикОплаты"); Оплата.ВыбратьДокументы(НачМесяца(Договор.СрокС),КонМесяца(Договор.СрокПо)); Пока Оплата.ПолучитьДокумент()=1 Цикл//по документам Оплата Оплата_ПериодПо=КонМесяца(Оплата.Период); Если (Оплата.Сектор=Договор.Место.Родитель) И (Договор.СрокС<=Оплата_ПериодПо) И (Договор.СрокПо>=Оплата.Период) Тогда//получили документ Оплата по договору Оплата.ВыбратьСтроки(); Пока Оплата.ПолучитьСтроку() = 1 Цикл// по местам Если Оплата.Место=Договор.Место Тогда//нашли строку по месту  //проверить дни НачальноеЧисло=ДатаЧисло(?(Оплата.Период<Договор.СрокС, Договор.СрокС, Оплата.Период)); КонечноеЧисло =ДатаЧисло(?(Оплата_ПериодПо>Договор.СрокПо, Договор.СрокПо, Оплата_ПериодПо));  //Сообщить(Строка(НачальноеЧисло)+"-"+Строка(КонечноеЧисло)); Для День = НачальноеЧисло По КонечноеЧисло Цикл//по столбцам Пометка=Оплата.ПолучитьАтрибут("Д"+строка(День)); Если (Пометка="Н") Тогда// нашли метку ДолгиЗа=ДолгиЗа+Формат(Оплата.Период,"ДММММГГГГ")+" "; Прервать;//дальше пометки не нужны КонецЕсли;// нашли метку КонецЦикла;//по дням Прервать;//другие места не нужны КонецЕсли;//нашли строку по месту КонецЦикла;//по строкам Оплаты КонецЕсли;//получили документ Оплата по договору КонецЦикла;//по документам Оплата Возврат(ДолгиЗа) КонецФункции | ||
Злопчинский 36 - 15.03.21 - 19:48 | (35) ужоснах ;-) но в той парадигме что есть - норм... | ||
Злопчинский 37 - 15.03.21 - 19:59 | Простая тупая переделка кода без включения мозга - 6-этажная хрень превращается в более менее линейный читаемый код..
. Функция ПроверитьДоговор(Договор) ДолгиЗа = ""; Оплата = СоздатьОбъект("Документ.ГрафикОплаты"); Оплата.ВыбратьДокументы(НачМесяца(Договор.СрокС),КонМесяца(Договор.СрокПо)); Пока Оплата.ПолучитьДокумент() = 1 Цикл//по документам Оплата Оплата_ПериодПо = КонМесяца(Оплата.Период); Если Оплата.Сектор <> Договор.Место.Родитель Тогда Продолжить; КонецЕсли; Если Договор.СрокС > Оплата_ПериодПо Тогда Продолжить; КонецЕсли; Если Договор.СрокПо < Оплата.Период Тогда Продолжить; КонецЕсли; Оплата.ВыбратьСтроки(); Пока Оплата.ПолучитьСтроку() = 1 Цикл// Тогда Продолжить; КонецЕсли; Если Оплата.Место <> Договор.Место Тогда Продолжить; КонецЕсли;  //проверить дни НачальноеЧисло = ДатаЧисло(?(Оплата.Период<Договор.СрокС, Договор.СрокС, Оплата.Период)); КонечноеЧисло = ДатаЧисло(?(Оплата_ПериодПо>Договор.СрокПо, Договор.СрокПо, Оплата_ПериодПо));  //Сообщить(Строка(НачальноеЧисло)+"-"+Строка(КонечноеЧисло)); Для День = НачальноеЧисло По КонечноеЧисло Цикл//по столбцам Пометка = Оплата.ПолучитьАтрибут("Д"+строка(День)); Если Пометка <> "Н" Тогда Продолжить; КонецЕсли; ДолгиЗа = ДолгиЗа + Формат(Оплата.Период,"ДММММГГГГ")+" "; Прервать;//дальше пометки не нужны КонецЦикла;// по дням Прервать;// другие места не нужны КонецЦикла;// по строкам Оплаты КонецЦикла;// по документам Оплата Возврат(ДолгиЗа) КонецФункции | ||
HawkEye 38 - 15.03.21 - 20:35 | (37) пошел бы дальше, выгрузил в ТЗ и найти(), еще быстрее было-бы, только смысл )))) | ||
Cyr 39 - 15.03.21 - 21:47 | (37) А можно ли подобное сделать через запрос? | ||
Злопчинский 40 - 15.03.21 - 22:13 | (39) что именно? стукайся в личку в скайп Zlopun если чо | ||
Злопчинский 41 - 15.03.21 - 22:16 | тут понимаешь какая закавыка - в запросе ты минимально к чему можешь адресоваться - это строка документа, отдельно вытянуть строку , в которой в колонках стоит "Н" не получится (это только в прямом запросе скорее всего получится может)
а так. максимум что в чорном запросе можно сделать - вытащить строку в которой хотя бы 1 раз встречается "Н" и тио я сомневаюсь что это будет быстрее чем перебором как у тебя. | ||
Злопчинский 42 - 15.03.21 - 22:17 | "отдельно вытянуть строку , в которой в колонках стоит "Н" не получится"
- читать как "отдельно вытянуть колонки, в которых стоит "Н" | ||
Злопчинский 43 - 15.03.21 - 22:18 | ща подумаю еще... | ||
Cthulhu 44 - 15.03.21 - 22:19 | не циклмтесь на запросах. через ТЗ это все имхо гораздо быстрее (во всех смыслах) | ||
Злопчинский 45 - 15.03.21 - 22:24 | В запросе будет такой текст (код с циклом выше)
Н = "Н";
...
|д1 = Документ.ГрафикОплаты.д1;
|д2 = Документ.ГрафикОплаты.д2;
..
|д31 = Документ.ГрафикОплаты.д31;
|Условие((д1=Н)ИЛИ(Д2=Н)...ИЛИ(Д31=Н));
.
тогда в выборку по запросу у тебя попадут только те строки документов где есть хотя бы одна Н . но я не думаю что такой запрос будет быстрее чем выборкой, хотя надо проверять... и запрос выгрузить в ТЗ и уже по строчкам ТЗ бегать, будет быстрее но имхо это не стоит усилий | ||
Злопчинский 46 - 15.03.21 - 22:26 | (44) угу
два варианта - простая выборка документов, выгрузка ТЧ документа в ТЗ и там аналогично как исходный код уже по ТЗ ходить.. но опять же я не думаю что это будет существенно быстрее | ||
Злопчинский 47 - 15.03.21 - 22:28 | второй вариант запросом выбрать ТОЛЬКО ПОДХОДЯЩИЕ документы по услвовиям шапки/договора, без учета строк, и уже по полученному списку документов ходить как в варианте исходном или в варианте 1. | ||
Злопчинский 48 - 15.03.21 - 22:29 | (0) "Для 200 договоров это занимает минуту." - и что? документ - на месяц, раз в месяц или раз в неделю пару раз запуститьи в тоге потратить 10 минут счета компа для получения данных -вообще проблем не вижу...
а если такой отчет собираетяс каждый день - тогда вопрос а нафуя вы туда весь месяц тогда запихнули... | ||
Cyr 49 - 16.03.21 - 06:42 | (48) короче, существующий отчёт в целом не плох и только с регистрами ещё попробовать остаётся... при желании | ||
Cyr 50 - 16.03.21 - 06:45 | (38) я пробовал через выгрузку в ТЗ. Не быстрее. | ||
Cyr 51 - 16.03.21 - 10:52 | (50) Хотя, если предварительно все договора рассортировать в ТЗ по датам и местам, то наверное быстрее будет. | ||
Cyr 52 - 18.03.21 - 11:24 | А может не с регистрами заморачиваться, а с "журналом расчётов" или с "Бухгалтерскими счетами"? | ||
Харлампий Дымба 53 - 18.03.21 - 15:44 | Ничего не понял в задаче, но скажу что:
1) регистры, бухитоги и расчеты в твоём случае вряд ли нужны
2) строки НачальноеЧисло=ДатаЧисло(?(Оплата.Период<Договор.СрокС, Договор.СрокС, Оплата.Период)); и КонечноеЧисло =ДатаЧисло(?(Оплата_ПериодПо>Договор.СрокПо, Договор.СрокПо, Оплата_ПериодПо)); должны стоять перед ВыбратьСтроки() - чуть быстрее будет;
3) если ты гоняешь в отчете список договоров и по каждому запускаешь Функция ПроверитьДоговор(Договор), то есть полную выборку по документам за весь период действия каждого договора - это долго. Тогда уж просто один раз пробегись по всем документам и собери данные о неоплаченных договорах в ТЗ. А функцию оставь если надо получить данные по одному договору.
4) заведи в табличной части документа реквизит "ПервыйНеоплаченныйДень" и при проведении документа пиши туда номер дня с пометкой, если не было оплаты, или 0 если ни в одной дате не будет пометки. Тогда твоя функция избавится от 31 перебора внутри цикла ВыбратьСтроки(); Пока ПолучитьСтроку() = 1 Цикл ПервыйНеоплаченныйДень=0; Для День = 1 По 31 Цикл Если Оплата.ПолучитьАтрибут("Д"+День) Тогда ПервыйНеоплаченныйДень=День Прервать; КонецЕсли; КонецЦикла; КонецЦикла; 5) Вместо совета (4) - Создай в договоре периодический реквизит "ДоговорНеОплачен" - с запретом изменять руками, только документом, "Число 1.0". При проведении документа пиши туда через УстановитьРеквизитСправочника 1 если есть ПервыйНеоплаченныйДень. Тогда для анализа договора тебе будет достаточно П=СоздатьОбъект("Периодический")//если будешь делать цикл по договорам - эту строку надо вынести из цикла, бо создание объекта "Периодический" - процесс относительно долгий П.ИСпользоватьОбъект(Договор,"ДоговорНеОплачен"); ДолгиЗа=""; П.ВыбратьЗначения(); Пока П.ПолучитьЗначение()=1 Цикл ДолгиЗа=ДолгиЗа+Формат(П.ТекущийДокумент().Оплата.Период,"ДММММГГГГ")+" "; КонецЦикла; Или просто в списке договоров по F5 пользователь увидит список неоплаченных графиков | ||
Mikeware 54 - 18.03.21 - 16:11 | (53) резюмирую:"если вы пытаетесь почесать правое ухо левой ногой, и это не совсем получается - изогните особым образом проволочку, зажмите ее зубами, и раскачивая этой проволокой фикус, медленно подводите правое ухо к нему, пока он не почешет вам ухо. если это не поможет - попытайтесь раскачивать кактус." | ||
Харлампий Дымба 55 - 18.03.21 - 18:28 | (54) Так задача была почесать правое ухо левой ногой?! А я думал, что ТС надо было выдрать кактус, поэтому и посоветовал раскачивание.
А если по делу - для пустой самописки, как у автора, использование периодического реквизита - самое простое. При оплате же бух входит в график платежей и убирает "Н", как я понял? Хотя если бы это была какая-то конфа на базе Бухии, то самое простое - проводка по забалансовому счету. С учетом того, что любой обороткой можно долги увидеть. | ||
Gucci76 56 - 18.03.21 - 18:56 | (32) ПолучитьСтрокуПОномеру, но для табличной части документа. Я ЗиК убыстрял в несколько раз: компоненту ставил 1СРР и в особо больших базах Получал строку не в документе, а в ТаблицеЗначений (менял модуль).
Это по моим воспоминаниям, т.к. я ЗиК забросил как только все перешли на "восьмерку", а это было очень давно. | ||
Cyr 57 - 19.03.21 - 10:43 | (55) Этим занимаются не бухи, а менеджеры. Они до этого в экселе эту табличку делали. Потом вогнали её в 1С в виде документа "График оплаты". У меня тоже мысль была через проводки сделать проведение документа и потом типа анализ счёта по субконто. |
|
Список тем форума |