Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Объединение двух таблиц значений
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 7.7
leo10k10
Тока закончил с одной таблицей как сразу стало ясно что мне для анализа нужна еще одна суть проблемы изложу на примере, и так есть у меня две таблицы значений Список_1 и Список_2 со следующими полями дата, параметр1, параметр2, значение. По сути таблица будет иметь вид:

---------------------Список_1----------------------|-----------------------Список_2---------------------
-ДатаСп_1-|-Пар1_Сп_1-|-Пар2_Сп_1-|-ЗначСп_1-|-ДатаСп_2-|-Пар1_Сп_2-|-Пар2_Сп_2-|-ЗначСп_2-|
01.01.2017-|------АА----|------БА-----|---ЗН_1.1--|02.01.2017-|------АБ----|------БА----|-ЗН_2.1---|
02.01.2017-|------АА----|------БА-----|---ЗН_1.2--|05.01.2017-|------АБ----|------ББ----|-ЗН_2.2---|
03.01.2017-|------АБ----|------ББ-----|---ЗН_1.3--|06.01.2017-|------АВ----|------БВ----|-ЗН_2.3---|
05.01.2017-|------АВ----|------БВ-----|---ЗН_1.4--|
06.01.2017-|------АВ----|------БВ-----|---ЗН_1.5--|

Мне нужно объединить эти две таблицы таким образом что бы при одинаковых параметрах сумировать их значения тоесть результат будет следующим:

------------------СпРезультат------------
-----Пар1----|-----Пар2-----|-Значение------------------| если все значения будут равны 10 то
------АА-------|------БА-------|ЗН_1.1+ЗН_1.2----------|------=20
------АБ-------|------БА-------|ЗН_2.1-------------------|------=10
------АБ-------|------БВ-------|ЗН_1.3+ ЗН_2.2----------|------=20
------АВ-------|------БВ-------|ЗН_1.4+ ЗН_1.5+ЗН_2.3-|------=30

Первым шагом думаю надо Список_1 и Список_2 свернуть по значению относительно параметров вот что вышло
Процедура РезТаб()
    Перем Список_1, Список_2, СпРезультат;
    Перем Запрос, ТекстЗапроса;
    
    Список_1 = СоздатьОбъект("ТаблицаЗначений");
    Список_1.НоваяКолонка("ДатаСп_1", "Дата");
    Список_1.НоваяКолонка ("Пар1_Сп_1", "Строка");
    Список_1.НоваяКолонка ("Пар2_Сп_1", "Строка");
    Список_1.НоваяКолонка ("ЗначСп_1", "Число");
    
    Список_2 = СоздатьОбъект("ТаблицаЗначений");
    Список_2.НоваяКолонка("ДатаСп_2", "Дата");
    Список_2.НоваяКолонка ("Пар1_Сп_2", "Строка");
    Список_2.НоваяКолонка ("Пар2_Сп_2", "Строка");
    Список_2.НоваяКолонка ("ЗначСп_2", "Число");
    
    СвСписок_1 = СоздатьОбъект("ТаблицаЗначений");
    СвСписок_1.НоваяКолонка ("Пар1", "Строка");
    СвСписок_1.НоваяКолонка ("Пар2", "Строка");
    СвСписок_1.НоваяКолонка ("Значение", "Число");
                                                  
    СвСписок_2 = СоздатьОбъект("ТаблицаЗначений");
    СвСписок_2.НоваяКолонка ("Пар1", "Строка");
    СвСписок_2.НоваяКолонка ("Пар2", "Строка");
    СвСписок_2.НоваяКолонка ("Значение", "Число");
    
    СпРезультат = СоздатьОбъект("ТаблицаЗначений");
    СпРезультат.НоваяКолонка ("Пар1", "Строка");
    СпРезультат.НоваяКолонка ("Пар2", "Строка");
    СпРезультат.НоваяКолонка ("Значение", "Число");
    
    Список_1.НоваяСтрока(1);
    Список_1.ДатаСп_1 = "01.01.2017";
    Список_1.Пар1_Сп_1 = "АА";
    Список_1.Пар2_Сп_1 = "БА";
    Список_1.ЗначСп_1 = 10;
    Список_1.НоваяСтрока(2);
    Список_1.ДатаСп_1 = "02.01.2017";
    Список_1.Пар1_Сп_1 = "АА";
    Список_1.Пар2_Сп_1 = "БА";
    Список_1.ЗначСп_1 = 10;
    Список_1.НоваяСтрока(3);
    Список_1.ДатаСп_1 = "03.01.2017";
    Список_1.Пар1_Сп_1 = "АБ";
    Список_1.Пар2_Сп_1 = "ББ";
    Список_1.ЗначСп_1 = 10;
    Список_1.НоваяСтрока(4);
    Список_1.ДатаСп_1 = "05.01.2017";
    Список_1.Пар1_Сп_1 = "АВ";
    Список_1.Пар2_Сп_1 = "БВ";
    Список_1.ЗначСп_1 = 10;
    Список_1.НоваяСтрока(5);
    Список_1.ДатаСп_1 = "06.01.2017";
    Список_1.Пар1_Сп_1 = "АВ";
    Список_1.Пар2_Сп_1 = "БВ";
    Список_1.ЗначСп_1 = 10;
    
    НомСп_1 = 5;
    Для Н = 1 По НомСп_1 Цикл
           Список_1.ПолучитьСтрокуПоНомеру(Н);
    //Сообщить(Шаблон("[Список_1.ДатаСп_1] Х [Список_1.Значение_1]"));
    КонецЦикла;
    
    Список_2.НоваяСтрока(1);
    Список_2.ДатаСп_2 = "02.01.2017";
    Список_2.Пар1_Сп_2 = "АБ";
    Список_2.Пар2_Сп_2 = "БА";    
    Список_2.ЗначСп_2 = 10;
    Список_2.НоваяСтрока(2);
    Список_2.ДатаСп_2 = "05.01.2017";
    Список_2.Пар1_Сп_2 = "АБ";
    Список_2.Пар2_Сп_2 = "ББ";    
    Список_2.ЗначСп_2 = 10;
    Список_2.НоваяСтрока(3);
    Список_2.ДатаСп_2 = "06.01.2017";
    Список_2.Пар1_Сп_2 = "АВ";
    Список_2.Пар2_Сп_2 = "БВ";    
    Список_2.ЗначСп_2 = 10;    
    НомСп_2 = 3;
    
    Для Н = 1 По НомСп_2 Цикл
           Список_2.ПолучитьСтрокуПоНомеру(Н);
    //Сообщить(Шаблон("[Список_2.ДатаСп_2] Х [Список_2.Значение_2]"));
    КонецЦикла;
    
    Список_1.ВыбратьСтроки();
    Список_1.Свернуть("Пар1_Сп_1, Пар2_Сп_1","ЗначСп_1");    
    Список_1.ВыбратьСтроки();
    Пока Список_1.ПолучитьСтроку() = 1 Цикл    
        СвСписок_1.НоваяСтрока();
        СвСписок_1.Пар1 = Список_1.Пар1_Сп_1;
        СвСписок_1.Пар2 = Список_1.Пар2_Сп_1;
        СвСписок_1.Значение = Список_1.ЗначСп_1;
        Сообщить(Шаблон("[СвСписок_1.Пар1] Х [СвСписок_1.Пар2] Х [СвСписок_1.Значение]"));
    КонецЦикла;
              
    Список_2.ВыбратьСтроки();
    Список_2.Свернуть("Пар1_Сп_2, Пар2_Сп_2","ЗначСп_2");    
    Список_2.ВыбратьСтроки();
    Пока Список_2.ПолучитьСтроку() = 1 Цикл    
        СвСписок_2.НоваяСтрока();
        СвСписок_2.Пар1 = Список_2.Пар1_Сп_2;
        СвСписок_2.Пар2 = Список_2.Пар2_Сп_2;
        СвСписок_2.Значение = Список_1.ЗначСп_1;
        Сообщить(Шаблон("[СвСписок_2.Пар1] Х [СвСписок_2.Пар2] Х [СвСписок_2.Значение]"));
    КонецЦикла;


А вот вторым шагом при объединении низнаю как лутше поступить циклом перепроверять одни данные с другими на примере это просто а в реальности там куча значений и параметров что в одной таблице так и в другой по этому думаю лутше зделать объдинение через запрос на основании полученых (свернутых таблиц значений) 64000000.gif .
И вот тут то я заплутался подскажите что не так с етим запросом.

 Запрос = СоздатьОбъект("ВЫБРАТЬ");
    ТекстЗапроса =
    "//{{ЗАПРОС(ВЫБРАТЬ)
    |ВЫБРАТЬ
    |    СвСписок_1.Пар1,
    |    СвСписок_1.Пар2,
    |    СвСписок_1.Значение,
    |ПОМЕСТИТЬ СвСписок_1
    |ИЗ
    |    &СвСписок_1 КАК СвСписок_1
    |;
    |ВЫБРАТЬ
    |    СвСписок_2.Пар1,
    |    СвСписок_2.Пар2,
    |    СвСписок_2.Значение,
    |ПОМЕСТИТЬ СвСписок_2
    |ИЗ
    |    &СвСписок_2 КАК СвСписок_2
    |;
    |ВЫБРАТЬ
    |    СвСписок_1.Пар1,
    |    СвСписок_1.Пар2,
    |    СвСписок_1.Значение,
    |    СвСписок_2.Пар1,
    |    СвСписок_2.Пар2,
    |    СвСписок_2.Значение    
    |ИЗ
    |    СвСписок_1 КАК СпРезультат
    |    ПОЛНОЕ СОЕДИНЕНИЕ СвСписок_2 КАК СвСписок_2
    |    ПО СвСписок_1.Пар1 = СвСписок_2.Пар1, СвСписок_1.Пар2 = СвСписок_2.Пар2";
    |"//}}ЗАПРОС
   ;
    Запрос.УстановитьПараметр("СпРезультат",Параметры.СпРезультат);


Буду благодарен за наглядную помощ.
Batchir
Всё нет так.
1. Что это?
Цитата
Запрос = СоздатьОбъект("ВЫБРАТЬ");

2. Мы ж о 7.7 ? Текст запроса написан под 1С 8

3. Что этим хотели сделать (если отталкиваться от текста запроса)?
Цитата
Запрос.УстановитьПараметр("СпРезультат",Параметры.СпРезультат);
leo10k10
Цитата(Batchir @ 31.03.17, 12:16) необходимо зарегистрироваться для просмотра ссылки
Всё нет так.
1. Что это?
Цитата
Запрос = СоздатьОбъект("ВЫБРАТЬ");
2. Мы ж о 7.7 ? Текст запроса написан под 1С 8

3. Что этим хотели сделать (если отталкиваться от текста запроса)?
Цитата
Запрос.УстановитьПараметр("СпРезультат",Параметры.СпРезультат);


Я ж не спорю что малоумный посему и нахомутал. Пытался слепить нужный для себя запрос на примерах других задач вот и вышел бред сывой кобылы. Для того чтобы розобратся я и прошу Вашей помощи.

Цитата(Batchir @ 31.03.17, 12:16) необходимо зарегистрироваться для просмотра ссылки
3. Что этим хотели сделать (если отталкиваться от текста запроса)?
Цитата
Запрос.УстановитьПараметр("СпРезультат",Параметры.СпРезультат);

этим думал будет создана промежуточная таблица с чотырмя полями Пар_1, Пар_2, Значение_1, Значение_2 но глубоко в душе понимаю что это тоже не то
Batchir
ну Вы пытаетесь использовать методы 8-й версии в 1С 7.7
Это на водит на мысль что Вы не понимаете что пишете и хотите что бы вам дали решение задачи.
К сожалению я уже давно не программирую на 7.7 поэтому подсказать как реализовать эту задачу запросом не смогу.
volodya1122
Ви ж робили подібну задачу для списку значень. Тут можна зробити аналогічно. а вкінці застосувати метод Сортировать, а потім Свернуть (почитайте в справці як працює метод "свернуть". В першім параметері вказуються реквізити по яких потрібно згорнути список, а в другому список реквізитів значення яких сумуються).
leo10k10
Цитата(Batchir @ 31.03.17, 13:17) необходимо зарегистрироваться для просмотра ссылки
К сожалению я уже давно не программирую на 7.7 поэтому подсказать как реализовать эту задачу запросом не смогу.

Спосибо за чесный ответ.

Цитата(volodya1122 @ 31.03.17, 14:22) необходимо зарегистрироваться для просмотра ссылки
Ви ж робили подібну задачу для списку значень. Тут можна зробити аналогічно. а вкінці застосувати метод Сортировать, а потім Свернуть (почитайте в справці як працює метод "свернуть". В першім параметері вказуються реквізити по яких потрібно згорнути список, а в другому список реквізитів значення яких сумуються).

Так дійсно я вже будував одну таблицю на основі двух але її формат як на мене не дозволяє згорнути ту таблицю до потрібного вигляду бо там привязка по даті а мені тепер потрібно привязатися до параметрів і основна проблема в тому, що таблиці мають різну кількість рядків відповідно одному рядку з першої таблиці можуть відповідати три чотири рядки з другої таблиці.
volodya1122
leo10k10 @ Сегодня, 15:14 необходимо зарегистрироваться для просмотра ссылки ,

Або ви нерозумієте логіки методу "Свернуть", або я недокінця розумію вашу задачу...
Кількість рядків немає значення. В результуючій таблиця є дані з першої таблиці і нижче дані з другої таблиці. Тобто в одній результуючій таблиці є вся інформація.
Що далі відбувається:
Піссля заповнення тідсумкової таблиці
пишете СпРезультат.Сортировать("Дата") Дані відсортуються по даті (тепер в вашій таблиці дані будуть в перемішку із першої і другої таблиці, але в порядку зростання дати. Хоча можна цього і неробити, а зразу переходити до слідуючого кроку
Слідуючим кроком
СпРезультат.Свернуть("пар1,пар2","Значення")
в результаті получите таблицю в якій просумуються значення при однаковвих параметрах.


igmig65
Так получится точно, но может это не оптимально:
Перебираете таблицу 1, при получении каждой строки тб1 перебираете тб2, и если (пар1тб1 = пар1тб2) И (пар2тб1 = пар2тб2) суммируете значения.
Это так, по быстрому, что в голову сразу пришло, но 100% можно оптимизировать, нужно подумать.
leo10k10
Цитата(igmig65 @ 01.04.17, 11:19) необходимо зарегистрироваться для просмотра ссылки
Так получится точно, но может это не оптимально:
Перебираете таблицу 1, при получении каждой строки тб1 перебираете тб2, и если (пар1тб1 = пар1тб2) И (пар2тб1 = пар2тб2) суммируете значения.
Это так, по быстрому, что в голову сразу пришло, но 100% можно оптимизировать, нужно подумать.


Да действительно перебором можно добится нужного результатат вот как в этом варианте решения
    Сообщить ("------Варіант рішення №1------");
    
    Список_1.ВыбратьСтроки();
    Список_1.Свернуть("Пар1_Сп_1, Пар2_Сп_1","ЗначСп_1");    
    Список_1.ВыбратьСтроки();
    Пока Список_1.ПолучитьСтроку() = 1 Цикл    
        СвСписок_1.НоваяСтрока();
        СвСписок_1.Пар1 = Список_1.Пар1_Сп_1;
        СвСписок_1.Пар2 = Список_1.Пар2_Сп_1;
        СвСписок_1.Значение = Список_1.ЗначСп_1;
        //Сообщить(Шаблон("[СвСписок_1.Пар1] Х [СвСписок_1.Пар2] Х [СвСписок_1.Значение]"));
    КонецЦикла;
              
    Список_2.ВыбратьСтроки();
    Список_2.Свернуть("Пар1_Сп_2, Пар2_Сп_2","ЗначСп_2");    
    Список_2.ВыбратьСтроки();
    Пока Список_2.ПолучитьСтроку() = 1 Цикл    
        СвСписок_2.НоваяСтрока();
        СвСписок_2.Пар1 = Список_2.Пар1_Сп_2;
        СвСписок_2.Пар2 = Список_2.Пар2_Сп_2;
        СвСписок_2.Значение = Список_2.ЗначСп_2;
        //Сообщить(Шаблон("[СвСписок_2.Пар1] Х [СвСписок_2.Пар2] Х [СвСписок_2.Значение]"));
    КонецЦикла;
    
    СвСписок_1.ВыбратьСтроки();
    СвСписок_2.ВыбратьСтроки();
    к = 0; ном = 0; кк = 0;
    КолСтрокСвСп_1 = СвСписок_1.КоличествоСтрок();
    КолСтрокСвСп_2 = СвСписок_2.КоличествоСтрок(); // здесь нужно применить метод возврата кол.строк в таблице ззначений
    Пока КолСтрокСвСп_1 > к Цикл    
        к = к + 1; сч = 0;
        СвСписок_1.ПолучитьСтрокуПоНомеру(к);
        //Сообщить("Цикл_1." + к);        
        Пока КолСтрокСвСп_2 > сч Цикл
            сч = сч + 1;
            СвСписок_2.ПолучитьСтрокуПоНомеру(сч);             
            //Сообщить ("Цикл_2." + сч);
            //Сообщить(Шаблон("[СвСписок_1.Пар1] Х [СвСписок_1.Пар2] Х [СвСписок_1.Значение]"));
            //Сообщить(Шаблон("[СвСписок_2.Пар1] Х [СвСписок_2.Пар2] Х [СвСписок_2.Значение]"));            
            Если (СвСписок_1.Пар1 = СвСписок_2.Пар1) и (СвСписок_1.Пар2 = СвСписок_2.Пар2) Тогда
                //Сообщить("параметры спосков одинаовы нада соединять в одну сточку");
                ном = ном + 1;
                СпРезПредвар.НоваяСтрока(ном);
                СпРезПредвар.Пар1 = СвСписок_1.Пар1;
                СпРезПредвар.Пар2 = СвСписок_1.Пар2;
                СпРезПредвар.Значение_1 = СвСписок_1.Значение;
                 СпРезПредвар.Значение_2 = СвСписок_2.Значение;
                 // здесь нужно изменить список2 убрать с нево выбраную стоку
                 СвСписок_2.УдалитьСтроку(сч);
                 КолСтрокСвСп_2 = КолСтрокСвСп_2 - 1;
                 Прервать;
            КонецЕсли;
            Если КолСтрокСвСп_2 = сч Тогда
                 ном = ном + 1;
                 СпРезПредвар.НоваяСтрока(ном);
                 СпРезПредвар.Пар1 = СвСписок_1.Пар1;
                 СпРезПредвар.Пар2 = СвСписок_1.Пар2;
                 СпРезПредвар.Значение_1 = СвСписок_1.Значение;
                  СпРезПредвар.Значение_2 = "";                 
                  //Сообщить("Запосной результат_1");
            КонецЕсли;            
        КонецЦикла;
        //Сообщить(Шаблон(ном + "." + "[СпРезПредвар.Пар1] Х [СпРезПредвар.Пар2] Х [СпРезПредвар.Значение_1] Х [СпРезПредвар.Значение_2]"));
    КонецЦикла;
    КолСтрокСвСп_2 = СвСписок_2.КоличествоСтрок();
    Пока КолСтрокСвСп_2 > 0 Цикл
        кк = кк + 1;
        СвСписок_2.ПолучитьСтрокуПоНомеру(кк);
        ном = ном + кк;
        СпРезПредвар.НоваяСтрока(ном);
        СпРезПредвар.Пар1 = СвСписок_2.Пар1;
        СпРезПредвар.Пар2 = СвСписок_2.Пар2;
        СпРезПредвар.Значение_1 = "";
        СпРезПредвар.Значение_2 = СвСписок_2.Значение;    
        КолСтрокСвСп_2 = КолСтрокСвСп_2 - 1;
    КонеЦцикла;
    
    СпРезПредвар.ВыбратьСтроки();
    Для Н = 1 По ном Цикл
    СпРезПредвар.ПолучитьСтрокуПоНомеру(Н);
    //Сообщить(Шаблон("[СпРезПредвар.Пар1] Х [СпРезПредвар.Пар2] Х [СпРезПредвар.Значение_1] Х [СпРезПредвар.Значение_2]"));
    КонецЦикла;
    
    СпРезПредвар.ВыбратьСтроки();
    Пока СпРезПредвар.ПолучитьСтроку() = 1 Цикл    
        СпРезультат.НоваяСтрока();
        СпРезультат.Пар1 = СпРезПредвар.Пар1;
        СпРезультат.Пар2 = СпРезПредвар.Пар2;
        СпРезультат.Значение = СпРезПредвар.Значение_1 + СпРезПредвар.Значение_2;
        Сообщить(Шаблон("[СпРезультат.Пар1] Х [СпРезультат.Пар2] Х [СпРезультат.Значение]"));
    КонецЦикла;


но это далеко не оптимально
а вот volodya1122 как всегда прав ну вопервых в том что я доконца так и не розобрался с методом свернуть и стем что этот вариант проще вот он

    кк = 0;
    КолСтрокСп_1 = Список_1.КоличествоСтрок();
    КолСтрокСп_2 = Список_2.КоличествоСтрок();
    Пока КолСтрокСп_2 > 0 Цикл
        кк = кк + 1;
        Список_2.ПолучитьСтрокуПоНомеру(кк);
        ном = КолСтрокСп_1 + кк;
        Список_1.НоваяСтрока(ном);
        Список_1.ДатаСп_1 = Список_2.ДатаСп_2;
        Список_1.Пар1_Сп_1 = Список_2.Пар1_Сп_2;
        Список_1.Пар2_Сп_1 = Список_2.Пар2_Сп_2;
        Список_1.ЗначСп_1 = Список_2.ЗначСп_2;            
        КолСтрокСп_2 = КолСтрокСп_2 - 1;
    КонеЦцикла;
    //СпРезультат2
    
    Список_1.ВыбратьСтроки();
    Список_1.Свернуть("Пар1_Сп_1, Пар2_Сп_1","ЗначСп_1");    
    Список_1.ВыбратьСтроки();
    Ном = Список_1.КоличествоСтрок();
    Для Н = 1 По Ном Цикл
    Список_1.ПолучитьСтрокуПоНомеру(Н);
    Сообщить(Шаблон("[Список_1.Пар1_Сп_1] Х [Список_1.Пар2_Сп_1] Х [Список_1.ЗначСп_1]"));
    КонецЦикла;


Извените если кого и роздрожал мой глупый вопрос
volodya1122
leo10k10 @ Сегодня, 12:56 необходимо зарегистрироваться для просмотра ссылки ,
цикл ще можна спростити. Там є лишні дії

Список_2.ВыбратьСтроки();
   Пока Список_2.ПолучитьСтроку()=1 Цикл
        //кк = кк + 1;
        //Список_2.ПолучитьСтрокуПоНомеру(кк);
        //ном = КолСтрокСп_1 + кк;
        // Список_1.НоваяСтрока(ном);
        Список_1.НоваяСтрока();
        Список_1.ДатаСп_1 = Список_2.ДатаСп_2;
        Список_1.Пар1_Сп_1 = Список_2.Пар1_Сп_2;
        Список_1.Пар2_Сп_1 = Список_2.Пар2_Сп_2;
        Список_1.ЗначСп_1 = Список_2.ЗначСп_2;            
       // КолСтрокСп_2 = КолСтрокСп_2 - 1;
    КонеЦцикла;
leo10k10
volodya1122 @ Вчера, 17:20 необходимо зарегистрироваться для просмотра ссылки ,
Спосибо
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.