Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Запрос ко всем документам. Нужна помощь

Запрос ко всем документам. Нужна помощь
Я
   Varlant1n
 
28.10.20 - 09:21
Передо мной стоит задача создание внешней обработки с одной лишь кнопкой, при нажатии на которую произойдет следующее:
Обработка через запрос обратится ко всем документам. В каждом документе будут удалены все, кроме 5-и первых элементов в документе за месяц. То есть, как пример, у меня есть Документ АвансовыйОтчет. В этом документе очень много элементов. И они добавляются уже 8 месяцев. В каждом месяце добавлялось порядка 1000 элементов. Так вот при нажатии на кнопку мне надо, чтобы обработка в документе АвансовыйОтчет разделила элементы по месяцам и в каждом месяце удалила все, кроме первых 5 добавленных в этот месяц.

В данный момент на руках у меня есть следующий код:

Для Каждого МетоданноеДокументы Из Метаданные.Документы Цикл
        ИмяДокумента = МетоданноеДокументы.Имя;
        Запрос = Новый Запрос;
        Запрос.Текст =  
        "ВЫБРАТЬ
        |    "+ИмяДокумента+".Ссылка
        |ИЗ
        |    Документ."+ИмяДокумента+" КАК "+ИмяДокумента+"
        |ГДЕ
        |    "+ИмяДокумента+".Дата МЕЖДУ &НачальнаяДата И &КонечнаяДата
        |УПОРЯДОЧИТЬ ПО
        |     Дата
        |ИТОГИ ПО
        |     Дата ПЕРИОДАМИ(МЕСЯЦ, &НачальнаяДата, &КонечнаяДата)";
        НачальнаяДата = Дата(2000,1,1);
        КонечнаяДата = Дата(2030,1,1);
        Запрос.УстановитьПараметр("НачальнаяДата",НачальнаяДата);
        Запрос.УстановитьПараметр("КонечнаяДата",КонечнаяДата);
        Результат = Запрос.Выполнить().Выгрузить();
        Счетчик = 0;
        Для каждого Элемент Из Результат Цикл
            Счетчик = Счетчик + 1;
            Если Счетчик > 5 Тогда
                Элемент.Ссылка.ПолучитьОбъект().УстановитьПометкуУдаления(Истина);
                ПомеченныеНаУдаление = НайтиПомеченныеНаУдаление();
                УстановитьМонопольныйРежим(Истина);
                УдалитьОбъекты(ПомеченныеНаУдаление, Истина);
            Иначе
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;

Но он не работает почему-то. При этом ошибку не выдает. В локальных переменных в ТипЗначения: АвансовыйОтчет, Null
   ДенисЧ
 
1 - 28.10.20 - 09:24
Для каждого Элемент Из Результат Цикл
            Счетчик = Счетчик + 1;
            Если Счетчик > 5 Тогда
            Иначе
                Прервать;
            КонецЕсли;

У тебя цикл не выполняется ни разу
   Varlant1n
 
2 - 28.10.20 - 09:27
Как я это могу исправить? У меня просто, видимо, мозгов не хватает... Буду Вам очень благодарен!
   ДенисЧ
 
3 - 28.10.20 - 09:30
(2) Попробовать почитать учебник информатики за 9й класс, где циклы описываются?
Или хотя бы предназачение оператора Прервать в справке?
   ДенисЧ
 
4 - 28.10.20 - 09:30
И кстати... Нигде не увидел проверку условия "первые 5 в _каждом_ месяце"...
   ИУБиПовиц
 
5 - 28.10.20 - 09:32
(2) ну наверное так
Если Счетчик > 5 Тогда
Прервать;
            Иначе
//удаление

                
            КонецЕсли;

И монопольный режим зачем устанавливать при каждой итерации в истину, и не скидывать в ложь.
В чем смысл 
(4) Ну итоги периодами сделал то, а конфигуратор сам догадается:)
   ИУБиПовиц
 
6 - 28.10.20 - 09:33
И наверное, это долго будет работать:)
   Chameleon1980
 
7 - 28.10.20 - 09:34
обходрезультатазапроса
   ГдеСобакаЗарыта
 
8 - 28.10.20 - 09:39
Человек, который придумал такое задание - больной. Держитесь от него подальше.
   Varlant1n
 
9 - 28.10.20 - 09:45
(5)
Для Каждого МетоданноеДокументы Из Метаданные.Документы Цикл
        ИмяДокумента = МетоданноеДокументы.Имя;
        Запрос = Новый Запрос;
        Запрос.Текст =  
        "ВЫБРАТЬ 
        |    "+ИмяДокумента+".Ссылка
        |ИЗ
        |    Документ."+ИмяДокумента+" КАК "+ИмяДокумента+"
        |ГДЕ
        |    "+ИмяДокумента+".Дата МЕЖДУ &НачальнаяДата И &КонечнаяДата
        |УПОРЯДОЧИТЬ ПО
        |     Дата
        |ИТОГИ ПО
        |     Дата ПЕРИОДАМИ(МЕСЯЦ, &НачальнаяДата, &КонечнаяДата)";
        НачальнаяДата = Дата(2000,1,1);
        КонечнаяДата = Дата(2030,1,1);
        Запрос.УстановитьПараметр("НачальнаяДата",НачальнаяДата);
        Запрос.УстановитьПараметр("КонечнаяДата",КонечнаяДата);
        Результат = Запрос.Выполнить().Выбрать();
        УстановитьМонопольныйРежим(Истина);
        Счетчик = 0;
        Для каждого Элемент Из Результат Цикл
            Счетчик = Счетчик + 1;
            Если Счетчик > 5 Тогда
                Прервать;
            Иначе
                Элемент.Ссылка.ПолучитьОбъект().УстановитьПометкуУдаления(Истина);
                ПомеченныеНаУдаление = НайтиПомеченныеНаУдаление();
                УдалитьОбъекты(ПомеченныеНаУдаление, Истина);
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;

Теперь 1С ругается таким образом: 
{Обработка.ОбезличиваниеДанных.Форма.Форма.Форма(32)}: Итератор для значения не определен
        Для каждого Элемент Из Результат Цикл
   Затейник
 
10 - 28.10.20 - 09:47
Тестовое задание?
   Varlant1n
 
11 - 28.10.20 - 09:47
(10) Да, проект в университете
   ДенисЧ
 
12 - 28.10.20 - 09:48
   Затейник
 
13 - 28.10.20 - 09:49
(11) Запрос в цикле? Сразу двойка. и на пересдачу.
   ИУБиПовиц
 
14 - 28.10.20 - 09:56
(9)
Результат = Запрос.Выполнить().Выбрать();
Верните выгрузить:)
   Волшебник
 
15 - 28.10.20 - 09:58
(12) Мне тоже глаза резануло
   ИУБиПовиц
 
16 - 28.10.20 - 09:59
(13) Ладно б еще работало, так еще и не работает как в задании требовалось:)
   Затейник
 
17 - 28.10.20 - 10:01
В этой задаче прекрасно всё! И сомнительные условия! и разрушительный характер самой обработки! и выборка ВСЕХ документов! И бессмысленное удаление в каждом месяце оставление лишь 5 документов. Кстати, вопрос, как ты определяешь эти 5 первых документов которые требуется оставить ? по какому признаку ? по дате ? по сумме ? или просто на обум?
   Varlant1n
 
18 - 28.10.20 - 10:03
(17) Я определяю 5 первых документов по дате. То есть мне надо в каждом документе оставить 5 первых добавленных, а остальные удалить...
   Волшебник
 
19 - 28.10.20 - 10:07
Обработка ТерминаторБазДанных
   Затейник
 
20 - 28.10.20 - 10:07
Но ведь пользователи могут вносить документы хаотично, сначала за 1 число, потом за 30, потом за 20, потом за 15. Получается перво добавленные документы у тебя в разных числах. Требуется уточнить условие задачи. Сортируем по дате документа или по дате фактического добавления?
   Varlant1n
 
21 - 28.10.20 - 10:10
(20) Я сортировал по Дате (возрастание). Чтобы от первых документов к последним шло всё

|УПОРЯДОЧИТЬ ПО
|     Дата
   ИУБиПовиц
 
22 - 28.10.20 - 10:11
(18) Как я понял, надо оставить первые 5 доков в месяце.
А в текущем виде Обработка оставит всего 5 доков каждого вида. вне зависимости от месяца
(20) Ну скорее всего по дате дока
   Затейник
 
23 - 28.10.20 - 10:15
(21)

Так запрос ты должен обходить по группировкам, а не сплошником весь.
   Varlant1n
 
24 - 28.10.20 - 10:17
(22) Но ведь я сортирую по периодам (Месяц)
|ИТОГИ ПО
|     Дата ПЕРИОДАМИ(МЕСЯЦ, &НачальнаяДата, &КонечнаяДата)";
   Затейник
 
25 - 28.10.20 - 10:19
Что-то типа такого http://catalog.mista.ru/1c/articles/125988/
   Затейник
 
26 - 28.10.20 - 10:25
После запроса ты должен получать не Таблицу значений, а ВЫБОРКУ!
и дальше обрабатывать данные из запроса выборкой по группировкой. еще пару вложенных циклов.
   ИУБиПовиц
 
27 - 28.10.20 - 10:26
не сортируешь, а говоришь что запрос будет иметь итоги
И надо Результат = Запрос.Выполнить().Выгрузить();
А или выборку с обходои, ну или дерево с обходом
   Varlant1n
 
28 - 28.10.20 - 10:32
(27) Вот я сделал следующее. Но все равно ошибка: {Обработка.ОбезличиваниеДанных.Форма.Форма.Форма(30)}: Метод объекта не обнаружен (Выбрать)
        ВыборкаДокумента = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруп




Результат = Запрос.Выполнить().Выгрузить();
        ВыборкаДокумента = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Дата");
        Счетчик = 0;
        Пока ВыборкаДокумента.Следующий() Цикл
            Счетчик = Счетчик + 1;
            Если Счетчик > 5 Тогда
                ВыборкаДокумента.Ссылка.ПолучитьОбъект().УстановитьПометкуУдаления(Истина);
                ПомеченныеНаУдаление = НайтиПомеченныеНаУдаление();
                УстановитьМонопольныйРежим(Истина);
                УдалитьОбъекты(ПомеченныеНаУдаление, Истина);
            Иначе
                Прервать;
            КонецЕсли;
        КонецЦикла;
   Волшебник
 
29 - 28.10.20 - 10:36
(28) Надо стараться. ВыборкаИзРезультатаЗапроса и ТаблицаЗначений — это разные объекты
   ИУБиПовиц
 
30 - 28.10.20 - 10:52
Результат = Запрос.Выполнить().Выгрузить();
надо
Результат = Запрос.Выполнить()

и
  Если Счетчик > 5 Тогда
                ВыборкаДокумента.Ссылка.ПолучитьОбъект().УстановитьПометкуУдаления(Истина);
                ПомеченныеНаУдаление = НайтиПомеченныеНаУдаление();
                УстановитьМонопольныйРежим(Истина);
                УдалитьОбъекты(ПомеченныеНаУдаление, Истина);
            Иначе
                Прервать;
            КонецЕсли;
:)
ну сразу ж прервется:) говорили ж уже
 
 Рекламное место пустует
   Varlant1n
 
31 - 28.10.20 - 11:18
У меня к вам, дорогие форумчане, вопрос. Нужно ли мне пользоваться ИТОГИ ПО для того, чтобы группировать по месяцам, или надо пользоваться ГРУППИРОВАТЬ ПО? Потому что как только я в запросе использую ИТОГИ ПО, он мне выдает в результате таблицу значений.
   Волшебник
 
32 - 28.10.20 - 11:19
(31) Скорее дерево значений
   ДенисЧ
 
33 - 28.10.20 - 11:19
(31) Если ты делаешь итоги по, то и выгружать нужно соответственно не плоскую таблицу, а дерево.
Посмотри параметры РезультатЗапроса.Выгрузить()
   Затейник
 
34 - 28.10.20 - 11:23
Таблица значений получается когда ты пишешь Результат = Запрос.Выполнить().Выгрузить();
А ты должен писать выборку ВыборкаПоИтогам = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПОГруппировкам, "Дата");

Пока ВыборкаПоИтогам.Следующий() Цикл

ВыборкаДокументов = ВыборкаПоИтогам.Выбрать();
  Пока ВыборкаДокументов.Следующий() Цикл

  КонецЦикла;
КонецЦикла;

Два вложенных цикла, первый по итогам, это твои месяца, второй цикл по документам внутри каждого месяца
   Varlant1n
 
35 - 28.10.20 - 11:24
У переменной Результат: Значение: ТаблицаЗначений и Тип: ТаблицаЗначений
Это то, что я получаю результатом запроса. По идее там уже всё расположено по дате и по каждому месяцу. Но я не могу теперь сделать выборку и с помощью счетчика удалить ненужные мне документы. Так как у меня ошибка из-за Ссылка.ПолучитьОбъект().
   Затейник
 
36 - 28.10.20 - 11:29
"У переменной Результат: Значение: ТаблицаЗначений и Тип: ТаблицаЗначений"

Вот здесь уже не правильно. Таблица значений тебе не нужна, она не подойдет для твоего проекта, так понятно ?
   Varlant1n
 
37 - 28.10.20 - 11:29
(36) Да, понятно. Сейчас буду пробовать сделать так, как вы сказали выше. Посмотрю как получится
   Затейник
 
38 - 28.10.20 - 11:32
Вот я сделал следующее. Но все равно ошибка: {Обработка.ОбезличиваниеДанных.Форма.Форма.Форма(30)}: Метод объекта не обнаружен (Выбрать)
        ВыборкаДокумента = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруп

Результат = Запрос.Выполнить().Выгрузить();

Так строчка должна быть одна.

1) Результат = Запрос.Выполнить().Выбрать(ОбходРезультатЗапроса.Погруппировкам, "Дата");
   Varlant1n
 
39 - 28.10.20 - 11:34
(34) Огромное спасибо Вам за помощь! Просто огромное! И все остальным и за советы и за насмешки надо мной (это придает мотивации изучать программирование). Всё получилось! Но у меня к Вам последний вопрос. Стоит ли в цикле по документам, писать Попытку? То есть может ли данная процедура дать ошибку в каком-то случае? Допустим, когда документов нет.
   ИУБиПовиц
 
40 - 28.10.20 - 12:40
(39) Если доков нет, то и  ошибки не будет, а вот если заблокирован может и дать
   ИУБиПовиц
 
41 - 28.10.20 - 12:46
И кстати, не очень хорошо что дергаешь сервер в цикле по метаданным, можно вообще все в запрос унести и одним запросом выдернуть.
Но чет я попробовал, как то тормознуто получилось, но у мну доков то много что б так извращаться над ними:)

&НаСервере
Процедура ОкНаСервере()
    запрос = Новый Запрос;
    ПервыйВход = Истина;
    для каждого мета из Метаданные.Документы цикл
        ИмяДок = Мета.Имя;
        
         Подзапрос =   "ВЫБРАТЬ
         |    АвансовыйОтчет.Ссылка КАК Ссылка,
         |    АвансовыйОтчет.Док КАК ИмяДока,
         |    НАЧАЛОПЕРИОДА(АвансовыйОтчет.Дата, МЕСЯЦ) КАК Месяц
         |ПОМЕСТИТЬ Док
         |ИЗ
         |    Документ.АвансовыйОтчет КАК АвансовыйОтчет
         |ГДЕ
         |    АвансовыйОтчет.Дата >= &Дата
         |Объединить ВСЕ 
         |";
         
         Подзапрос = Стрзаменить(Подзапрос,"АвансовыйОтчет.Док", """" + ИмяДОк + """" );
         Подзапрос = Стрзаменить(Подзапрос,"АвансовыйОтчет",ИмяДОк );
        

         Если не ПервыйВход тогда
            Подзапрос = Стрзаменить(Подзапрос,"ПОМЕСТИТЬ Док","" );
        КонецЕсли;
        
 
                 
        
        Запрос.Текст = Запрос.Текст + Подзапрос;
        ПервыйВход = ЛОЖЬ;
        
    КонецЦикла;
    

запрос.Текст = лев(Запрос.Текст, СтрДлина(Запрос.Текст)  - 16);

запрос.Текст = запрос.Текст + "
     |;
         |ВЫБРАТЬ РАЗЛИЧНЫЕ
         |    Док.Ссылка КАК Ссылка,
         |    Док.Месяц КАК Месяц,
     |    Док.ИмяДока КАК ИмяДока, 
         |    СУММА(1) КАК Счетчик
         |ИЗ
         |    Док КАК Док
         |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Док КАК Док1
         |        ПО Док.Месяц = Док1.Месяц
         |            И Док.ИмяДока = Док1.ИмяДока 
         |            И Док.Ссылка.МоментВремени <= Док1.Ссылка.МоментВремени
         |
         |СГРУППИРОВАТЬ ПО
         |    Док.Ссылка,
         |    Док.Месяц ,
         |    Док.ИмяДока 
         |
         |ИМЕЮЩИЕ
         |    КОЛИЧЕСТВО(Док1.Ссылка) <= 2//тут 5 надо, но еще тормознутее будет

         |
         |УПОРЯДОЧИТЬ ПО
         |    ИмяДока,
         |    Месяц,
         |    Ссылка" ;

Запрос.УстановитьПараметр("Дата",объект.Дата);
тз = Запрос.Выполнить().Выгрузить();

СзНаУдаление = Новый СписокЗначений;

для каждого стр из тз цикл
    СзНаУдаление.Добавить(Стр.Ссылка);
КонецЦикла;

для каждого эл из СзНаУдаление цикл
    Об = эл.Значение;
    Сообщить(ОБ);
    //тут устанавливаешь пометку на удаление

КонецЦикла;

//тут ищешь помеченные и удаляешь, 




    
КонецПроцедуры
   Chameleon1980
 
42 - 28.10.20 - 13:37
развернули наконец (7)
   Волшебник
 
43 - 28.10.20 - 13:40
(42) Ты знал, ты знал...


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.