1С 8.3 Сравнение двух таблиц значений
Данные > Примеры кода 1С > 1С 8.3 Таблица значений
Перейти в раздел примеры кода 1С 8.3:
При наличии БСП в конфигурации рекомендуется использовать метод КоллекцииИдентичны (сравнивает две коллекции строк (в т.ч. ТаблицаЗначений), для которых доступен обход посредством оператора Для каждого … Из … Цикл.
Метод N0 Сравнения таблиц значений (полностью) в 1С 8.3:
Функция Сравнить_Две_Таблицы_Значений(ТЗn1, ТЗn2) Экспорт
// Данный метод программно сравнивает две таблицы значений по всем признакам
// Данный метод программно сравнивает две таблицы значений по всем признакам
Если ТипЗнч(ТЗn1) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N1 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТипЗнч(ТЗn2) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N2 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Количество() <> ТЗn2.Количество() Тогда
Сообщить("Количество строк у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Колонки.Количество() <> ТЗn2.Колонки.Количество() Тогда
Сообщить("Количество колонок у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
// Предварительно сортируем обе таблицы по одному и тому же уникальному ключу
ТЗn1.Сортировать("УникКлюч Возр"); // прим. УникКлюч - свой идентиф.
ТЗn2.Сортировать("УникКлюч Возр");
// Преобразуем
СтрВнутрТЗn1 = ЗначениеВСтрокуВнутр(ТЗn1.Скопировать());
СтрВнутрТЗn2 = ЗначениеВСтрокуВнутр(ТЗn2.Скопировать());
Если СтрВнутрТЗn1 <> СтрВнутрТЗn2 Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Сообщить("Параметр N1 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТипЗнч(ТЗn2) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N2 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Количество() <> ТЗn2.Количество() Тогда
Сообщить("Количество строк у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Колонки.Количество() <> ТЗn2.Колонки.Количество() Тогда
Сообщить("Количество колонок у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
// Предварительно сортируем обе таблицы по одному и тому же уникальному ключу
ТЗn1.Сортировать("УникКлюч Возр"); // прим. УникКлюч - свой идентиф.
ТЗn2.Сортировать("УникКлюч Возр");
// Преобразуем
СтрВнутрТЗn1 = ЗначениеВСтрокуВнутр(ТЗn1.Скопировать());
СтрВнутрТЗn2 = ЗначениеВСтрокуВнутр(ТЗn2.Скопировать());
Если СтрВнутрТЗn1 <> СтрВнутрТЗn2 Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Метод N1 Сравнения таблиц значений (аналог типового) в 1С 8.3:
Функция Сравнить_Две_Таблицы_Значений(ТЗn1, ТЗn2) Экспорт
// Данный метод программно сравнивает две таблицы значений по характеристикам и значениям
Если ТипЗнч(ТЗn1) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N1 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТипЗнч(ТЗn2) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N2 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Количество() <> ТЗn2.Количество() Тогда
Сообщить("Количество строк у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Колонки.Количество() <> ТЗn2.Колонки.Количество() Тогда
Сообщить("Количество колонок у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
// Провека полей
Для Каждого КолонкаТЗn Из ТЗn1.Колонки Цикл
Если ТЗn2.Колонки.Найти(КолонкаТЗn.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Для Каждого КолонкаТЗn Из ТЗn2.Колонки Цикл
Если ТЗn1.Колонки.Найти(КолонкаТЗn.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// Формирование строки индекса (для оптимизации поиска по ТЗ)
СтрокаИндексаТЗ = "";
Для Каждого КолонкаТЗn Из ТЗn1.Колонки Цикл
Если СтрокаИндексаТЗ = "" Тогда
СтрокаИндексаТЗ = КолонкаТЗn.Имя;
Иначе
СтрокаИндексаТЗ = СтрокаИндексаТЗ+","+КолонкаТЗn.Имя;
КонецЕсли;
КонецЦикла;
// Вставка индекса
ТЗn2.Индексы.Добавить(СтрокаИндексаТЗ);
// Сравнения имён колонок ТЗ (необязательно если заведомо различны, можно закомментировать)
//Для Каждого СтрокаТаблицы Из ТЗn1 Цикл
// Для Каждого КолонкаТаблицы Из ТЗn1.Колонки Цикл
// Для Каждого СтрокаТаблицы Из ТЗn2 Цикл
// Если СтрокаТаблицы[КолонкаТаблицы.Имя] <> СтрокаТаблицы[КолонкаТаблицы.Имя] Тогда
// Сообщить("Имя колонки ТЗ N1 не совпадает с именем колонки ТЗ N2");
// Возврат Ложь;
// КонецЕсли;
// КонецЦикла;
// КонецЦикла;
//КонецЦикла;
// Проверка записей
Для Каждого СтрокаТаблицы Из ТЗn1 Цикл
СтруктураПоиска = Новый Структура;
Для Каждого Колонка Из ТЗn1.Колонки Цикл
СтруктураПоиска.Вставить(Колонка.Имя, СтрокаТаблицы[Колонка.Имя]);
КонецЦикла;
СтрокиТаблицы = ТЗn2.НайтиСтроки(СтруктураПоиска);
Если СтрокиТаблицы.Количество() <> 1 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// Формирование строки индекса (для оптимизации поиска по ТЗ)
СтрокаИндексаТЗ = "";
Для Каждого КолонкаТЗn Из ТЗn2.Колонки Цикл
Если СтрокаИндексаТЗ = "" Тогда
СтрокаИндексаТЗ = КолонкаТЗn.Имя;
Иначе
СтрокаИндексаТЗ = СтрокаИндексаТЗ+","+КолонкаТЗn.Имя;
КонецЕсли;
КонецЦикла;
// Вставка индекса
ТЗn2.Индексы.Добавить(СтрокаИндексаТЗ);
Для Каждого СтрокаТаблицы Из ТЗn2 Цикл
СтруктураПоиска = Новый Структура;
Для Каждого Колонка Из ТЗn2.Колонки Цикл
СтруктураПоиска.Вставить(Колонка.Имя, СтрокаТаблицы[Колонка.Имя]);
КонецЦикла;
СтрокиТаблицы = ТЗn1.НайтиСтроки(СтруктураПоиска);
Если СтрокиТаблицы.Количество() <> 1 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
// Данный метод программно сравнивает две таблицы значений по характеристикам и значениям
Если ТипЗнч(ТЗn1) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N1 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТипЗнч(ТЗn2) <> Тип("ТаблицаЗначений") Тогда
Сообщить("Параметр N2 не является Таблицой значений");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Количество() <> ТЗn2.Количество() Тогда
Сообщить("Количество строк у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
Если ТЗn1.Колонки.Количество() <> ТЗn2.Колонки.Количество() Тогда
Сообщить("Количество колонок у таблиц значений различное");
Возврат Ложь;
КонецЕсли;
// Провека полей
Для Каждого КолонкаТЗn Из ТЗn1.Колонки Цикл
Если ТЗn2.Колонки.Найти(КолонкаТЗn.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Для Каждого КолонкаТЗn Из ТЗn2.Колонки Цикл
Если ТЗn1.Колонки.Найти(КолонкаТЗn.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// Формирование строки индекса (для оптимизации поиска по ТЗ)
СтрокаИндексаТЗ = "";
Для Каждого КолонкаТЗn Из ТЗn1.Колонки Цикл
Если СтрокаИндексаТЗ = "" Тогда
СтрокаИндексаТЗ = КолонкаТЗn.Имя;
Иначе
СтрокаИндексаТЗ = СтрокаИндексаТЗ+","+КолонкаТЗn.Имя;
КонецЕсли;
КонецЦикла;
// Вставка индекса
ТЗn2.Индексы.Добавить(СтрокаИндексаТЗ);
// Сравнения имён колонок ТЗ (необязательно если заведомо различны, можно закомментировать)
//Для Каждого СтрокаТаблицы Из ТЗn1 Цикл
// Для Каждого КолонкаТаблицы Из ТЗn1.Колонки Цикл
// Для Каждого СтрокаТаблицы Из ТЗn2 Цикл
// Если СтрокаТаблицы[КолонкаТаблицы.Имя] <> СтрокаТаблицы[КолонкаТаблицы.Имя] Тогда
// Сообщить("Имя колонки ТЗ N1 не совпадает с именем колонки ТЗ N2");
// Возврат Ложь;
// КонецЕсли;
// КонецЦикла;
// КонецЦикла;
//КонецЦикла;
// Проверка записей
Для Каждого СтрокаТаблицы Из ТЗn1 Цикл
СтруктураПоиска = Новый Структура;
Для Каждого Колонка Из ТЗn1.Колонки Цикл
СтруктураПоиска.Вставить(Колонка.Имя, СтрокаТаблицы[Колонка.Имя]);
КонецЦикла;
СтрокиТаблицы = ТЗn2.НайтиСтроки(СтруктураПоиска);
Если СтрокиТаблицы.Количество() <> 1 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// Формирование строки индекса (для оптимизации поиска по ТЗ)
СтрокаИндексаТЗ = "";
Для Каждого КолонкаТЗn Из ТЗn2.Колонки Цикл
Если СтрокаИндексаТЗ = "" Тогда
СтрокаИндексаТЗ = КолонкаТЗn.Имя;
Иначе
СтрокаИндексаТЗ = СтрокаИндексаТЗ+","+КолонкаТЗn.Имя;
КонецЕсли;
КонецЦикла;
// Вставка индекса
ТЗn2.Индексы.Добавить(СтрокаИндексаТЗ);
Для Каждого СтрокаТаблицы Из ТЗn2 Цикл
СтруктураПоиска = Новый Структура;
Для Каждого Колонка Из ТЗn2.Колонки Цикл
СтруктураПоиска.Вставить(Колонка.Имя, СтрокаТаблицы[Колонка.Имя]);
КонецЦикла;
СтрокиТаблицы = ТЗn1.НайтиСтроки(СтруктураПоиска);
Если СтрокиТаблицы.Количество() <> 1 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Метод N2 Сравнения таблиц значений (по строкам) в 1С 8.3:
Функция Сравнить_Две_Таблицы_Значений_ПоСтрокам(ТЗn1, ТЗn2, ИзмеренияТЗ) Экспорт
ВсеКолонкиТЗ = "";
Для Каждого Колонка Из ТЗn1.Колонки Цикл
ВсеКолонкиТЗ = ВсеКолонкиТЗ + ", " + Колонка.Имя
КонецЦикла;
ВсеКолонкиТЗ = Сред(ВсеКолонкиТЗ, 2);
ТаблицаТЗn2 = ТЗn2.Скопировать();
ТаблицаТЗn2.Колонки.Добавить("Знак", Новый ОписаниеТипов("Число"));
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Знак");
//разница с методом по столбцам (начало)
Для Каждого Строка Из ТЗn1 Цикл
ЗаполнитьЗначенияСвойств(ТаблицаТЗn2.Добавить(), Строка);
КонецЦикла;
//разница с методом по столбцам (начало)
ТаблицаТЗn2.Колонки.Добавить("Подсчет");
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Подсчет");
ТаблицаТЗn2.Свернуть(ВсеКолонкиТЗ, "Знак, Подсчет");
Результат = ТаблицаТЗn2.Скопировать(Новый Структура("Подсчет", 1), ВсеКолонкиТЗ + ", Знак");
Результат.Сортировать(ИзмеренияТЗ);
Возврат Результат
КонецФункции
ВсеКолонкиТЗ = "";
Для Каждого Колонка Из ТЗn1.Колонки Цикл
ВсеКолонкиТЗ = ВсеКолонкиТЗ + ", " + Колонка.Имя
КонецЦикла;
ВсеКолонкиТЗ = Сред(ВсеКолонкиТЗ, 2);
ТаблицаТЗn2 = ТЗn2.Скопировать();
ТаблицаТЗn2.Колонки.Добавить("Знак", Новый ОписаниеТипов("Число"));
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Знак");
//разница с методом по столбцам (начало)
Для Каждого Строка Из ТЗn1 Цикл
ЗаполнитьЗначенияСвойств(ТаблицаТЗn2.Добавить(), Строка);
КонецЦикла;
//разница с методом по столбцам (начало)
ТаблицаТЗn2.Колонки.Добавить("Подсчет");
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Подсчет");
ТаблицаТЗn2.Свернуть(ВсеКолонкиТЗ, "Знак, Подсчет");
Результат = ТаблицаТЗn2.Скопировать(Новый Структура("Подсчет", 1), ВсеКолонкиТЗ + ", Знак");
Результат.Сортировать(ИзмеренияТЗ);
Возврат Результат
КонецФункции
Метод N3 Сравнения таблиц значений (по столбцам) в 1С 8.3:
Функция Сравнить_Две_Таблицы_Значений_ПоСтолбцам(ТЗn1, ТЗn2, ИзмеренияТЗ) Экспорт
ВсеКолонкиТЗ = "";
Для Каждого Колонка Из ТЗn1.Колонки Цикл
ВсеКолонкиТЗ = ВсеКолонкиТЗ + ", " + Колонка.Имя
КонецЦикла;
ВсеКолонкиТЗ = Сред(ВсеКолонкиТЗ, 2);
ТаблицаТЗn2 = ТЗn2.Скопировать();
ТаблицаТЗn2.Колонки.Добавить("Знак", Новый ОписаниеТипов("Число"));
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Знак");
Для Каждого Строка Из ТЗn1 Цикл
ЗаполнитьЗначенияСвойств(ТаблицаТЗn2.Добавить(), Строка);
КонецЦикла;
//разница с методом по строкам (начало)
Для а = 1 По ТЗn1.Количество() Цикл
ТЗn2.Вставить(0);
КонецЦикла;
Для а = 0 По ТЗn1.Колонки.Количество() - 1 Цикл
ТЗn2.ЗагрузитьКолонку(ТЗn1.ВыгрузитьКолонку(а), а);
КонецЦикла;
//разница с методом по строкам (конец)
ТаблицаТЗn2.Колонки.Добавить("Подсчет");
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Подсчет");
ТаблицаТЗn2.Свернуть(ВсеКолонкиТЗ, "Знак, Подсчет");
Результат = ТаблицаТЗn2.Скопировать(Новый Структура("Подсчет", 1), ВсеКолонкиТЗ + ", Знак");
Результат.Сортировать(ИзмеренияТЗ);
Возврат Результат
КонецФункции
ВсеКолонкиТЗ = "";
Для Каждого Колонка Из ТЗn1.Колонки Цикл
ВсеКолонкиТЗ = ВсеКолонкиТЗ + ", " + Колонка.Имя
КонецЦикла;
ВсеКолонкиТЗ = Сред(ВсеКолонкиТЗ, 2);
ТаблицаТЗn2 = ТЗn2.Скопировать();
ТаблицаТЗn2.Колонки.Добавить("Знак", Новый ОписаниеТипов("Число"));
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Знак");
Для Каждого Строка Из ТЗn1 Цикл
ЗаполнитьЗначенияСвойств(ТаблицаТЗn2.Добавить(), Строка);
КонецЦикла;
//разница с методом по строкам (начало)
Для а = 1 По ТЗn1.Количество() Цикл
ТЗn2.Вставить(0);
КонецЦикла;
Для а = 0 По ТЗn1.Колонки.Количество() - 1 Цикл
ТЗn2.ЗагрузитьКолонку(ТЗn1.ВыгрузитьКолонку(а), а);
КонецЦикла;
//разница с методом по строкам (конец)
ТаблицаТЗn2.Колонки.Добавить("Подсчет");
ТаблицаТЗn2.ЗаполнитьЗначения(1, "Подсчет");
ТаблицаТЗn2.Свернуть(ВсеКолонкиТЗ, "Знак, Подсчет");
Результат = ТаблицаТЗn2.Скопировать(Новый Структура("Подсчет", 1), ВсеКолонкиТЗ + ", Знак");
Результат.Сортировать(ИзмеренияТЗ);
Возврат Результат
КонецФункции
3
комментарии
Юрий
03 май 2024
Если интересует просто равенство, а не поиск различий, то работает "ТаблицаЗначений1 = ТаблицаЗначений2"
Сток
16 сен 2021
Смотрите код - первый метод будет более универсальный. Второй метод сравнивает строки, третий - столбцы. Методы различные и каждый будет актуален для определенной ситуации.
а
16 сен 2021
ну так какой чем лучше?
____________________
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник