Имя: Пароль:
1C
1С v8
Знатокам общих модулей типовых. Сравнить таблицы значений. Есть готовенькое?
0 fisher
 
20.08.12
12:44
Таблицы изначально не совсем одинаковы по структуре.
Необходимо сравнивать значения в указанных колонках первой таблицы со значениями в указанных колонках второй таблицы. Результат - просто булево. Одинаковы таблицы или нет. Ессно сортировка одинакова, разное количество строк - сразу возвращает ложь и т.п.
Возникла такая вот необходимость и уже бросился было писать, но притормозил. А вдруг, думаю, велосипед изобретаю? Сравнение структур таблиц в типовых нашел. А такой фигни как мне нужно случайно нету?
1 Axel2009
 
20.08.12
12:45
в инструментах разработчика есть сравнение таблиц в консоли запросов
2 Ненавижу 1С
 
гуру
20.08.12
12:45
Функция СравнитьТаблицыЗначений(ТаблицаЗначений1, ТаблицаЗначений2)

   Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда
       Возврат Ложь;
   КонецЕсли;
   
   Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда
       Возврат Ложь;
   КонецЕсли;

   Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда
       Возврат Ложь;
   КонецЕсли;

   Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
       
       Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
           Возврат Ложь;
       КонецЕсли;
       
       Для каждого СтрокаТаблицы Из ТаблицаЗначений1 Цикл
       
           Попытка
           
               Если СтрокаТаблицы[Колонка.Имя] <> ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы)][Колонка.Имя] Тогда
               
                   Возврат Ложь;
               
               КонецЕсли;
           
           Исключение
               
               Возврат Ложь;
               
           КонецПопытки;
       
       КонецЦикла;
   
   КонецЦикла;
   
   Возврат Истина;
   
КонецФункции
3 fisher
 
20.08.12
12:51
(2) Это видел... Но мне чуть другое надо. Надо сравнивать разноименные колонки (передавать соответствие). Количество колонок тоже неодинаково в исходных таблицах. Понятно, что ничего сложного... Раз нету - допилим.
4 mikeA
 
20.08.12
13:05
(3) колонки переименуй
5 Reset
 
20.08.12
13:11
(3) Изменить-то только строку
"Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл", чтоб не из колонок, а из параметра имена брало
и обращение к имени вместо .Имя на .Ключ и .Значение
6 fisher
 
20.08.12
13:15
(5) Да сделал уже. Спасибо. Получилось вот такое, если охота попинать (там еще немного специфики для моих задач):

// Функция - возвращает результат сравнения таблицы с другой таблицей и константами (опционально)
//
// Параметры:
//    ОсновнаяТаблица - таблица, для которой производится анализ
//  СравниваемаяТаблица - таблица, данные которой сравниваются с основной таблицей
//    СтруктураСравниваемыхКолонок - структура, ключами которой выступают имена колонок основной таблицы, а значениями - связанные имена колонок сравниваемой таблицы
//    СтруктураСравниваемыхКонстант - структура, ключами которой выступают имена колонок основной таблицы, а значениями - константы, сравниваемые со значениями в колонках основной таблицы
//
// Возвращаемое значение:
//    истина, если указанные данные таблиц идентичны и ложь - в противном случае
//
Функция СравнитьДанныеТаблиц(ОсновнаяТаблица, СравниваемаяТаблица, СтруктураСравниваемыхКолонок, СтруктураСравниваемыхКонстант = Неопределено)
   
   КоличествоСтрок = ОсновнаяТаблица.Количество();
   
   Если КоличествоСтрок <> СравниваемаяТаблица.Количество() Тогда
       Возврат Ложь;
   КонецЕсли;
   
   Если КоличествоСтрок = 0 Тогда
       Возврат Истина;
   КонецЕсли;
   
   ДанныеИдентичны = Истина;
   
   Для ИндексСтроки = 0 По КоличествоСтрок - 1 Цикл
       
       Для Каждого Элемент Из СтруктураСравниваемыхКолонок Цикл
           Если ОсновнаяТаблица[ИндексСтроки][Элемент.Ключ] <> СравниваемаяТаблица[ИндексСтроки][Элемент.Значение] Тогда
               ДанныеИдентичны = Ложь;
               Прервать;
           КонецЕсли;
       КонецЦикла;
       
       Если НЕ ДанныеИдентичны Тогда
           Прервать;
       КонецЕсли;
       
       Если СтруктураСравниваемыхКонстант <> Неопределено Тогда
       
           Для Каждого Элемент Из СтруктураСравниваемыхКонстант Цикл
               Если ОсновнаяТаблица[ИндексСтроки][Элемент.Ключ] <> Элемент.Значение Тогда
                   ДанныеИдентичны = Ложь;
                   Прервать;
               КонецЕсли;
           КонецЦикла;
           
           Если НЕ ДанныеИдентичны Тогда
               Прервать;
           КонецЕсли;
           
       КонецЕсли;    
       
   КонецЦикла;
   
   Возврат ДанныеИдентичны;
   
КонецФункции
7 fisher
 
20.08.12
13:15
Еще не тестил :)
8 Fragster
 
гуру
20.08.12
13:21
сгенерированный текст запроса с объединением...
9 Fragster
 
гуру
20.08.12
13:22
а циклы в цикле - лажа
10 fisher
 
20.08.12
13:26
Годный вброс :)
11 Reset
 
20.08.12
13:27
(6) Я бы количество на 0 не проверял, т.к. и без этого сработает правильно, а, исходя из того, что таблицы (вероятно) будут не пустые,как правило, эта проверка будет отрабатывать лишний раз вхолостую.
Проверка констант просится в отдельную функцию, т.к. вроде к сравнению таблиц не относится (хотя может это требование специфики)
Внешним циклом я бы сделал цикл по именам, "скешировав" их в переменные, чтобы при переборе строк не обращаться к элементам структуры

Хотя это все мелочи, чисто если задаться целью подокапываться ;)
12 fisher
 
20.08.12
13:30
(11) Согласен, что скрестил ежа и ужа... В разных функциях правильнее. Чисто под мою задачу заточка. Там оно всегда парно проверяется.
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший