Имя: Пароль:
1C
1С v8
Счетчик строк заново для каждого типа документов, пакет запросов с объединением
, ,
0 DenYuliya
 
30.05.23
12:20
Всем привет, подскажите,пожалуйста, не могу сообразить, как реализовать в запросе реквизит "Строка_номер" (грубо говоря некий счетчик строк). Чтобы для каждого типа документов счетчик начинался заново!
Есть запрос, в нем, допустим, 3 временные таблицы: ВТ_Продажи, ВТ_Покупки, ВТ_Перемещения. У каждой из них есть реквизит "Строка_номер". В результате, допустим, 10 значений  - соответственно, значения "Строка_номер" от 1 до 10.

Далее все временные таблицы объединением "схлопываются" в единую таблицу в пакетном запросе. И вот я никак не могу сообразить, как мне так сделать, чтобы значения реквизита "Строка_номер" начинались заново для результата каждой из ВТ? А то у меня получается просто типовой счетчик строк для результирующей таблицы, типа "от 1 до 10" по общему кол-ву строк.

Например, у нас 2 документа в ВТ_Продажи, 3 документа в ВТ_Покупки, 1 документ в ВТ_Перемещения, итого 6 строк (документов).
Значит, в итоговой таблице (через объединения) реквизит "Строка_номер"должен быть не "от 1 до 6", а

"Строка_номер 1"  ДокументПродажа1
"Строка_номер 2"  ДокументПродажа2
"Строка_номер 1"  ДокументПокупка1
"Строка_номер 2"  ДокументПокупка2
"Строка_номер 3"  ДокументПокупка3
"Строка_номер 1"  ДокументПеремещение1
1 Мультук
 
гуру
30.05.23
12:48
(0)


Я как-то не так делаю, или что ?
===

ВЫБРАТЬ ПЕРВЫЕ 10
    т1.Ссылка КАК Ссылка,
    АВТОНОМЕРЗАПИСИ() КАК Номер
ПОМЕСТИТЬ ВТ_1    
ИЗ
    Справочник.Номенклатура КАК т1
;


ВЫБРАТЬ ПЕРВЫЕ 5
    т1.Ссылка КАК Ссылка,
    АВТОНОМЕРЗАПИСИ() КАК Номер
ПОМЕСТИТЬ ВТ_2    
ИЗ
    Справочник.Валюты КАК т1
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_1.Ссылка КАК Ссылка,
    ВТ_1.Номер КАК Номер
ИЗ
    ВТ_1 КАК ВТ_1
    
ОБЪЕДИНИТЬ ВСЕ     


ВЫБРАТЬ
    ВТ_2.Ссылка КАК Ссылка,
    ВТ_2.Номер КАК Номер
ИЗ
    ВТ_2 КАК ВТ_2
2 DenYuliya
 
30.05.23
13:22
(1) спасибо, попробую! Вот такое еще нашла https://skill-blog.ru/no-rubrick/numeracziya-strok-v-zaprose-1s-i-ne-tolko/
3 azernot
 
30.05.23
13:32
(0) Зачем?
4 DenYuliya
 
30.05.23
14:00
(3) надо для выгрузки в стороннюю систему такую колонку.  Это по-умному называется "Нумерация строк внутри группировки", по ссылке выше прямо отличный пример.
Только (рука-лицо), у меня там так 15 временных таблиц, соединяемых друг с другом всяко-разно, а потом объединяемых в итоговом пакетном запросе. У меня глаз дергается от идеи к этому делу прикурочить еще 10 временных таблиц для добавления нумерации)))))). Лютая жесть какая-то выходит, я думала, что "есть способ проще".
5 azernot
 
30.05.23
14:25
(4) Ну, может быть тогда проще в момент обхода результата запроса при выгрузке счётчик добавить?
6 azernot
 
30.05.23
14:37
Ну или закинуть свой запрос в СКД, там сделать группировку по типу, и использовать системное поле "НомерПоПорядкуВГруппировке", но что-то мне подсказывает, что от этого глаз ещё больше начнёт дёргаться.
7 DenYuliya
 
30.05.23
14:46
(5) у меня просто ТЗ.Выгрузить(), а потом это результат выгружается в csv, прямо "как он есть", без всяких обходов. Боюсь, я не готова устанавливать нумерацию в момент записи в csv (если это вообще реально), потому как я с этим csv зат***ха***сь адски.
Можно, конечно, теоретически, разобрать ТЗ_РезультатЗапроса1, в цикле его обойти, добавив колонку со счетчиком, потом его заново в коде "собрать" в  новую ТЗ_РезультатЗапроса2 и уже ее загрузить в csv. Но, боюсь, я в этом деле окончательно запутаюсь, накосячу и вряд ли это будет быстрее и эффективнее, чем добавить ВТ в запрос.

(6) у меня внешняя обработка, туда вроде как СКД не прикорячить же? В простом "Конструкторе запроса" не нашла системных полей.
9 mikecool
 
30.05.23
14:55
(7) эээ, а что мешает между " ТЗ.Выгрузить()" и "результат выгружается в csv," воткнуть еще один цикл?
10 azernot
 
30.05.23
15:06
(7) СКД можно прикорячить куда угодно.
Результат запроса можно выгрузить в дерево с группировкой по нужному типу, обойти дерево и сформировать ТЗ.

Например, запрос:

Выбрать
Ссылка как Ссылка,
"Продажи" как Тип
Из ВТ_Продажи

Объединить все

Выбрать
Ссылка
"Закупки"
Из ВТ_Закупки

Объединить все
Ссылка
"Перемещения"
ИЗ ВТ_Перемещения

Итоги по
Тип

Далее из запроса - дерево.

Дерево = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("НомерПоПорядкуВГруппе", Новый ОписаниеТипов("Число")); //Добавляем свою колонку счётчика

Для Каждого Колонка Из Дерево.Колонки Цикл
   ТЗ.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;


Для каждого СтрокаТип Из Дерево.Строки Цикл
  Счетчик = 0;
  Для каждого СтрокаЗаписей из СтрокаТип.Строки Цикл
     Счетчик = Счетчик + 1;
     НоваяСтрокаТЗ = ТЗ.Добавить();
     НоваяСтрокаТЗ.НомерПоПорядкуВГруппе = Счетчик;
     ЗаполнитьЗначенияСвойств(НоваяСтрокаТЗ, СтрокаЗаписей);
  КонецЦикла;
КонецЦикла;


Вуаля, имеем ТЗ с счётчиком по группам. Наглядно. И можно использовать несколько уровней группировки.

Можно конечно не заморачиваться с деревом, а просто упорядочить в запросе данные по типу, перебрать ТЗ устанавливая счётчик, а при смене типа обнулять значение счётчика. Менее наглядно, зато быстее и без лишней мороки.
11 DenYuliya
 
30.05.23
15:09
(9) я вроде бы выше этот вариант и описала: "Можно, конечно, теоретически, разобрать ТЗ_РезультатЗапроса1, в цикле его обойти, добавив колонку со счетчиком, потом его заново в коде "собрать" в  новую ТЗ_РезультатЗапроса2 и уже ее загрузить в csv. Но, боюсь, я в этом деле окончательно запутаюсь, накосячу и вряд ли это будет быстрее и эффективнее, чем добавить ВТ в запрос.".

Или имеется в виду что-то другое?

Мешает трудоемкость продумывания алгоритма обхода в цикле этого космолета и тестирования, чтобы ничего не продолбалось. + не очень понимаю, чем обход запроса в цикле сильно лучше прикорячивания еще кучки временных таблиц. Мне КАЖЕТСЯ (возможно, мне только кажется), что в запросе это будет сделать проще.
12 azernot
 
30.05.23
15:12
(11) Решать вам. Если количество типов у вас фиксировано и неизменно, правильнее и быстрое - добавить ВТ в запросе. А вот если заранее количество возможных типов неизвестно, если они динамически определяются в запросе, вы физически не сможете под каждый тип определить отдельную ВТ. Тогда методика постобхода результата запроса - вам в помощь.
13 DenYuliya
 
30.05.23
15:13
(10) "Можно конечно не заморачиваться с деревом, а просто упорядочить в запросе данные по типу, перебрать ТЗ устанавливая счётчик, а при смене типа обнулять значение счётчика. Менее наглядно, зато быстее и без лишней мороки." - вот это очень спасибо за совет! попробую, напишу, что получится).

А почему все так дружно стали обсуждать присвоение номера в цикле при обходе результата запроса? Добавлять колонку счетчика в самом запросе - такой гемор, что проще результат в цикле обойти?
Я просто, если честно, вообще изначально забыла про эту колонку и еще даже не начинала ее прикорячивать, хотя сдать надо было "уже вчера"). Так, по-быстрому пару вариантов проверила, не получилось и решила сначала основное доделать, а потом счетчиком заняться вплотную.
14 DenYuliya
 
30.05.23
15:15
(12) количество типов фиксированно и неизменно. 4 типа. Просто для каждого типа по несколько ВТ получаются, т.к. они, прежде чем придти к Тип1_Итог, соединяются с кучей разной гадости.
15 azernot
 
30.05.23
15:17
(13) Потому что чаще всего количество группировок заранее неизвестно.
Например, я выбираю данные о продажах, а там у меня РеализацияТоваровУслуг, и ОтчетОРознинчныхПродажах, Отчёт комиссионера и ещё какие-нибудь документы. И это разные типы. А завтра кто-то добавит ещё регистратор. Поэтому проще сразу написать универсально. А не заниматься переписыванием запроса каждый раз.
16 DenYuliya
 
30.05.23
15:24
(15) а, нет, тут все четко и фиксированно. Во-всяком случае, если ТЗ не изменят - но тогда придется все переписывать).
Спасибо, поняла, буду переваривать информацию.
17 azernot
 
30.05.23
15:34
(16) Заодно попробуйте переварить физический смысл такого счётчика. Для чего он нужен принимающей стороне? Что к примеру, будет, если у вас везде будет стоять 0? А что будет если в одном сеансе обмена в строке "Продажа" № 1 будет один документ, а в другом сеансе обмена уже другой? Т.е. надо понять, этот счётчик - чистая формальность или всё же на него возложена какая-то функция? Вдруг принимающая сторона воспринимает его как идентификатор, подразумевая инкрементальный обмен, а вы его заполняете чуть ли не случайным образом?
Общее правило подобных обменов - сократить передаваемую информацию до необходимого минимума, избавляться от данных, которые не имеют никакого объективного смысла.
18 DenYuliya
 
30.05.23
15:51
(17) " А что будет если в одном сеансе обмена в строке "Продажа" № 1 будет один документ, а в другом сеансе обмена уже другой?" - вряд ли, это выгрузка в MS Navision, она не передает ссылку на документ, только числа и определенные коды складов. И не рег.заданием, а раз в х-времени пользователь вручную делает "тык-тык".
"Общее правило подобных обменов - сократить передаваемую информацию до необходимого минимума, избавляться от данных, которые не имеют никакого объективного смысла"- а вот тут полностью согласна, уже думала об этом, а точно ли оно им надо.
19 DenYuliya
 
30.05.23
17:32
(17) " физический смысл такого счётчика" - некая отмашка стороне приемника,  что пошел новый тип документа.
20 DenYuliya
 
30.05.23
19:11
А кто-нибудь что-нибудь знает про АВТОНОМЕРЗАПИСИ()?
Я попробовала - получается какая-то хренота.

У меня 4 типа документов, и для каждого - по 2 ВТ (сначала просто документы с отборами, потом к ВТ_ПростоДокументы всякая ерунда цепляется). Потом вся эта каша через в пакете объединяется в общую таблицу. То есть суммарно ПОКА ЧТО 12 ВТ и 1 пакет. Читала, что при большом кол-ве ВТ - АВТОНОМЕРЗАПИСИ() плохо работает, или это вранье? Попробовала оставить поменьше ВТ в запросе -все равно хрень. Нумерация начинается не с 1, а черт знает как.
Какой сервер, скуль или постгри - не знаю.
21 DenYuliya
 
30.05.23
19:33
к (20) Какой сервер, скуль или постгри - не знаю, вроде бы скуль
22 Мультук
 
гуру
30.05.23
20:07
(20)

https://its.1c.ru/db/v8313doc#bookmark:dev:TI000000495

Там написано, что в общем случае 1С не гарантирует нумерацию с 1.

Имхо, решение из (10) можно было уже реализовать и даже протестировать.

P.S.
Я всё же прочитал ИТС на предмет АВТОНОМЕРЗАПИСИ()
Что-то вроде sin() и cos() -- вроде функция есть , но {censored}
23 DenYuliya
 
31.05.23
17:56
(22) "Имхо, решение из (10) можно было уже реализовать и даже протестировать" - да у меня "внезапно" накидалось сверху, что "хотим еще вот это, это и вот это" ну как обычно все. Так что с колонкой по-прежнему "конь не валялся"
24 DenYuliya
 
31.05.23
18:00
(22) "Там написано, что в общем случае 1С не гарантирует нумерацию с 1." - читала данное описание, что-то тоже не поняла, "Суслик есть, но его как бы нет". Но решила, что вдруг это я тупая и не поняла глубокую сущность идеи.
Потому что один раз в консоли у меня вроде все встало просто идеально, счет с "1", правда там было всего 2 ВТ было. А потом это самое "идеально" перенести на рабочий вариант с "много ВТ" не удалось. И теперь я уже сомневаюсь, может мне приснился тот "идеальный" раз))).
25 DenYuliya
 
02.06.23
11:46
Короче, в итоге сделала через Автономерзаписи(). Что имеем: изначально 4 типа документов, из 1 типа документа надо было сделать 2 строки, как бы разбить на ДокументТип1_Отбор1/ДокументТип1_Отбор2. То есть из 4 документов разных типов - 8 строк. Но при этом нумерация строк (отдельный столбик) для каждого ТИПА документа (то есть строки в разрезе разных отборов в рамках одного типа считаются сквозной нумерацией).
1) Делаем 4 ВТ, в каждой из которых Объединение 2 запросов (ВТ_ДокументТип1 состоит из объединения ДокументТип1_Отбор1 + ДокументТип1_Отбор2).
2) Делаем следующие 4 ВТ (ВТ_ДокументТип1_Итог, ВТ_ДокументТип2_Итог и тд.), куда переносим ВТ, созданные на предыдущем этапе (которые с объединением внутри). Потому что ВАЖНЫЙ МОМЕНТ: Автономерзаписи() не работает в ВТ, где используется Объединение. И при этом Автономерзаписи() работает только в ВТ. Получается, нужно для использования Автономерзаписи() создавать некую буферную ВТ. Добавляем пустое поле, туда вставляем Автономерзаписи(), даем ему синоним типа НомерСтроки.  
3)  Создаем итоговый запрос пакета, куда переносим созданные на предыдущем этапе ВТ (ВТ_ДокументТип1_Итог), объединяем их. Порядок по НомерСтроки.

Пыталась сделать через Книга знаний: Нумерация строк в запросе и (2) (когда добавляешь дублирующую таблицу и с ней соединяешь внутренним соединением). У меня какая-то чушь получилась, точнее я не смогла корректно пронумеровать одну ВТ, в которой ранее через "Объединить" были положены 2 запроса к одному документу, но один - к самому Документ.Ссылка, а другой к ТЧ этого же документа.