Вопрос!
Имеем 2 таблицы значений. пр. (ТЗ_1) и (ТЗ_2)
Сначала необходимо найти одинаковые строки в первой таблице (ТЗ_1) и сплюсовать их по определенному значению например "Сумма", далее найти одинаковые строки во второй таблице (ТЗ_2) и сплюсовать их по определенному значению "Сумма", а далее найти одинаковые строки второй таблицы с первой таблицей и если имеются одинаковые строки по найденым строкам то сплюсовать их так же по "Сумма". Каков может быть пример реализации в таком случае?
ВЫБРАТЬ
ТЗ1.Поле1,
ТЗ1.Поле2,
ТЗ1.Сумма1
ПОМЕСТИТЬ ВТ_1
ИЗ
ТЗ1 КАК ТЗ1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_1.Поле1,
ВТ_1.Поле2,
СУММА(ВТ_1.Сумма1) КАК Сумма1
ПОМЕСТИТЬ ВТ_1_Группировка
ИЗ
ВТ_1 КАК ВТ_1
СГРУППИРОВАТЬ ПО
ВТ_1.Поле1,
ВТ_1.Поле2
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ТЗ2.Поле21,
ТЗ2.Поле22,
ТЗ2.Сумма2
ПОМЕСТИТЬ ВТ_2
ИЗ
ТЗ2 КАК ТЗ2
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_2.Поле21,
ВТ_2.Поле22,
СУММА(ВТ_2.Сумма2) КАК Сумма2
ПОМЕСТИТЬ ВТ_2_Группировка
ИЗ
ВТ_2 КАК ВТ_2
СГРУППИРОВАТЬ ПО
ВТ_2.Поле21,
ВТ_2.Поле22
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_1_Группировка.Поле1,
ВТ_1_Группировка.Поле2,
ВТ_1_Группировка.Сумма1,
1 КАК НомерТаблицы
ПОМЕСТИТЬ ВТ_Объединенные
ИЗ
ВТ_1_Группировка КАК ВТ_1_Группировка
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ВТ_2_Группировка.Поле21,
ВТ_2_Группировка.Поле22,
ВТ_2_Группировка.Сумма2,
2
ИЗ
ВТ_2_Группировка КАК ВТ_2_Группировка
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Объединенные.Поле1,
ВТ_Объединенные.Поле2,
СУММА(ВТ_Объединенные.Сумма1) КАК Сумма1,
СУММА(ВТ_Объединенные.НомерТаблицы) КАК НомерТаблицы
ПОМЕСТИТЬ Вариант1
ИЗ
ВТ_Объединенные КАК ВТ_Объединенные
СГРУППИРОВАТЬ ПО
ВТ_Объединенные.Поле2,
ВТ_Объединенные.Поле1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЕСТЬNULL(ВТ_1_Группировка.Поле1, ВТ_2_Группировка.Поле21) КАК Поле1,
ЕСТЬNULL(ВТ_1_Группировка.Поле2, ВТ_2_Группировка.Поле22) КАК Поле2,
СУММА(ЕСТЬNULL(ВТ_1_Группировка.Сумма1, 0) + ЕСТЬNULL(ВТ_2_Группировка.Сумма2, 0)) КАК Сумма,
ВЫБОР
КОГДА НЕ ВТ_1_Группировка.Поле1 ЕСТЬ NULL
И НЕ ВТ_2_Группировка.Поле21 ЕСТЬ NULL
ТОГДА 3
КОГДА ВТ_1_Группировка.Поле1 ЕСТЬ NULL
ТОГДА 2
ИНАЧЕ 1
КОНЕЦ КАК НомерТаблицы
ПОМЕСТИТЬ Варинат2
ИЗ
ВТ_1_Группировка КАК ВТ_1_Группировка
ПОЛНОЕ СОЕДИНЕНИЕ ВТ_2_Группировка КАК ВТ_2_Группировка
ПО ВТ_1_Группировка.Поле1 = ВТ_2_Группировка.Поле21
И ВТ_1_Группировка.Поле2 = ВТ_2_Группировка.Поле22
СГРУППИРОВАТЬ ПО
ЕСТЬNULL(ВТ_1_Группировка.Поле1, ВТ_2_Группировка.Поле21),
ЕСТЬNULL(ВТ_1_Группировка.Поле2, ВТ_2_Группировка.Поле22),
ВЫБОР
КОГДА НЕ ВТ_1_Группировка.Поле1 ЕСТЬ NULL
И НЕ ВТ_2_Группировка.Поле21 ЕСТЬ NULL
ТОГДА 3
КОГДА ВТ_1_Группировка.Поле1 ЕСТЬ NULL
ТОГДА 2
ИНАЧЕ 1
КОНЕЦ
ТаблицаЗначений (ValueTable)
Свернуть (GroupBy)
Синтаксис:
Свернуть(<КолонкиГруппировок>, <КолонкиСуммирования>)
Параметры:
<КолонкиГруппировок> (обязательный)
Тип: Строка.
Имена колонок, разделенные запятыми, по которым необходимо группировать строки таблицы значений.
<КолонкиСуммирования> (необязательный)
Тип: Строка.
Имена колонок, разделенные запятыми, по которым необходимо суммировать значения в строках таблицы значений.
Описание:
Осуществляет свертку таблицы значений по указанным колонкам группировки. Строки, у которых совпадают значения в колонках, указанных в первом параметре, сворачиваются в одну строку. Значения этих строк, хранящиеся в колонках, указанных во втором параметре, накапливаются.
Важно! Списки колонок не должны пересекаться. Колонки, не вошедшие ни в один из списков колонок, после выполнения метода удаляются из таблицы значений.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Примечание:
Если в колонке установлен тип и он единственный, то при суммировании будет предприниматься попытка преобразования значения к типу Число.
Если колонке не присвоены типы, то в процессе суммирования будут принимать участие только значения, имеющие тип Число, значения других типов будут игнорироваться.
Если в колонке несколько типов и среди них есть тип Число, то в процессе суммирования будут принимать участие только значения, имеющие тип Число, значения других типов будут игнорироваться.
Если в колонке несколько типов и среди них нет типа Число, то результат суммирования будет 0, который будет присвоен в соответствующую колонку, где будет преобразован к значению по умолчанию для типа, установленного в колонке.
Пример:
ТаблицаЦен.Свернуть("Товар, Валюта", "Цена");
ТЗ1.Свернуть();
ТЗ2.Свернуть();
Для Каждого Элт Из ТЗ2 Цикл
НовСтрТЗ1 = ТЗ1.Добавить();
ЗаполнитьЗначенияСвойств(НовСтрТЗ1, Элт);
КонецЦикла;
ТЗ1.Свернуть();
(39)по вашей версии, он сначала должен все таблицы разобрать по типам и строкам, проанализировать их (по сути - вручную), а потом объединять-искать-проверять строки на повтор.
А если строки и так уже будут искомые (известные) - зачем их автоматически еще раз анализировать?
по вашей версии, он сначала должен все таблицы разобрать по типам и строкам, проанализировать их (по сути - вручную), а потом объединять-искать-проверять строки на повтор.
т.с пишет
Сначала необходимо найти одинаковые строки в первой таблице (ТЗ_1) и сплюсовать их по определенному значению например "Сумма"
Если ЗначениеВСтрокуВнутр(ТЗ_1) <> ЗначениеВСтрокуВнутр(ТЗ_2) Тогда
типизация нужна перед созданием и наполнением таблиц, допустип для того чтобы значения сумма могла принимать отрицательное значение. В вопросе мало что описано, может и поиск пригодится...
В общем нужно больше данных, ведь не понятно что будет с таблицами на выходе???
Запрос к первой ТЗ с группировкой, результат во временную таблицу.
Запрос ко второй ТЗ с группировкой, результат во временную таблицу2.
Запрос с объединением ВТ1 и ВТ2 с группировкой.
Примерно так.
(2) Судя по условию задачи и одинаковости полей везде, можно и сразу получить данные из обоих таблиц объединением и сгруппировать их со всеми полями групповыми кроме "суммы".
Я не помню какое там ограничение на операции при непосредственном помещении данных из внешнего источника, возможно все таки 3 временных таблицы нужно будет деалть. Но группировки достаточно будет и одной.
(5)а где у него вообще "ТЗ1-32", и почему к этой переменной сразу ".Выгрузить()"?
Откуда берется, что выгружается?
Притом, что изначально "Таблица0" и "Таблица0" - это аргументы функции, входящие параметры. И вообще неизвестно, что там передается.
ВЫБРАТЬ
ТЗ1.Поле1,
ТЗ1.Поле2,
ТЗ1.Сумма1
ПОМЕСТИТЬ ВТ_1
ИЗ
ТЗ1 КАК ТЗ1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_1.Поле1,
ВТ_1.Поле2,
СУММА(ВТ_1.Сумма1) КАК Сумма1
ПОМЕСТИТЬ ВТ_1_Группировка
ИЗ
ВТ_1 КАК ВТ_1
СГРУППИРОВАТЬ ПО
ВТ_1.Поле1,
ВТ_1.Поле2
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ТЗ2.Поле21,
ТЗ2.Поле22,
ТЗ2.Сумма2
ПОМЕСТИТЬ ВТ_2
ИЗ
ТЗ2 КАК ТЗ2
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_2.Поле21,
ВТ_2.Поле22,
СУММА(ВТ_2.Сумма2) КАК Сумма2
ПОМЕСТИТЬ ВТ_2_Группировка
ИЗ
ВТ_2 КАК ВТ_2
СГРУППИРОВАТЬ ПО
ВТ_2.Поле21,
ВТ_2.Поле22
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_1_Группировка.Поле1,
ВТ_1_Группировка.Поле2,
ВТ_1_Группировка.Сумма1,
1 КАК НомерТаблицы
ПОМЕСТИТЬ ВТ_Объединенные
ИЗ
ВТ_1_Группировка КАК ВТ_1_Группировка
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ВТ_2_Группировка.Поле21,
ВТ_2_Группировка.Поле22,
ВТ_2_Группировка.Сумма2,
2
ИЗ
ВТ_2_Группировка КАК ВТ_2_Группировка
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Объединенные.Поле1,
ВТ_Объединенные.Поле2,
СУММА(ВТ_Объединенные.Сумма1) КАК Сумма1,
СУММА(ВТ_Объединенные.НомерТаблицы) КАК НомерТаблицы
ПОМЕСТИТЬ Вариант1
ИЗ
ВТ_Объединенные КАК ВТ_Объединенные
СГРУППИРОВАТЬ ПО
ВТ_Объединенные.Поле2,
ВТ_Объединенные.Поле1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЕСТЬNULL(ВТ_1_Группировка.Поле1, ВТ_2_Группировка.Поле21) КАК Поле1,
ЕСТЬNULL(ВТ_1_Группировка.Поле2, ВТ_2_Группировка.Поле22) КАК Поле2,
СУММА(ЕСТЬNULL(ВТ_1_Группировка.Сумма1, 0) + ЕСТЬNULL(ВТ_2_Группировка.Сумма2, 0)) КАК Сумма,
ВЫБОР
КОГДА НЕ ВТ_1_Группировка.Поле1 ЕСТЬ NULL
И НЕ ВТ_2_Группировка.Поле21 ЕСТЬ NULL
ТОГДА 3
КОГДА ВТ_1_Группировка.Поле1 ЕСТЬ NULL
ТОГДА 2
ИНАЧЕ 1
КОНЕЦ КАК НомерТаблицы
ПОМЕСТИТЬ Варинат2
ИЗ
ВТ_1_Группировка КАК ВТ_1_Группировка
ПОЛНОЕ СОЕДИНЕНИЕ ВТ_2_Группировка КАК ВТ_2_Группировка
ПО ВТ_1_Группировка.Поле1 = ВТ_2_Группировка.Поле21
И ВТ_1_Группировка.Поле2 = ВТ_2_Группировка.Поле22
СГРУППИРОВАТЬ ПО
ЕСТЬNULL(ВТ_1_Группировка.Поле1, ВТ_2_Группировка.Поле21),
ЕСТЬNULL(ВТ_1_Группировка.Поле2, ВТ_2_Группировка.Поле22),
ВЫБОР
КОГДА НЕ ВТ_1_Группировка.Поле1 ЕСТЬ NULL
И НЕ ВТ_2_Группировка.Поле21 ЕСТЬ NULL
ТОГДА 3
КОГДА ВТ_1_Группировка.Поле1 ЕСТЬ NULL
ТОГДА 2
ИНАЧЕ 1
КОНЕЦ
Сам запрос сообщением выше.
ВТ_1 - первая ТЗ.
ВТ_2 - вторая ТЗ.
В конструкторе запроса необходимо описать все поля ТЗ. Наши ТЗ помещаем во временные таблицы.
После этого создаем еще по запросу для каждой ВТ и группируем из по полям и суммируем по сумме.
Далее два возможных варианта
1. Объединение
2. Полное соединение таблиц
В полном соединении связываем по всем полям кроме суммы.
В обоих вариантах группируем поля и суммируем сумму.
Также выведено дополнительное поле чтобы понимать 1 или 2 это таблица, если в результате получаем 3 то сумма из первой и второй таблицы, если 1 то только из первой, если 2 то из второй.
Также выведено дополнительное поле чтобы понимать 1 или 2 это таблица, если в результате получаем 3 то сумма из первой и второй таблицы, если 1 то только из первой, если 2 то из второй.
Это как раз мне подходит! Но как выбрать "Поле1" если при выполнении и выгрузке запроса мы имеем только колонку "Количество"?
В первой таблице могут быть одинаковые строки по трем значениям. Так же и во второй таблице могут быть одинаковые строки по трем значениям.
Во второй таблице могут совпадать строки с первой таблицей. Совпадающие строки должны быть суммированы по полю ЧисловоеПоле. В конечном итоге должно получиться Если совпадают строки то сумма ЧисловоеПоле по совпавшим, иначе для каждой из не совпавших собственное ЧисловоеПоле.
ТЗ1.Свернуть("Хар,Цвет,Пластик","Расход");
ТЗ2.Свернуть("Хар,Цвет,Пластик","Расход");
СтруктураОтбора = Новый Структура;
Для Каждого СтрокаТЗ2 из ТЗ2 Цикл
СтруктураОтбора.Очистить();
СтруктураОтбора.Вставить("Хар", СтрокаТЗ2.Хар);
СтруктураОтбора.Вставить("Цвет", СтрокаТЗ2.Цвет);
СтруктураОтбора.Вставить("Пластик", СтрокаТЗ2.Пластик);
Расход2 = СтрокаТЗ2.Расход;
мНайденныеСтроки = ТЗ1.НайтиСтроки(СтруктураОтбора);
Для Индекс = 0 По мНайденныеСтроки.Количество() - 1 Цикл
СтрокаТЗ1 = мНайденныеСтроки[Индекс];
СтрокаТЗ1.Расход = СтрокаТЗ1.Расход + Расход2;
КонецЦикла;
КонецЦикла;
(10) я может немного не допонял условие задачи.
Но нельзя ли просто в первую таблицу добавить другую (или в копию первой) и вызвать старый добрый Свернуть?
(11)можно. Я просто сначала свернул, потом добавил, чтоб добавлять меньше. Из 25 комментария следует, что так лучше топикстартеру, поскольку так не теряются строчки, которые есть только во второй таблице. Из изначальной постановки было непонятно, что они нужны.
(20) Но в таком случае некоторые уникальные строки из ТЗ_2 суммируются со строками из ТЗ_1 по полю "Расход" А необходимо чтобы если строка уникальна то она имела свой "Расход" а не сплюсованный со строкой из ТЗ_1
Вообще кстати в условии не говорится, что таблица типизирована. Поэтому вариантом решения без запроса будет свертывание по полям ресурсов, затем в цикле перебор строк и поиск методом НайтиСтроки в таблице по структуре полей, затем добавление суммы к сумме в строке суммами из найденных строк.
(37)НайтиСтроки ищет строки целиком.
А все, почему-то, забывают, что у ТС в разных таблицах - может быть что угодно в одинаково названных полях. Вплоть до разных типов данных, кстати.
ТЗ_1.Свернуть("<Поля группировки>", "Сумма");
ТЗ_2.Свернуть("<Поля группировки>", "Сумма");
Для каждого Стр из ТЗ_1 Цикл
МассивСтрокТЗ_2 = ТЗ_2.НайтиСтроки(Новый Структура("<Поля группировки>", <Значения полей>));
Для Каждого Эл из МассивСтрокТЗ_2 Цикл
Стр.Сумма = Стр.Сумма + Эл.Сумма;
КонецЦикла;
КонецЦикла;
(38) тогда делается колонка Источник со значением 1 в первой таблице и 2 в другой.
Таблицы сливаются в одну с суммой по Сумма.
Далее по колонке Источник определяется, есть ли строка в первой таблице (1) или в другой (2) или в обоих (3). Экономнее и быстрее.
(42)в смысле, как определяется? У ТС не указано, какое поле - ключевое, и определяет "эта строка равна той строке".
Там может быть все, что угодно, сравнивать по такой постановке задачи - нужно целиком строка-к-строке, по каждому полю.
(38)у вас таблицы должны быть однозначно типизированы, плюс - определены ключевые поля, которые должны совпадать в обеих таблицах, и быть обязательно заполнены.
Да еще и все <Значения полей> (т.е. предугадать, какие значения - повторные; иначе - грузите все-ко-всему для сравнения) нужно жестко определить и передать.
Т.е. по сути - сравнивается одна и та же таблица сама к себе. Что может в корне отличаться от "авторского" замысла.
Не говоря уже про производительность - на реальных таблицах от тысяч строк все встанет колом (соединение "все-ко-всему").
здесь право нужно топить за массив
Функция ИсключающееИЛИ(Массив1, Массив2)
Результат = Новый Массив;
Повтор = Новый Соответствие;
Для каждого Элемент Из Массив1 Цикл
Повтор[Элемент] = ?(Повтор[Элемент] = Неопределено, Ложь, Истина);
КонецЦикла;
Для каждого Элемент Из Массив2 Цикл
Повтор[Элемент] = ?(Повтор[Элемент] = Неопределено, Ложь, Истина);
КонецЦикла;
Для каждого Элемент Из Повтор Цикл
Если НЕ Элемент.Значение Тогда
Результат.Добавить(Элемент.Ключ);
КонецЕсли
КонецЦикла;
Возврат Результат;//массив
КонецФункции