Функция сравнения значений (рекурсивно)

30.12.22

Разработка - Универсальные функции

Позволяет сравнивать значение с эталонным как строго (точное совпадение полей, количества и последовательности элементов массивов), так и не строго (все элементы эталона есть в значении).

Для расширения Атташе, которое я скоро представлю на ваш суд (что это такое и для чего нужно, пока рассказывать не стану, сохраню интригу ;)) потребовалась возможность рекурсивного сравнения "сложных" значений. Например структур, массивов, соответствий. В итоге родилась функция, которой я и решил поделиться с сообществом:

Функция СравнитьЗначения(
    Значение, 
    Эталон, 
    ВызыватьИсключение=Ложь, 
    СтрогоеСравнение=Ложь, 
    СтрогоеСравнениеМассивов=Неопределено, 
    СтрогоеСравнениеСтруктур=Неопределено, 
    СтрогоеСравнениеСоответствий=Неопределено
)

Описание параметров:

Значение - сравниваемое значение. Может быть скалярным значением, а так же массивом, структурой или соответствием;

Эталон - эталонное значение, с которым будет сравниваться значение. Ожидается, что Значение будет того же типа и иметь ту же структуру, что и Эталон. Подробнее см. параметр СтрогоеСравнение;

ВызыватьИсключение - Если Истина - функция вызовет исключение с текстом описывающим на каком этапе произошла ошибка сравнения. Если Ложь - исключение вызвано не будет, а текст, описывающий ошибку сравнения функция вернёт в качестве результата. Если параметр имеет тип "Строка", то эта строка будет добавлена первой строкой к описанию ошибки сравнения если таковая произойдёт. Не обязательный. По умолчанию Ложь;

СтрогоеСравнение - общая настройка строгого сравнения. Если Истина - Значение должно полностью соответствовать Эталону. Наличие лишних полей и элементов не допускается. Порядок элементов в массиве так же важен. Если Ложь - Значение может содержать больше полей и/или элементов. Порядок элементов в массивах не важен. Главное чтобы все поля и элементы из Эталона содержались в Значении. Не обязательный. По умолчанию Ложь;

СтрогоеСравнениеМассивов - настройка строгости сравнения массивов. Имеет то же действие, что и СтрогоеСравнение, но распространяется только на массивы содержащиеся в Значении; Не обязательный. По умолчанию используются настройки заданные параметром СтрогоеСравнение;

СтрогоеСравнениеСтруктур - аналогично СтрогоеСравнениеМассивов, но действует только на структуры внутри значения;

СтрогоеСравнениеСоответствий - аналогично СтрогоеСравнениеМассивов, но действует только на соответствия внутри значения;

Возвращаемое значение

Функция возвращает Истина если Значение подходит к Эталону с учётом критериев строгого сравнения. В противном случае возвращает строку описывающую на каком этапе сравнения произошла ошибка. Если значение параметра ВызыватьИсключение равно Истина, в случае ошибки сравнения вместо возврата будет вызвано исключение с тем же текстом. Если ВызыватьИсключение имеет тип строка - текст исключения будет дополнен спереди этой строкой. Это удобно для сравнений в цикле, чтобы получать, например, номер итерации в тексте исключения и в некоторых других случаях.

Примеры использования

Пример 1
Результат = СравнитьЗначения(
	СтрРазделить("Мама мыла раму", " "),
	СтрРазделить("Мама мыла папу", " ")
);

// Результат = "Элемент эталона [2] не найден в массиве"
Пример 2 
Результат = СравнитьЗначения(
	СтрРазделить("Мама мыла раму и папу", " "),
	СтрРазделить("Мама мыла папу", " "),
);

// Результат = Истина
Пример 3
Результат = СравнитьЗначения(
	Новый Структура("Имя, Фамилия, ГодРождения, Обучение", 
		"Вася", 
		"Иванов", 
		1990, 
		Новый Структура("НомерДетСада, НомерШколы, НазваниеИнститута",
			13,
			1252,
			"МГУ"
		)
	),
	Новый Структура("Имя, Фамилия, ГодРождения, Обучение", 
		"Вася", 
		"Иванов", 
		1990, 
		Новый Структура("НазваниеИнститута",
			"МЭИ"
		)
	),
	"Ошибка на итерации №5"
);

// Вызовет исключение с текстом: Ошибка на итерации №5:
//                               Ошибка в поле Обучение:
//                               Ошибка в поле НазваниеИнститута:
//                               Значение (МГУ) не равно эталону (МЭИ)

 

Полный текст функции

// Сравнивает значение с эталоном. Удобно использовать 
// для тестирования
//
// Параметры:
//	Значение - Произвольный - значение, которое надо сравнить с эталонным
//	Эталон - Произвольный - эталонное значение, с которым будет сравниваться Значение
//  ВызыватьИсключение - Булево, Строка - вызвать исключение если значение не соответствует эталону
//								          Если задана строка - она будт использована при вызове исключения в качестве первой строки
// 										  (не обязательный) - по умолчанию Ложь (не вызывать)
//	СтрогоеСравнение - Булево - тип сравнения по умолчанию. 
//								Ложь - проверять только наличие элементов эталона в значении
//								Истина - проверять полное соответствие значения эталону
//								(не обязательный) - по умолчанию Ложь
//	СтрогоеСравнениеМассивов - Булево, Неопределено - тип сравнения для массивов. Если Неопределено
//													 используется параметр СтрогоеСравнение
//													 (не обязательный) - по умолчание Неопределено
//	СтрогоеСравнениеСтруктур - Булево, Неопределено - тип сравнения для структур. Если Неопределено
//													 используется параметр СтрогоеСравнение
//													 (не обязательный) - по умолчание Неопределено
//	СтрогоеСравнениеСоответствий - Булево, Неопределено - тип сравнения для соответствий. Если Неопределено
//													 используется параметр СтрогоеСравнение
//													 (не обязательный) - по умолчание Неопределено
//
// Возвращаемое значение:
//	Булево, Строка - Истина - значение соответствует эталону
//			 		Строка - описание несоответствия
//
Функция СравнитьЗначения(Значение, Эталон, ВызыватьИсключение=Ложь, СтрогоеСравнение=Ложь, СтрогоеСравнениеМассивов=Неопределено, СтрогоеСравнениеСтруктур=Неопределено, СтрогоеСравнениеСоответствий=Неопределено) Экспорт
	
	Если ТипЗнч(Значение) <> ТипЗнч(Эталон) Тогда
		Результат = СтрШаблон("Тип значения: %1 не равен типу эталона: %2", ТипЗнч(Значение), ТипЗнч(Эталон));
	ИначеЕсли ТипЗнч(Значение) = Тип("Массив") Тогда
		#Область СравнениеМассивов
		Если Значение.Количество() < Эталон.Количество() Тогда
			Результат = СтрШаблон("Количество элементов в массиве (%1) меньше чем в эталоне (%2)", Значение.Количество(), Эталон.Количество());
		ИначеЕсли ?(СтрогоеСравнениеМассивов = Неопределено, СтрогоеСравнение, СтрогоеСравнениеМассивов) Тогда
			// Сравнить строго
			Результат = Истина;
			Если Значение.Количество() <> Эталон.Количество() Тогда
				Результат = СтрШаблон("Количество элементов в массиве (%1) не равно количеству в эталоне (%2)", Значение.Количество(), Эталон.Количество());;
			Иначе
				Для Индекс = 0 По Значение.Количество()-1 Цикл
					РезультатСравнения = СравнитьЗначения(Значение[Индекс], Эталон[Индекс], Ложь, СтрогоеСравнение, СтрогоеСравнениеМассивов, СтрогоеСравнениеСтруктур, СтрогоеСравнениеСоответствий);
					Если РезультатСравнения <> Истина  Тогда
						Результат = СтрШаблон("Ошибка в элементе [%1]:
								|", Индекс) + РезультатСравнения;
						Прервать;
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
		Иначе
			// Сравнить не строго
			Результат = Истина;
			Индекс = 0;
			Для Каждого ЭлементЭталона Из Эталон Цикл
				НайденЭлементЗначения = Ложь;
				Для Каждого ЭлементЗначения Из Значение Цикл
					Если Истина = СравнитьЗначения(ЭлементЗначения, ЭлементЭталона, Ложь, СтрогоеСравнение, СтрогоеСравнениеМассивов, СтрогоеСравнениеСтруктур, СтрогоеСравнениеСоответствий) Тогда
						НайденЭлементЗначения = Истина;
						Прервать;
					КонецЕсли;
				КонецЦикла;
				Если Не НайденЭлементЗначения Тогда
					Результат = СтрШаблон("Элемент эталона [%1] не найден в массиве", Индекс);
					Прервать;
				КонецЕсли; 
				Индекс = Индекс + 1;
			КонецЦикла;
		КонецЕсли;        
		#КонецОбласти
	ИначеЕсли ТипЗнч(Значение) = Тип("Структура") Тогда
		#Область СравнениеСтруктур
        Результат = Истина;
		Если Значение.Количество() < Эталон.Количество() Тогда
			Результат = СтрШаблон("Количество полей в структуре (%1) меньше чем в эталоне (%2)", Значение.Количество(), Эталон.Количество());
		ИначеЕсли Истина
				И ?(СтрогоеСравнениеСтруктур = Неопределено, СтрогоеСравнение, СтрогоеСравнениеСтруктур) 
				И Значение.Количество() <> Эталон.Количество() 
			Тогда 
			Результат = СтрШаблон("Количество полей в структуре (%1) не равно количеству в эталоне (%2)", Значение.Количество(), Эталон.Количество());;
		Иначе
			Для Каждого Элемент Из Эталон Цикл
				Если Значение.Свойство(Элемент.Ключ) Тогда
					РезультатСравнения = СравнитьЗначения(Значение[Элемент.Ключ], Элемент.Значение, Ложь, СтрогоеСравнение, СтрогоеСравнениеМассивов, СтрогоеСравнениеСтруктур, СтрогоеСравнениеСоответствий);
					Если РезультатСравнения <> Истина Тогда
						Результат = СтрШаблон("Ошибка в поле %1:
								|", Элемент.Ключ) + РезультатСравнения;
						Прервать;
					КонецЕсли;
				Иначе
					Результат = СтрШаблон("Поле %1 отсутсвует в структуре", Элемент.Ключ);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		#КонецОбласти
	ИначеЕсли ТипЗнч(Значение) = Тип("Соответствие") Тогда
		#Область СравнениеСоответствий
        Результат = Истина;
		Если Значение.Количество() < Эталон.Количество() Тогда
			Результат = СтрШаблон("Количество записей в соответствии (%1) меньше чем в эталоне (%2)", Значение.Количество(), Эталон.Количество());
		ИначеЕсли Истина
				И ?(СтрогоеСравнениеСоответствий = Неопределено, СтрогоеСравнение, СтрогоеСравнениеСоответствий) 
				И Значение.Количество() <> Эталон.Количество() 
			Тогда 
			Результат = СтрШаблон("Количество записей в соответствии (%1) не равно количеству в эталоне (%2)", Значение.Количество(), Эталон.Количество());;
		Иначе
			Для Каждого Элемент Из Эталон Цикл 
				РезультатСравнения = СравнитьЗначения(Значение[Элемент.Ключ], Элемент.Значение, Ложь, СтрогоеСравнение, СтрогоеСравнениеМассивов, СтрогоеСравнениеСтруктур, СтрогоеСравнениеСоответствий);
				Если РезультатСравнения <> Истина Тогда
					Результат = СтрШаблон("Ошибка в записи %1:
							|", Элемент.Ключ) + РезультатСравнения;
					Прервать;
				КонецЕсли;
			КонецЦикла;   
		КонецЕсли;
		#КонецОбласти
	Иначе               
		Если Значение <> Эталон Тогда
			Результат = СтрШаблон("Значение (%1) не равно эталону (%2)", Значение, Эталон);
		Иначе
			Результат = Истина;
		КонецЕсли;
	КонецЕсли;
	
	Если Результат <> Истина Тогда    
		Если ВызыватьИсключение = Истина Тогда
			ВызватьИсключение Результат;  
		ИначеЕсли ВызыватьИсключение <> Ложь Тогда
			ВызватьИсключение ВызыватьИсключение + "
				|" + Результат; 
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

Пользуйтесь на здоровье )

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2859    1    John_d    10    

56

GUID в 1С 8.3 - как с ними быть

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

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4994    atdonya    22    

51

Переоткрытие внешних обработок

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

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    4091    ke.92@mail.ru    16    

62

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

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

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

28.08.2023    9331    YA_418728146    6    

143

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

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

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

2 стартмани

22.08.2023    2197    24    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    16329    142    sapervodichka    112    

130

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

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

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

18.07.2022    7345    quazare    8    

110
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. alex_sayan 06.01.23 20:48 Сейчас в теме
Ужасный код
vadim1011985; pavlov_dv; Varsaavius; awk; +4
2. DrWeb3 71 07.01.23 17:19 Сейчас в теме
(1) Спасибо за ваше мнение, но я предпочёл бы конструктивную критику. Выносить что-то во вспомогательные функции не предлагайте. В остальном готов прислушаться к мнению более опытных коллег
+
5. awk 741 07.01.23 22:04 Сейчас в теме
(2) Это конструктивно. Код - г..вно.
+
9. DrWeb3 71 09.01.23 10:43 Сейчас в теме
(5) Да, Василий, вы правы. Зато ваш код близок к идеалу. Да что там говорить, он просто совершенен. Но к сожалению у нас с вами разные представления о конструктивности, поэтому дальнейший разговор на эту тему считаю не имеющим никакого смысла.
+
17. awk 741 09.01.23 15:04 Сейчас в теме
(9) Нет, мой код не всегда и не везде близок к идеалу. Так же как и вы не всегда говнокодите (я надеюсь).

С критериями говнокода можно ознакомиться на сайте ИТС https://its.1c.ru/db/v8std.
+
6. shard 279 08.01.23 10:36 Сейчас в теме
(2) много ИначеЕсли, имхо. Возможно будет легче восприниматься если сразу делать возврат результата.
+
10. DrWeb3 71 09.01.23 10:52 Сейчас в теме
(6) легче бы воспринималось вероятно, если бы не надо было каждый раз проверять что делать, возвращать результат или кидать исключение. В общем получилось то, что получилось. Задачу свою главное выполняет. Кому-то как пишут выше - г...вно, а кому-то лень изобретать и возьмет готовое. Короче каждый найдёт то, что ищет. ;)
+
16. vadim1011985 99 09.01.23 15:00 Сейчас в теме
(2) А Вы сами пробовали нестрогим сравнением массивов сравнить 2 массива хотя бы по 1 тыс элементов в каждом ?
+
21. DrWeb3 71 09.01.23 16:44 Сейчас в теме
(16) такой задачи не стояло. Какая была задача описал в (19). Эталон - это как правило, что-то маленькое, содержащее только лишь то, что надо проверить. Но если скажем стоит задача нестрогого сравнения двух массивов по 1000 элементов какое более оптимальное, с точки зрения количества итераций, решение предложите вы?
+
23. vadim1011985 99 09.01.23 18:04 Сейчас в теме
(21)
Но если скажем стоит задача нестрогого сравнения двух массивов по 1000 элементов какое более оптимальное, с точки зрения количества итераций, решение предложите вы?


Как вариант преобразование в ТЗ и запрос с Внутренним соединением для 2-х массивов из 1000 элементов это 2000 итераций . Против 1 000 000 по вашей схеме.
+
24. DrWeb3 71 09.01.23 18:28 Сейчас в теме
(23) хороший вариант для скалярных элементов в массиве. А что делать с массивом соответствий?

Процедура КомандаВыполнить(Команда)                       
	Массив1 = Новый Массив();
	Массив2 = Новый Массив();
	
	Для Индекс = 0 По 999 Цикл
		Массив1.Добавить(Индекс);
		Массив2.Добавить(999-Индекс);
	КонецЦикла;
	
	атК.СравнитьЗначения(Массив1, Массив2, Истина);
КонецПроцедуры
Показать


Потестил. Это выполняется у меня около 90 сек. Замером производительности видно, что можно пооптимизировать. Подумаю.
+
25. vadim1011985 99 09.01.23 18:34 Сейчас в теме
(24) Все тоже самое - преобразуешь соответствие (структуру) в ТЗ и сравниваешь. А вообще в БСП появился уже готовый инструментарий для этих целей. Может даже свой код перепишу под БСП
+
26. DrWeb3 71 10.01.23 08:10 Сейчас в теме
(25) Я не правильно выразился. Имел ввиду вложенность. Массив структур (соответствий) я конечно преобразую, но дальше как? Одно из полей структуры скажем массив, элементы которого другие структуры. У меня голова начинает пухнуть только от одной мысли о подобных преобразованиях. Мне хотелось универсальный инструмент, который сравнивает подобные вещи не взирая на то из чего они состоят и количество уровней вложенности.

Если поделитесь ссылочкой на описание подобного инструмента в БСП - думаю не я один буду вам благодарен
+
3. alex_sayan 07.01.23 17:37 Сейчас в теме
(2) а что за неприязнь к вспомогательным функциям? Это как раз хорошая практика - декомпозировать громоздкий код на более мелкие методы. Как минимум снижается цикломатическая сложность кода (в нашем случае она просто запредельная). Читающему оный не придётся вгрызаться глазами во всю портянку кода, он прочитает только интересующий его кусочек

А если по примеру:
1. Плохой подход делать универсальный код, который делает всё и сразу. Должна быть декомпозиция
2. Гораздо лучше будет, если вместо одной функции будет несколько отдельных: СравнитьМассив(), СравнитьСтруктуру()... Как бы клиентский код заранее знает, с какими типами он работает
3. Возвращать одной и той же функцией значения разных типов - плохая практика. Она приводит к засорению вызывающего функцию кода мусорными проверками возвращенного значения
4. СтрогоеСравнение... пардоньте, это какая-то фигня полнейшая
5. Обилие флагов во входящих параметрах опять же говорит о том, что функцию нужно было разбить на несколько
sansys; pavlov_dv; awk; +3
4. user612295_death4321 07.01.23 18:17 Сейчас в теме
(3) А нужно ли читать что там внутри? Судя по статье, тебе дают программный интерфейс, бери и юзай его. Ну а если он не решает твоих потребностей, то и нафиг его тогда :)
Поручик; +1
11. DrWeb3 71 09.01.23 10:55 Сейчас в теме
(4) Да, спасибо. Это действительно инструмент для решения вполне определенной задачи.
+
7. DrWeb3 71 08.01.23 12:08 Сейчас в теме
(3) У меня нет неприязни к вспомогательным функциям, но в данном случае назовём это требованием заказчика. Поэтому (при всей своей любви принесенной из NetBeans к функциям не более 20 строк длинной) - пришлось делать так. И именно поэтому были использованы области, чтобы хотя бы можно было скрыть отдельно проверку массивов, структур и соответствий и разобраться с тем, с чем хочется. По вспомогательным функциям думаю ответил.

Теперь по пунктам.

1. Согласен. Но этот конкретный код делает простую вещь. Сравнение двух сложных значений. Более ничего.

2. Не согласен. Задача была сравнивать два значения содержащие неограниченную вложенность и неизвестные типы. Вы редко сталкиваетесь с массивами соответствий содержащими в себе массивы? Попробуйте написать интеграцию с каким-нибудь маркетплейсом. Очень увлекательное занятие.

3. Согласен и всячески стараюсь этого избегать, но в данном случае скрепя сердце пошёл на это. Тип Булево возвращается только в случае равенства значений. Так что проверка Если СравнениеЗначений(...) = Истина Тогда - не такая сложная вещь. Конкретно я пользую своё "творение" только в варианте с вызовом исключения при юнит тестировании и вызывают это как процедуру. Но решил, что мало-ли кому захочется разбирать возвращаемое значение без конструкции Попытка-Исключение. Такая возможность есть. Изначально возвращалась просто Ложь и где ошибка в значении приходилось анализировать в отладчике.

4. Оценочное суждение это конечно хорошо, но давайте как-то более аргументированно, потому что я тупо не понимаю что вы имеете ввиду. Если у меня есть массив и мне надо убедиться что в нем есть значения 3 и "Вася" - это не строгое сравнение. Если у меня есть массив и он должен быть равен массиву [12, 8, Ложь, "Вася", 6, 3] то это строгое сравнение. Но вам фигнёй видимо кажется что-то другое. Прошу пояснить.

5. Не согласен. Обилие множества необязательных параметров, позволяющих тонко настроить что-то, что в 99% случаев настройки не требует скорее говорит о хорошем тоне, но это на мой личный вкус.
Yashazz; +1
15. Поручик 4674 09.01.23 13:10 Сейчас в теме
(7)
массивами соответствий содержащими в себе массивы?

Это интеграция или обмен данными с ЕГРЗ, которые я делал ещё в 2018 году и дорабатывал в 2021. Туда надо передавать фееричную JSON-структуру, состоящую из обычных типов, массивов, а внутри массива мог быть ещё массив. Всё это добро сначала формировалось в обычную структуру 1С, потом записывалось в JSON для передачи на сайт.
+
18. vadim1011985 99 09.01.23 15:12 Сейчас в теме
(15) Ну особо сложного тут я не не увидел преобразование сложной структуры в Json вообще всего пару строк делается.

У меня была похожая задача - надо было отлавливать изменения в 1с для передачи на сайт и сравнения я делал немного другим способом.
+
20. DrWeb3 71 09.01.23 16:39 Сейчас в теме
(18) если бы было нужно только строгое сравнение - было бы наверно проще преобразовать в json и сравнить тексты. Ответил в (19) откуда взялась потребность в нестрогом сравнении
+
22. vadim1011985 99 09.01.23 17:04 Сейчас в теме
(20) Это по поводу качества кода. При больших массивах данных даже примитивных типов у Ваще сравние зависает и становиться непригодным. А представьте например приедет массив структур на 10 000 ном. позиций который надо будет вот так вот нестрого сравнить.

Опять же сам столкнулся с такой проблемой , но я предпочел в данном случае привести все к одному знаменателю (т.е сравниваемое значение пытаюсь привести к эталону и сравнить уже полученный результат представлением эталона через преобразование ЗначениеВСтрокуВнутр Эталона и сравниваемого значения) . Конечно минусом данного метода является ложные срабатывания , так как важен порядок элементов в массиве. Но лучше лишний раз зарегистрировать изменения к обмену чем ждать пока он сравнит каждый с каждым

              //Тут ДанныеСотрудника1С - Сложная Структура которая может содержать как примитивные типы , так и массивы и 
                 массивы структур 
             //СотрудникиTeamID[0] - Данные полученные из внешнего сервиса преобразованные с помощью функцкии в структуру 
 

	        КопияДляСравнения1с = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(ДанныеСотрудника1С));
		КопияДляСравненияTeam = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(СотрудникиTeamID[0]));
		
		СтруктураДляСравнения = СравнитьДанные(КопияДляСравнения1с,КопияДляСравненияTeam);
		
		ЕстьРазличия = ЗначениеВСтрокуВнутр(КопияДляСравнения1с)<>ЗначениеВСтрокуВнутр(СтруктураДляСравнения); 


Функция СравнитьДанные(Знач Данные1с, ДанныеTeam)
	
	СтруктураВозврата = Новый Структура; 
	
	Если ДанныеTeam.Свойство("schemas") Тогда 
		ДанныеTeam.Удалить("schemas");
	КонецЕсли;
	
	Если Данные1с.Свойство("schemas") Тогда 
		Данные1с.Удалить("schemas");
	КонецЕсли;
	
	Для Каждого Поле из Данные1с Цикл 			
		
		Если НЕ ДанныеTeam.Свойство(Поле.Ключ) Тогда 	
			ДанныеTeam.Удалить(Поле.Ключ);
		Иначе		
			Если ТипЗнч(ДанныеTeam[Поле.Ключ]) = Тип("Дата") Тогда
				СтруктураВозврата.Вставить(Поле.Ключ,Формат(НачалоДня(ДанныеTeam[Поле.ключ]),"ДФ=yyyy-MM-dd"));
			ИначеЕсли ТипЗнч(ДанныеTeam[Поле.Ключ]) = Тип("Структура") Тогда	
				СтруктураВозврата.Вставить(Поле.Ключ,СравнитьДанные(Данные1с[Поле.Ключ],ДанныеTeam[Поле.ключ]))					
			ИначеЕсли ТипЗнч(ДанныеTeam[Поле.Ключ]) = Тип("Массив") Тогда	
				Если Поле.Значение.Количество() = ДанныеTeam[Поле.Ключ].Количество() Тогда 									
					МассивДляВставки = Новый Массив;	
					
					Для К = 0 По Поле.Значение.Количество()-1 Цикл
						МассивДляВставки.Добавить(СравнитьДанные(Данные1с[Поле.Ключ][К],ДанныеTeam[Поле.ключ][К])); 
					КонецЦикла; 
					
					СтруктураВозврата.Вставить(Поле.Ключ,МассивДляВставки);		
				КонецЕсли;
			Иначе		
				СтруктураВозврата.Вставить(Поле.Ключ,ДанныеTeam[Поле.ключ]);		
			КонецЕсли;			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат СтруктураВозврата;  
	
КонецФункции   
Показать
+
27. alex_sayan 10.01.23 10:23 Сейчас в теме
(7)

2. В чем тут проблема использовать отдельные функции?
4. Не должна одна функция работать как-то по-разному в разных местах. Это должны быть _разные_ функции
5. Нет. Обилие флагов в параметрах целиком и полностью говорит о плохом тоне. О том что метод делает много всего и сразу

Обыденная ситуация. Программист забыл какой-то из флагов, функция отработала иначе. А проблема вскрылась спустя время. Стрельнула совсем в другом месте
+
29. DrWeb3 71 10.01.23 11:16 Сейчас в теме
(27)
2. В чем тут проблема использовать отдельные функции?

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


4. Не должна одна функция работать как-то по-разному в разных местах. Это должны быть _разные_ функции
5. Нет. Обилие флагов в параметрах целиком и полностью говорит о плохом тоне. О том что метод делает много всего и сразу


Не знаю как изобразить задумавшийся смайлик. Предлагаете сделать _разные_ функции типа:

Функция СравнитьЗначенияСоСтрогимСравнениемМассивовНоНеСтрогимСравнениемСтруктурИВызовомИсключенияВСлучаеОшибкиСравнения(Значение, Эталон) Экспорт


УмнО, но мне проще флаг в параметре. Кому надо сделает обёртки с подобными названиями, чтобы не путаться. БСП кстати обёртками не брезгует.
+
8. Aphanas 92 09.01.23 04:27 Сейчас в теме
Код нормальный. Задача странная.
12. DrWeb3 71 09.01.23 11:04 Сейчас в теме
(8) интересно в чем странность задачи? Хотя вероятно вы правы. Я не люблю стандартные задачи. Я люблю нестандартные, "странные" и "нерешаемые"
+
13. Aphanas 92 09.01.23 12:52 Сейчас в теме
(12) Это нормальная, нужная функция. Но, лично для меня возможно, это не совсем подходит. Массивы, структуры, соответствия... Имхо, обычно сравнения сводятся к таблицам или деревьям. Не совсем понятно, почему тут такой выбор. Я подумал, тут есть рекурсивное сравнение объектов - элементов, документов и т.п. Но это наверное, другой объем работы уже будет.
+
19. DrWeb3 71 09.01.23 16:36 Сейчас в теме
(13) Да, я понял. Выбор такой, как я уже писал в другой ветке, потому что основное применение - это тесты интеграций. JSON 1С преобразует в соответствия и массивы, ну а структуры появились уже что называется "до кучи", тем более, что в одной из интеграций мы конвертируем полученное соответствие в структуру с переводом названий полей на русский. И основная задача этой функции сравнивать что-то полученное со стороннего сервиса с неким эталоном в котором естественно заданы только те поля, которые нас волнуют на стороне 1С, а большое количество "мусора" возвращаемое сторонними API у нас не используется, так что прописывать конкретные ожидаемые значения в тестах нет большого смысла, отсюда родилось "нестрогое" сравнение.

Для объектов принцип тот же, но к сожалению (а может и к счастью) реквизиты нельзя обойти с помощью Для Каждого... И если бы была необходимость, чтобы не запутывать самого себя еще больше - возможно "дорос" бы до вспомогательных функций.
+
14. Поручик 4674 09.01.23 13:02 Сейчас в теме
Нормальный код, по сравнению с многими моментами из БСП. Даже вполне нормальный код.
+
28. alex_sayan 10.01.23 10:40 Сейчас в теме
(4) не стоит ожидать, что другой код будет работать как-то иначе. И да, из-за побочки, управляемой обильными флагами в параметрах, придётся туда заныривать
+
31. user612295_death4321 10.01.23 12:03 Сейчас в теме
(28) К программному интерфейсу приложен соответствующий комментарий. Когда я юзаю программный интерфейс БСП, мне примерно с 85% вероятностью пофиг что там написано внутри метода, лишь бы я понимал какие входные параметры мне ему передать и что на выходе я получу.

Лезть внутрь, это уже какие то наверное слишком специфичные случаи, имхо.
+
30. DAAbramov 10 10.01.23 11:30 Сейчас в теме
Такой метод уже есть в БСП, смотрите
ОбщегоНазначения.КоллекцииИдентичны
ОбщегоНазначения.ДанныеСовпадают
vadim1011985; +1
Внимание! Тема сдана в архив