Добрый день, коллеги! Не могу сообразить простую в принципе вещь. Есть справочник, в нем три ТЧ, каждая со своими реквизитами. Есть три РС с таким же набором реквизитов, куда эти таб. части нужно поместить. Как сделать это красиво? Как мыслю:
1 Делаем запрос:
апрос.Текст = "ВЫБРАТЬ
| Контрагенты.ТЗКоммуникация.(
| Дата КАК Дата,
| Сотрудник КАК Сотрудник,
| Тип КАК Тип,
| Описание КАК Описание,
| ВходИсход КАК ВходИсход,
| Ссылка КАК ОбъектКоммуникации
| ) КАК ТЗКоммуникация,
| Контрагенты.ПрофессиональныеНавыки.(
| ПрофНавык КАК ПрофНавык,
| Примечание КАК Примечание,
| Ссылка КАК Ссылка
| ) КАК ПрофессиональныеНавыки,
| Контрагенты.Автомобили.(
| МаркаМодель КАК МаркаМодель,
| Тип КАК Тип,
| Мест КАК Мест,
| Примечание КАК Примечание,
| Ссылка КАК Ссылка
| ) КАК Автомобили
|ИЗ
| Справочник.Контрагенты КАК Контрагенты";
Выборка = Запрос.Выполнить().Выбрать();
Показать
2. Дальше нам надо из этого запроса получить три ТЗ, чтобы каждую загрузить в свой регистр. Но вот туплю как это сделать...
(1) можете в одном запросе получить все данные, а после в цикле, с помощью метода ЗаполнитьЗначенияСвойств() добавлять заполнять значения записей регистра.
Во-первых всем спасибо! Ключевой момент вопроса - как сделать красиво. Задача в принципе разовая и тут можно хоть запрос в цикле. Ибо всё равно коду работать один раз только. Но хочется сделать именно правильно, красиво и оптимизировано, чтобы потом, когда здача такая возникнет уже по серьезному, четко понимать алгоритм.
(6) Про заполнить значения свойств я знаю, но тут цикл получается, как-то не очень отимизировано.
(2) Можно в принципе и три разных запроса написать, получить в каждом свою ТЗ и не парится. Но как-то опять же не оптимально получается. Три разо одни и те же данные шурудить.
(3) Была такая мысль, и кажется самой правильной по сути, но как разделять? Через
Отбор по контрагенту мне не нужен, мне надо по всем. Получается, что я просто прямо указываю элемент выборки (в нашем случае ТЧ) и выгружаю его в ТЗ. И всё? Завтра буду пробовать)
(9) Конечно цикл, если перебираете всех контрагентов. Я просто подумал, что это у Вас опечатка, и вставил условие отбора по ссылке.
И да, выбранные поля, которые являются табличной частью, в выборке будут иметь тип "РезультатЗапроса". Соответственно его можно выгружать в таблицу значений методом "Выгрузить".
(10) Тут получается надо циклом двигаться по контрагентам, на каждого получать ТЗ, загружать ее в регистр, двигаться дальше.... В общем оптимизация так себе. Всегда считал, что цикл на больших объемах данных (а тут контрагентов что-то порядка 20 тыс.) - это крайне плохо.
Попрыгал и так и эдак и всё же пришел к (2) т.е. обращаться не к справочнику, а к конкретной таблице. Сделал пакет из трех запросов и после 2-3 минут (!!!) жевания, 1с выкидывала ошибку о недостатке памяти. Тогда решил сделать три отдельных запроса. Получилось так:
Новый Запрос - запрос к таблице 1- Выгрузка данных в ТЗ - Загрузка в РС. // Первая
Новый Запрос - запрос к таблице 2- Выгрузка данных в ТЗ - Загрузка в РС. // Вторая
Новый Запрос - запрос к таблице 3 - Выгрузка данных в ТЗ - Загрузка в РС. // Третья
Весь код отработал за 20-30 сек. без всяких проблем. В очередной убедился, что "правильно" не значит хорошо, а то, что на первый взгляд выглядит костылями, является оптимальным, на практике, решением.
Тут получается надо циклом двигаться по контрагентам, на каждого получать ТЗ, загружать ее в регистр, двигаться дальше.... В общем оптимизация так себе.
Извините, не очень хорошо понял суть проблемы. Что значит "двигаться по контрагентам" и почему в Вашем конечном примере Вы не "двигаетесь" по ним.
(18) Давайте попробую объяснить! У нас есть справочник Контрагенты. В нем есть три ТЧ из которых данные нужно выгрузить в три разных Регистра Сведений. В регистре все те же реквизиты (разделенные на Измерения и Ресурсы) + еще одно измерение Контрагент которое является ссылкой на тот самый элемент справочника. Нам нужно загрузить данные в регистр за раз из ТЗ. т.е. иметь единую ТЗ, в которой будут все данные по всем контрагентам т.е. единое целое из записей ТЧ всех контрагентов. В вашем примере, мы обращаемся к справочнику Контрагенты и получаем выборку в разрезе элемента этого справочника (Контрагента). Иными словами:
Пока Выборка.Следующий() цикл // Идем по списку элементов
// Тут выгружаем табличные части конкретного элемента.
Таблица1 = Выборка.ТЗКоммуникация.Выгрузить();
Таблица2 = Выборка.ПрофессиональныеНавыки.Выгрузить();
Таблица3 = Выборка.Автомобили.Выгрузить();
КонецЦикла;
(24) Спасибо, теперь понял о чем речь. Действительно, я предлагал решение не той задачи, что стояла перед Вами. И быстрее сработает запрос к отдельной таблице и загрузка результата в регистр целиком.
Что касается "правильности", то этот вопрос не может рассматриваться отдельно от задачи. Мой пример вполне правильный, если бы Вы делали записи в регистр, скажем, при записи контрагента. Т.е. запись осуществлялась в разрезе отдельных контрагентов. Но Ваша задача не такая, поэтому и пример мой не подходит.
Опять же, все зависит от требований к алгоритму. Вы пожертвовали оперативной памятью в пользу скорости выполнения. Если бы Вы проделывали подобное обновление регистра на регулярной основе, возможно, озвученный Вами подход пришлось бы пересмотреть.
(28) Правильность, разумеется, может быть оценена только в рамках задачи, тут я с вами полностью согласен! По поводу оперативной памяти, ну вот я как раз и делю алгоритм выполнения на три разных запроса, т.к. в одном запросе (пакетном) идет перерасход памяти. А так получается, что мы обработали массив нужных данных (конкретную ТЧ), освободили память и поехали дальше.
(4) Не удобнее , а длиннее и уж тем более не практичнее. а про правильность - даже смешно!
вы предлагаете удлинить время работы процедуры??? ))))))))))))
(12) ну кому как
мне удобнее выполнить один пакетный запрос, получить сразу три готовых результата и обработать, о чем и пишут в (2)
про правильность, может, конечно и перебор, просто меня учили - можно получить все данные одним запросом, получай
(13) Вы все же отделите мух от котлет...
Вы предлагаете 3 запроса вместо одного, а потом утверждаете что пакетный запрос выгоднее.
Ясно что для суперсложных запросов пакетный запрос выгоден.
Здесь же запрос на уровне таблицы умножения 2х2 - мы сразу можем получить все данные, выгружая потом их туда куда нужно, сформировав заранее
нужные ТЗ с нужными колонками.
Это по любому будет работать быстрее чем 3 отдельных запроса , если данных много , а принцип получения их элементарный.
(27) Можете привести пример кусочка кода? Что-то не могу сообразить о чем вы. Мы в запросе должны создать еще одну колонку и присвоить туда имя таблицы?
Ваша задача решается как минимум 2-мя способами:
1. запросом вида Выбрать * ИЗ Таблица1; Выбрать * ИЗ Таблица2; Выбрать * ИЗ Таблица3
2. Запросом вида Выбрать *, 1 КАК ИмяТаблицы ИЗ Таблица1 ОБЪЕДИНИТЬ ВСЕ Выбрать *, 2 ИЗ Таблица2 ОБЪЕДИНИТЬ ВСЕ Выбрать *, 3 ИЗ Таблица3
(32) Ну первый вариант, я примерно так и хотел - получаю очень долгое выполнение и ошибку на нехватку памяти. Второй вариант, это по сути своей то, что выносилось в тему вопроса, это здорово. На практике не пробовал, но в теории вполне себе решение задачи. Спасибо!