Результат запроса в несколько ТЗ

1. Serega-artem 16 07.05.20 15:21 Сейчас в теме
Добрый день, коллеги! Не могу сообразить простую в принципе вещь. Есть справочник, в нем три ТЧ, каждая со своими реквизитами. Есть три РС с таким же набором реквизитов, куда эти таб. части нужно поместить. Как сделать это красиво? Как мыслю:

1 Делаем запрос:

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


2. Дальше нам надо из этого запроса получить три ТЗ, чтобы каждую загрузить в свой регистр. Но вот туплю как это сделать...
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
6. abasovit 5 07.05.20 18:04 Сейчас в теме
(1) можете в одном запросе получить все данные, а после в цикле, с помощью метода ЗаполнитьЗначенияСвойств() добавлять заполнять значения записей регистра.

Вот на форуме, немного похожая на вашу, задача решалась уже ЗаполнитьЗначенияСвойств 1с 8.3
7. Serega-artem 16 07.05.20 19:16 Сейчас в теме
Во-первых всем спасибо! Ключевой момент вопроса - как сделать красиво. Задача в принципе разовая и тут можно хоть запрос в цикле. Ибо всё равно коду работать один раз только. Но хочется сделать именно правильно, красиво и оптимизировано, чтобы потом, когда здача такая возникнет уже по серьезному, четко понимать алгоритм.
(6) Про заполнить значения свойств я знаю, но тут цикл получается, как-то не очень отимизировано.
(2) Можно в принципе и три разных запроса написать, получить в каждом свою ТЗ и не парится. Но как-то опять же не оптимально получается. Три разо одни и те же данные шурудить.
(3) Была такая мысль, и кажется самой правильной по сути, но как разделять? Через

 ТЗ.Скопировать(СтруктураОтбора)


? Но что тогда будет отбором?
11. LifeRock 07.05.20 22:15 Сейчас в теме
(7)
Можно в принципе и три разных зап


Не три разных запроса, а одним запросом сразу получить три таблицы
8. dhurricane 07.05.20 20:05 Сейчас в теме
(1) Так ведь вы уже все, что надо, сделали. Остались детали :-)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка", Контрагент);
Запрос.Текст = 
"ВЫБРАТЬ
|    Контрагенты.ТЗКоммуникация,
|    Контрагенты.ПрофессиональныеНавыки,
|    Контрагенты.Автомобили
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    Контрагенты.Ссылка = &Ссылка";

Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();

Таблица1 = Выборка.ТЗКоммуникация.Выгрузить();
Таблица2 = Выборка.ПрофессиональныеНавыки.Выгрузить();
Таблица3 = Выборка.Автомобили.Выгрузить();
Показать
9. Serega-artem 16 07.05.20 21:02 Сейчас в теме
(8) Так, а поясните тогда)

Выборка.Следующий();



А тут разве не цикл?

Отбор по контрагенту мне не нужен, мне надо по всем. Получается, что я просто прямо указываю элемент выборки (в нашем случае ТЧ) и выгружаю его в ТЗ. И всё? Завтра буду пробовать)
10. dhurricane 07.05.20 21:24 Сейчас в теме
(9) Конечно цикл, если перебираете всех контрагентов. Я просто подумал, что это у Вас опечатка, и вставил условие отбора по ссылке.

И да, выбранные поля, которые являются табличной частью, в выборке будут иметь тип "РезультатЗапроса". Соответственно его можно выгружать в таблицу значений методом "Выгрузить".
YannikAlx; +1 Ответить
14. пользователь 08.05.20 10:41
Сообщение было скрыто модератором.
...
15. Serega-artem 16 08.05.20 10:43 Сейчас в теме
Давайте подведем итоги)

(10) Тут получается надо циклом двигаться по контрагентам, на каждого получать ТЗ, загружать ее в регистр, двигаться дальше.... В общем оптимизация так себе. Всегда считал, что цикл на больших объемах данных (а тут контрагентов что-то порядка 20 тыс.) - это крайне плохо.

Попрыгал и так и эдак и всё же пришел к (2) т.е. обращаться не к справочнику, а к конкретной таблице. Сделал пакет из трех запросов и после 2-3 минут (!!!) жевания, 1с выкидывала ошибку о недостатке памяти. Тогда решил сделать три отдельных запроса. Получилось так:

Новый Запрос - запрос к таблице 1- Выгрузка данных в ТЗ - Загрузка в РС. // Первая
Новый Запрос - запрос к таблице 2- Выгрузка данных в ТЗ - Загрузка в РС. // Вторая
Новый Запрос - запрос к таблице 3 - Выгрузка данных в ТЗ - Загрузка в РС. // Третья

Весь код отработал за 20-30 сек. без всяких проблем. В очередной убедился, что "правильно" не значит хорошо, а то, что на первый взгляд выглядит костылями, является оптимальным, на практике, решением.
18. dhurricane 08.05.20 10:47 Сейчас в теме
(15)
Тут получается надо циклом двигаться по контрагентам, на каждого получать ТЗ, загружать ее в регистр, двигаться дальше.... В общем оптимизация так себе.
Извините, не очень хорошо понял суть проблемы. Что значит "двигаться по контрагентам" и почему в Вашем конечном примере Вы не "двигаетесь" по ним.
24. Serega-artem 16 08.05.20 10:56 Сейчас в теме
(18) Давайте попробую объяснить! У нас есть справочник Контрагенты. В нем есть три ТЧ из которых данные нужно выгрузить в три разных Регистра Сведений. В регистре все те же реквизиты (разделенные на Измерения и Ресурсы) + еще одно измерение Контрагент которое является ссылкой на тот самый элемент справочника. Нам нужно загрузить данные в регистр за раз из ТЗ. т.е. иметь единую ТЗ, в которой будут все данные по всем контрагентам т.е. единое целое из записей ТЧ всех контрагентов. В вашем примере, мы обращаемся к справочнику Контрагенты и получаем выборку в разрезе элемента этого справочника (Контрагента). Иными словами:

Пока Выборка.Следующий() цикл // Идем по списку элементов 
                // Тут выгружаем табличные части  конкретного элемента. 
Таблица1 = Выборка.ТЗКоммуникация.Выгрузить();
Таблица2 = Выборка.ПрофессиональныеНавыки.Выгрузить();
Таблица3 = Выборка.Автомобили.Выгрузить();
            КонецЦикла; 
28. dhurricane 08.05.20 11:22 Сейчас в теме
(24) Спасибо, теперь понял о чем речь. Действительно, я предлагал решение не той задачи, что стояла перед Вами. И быстрее сработает запрос к отдельной таблице и загрузка результата в регистр целиком.

Что касается "правильности", то этот вопрос не может рассматриваться отдельно от задачи. Мой пример вполне правильный, если бы Вы делали записи в регистр, скажем, при записи контрагента. Т.е. запись осуществлялась в разрезе отдельных контрагентов. Но Ваша задача не такая, поэтому и пример мой не подходит.

Опять же, все зависит от требований к алгоритму. Вы пожертвовали оперативной памятью в пользу скорости выполнения. Если бы Вы проделывали подобное обновление регистра на регулярной основе, возможно, озвученный Вами подход пришлось бы пересмотреть.
29. Serega-artem 16 08.05.20 11:30 Сейчас в теме
(28) Правильность, разумеется, может быть оценена только в рамках задачи, тут я с вами полностью согласен! По поводу оперативной памяти, ну вот я как раз и делю алгоритм выполнения на три разных запроса, т.к. в одном запросе (пакетном) идет перерасход памяти. А так получается, что мы обработали массив нужных данных (конкретную ТЧ), освободили память и поехали дальше.
2. LifeRock 07.05.20 15:28 Сейчас в теме
Почему не сделать три подзапроса и не использовать Запрос.ВыполнитьПакет()
4. VictorRGB2 13 07.05.20 17:27 Сейчас в теме
в (2) практичнее, удобнее и в целом правильнее
5. Vladimir-R 167 07.05.20 18:00 Сейчас в теме
(4) несколько раз выполнять один и тот же запрос правильнее?!
12. YannikAlx 43 08.05.20 08:53 Сейчас в теме
(4) Не удобнее , а длиннее и уж тем более не практичнее. а про правильность - даже смешно!
вы предлагаете удлинить время работы процедуры??? ))))))))))))
13. VictorRGB2 13 08.05.20 10:12 Сейчас в теме
(12) ну кому как
мне удобнее выполнить один пакетный запрос, получить сразу три готовых результата и обработать, о чем и пишут в (2)
про правильность, может, конечно и перебор, просто меня учили - можно получить все данные одним запросом, получай
nomad_irk; +1 Ответить
16. YannikAlx 43 08.05.20 10:45 Сейчас в теме
(13) Вы все же отделите мух от котлет...
Вы предлагаете 3 запроса вместо одного, а потом утверждаете что пакетный запрос выгоднее.
Ясно что для суперсложных запросов пакетный запрос выгоден.
Здесь же запрос на уровне таблицы умножения 2х2 - мы сразу можем получить все данные, выгружая потом их туда куда нужно, сформировав заранее
нужные ТЗ с нужными колонками.
Это по любому будет работать быстрее чем 3 отдельных запроса , если данных много , а принцип получения их элементарный.
17. nomad_irk 76 08.05.20 10:46 Сейчас в теме
(16)Да вы поймите простую вещь: эти три запроса - это одна транзакция вида 1С - SQL, т.к. три запроса существуют только в терминах СУБД.
20. YannikAlx 43 08.05.20 10:50 Сейчас в теме
(17) Я не понял что вы имеете ввиду под 3 запросами в таком случае....
Вот в (8) предложен на мой взгляд самый рациональный путь решения...
22. nomad_irk 76 08.05.20 10:54 Сейчас в теме
(20)Пакетный запрос из (2).вида

Выбрать * ИЗ Таблица1; Выбрать * ИЗ Таблица2; Выбрать * ИЗ Таблица3
19. Serega-artem 16 08.05.20 10:47 Сейчас в теме
(16) Любопытно! А предложите алгоритм разделения ТЗ ? Приведите, пример кода, как вы видите решение этой задачи?
21. YannikAlx 43 08.05.20 10:50 Сейчас в теме
(19) в посте (8) уже все предложено. Что вас в нем не устраивает?
26. Serega-artem 16 08.05.20 10:59 Сейчас в теме
(21) Вот тут попробовал объяснить, что не устраивает:

http://forum.infostart.ru/forum9/topic240672/message2439111/#message2439111
23. nomad_irk 76 08.05.20 10:55 Сейчас в теме
(19)Да блин....У ТЗ есть колонка с определяющим значением. По этому значению отбираются строки в ТЗ.
25. Serega-artem 16 08.05.20 10:58 Сейчас в теме
27. nomad_irk 76 08.05.20 11:05 Сейчас в теме
(25)ну например "ИмяТаблицы", в которую присваиваем определенное значение для всего массива строк, содержащихся в одной из таблиц.
30. Serega-artem 16 08.05.20 11:32 Сейчас в теме
(27) Можете привести пример кусочка кода? Что-то не могу сообразить о чем вы. Мы в запросе должны создать еще одну колонку и присвоить туда имя таблицы?
31. nomad_irk 76 08.05.20 11:42 Сейчас в теме
(30)Да.

Ваша задача решается как минимум 2-мя способами:
1. запросом вида Выбрать * ИЗ Таблица1; Выбрать * ИЗ Таблица2; Выбрать * ИЗ Таблица3
2. Запросом вида Выбрать *, 1 КАК ИмяТаблицы ИЗ Таблица1 ОБЪЕДИНИТЬ ВСЕ Выбрать *, 2 ИЗ Таблица2 ОБЪЕДИНИТЬ ВСЕ Выбрать *, 3 ИЗ Таблица3
32. nomad_irk 76 08.05.20 12:55 Сейчас в теме
(30)В случае варианта №1:

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

НЗ = РегистрыСведений.<ИмяРегистра1>.СоздатьНаборЗаписей();
НЗ.Загрузить(Результат[0].Выгрузить());
НЗ.Записать();

НЗ = РегистрыСведений.<ИмяРегистра2>.СоздатьНаборЗаписей();
НЗ.Загрузить(Результат[1].Выгрузить());
НЗ.Записать();

НЗ = РегистрыСведений.<ИмяРегистра3>.СоздатьНаборЗаписей();
НЗ.Загрузить(Результат[2].Выгрузить());
НЗ.Записать();
Показать



В случае варианта №2:

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

Отбор = Новый Структура("ИмяТаблицы", 1);
ТаблицаЗаписей = ТЗ.Скопировать(Отбор, "Нужные, Имена, Колонок");
НЗ = РегистрыСведений.<ИмяРегистра1>.СоздатьНаборЗаписей();
НЗ.Загрузить(ТаблицаЗаписей);
НЗ.Записать();


Отбор = Новый Структура("ИмяТаблицы", 2);
ТаблицаЗаписей = ТЗ.Скопировать(Отбор, "Нужные, Имена, Колонок");
НЗ = РегистрыСведений.<ИмяРегистра2>.СоздатьНаборЗаписей();
НЗ.Загрузить(ТаблицаЗаписей);
НЗ.Записать();


Отбор = Новый Структура("ИмяТаблицы", 3);
ТаблицаЗаписей = ТЗ.Скопировать(Отбор, "Нужные, Имена, Колонок");
НЗ = РегистрыСведений.<ИмяРегистра3>.СоздатьНаборЗаписей();
НЗ.Загрузить(ТаблицаЗаписей);
НЗ.Записать();
Показать
33. Serega-artem 16 08.05.20 13:18 Сейчас в теме
(32) Ну первый вариант, я примерно так и хотел - получаю очень долгое выполнение и ошибку на нехватку памяти. Второй вариант, это по сути своей то, что выносилось в тему вопроса, это здорово. На практике не пробовал, но в теории вполне себе решение задачи. Спасибо!
34. nomad_irk 76 08.05.20 13:46 Сейчас в теме
(33)
Ну первый вариант, я примерно так и хотел - получаю очень долгое выполнение и ошибку на нехватку памяти.


Эээ....а вы точно запрос написали правильно? Если у вас нехватка памяти, то второй вариант скорее всего приведет к тому же.
3. Vladimir-R 167 07.05.20 16:57 Сейчас в теме
Почему не выгрузить в одну ТЗ и не копировать потом в нужное количество?
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот