Сравнение таблиц значений (табличных частей)

06.12.13

Разработка - Математика и алгоритмы

Задача такова, сравнить 2 таблицы значений (Табличные части) и выдать результат, о том что в них изменилось, применительно к реальной задаче будет звучать так, показать пользователю что изменилось в документе.

Скачать файлы

Наименование Файл Версия Размер
ПримерСравниванияТЗПоСтрокамСИспользованиемУдельногоВеса.epf
.epf 7,05Kb
40
.epf 7,05Kb 40 Скачать бесплатно

Всем Привет!

Данная публикация в основном рассчитана на новичков, но надеюсь что и бывалые найдут что то полезное.

Собственно задача можно сказать несложная, но готовых вариантов я не увидел на просторах интернета.

Задача такова, сравнить 2 таблицы значений (Табличные части) и выдать результат, о том что в них изменилось, применительно к реальной задаче будет звучать так, показать пользователю что изменилось в документе. Допустим пусть это будут 2 разные версии объектов записанные в ИБ, конечно многие могут сказать (или подумать) может быть научить пользователя пользоваться обработкой История изменений объектов. Всё конечно хорошо в теории, но История изменения объектов (допустим УПП 1.3.38.3) обладает рядом недостатков, а именно:

  1. При версии объекта больше 999 при работе вызывает ошибку, оно и понятно разработчики не позаботились о корректном переводе (Строка – Число и обратно), но да бог с ними, не об этом речь.
  2. Обработка сравнивает табличные части по индексам, т.е. если строка будет перемещена с 1-й на 3-ю позицию, обработка покажет изменения, а они были? Тоже думаю что нет.

Накидал небольшой кусочек кода, как выкрутится из такой ситуации.

  1. Дано:

Таблица значений эталон, с ней будем сравнивать.

 

 

Таблица значений, которую  будем сравнивать.

 

Колонки «ВесСтроки, Идентификатор,БылВыбран» были добавлены для успешного анализа.

 2. Думаю описывать заполнение таблиц нет смысла, они должны у нас уже быть по задаче, отмечу только что для успешной обработки нам понадобится дополнительная структура «СтруктураВеса».

Дело в том что, при таком подходе мы сможем более  гибко настроить алгоритм для соответствия строк.

 

Возьмём пример из таблиц Выше

Строка Номер 2 в обоих таблицах содержит всего 1 изменение , а если их будет 2 и более ?

Ответ прост, при таком подходе мы можем легко настроить алгоритм так, что при совпадении только по номенклатуре  строки сопоставятся или нет, а если изменят только номенклатуру и остальные значения в строке будут нетронутыми сопоставлять ли такие строки или нет? Именно за этим мы и делаем табличку с весом значимости колонки.

 3. Так же нам понадобится таблица куда мы будем записывать результат работы алгоритма, рисунок уже после отработки алгоритма.

 

Как видим имея такую табличку, соединяя через неё сравниваемые таблицы мы всегда можем показать пользователям, что было изменено, добавлено, удалено, осталось без изменений и это всё без привязки к конкретной строке, анализируются все строки.

 

Собственно весь код ниже, так же выкладываю обработку с примером.


Функция ПровестиАнализ(ТЗИсточник,ТЗПриемник,ТЗАнализ,МассивКолонок,СтруктураВеса)

    Для Каждого Строка из ТЗИсточник Цикл
       
МаксимальныйПорог   = СтруктураВеса.Количество() + 1;
       
МинимальныйПорог    = 3;
       
ТЗПриемник.ЗаполнитьЗначения(0,"ВесСтроки");
        Для Каждого
СтрокаПоиска из ТЗПриемник Цикл
            Если
СтрокаПоиска.БылВыбран Тогда
                Продолжить;
            КонецЕсли;
           
ВесСтроки = 0;
            Для каждого
Колонка Из МассивКолонок Цикл
               
ЗначениеИсточник = Строка[Колонка];
               
ЗначениеПриемник = СтрокаПоиска[Колонка];
                Если
СтруктураВеса.Свойство(Колонка) Тогда
                    
Вес = СтруктураВеса[Колонка];
                Иначе
                     Продолжить;
                КонецЕсли;
                Если
ЗначениеИсточник = ЗначениеПриемник Тогда
                   
ВесСтроки = ВесСтроки + Вес;
                КонецЕсли;
            КонецЦикла;
           
СтрокаПоиска.ВесСтроки = ВесСтроки;
        КонецЦикла;

       
ТЗПриемник.Сортировать("ВесСтроки Убыв, БылВыбран Убыв");

        Для Каждого
СтрокаПоиска из ТЗПриемник Цикл
            Если
СтрокаПоиска.БылВыбран Тогда
                Продолжить;
            КонецЕсли;

            Если СтрокаПоиска.ВесСтроки = МаксимальныйПорог Тогда
                СтрокаПоиска.БылВыбран = Истина;
               
НоваяСтрока = ТЗАнализ.Добавить();
               
НоваяСтрока.ИдентификаторИсточник = СтрокаПоиска.Идентификатор;
               
НоваяСтрока.ИдентификаторПриемник = Строка.Идентификатор;
               
НоваяСтрока.Состояние = "Совпадение";
                Прервать;
            ИначеЕсли
СтрокаПоиска.ВесСтроки >= МинимальныйПорог Тогда
               
СтрокаПоиска.БылВыбран = Истина;
               
НоваяСтрока = ТЗАнализ.Добавить();
               
НоваяСтрока.ИдентификаторИсточник = СтрокаПоиска.Идентификатор;
               
НоваяСтрока.ИдентификаторПриемник = Строка.Идентификатор;
               
НоваяСтрока.Состояние = "Изменен";
                Прервать;
            ИначеЕсли
СтрокаПоиска.ВесСтроки < МинимальныйПорог Тогда
               
НоваяСтрока = ТЗАнализ.Добавить();
               
НоваяСтрока.ИдентификаторИсточник = СтрокаПоиска.Идентификатор;
               
НоваяСтрока.Состояние = "Удален";
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;

   
Отбор = Новый Структура;
   
Отбор.Вставить("БылВыбран", Ложь);
   
НайденныеСтроки = ТЗПриемник.НайтиСтроки(Отбор);

    Для Каждого
НайденнаяСтрока из НайденныеСтроки Цикл
       
СтрокаПоиска.БылВыбран = Истина;
       
НоваяСтрока = ТЗАнализ.Добавить();
       
НоваяСтрока.ИдентификаторПриемник = НайденнаяСтрока.Идентификатор;
       
НоваяСтрока.Состояние = "Добавлен";
    КонецЦикла;

    Возврат
ТЗАнализ;

КонецФункции
// ПровестиАнализ(ТЗИсточник,ТЗПриемник,ТЗАнализ)
 

Надеюсь статья была полезной.

См. также

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8822    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16144    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7243    quazare    8    

109

Хитрости СКД. Часть 3

СКД Универсальные функции Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

Столкнулся с тем, что мне приходится писать гору отчетов. Во многих приходится использовать повторяющиеся приемы. Решил написать шпаргалку, которая, надеюсь пригодится не только мне. В этой статье: Объединение ячеек в отчете только на определенном уровне иерархии, Постобработка итогов в табличном документе, Скрытие колонок в зависимости от количества месяцев в периоде.

28.05.2022    9294    milkers    11    

94

Модули общего назначения - готовые полезные функции и процедуры конфигураций на БСП

Универсальные функции БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данной статье я рассматриваю несколько полезных "классических" функций и процедур для работы с данными, которые уже встроены в БСП и готовы к использованию.

25.04.2022    14981    quazare    11    

138

Несколько простых приемов для удобной работы в конфигураторе

Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Простая и удобная среда разработки 1С:Предприятия позволяет практически любому человеку начать работать под капотом 1С - в конфигураторе. Время идет, новички становятся программистами, специалистами, а об удобных приемах работы узнают годами, по ходу своего карьерного пути. А здорово было бы, если бы все знали удобные приемы в начале своего пути? Эти несколько приемов будут полезны новичкам, так как они затрагивают ту область работы, с которой приходится сталкиваться в начале карьеры.

12.11.2021    17467    acces969    95    

148
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kwazi 615 07.12.13 12:56 Сейчас в теме
в бсп есть подсистема версионирование и есть отчет по сравнению версий там уже все есть
2. echo77 1868 07.12.13 19:28 Сейчас в теме
(1) Автор пишет о существовании нескольких багов этого отчета.
Я бы взял этот отчет за основу и допилил
3. Xatori111 18 07.12.13 22:11 Сейчас в теме
(2)Это всего лишь пример как можно сравнить таблицы, а отчёт допилить не проблема, вопрос надо ли?
Дмитрий74Чел; +1 Ответить
4. Yashazz 4709 08.12.13 12:07 Сейчас в теме
1. Таких сравнивалок для таблиц значений уже было вагон, и я не понимаю, почему авторы почти всех их делают НЕ через запрос.
2. Если делать не для себя, а для пользователя, то я бы предложил игры с самим интерфейсом документа (например, изменить фон нужных полей и ячеек табчастей другим цветом, для изменившихся/добавленных итд, вопрос только про удалённые).
5. Поручик 4670 09.12.13 07:58 Сейчас в теме
(4) Сделай через запрос, оценим поделие.
Evil Beaver; +1 Ответить
6. Yashazz 4709 09.12.13 23:23 Сейчас в теме
(5) Изволите желать через СКД, да с наборами, аль бо по-простому, в обычном запросе? )))
7. Поручик 4670 09.12.13 23:55 Сейчас в теме
(6) Сделайте весь список, пожалуйста. Я бы не отказался посмотреть на СКД с наборами
8. soap 65 11.12.13 15:14 Сейчас в теме
Для обычного запроса как то так простейший пример

ТЗ1=Новый ТаблицаЗначений ;
ТЗ2=Новый ТаблицаЗначений;
ТЗ1.Колонки.Добавить("П1");
ТЗ1.Колонки.Добавить("П2");
ТЗ1.Колонки.Добавить("П3");
ТЗ2.Колонки.Добавить("П1");
ТЗ2.Колонки.Добавить("П2");
ТЗ2.Колонки.Добавить("П3");

Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(ТЗ1.П1,ТЗ2.П1) КАК П1,
| ЕСТЬNULL(ТЗ1.П1,1) КАК Удалено,
| ЕСТЬNULL(ТЗ2.П1,2) КАК Добавлено,
| ТЗ1.П2 КАК П2_Начальное ,
| ТЗ2.П2 КАК П2_Текущее ,
| ТЗ1.П3 КАК П3_Начальное ,
| ТЗ2.П3 КАК П3_Текущее,
| ВЫБОР
| Когда ТЗ1.П2<>ТЗ2.П2
| Тогда 3
| ИНАЧЕ 4
| КОНЕЦ КАК ИзмененоП2,
| ВЫБОР
| Когда ТЗ1.П3<>ТЗ2.П3
| Тогда 3
| ИНАЧЕ 4
| КОНЕЦ КАК ИзмененоП3
| ИЗ
| ТЗ1 КАК ТЗ1
| ПОЛНОЕ СОЕДИНЕНИЕ ТЗ2 КАК ТЗ2
| ПО ТЗ2.П1=ТЗ2.П1";
9. amyd 94 12.12.13 10:03 Сейчас в теме
тоже самое, но на основе запросов, все же перебирать табличные части, пускай и в цикле, "мовитон", особенно если ТЗ за 5000 записей.
сначала хотел вывести "контр публикацию" с ссылкой на эту, но уж очень хорошо расписана, поэтому просто дополню в комментарии своей процедурой сравнения на основе запросов
функция ТабличныеЧастиРазныеУлучшенная(ТаблицаДо,ТаблицаПосле,ТаблицаРасхождений=неопределено) экспорт
	//ТаблицаДо=док.Товары.Выгрузить();
	//	ТаблицаПосле=док.Товары.Выгрузить();
	ТекстЗапроса="Выбрать ";	
	
	для каждого эл из ТаблицаДо.Колонки цикл
		если эл.Имя="КлючСтроки" тогда
			продолжить;
		конецесли;
		ТекстЗапроса = ТекстЗапроса +"
		| ТТДо."+эл.Имя+",";
	конеццикла;
	ТекстЗапроса=Лев(ТекстЗапроса,стрдлина(ТекстЗапроса)-1);
	ТекстЗапроса = ТекстЗапроса+"
	|поместить ТаблоДо 
	|из 
	|	&ТабДо как ТТДо
	|;	
	|Выбрать";
	для каждого эл из ТаблицаДо.Колонки цикл
		если эл.Имя="КлючСтроки" тогда
			продолжить;
		конецесли;
		
		ТекстЗапроса = ТекстЗапроса +"
		| ТТПосле."+эл.Имя+",";
	конеццикла;
	ТекстЗапроса=Лев(ТекстЗапроса,стрдлина(ТекстЗапроса)-1);	
	ТекстЗапроса = ТекстЗапроса+"
	|поместить ТаблоПосле 
	|из 
	|	&ТабПосле как ТТПосле
	|;
	|выбрать" ;
	для каждого эл из ТаблицаДо.Колонки цикл
		если эл.Имя="КлючСтроки" тогда
			продолжить;
		конецесли;
		
		ТекстЗапроса = ТекстЗапроса +"
		| Сборочный."+эл.Имя+",";
	конеццикла;
	ТекстЗапроса = ТекстЗапроса+"
	| ЕстьNULL(сумма(Сборочный.Контроль),0) как Контроль
	|из 
	|	(
	|выбрать " ;
	для каждого эл из ТаблицаДо.Колонки цикл
		если эл.Имя="КлючСтроки" тогда
			продолжить;
		конецесли;
		
		ТекстЗапроса = ТекстЗапроса +"
		| ТаблоДо."+эл.Имя+",";
	конеццикла;
	ТекстЗапроса = ТекстЗапроса+"
	|   -1 как Контроль
	| из  ТаблоДо как ТаблоДо
	|	 
	|Объединить все
	|
	| Выбрать ";
	для каждого эл из ТаблицаДо.Колонки цикл
		если эл.Имя="КлючСтроки" тогда
			продолжить;
		конецесли;
		
		ТекстЗапроса = ТекстЗапроса +"
		| ТаблоПосле."+эл.Имя+",";
	конеццикла;
	ТекстЗапроса = ТекстЗапроса+"
	|   1
	| из  ТаблоПосле как ТаблоПосле
	| ) как Сборочный
	| сгруппировать по";
	для каждого эл из ТаблицаДо.Колонки цикл
		если эл.Имя="КлючСтроки" тогда
			продолжить;
		конецесли;
		
		ТекстЗапроса = ТекстЗапроса +"
		| Сборочный."+эл.Имя+",";
	конеццикла;
	ТекстЗапроса=Лев(ТекстЗапроса,стрдлина(ТекстЗапроса)-1);	
	
	запр = новый Запрос(ТекстЗапроса);
	
	Запр.УстановитьПараметр("ТабДо",ТаблицаДо);
	Запр.УстановитьПараметр("ТабПосле",ТаблицаПосле);
	
	ВЫЗаДН = запр.Выполнить().Выгрузить();
	ТаблицаРасхождений=ВЫЗаДН.Скопировать();
	если ВЫЗаДН.найти(1,"контроль")<> неопределено или ВЫЗаДН.найти(-1,"контроль")<>неопределено тогда
		возврат истина;
	иначе
		возврат ложь;
	конецесли;
	
	
конецфункции	
Показать
Оставьте свое сообщение