Имя: Пароль:
1C
1С v8
Удаление по счетчику в результате запроса с группировкой.
0 Varlant1n
 
13.11.20
14:36
Добрый день, дорогие форумчане! У меня вопрос к вам. Мне надо в документе ПриходныйКассовыйОрдер оставить по 10 доков за каждый день. Я написал обработку. Но в данной обработке просто остаются 10 доков за первый день, остальное удаляется. Можете подсказать что тут не так?


Процедура УдалениеДокументовНаСервере()
    
        Запрос = Новый Запрос;
        Запрос.Текст =  
        "ВЫБРАТЬ
        |    Ссылка
        |ИЗ
        |    Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер
        |ГДЕ
        |    ПриходныйКассовыйОрдер.Дата МЕЖДУ &НачальнаяДата И &КонечнаяДата
        |УПОРЯДОЧИТЬ ПО
        |     Дата
        |ИТОГИ ПО
        |     Дата ПЕРИОДАМИ(ДЕНЬ, &НачальнаяДата, &КонечнаяДата)";
        НачальнаяДата = Дата(2020,8,31);
        КонечнаяДата = Дата(2020,11,30);
        Запрос.УстановитьПараметр("НачальнаяДата",НачальнаяДата);
        Запрос.УстановитьПараметр("КонечнаяДата",КонечнаяДата);
        ВыборкаПоИтогам = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПОГруппировкам, "Дата");
        УстановитьМонопольныйРежим(Истина);
        Счетчик = 0;
        
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    Количество(Ссылка) КАК Количество
        |ИЗ
        |    Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер
        |ГДЕ Дата >= ДАТАВРЕМЯ(2020,8,31)";
        РезультатЗапроса = Запрос.Выполнить();
        Выборка = РезультатЗапроса.Выбрать();
        
        Если Выборка.Следующий() Тогда
            Если Выборка.Количество > 10 Тогда
                Пока ВыборкаПоИтогам.Следующий() Цикл
                    ВыборкаДокументов = ВыборкаПоИтогам.Выбрать();
                    Пока ВыборкаДокументов.Следующий() Цикл
                        Счетчик = Счетчик + 1;
                        Если Счетчик > 10 Тогда
                            ДокОбъект = ВыборкаДокументов.Ссылка.ПолучитьОбъект();
                            ДокОбъект.Удалить();
                        Иначе
                            Прервать;
                        КонецЕсли;
                    КонецЦикла;
                КонецЦикла;
            КонецЕсли;
        КонецЕсли;
    
КонецПроцедуры
1 Креатив
 
13.11.20
19:30
(0) Запрос по приходникам сделай без всяких итогов и выгрузи в ТЗ.
Дальше удаляешь из ТЗ строки. Удалил 10 из текущей даты - остальные по этой дате удаляй вместе с документами.
Не забудь контроль количества строк в ТЗ и то, что в какой-то день может быть меньше 10-ти приходников.
2 Said_We
 
14.11.20
16:55
Так как данная операция разовая, то через ВТ можно сделать так как ниже. Необходимо удалить всё что попадет в выборку. Установить три параметра: ДатаН, ДатаК и КолДокументовВДнеОставить.
В данном случае остаются по "КолДокументовВДнеОставить" ПЕРВЫХ документов в дне. Но можно оставлять не только первых, но и по другому.

ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(ПриходныйКассовыйОрдер.Дата, ДЕНЬ) КАК НачалоДня,
    ПриходныйКассовыйОрдер.Дата КАК Дата,
    ПриходныйКассовыйОрдер.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_Документы
ИЗ
    Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер
ГДЕ
    ПриходныйКассовыйОрдер.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&ДатаН, ДЕНЬ) И КОНЕЦПЕРИОДА(&ДатаК, ДЕНЬ)

ИНДЕКСИРОВАТЬ ПО
    НачалоДня,
    Дата,
    Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Документы.НачалоДня КАК НачалоДня,
    ВТ_Документы.Дата КАК Дата,
    ВТ_Документы.Ссылка КАК Ссылка,
    КОЛИЧЕСТВО(ВТ_Документы1.НачалоДня) + 1 КАК Количество
ИЗ
    ВТ_Документы КАК ВТ_Документы
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Документы КАК ВТ_Документы1
        ПО ВТ_Документы.НачалоДня = ВТ_Документы1.НачалоДня
            И ВТ_Документы.Дата > ВТ_Документы1.Дата
            И ВТ_Документы.Ссылка > ВТ_Документы1.Ссылка

СГРУППИРОВАТЬ ПО
    ВТ_Документы.НачалоДня,
    ВТ_Документы.Дата,
    ВТ_Документы.Ссылка

ИМЕЮЩИЕ
    КОЛИЧЕСТВО(ВТ_Документы1.НачалоДня) + 1 > &КолДокументовВДнеОставить


P.S.
Не за что!
3 Chameleon1980
 
14.11.20
17:12
не нужно везде индексы
4 Said_We
 
14.11.20
17:20
(3) Это кто такое всем рассказал?
Это разовая операция.

А вот пример, когда он нужен:
Замер двух запросов. Неожиданный результат
5 Said_We
 
14.11.20
17:21
(3) В общем случае и ВТ не нужен. Это просто пример, а не готовое решение.
6 Said_We
 
14.11.20
18:19
(3) Человеку в (0) задали в университете тестовые задания. Вот сидит, что-то сам делает. Что-то получается, а что-то нет. Его необходимо просто на мысль натолкнуть - не более того. Доделывать и додумывать должен сам.
7 Said_We
 
15.11.20
14:11
(0) Правда в решении в (2) нет счётчика, а есть ними рация. И совсем нет группировки. Они обязательны по заданию или нет?
8 Ненавижу 1С
 
гуру
15.11.20
14:33
ВЫБРАТЬ
    ПриходныйКассовыйОрдер.Ссылка КАК Ссылка
ИЗ
    Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер
ГДЕ
    НЕ ПриходныйКассовыйОрдер.Ссылка В
                (ВЫБРАТЬ ПЕРВЫЕ 10
                    Т.Ссылка
                ИЗ
                    Документ.ПриходныйКассовыйОрдер КАК Т
                ГДЕ
                    НАЧАЛОПЕРИОДА(Т.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(ПриходныйКассовыйОрдер.Дата, ДЕНЬ)
                УПОРЯДОЧИТЬ ПО
                    Т.Дата)
9 Said_We
 
15.11.20
15:03
(8) Я правильно понимаю, что запрос вернёт все строки за все дни, кроме максимум 10 записей в сумме за за один или несколько дней?
10 RomanYS
 
15.11.20
16:33
(8) рискованно)
(0) Идея правильная: обход с итогами по дням, внутри дня первые 10 пропускаем. В реализации конечно накосячил: второй запрос конечно не нужен

Пока ВыборкаПоДням.Следующий() Цикл
   Сч = 0;
   ...
   Пока Выборка.Следующий() Цикл
      Сч = Сч + 1;
      Если Сч < 10 Тогда
         продолжить;
      КонецЕсли;
      ...
11 Ненавижу 1С
 
гуру
15.11.20
17:20
(9) внрнет все записи кроме первых 10 в каждом дне
12 Said_We
 
15.11.20
19:18
(10) Чем рискованно? Ну да, иногда в таких конструкциях не работает "УПОРЯДОЧИТЬ ПО Т.Дата". Но если работает, то уже работает.
13 RomanYS
 
15.11.20
19:22
(12) Как отработает коррелированный (это именно он) на продуктивном объеме данных - хз, можно подвесить сервак. Я сам иногда ими балуюсь, но это не тот случай - здесь они ни к чему.
14 Ненавижу 1С
 
гуру
15.11.20
19:23
(13) вроде пишут, что операция разовая
15 RomanYS
 
15.11.20
19:28
(14) Так убить продуктивный сервер и один раз достаточно))
16 RomanYS
 
15.11.20
19:30
(14) На самом деле прикольная штука, если нужно было получить только по 10 записей я бы тоже задумался о кор. запросе. Но если надо "кроме 10" - то однозначно итог и счётчик в постобработке.
17 Said_We
 
15.11.20
19:31
(13) Для разовой операции, самое то.
(15) + Это задание в универе от преподавателя - никакого продуктива.
+ к (12) "УПОРЯДОЧИТЬ ПО Т.Дата" действительно иногда не отрабатывает, но сталкивался я это только на СКД. Т.е. в консоле запрос отрабатывает, а в СКД начинает "чудить". Тут нет СКД, поэтому....
18 Ненавижу 1С
 
гуру
15.11.20
19:32
(16) по сути план запроса один и тот же
19 Said_We
 
15.11.20
19:32
(16) Если можно получить сразу те записи, которые тебя интересуют одним запросом и без пост обработки результата, то так и надо делать.
20 RomanYS
 
15.11.20
19:35
(18) не уверен
(19) не в данном случае
(17) если препод знаком со стандартами 1С - то может и зарезать, если цель удивить препода - то да шанс))
21 RomanYS
 
15.11.20
19:38
(8) запустил для теста на файловой базе - висит минуту уже)))
22 Said_We
 
15.11.20
19:49
Так фильтр по периодами добавил?
23 Said_We
 
15.11.20
19:50
Т9 задолбал....
24 RomanYS
 
15.11.20
19:57
(22) А какая разница тупой запрос с итогами на тех же данных - меньше секунды. В таблице около 8к записей
(21) запрос отработал, замер не делал но явно больше минуты - т.е. на ДВА порядка минимум медленнее... +риск падения
25 Ненавижу 1С
 
гуру
15.11.20
20:51
(21) я забыл, когда использовал файловые в продакте
26 RomanYS
 
15.11.20
20:59
(25) На продакшене я бы такое не стал запускать, там не 8к может быть)
Программист всегда исправляет последнюю ошибку.