Поиск строки XML-файла, содержащей значение, не соответствующее типу свойства XDTO пакета

25.01.21

Интеграция - Файловый обмен (TXT, XML, DBF), FTP

Ведется обмен со сторонней системой через XML-файлы. XML-файлы содержат данные, соответствующие ПакетуXDTO, и загружаются с использованием ФабрикиXDTO. Сторонняя система не всегда корректно формирует XML-файл и при загрузке файла метод ПрочитатьXML() ФабрикиXDTO выбрасывает исключение. По описанию ошибки не всегда можно понять, какая именно секция содержит некорректное значение.

Скачать исходный код

Наименование Файл Версия Размер
ПроверкаКорректностиXMLФайла.epf
.epf 10,09Kb
24
.epf 10,09Kb 24 Скачать

Формат загружаемого файла должен соответствовать ПакетуXDTO

<?xml version="1.0" encoding="UTF-8"?>
<My-Object xmlns="http://www.MyURL" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<header>
		<num>2019-02-10</num> <!-------тут должно быть число----->
		<sender-id>00001</sender-id>
		<reciever-id>00000</reciever-id>
		<created-date>2019-02-11T08:09:09</created-date>
	</header>
	<docs>
		<doc>
			<doc-date>100</doc-date> <!-------тут должна быть дата----->
			<doc-num>1</doc-num>
			<doc-gds>
				<doc-gd>
					<line-num>1</line-num>
					<gd-code>000001</gd-code>
					<qnty>10</qnty>
					<sum>1000</sum>
					<price>100</price>
				</doc-gd>
			</doc-gds>
		</doc>
	</docs>
</My-Object>

Но сторонняя система ничего не знает об XDTO и XSD. Она формирует по сути текстовый файл определенного формата. Поэтому при его создании валидность не проверяется.

При больших объемах XML-файлов поиск секции содержащей некорректное значение становится проблемой. Ошибки выдаваемые платформой не очень информативны

Мы можем отсюда понять, что некая секция вместо даты содержит значение "100". Нам нужно найти секцию, которая согласно ПакетуXDTO имеет тип "Дата", но при этом содержит значение "100". Значение "100" может встречаться в файле многократно, а типы секций в XML-файле не обозначены.

Со значением "2019-02-10" и типом Integer ситуация аналогичная.

Если читать XML-файл построчно, то сопоставить получаемые данные с ПакетомXDTO будет проблематично. Поэтому реализация выполнена  через ДокументDOM.

Алгоритм следующий:

  1. Читаем XML-файл в ДокументDOM
  2. Получаем корневой узел.
  3. Затем последовательно перебираем соседние узлы первого уровня вложенности
  4. Читаем полученный узел ФабрикойXDTO с указанием типа
  5. Если чтение произошло без ошибок переходим к следующему соседнему узлу и переходим к пункту 4
  6. Если чтение узла выбросило исключение, то проверяем тип и состав вложенного узла
  7. Если дочерний узел содержит простое значение, значит оно и является некорректным. Получаем следующий соседний узел и переходим к пункту 4
  8. Если вложенный узел содержит дочерние узлы, то проверяем должен ли он их содержать согласно ПакетуXDTO. Если нет, значит этот узел и является некорректным. Получаем следующий соседний узел и переходим к пункту 4
  9. Если вложенный узел содержит дочерние узлы, то последовательно получаем каждый из них. Проверяем есть ли такой узел в ПакетеXDO. Если нет, значит этот узел и является некорректным. Получаем следующий соседний узел и переходим к пункту 4
  10. После перебора всех вложенных узлов проверяем, что все обязательные узлы присутствую.

Таким образом мы получим все некорректные узлы. Но остается другая проблема. Как узнать в какой строке XML-файла находится некорректный узел?

Для этого необходимо некорректному узлу добавить атрибут, в качестве значения подставить UID и затем сохранить ДокументDOM во временный файл. Список подставленных UIDов и описание причины некорректности узла сохраняются в ТЗ. Полученный файл можно прочитать построчно и в случае обнаружения в строке ранее сохраненного UIDа можно понять в какой строке содержится некорректный узел и в чем именно ошибка.Так же во время чтения можно удалить ранее созданный атрибут и его значение, после чего файл примет первоначальный вид.

Ниже приведен пример кода, который выполняет все эти функции.

&НаСервере
Процедура ПроверитьНаСервере(АдресПроверяемогоФайла)
	
	#Область ЧтениеДокументаДОМ
	//Читаем файл из временного хранилища
	Поток = ПолучитьИзВременногоХранилища(АдресПроверяемогоФайла).ОткрытьПотокДляЧтения();
	ЧтениеХМЛ = Новый ЧтениеXML;
	ЧтениеХМЛ.ОткрытьПоток(Поток);
	ПостроительДОМ = Новый ПостроительDOM;
	ДокументДОМ	= ПостроительДОМ.Прочитать(ЧтениеХМЛ);
	ЧтениеХМЛ.Закрыть();
	Поток.Закрыть();
	#КонецОбласти
	
	#Область ОбходДереваДОМ
	//Обходим дерево ДОМ
	ОбходДереваDOM = Новый ОбходДереваDOM(ДокументДОМ);
	//Получаем корневой узел
	ОбходДереваDOM.СледующийУзел();
	//Получаем тип корневого узла
	ТипОбъектаXDTO = ФабрикаXDTO.Тип("http://www.MyURL", "MyObject");
	//Получаем первый вложенный узел
	УзелDOM = ОбходДереваDOM.СледующийУзел();
	Пока УзелDOM <> Неопределено Цикл

		#Область ПоискСвойстваОбъектаXDTOПоЛокальномуИмениУзла
		СвойствоОбъектаXDTO = Неопределено;
		Для Каждого СвойствоXDTO Из ТипОбъектаXDTO.Свойства Цикл
			Если СвойствоXDTO.ЛокальноеИмя = УзелDOM.ИмяУзла Тогда
				//СвойствоТипОбъектаXDTO = ФабрикаXDTO.Тип(СвойствоXDTO.Тип.URIПространстваИмен, СвойствоXDTO.Тип.Имя);
				СвойствоОбъектаXDTO = СвойствоXDTO;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Если СвойствоОбъектаXDTO = Неопределено Тогда
			Сообщить("Объект " + УзелDOM.РодительскийУзел.ИмяУзла + " неивестное свойство " + УзелDOM.ИмяУзла);
			УзелDOM = ОбходДереваDOM.СледующийСоседний();
			Продолжить;
		КонецЕсли;
		#КонецОбласти
		
		ПроверитьУзел(УзелDOM, СвойствоОбъектаXDTO.Тип);
		
		//Получаем следующий узел на этом же уровне вложенности
		УзелDOM = ОбходДереваDOM.СледующийСоседний();
	КонецЦикла;
	#КонецОбласти
	
	#Область ЗаписьДокументаДОМ
	//Записываем документ ДОМ в поток
	Поток = Новый ПотокВПамяти ;
	ЗаписьХМЛ = Новый ЗаписьXML;
	ЗаписьХМЛ.Отступ = Истина;
	ЧетыреПробела = "    ";
	ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", , Истина, Ложь, ЧетыреПробела);
	ЗаписьХМЛ.ОткрытьПоток(Поток, ПараметрыЗаписи);
	ЗаписьДОМ = Новый ЗаписьDOM;
	ЗаписьДОМ.Записать(ДокументДОМ, ЗаписьХМЛ);
	ЗаписьХМЛ.Закрыть();
	#КонецОбласти
	
	ПозицияКурсора = 0;
	Смещение	   = 0;
	
	//Закрываем Поток для записи и открываем для чтения
	Поток = Поток.ЗакрытьИПолучитьДвоичныеДанные().ОткрытьПотокДляЧтения();
	//Читаем текст документа ДОМ из потока
	ТекстовыйДокумент.Прочитать(Поток);
	Поток.Закрыть();
	Для НомерСтроки = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
		ТекстСтроки = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);
		Для Каждого СтрокаТаблицыОшибок Из ТаблицаОшибок Цикл
			Если  СтрокаТаблицыОшибок.Обработана Или СтрНайти(ТекстСтроки, СтрокаТаблицыОшибок.ИД) = 0 Тогда
				Продолжить;
			КонецЕсли;
			СтрокаТаблицыОшибок.Номер	   = НомерСтроки;
			СтрокаТаблицыОшибок.Обработана = Истина;
			СтрокаТаблицыОшибок.Закладка   = ПозицияКурсора + 1 + СтрДлина(ТекстСтроки) - СтрДлина(СокрЛП(ТекстСтроки)) - Смещение;
			
			Смещение = Смещение + СтрДлина("Error=""""00000000-0000-0000-0000-000000000000""");
			
			ТекстовыйДокумент.ЗаменитьСтроку(НомерСтроки, СтрЗаменить(ТекстСтроки, " Error=""" + СтрокаТаблицыОшибок.ИД + """", "")); 
		КонецЦикла;
		ПозицияКурсора = ПозицияКурсора + СтрДлина(ТекстСтроки) + 1;
	КонецЦикла;	
	
КонецПроцедуры

&НаСервере
Процедура ПроверитьУзел(УзелDOM, ТипXDTO)
	
	//Пытаемся прочитать УзелDOM ФабрикойXDTO
	УзелКорректный = Истина;
	
	#Область ЧтениеУзловДОМ
	ЧтениеУзловDOM = Новый ЧтениеУзловDOM;
	ЧтениеУзловDOM.Открыть(УзелDOM);
	Попытка
		Фабрика = ФабрикаXDTO.ПрочитатьXML(ЧтениеУзловDOM, ТипXDTO);
	Исключение
		УзелКорректный = Ложь;
	КонецПопытки;
	ЧтениеУзловDOM.Закрыть();
	#КонецОбласти
	
	//Если узел корректный, выходим из рекурсии
	Если УзелКорректный Тогда
		Возврат;
	КонецЕсли;
	//Если это свойство содержащее простое значение, значит оно некорректное
	Если ТипЗнч(УзелDOM.ПервыйДочерний) = Тип("ТекстDOM") Или ТипЗнч(ТипXDTO) = Тип("ТипЗначенияXDTO") Тогда
		ТекстСообщения = "Узел """ + УзелDOM.ИмяУзла + """ (тип """ +  ТипXDTO.Имя + """) содержит некорректное значение """ + УзелDOM.ТекстовоеСодержимое + """";
		ЗарегистрироватьОшибку(УзелDOM, ТекстСообщения); 
	//Есть вложенные, а их быть не должно	
	ИначеЕсли УзелDOM.ЕстьДочерниеУзлы() И ТипXDTO.Свойства.Количество() = 0 Тогда
		ТекстСообщения = "Узел """ + УзелDOM.ИмяУзла + """ не должен содержать вложенных секций.";
		ЗарегистрироватьОшибку(УзелDOM, ТекстСообщения);
	//Не вложенных, а они должны быть
	ИначеЕсли Не УзелDOM.ЕстьДочерниеУзлы() И ТипXDTO.Свойства.Количество() <> 0 Тогда
		ТекстСообщения = "Узел """ + УзелDOM.РодительскийУзел.ИмяУзла + """ содержит пустую секцию """ + УзелDOM.ИмяУзла + """";
		ЗарегистрироватьОшибку(УзелDOM, ТекстСообщения);
	Иначе
		//Получаем свойства соответствующего ТипаXDTO
		УзелDOMСвойстваXDTO = Новый ТаблицаЗначений;
		УзелDOMСвойстваXDTO.Колонки.Добавить("ТипXDTO");
		УзелDOMСвойстваXDTO.Колонки.Добавить("ЛокальноеИмя",   Новый ОписаниеТипов("Строка"));
		УзелDOMСвойстваXDTO.Колонки.Добавить("Существует",	   Новый ОписаниеТипов("Булево"));
		УзелDOMСвойстваXDTO.Колонки.Добавить("НеОбязательное", Новый ОписаниеТипов("Булево"));
		Для Каждого СвойствоТипаXDTO Из ТипXDTO.Свойства Цикл
			НоваяСтрока = УзелDOMСвойстваXDTO.Добавить();
			НоваяСтрока.ТипXDTO			= СвойствоТипаXDTO.Тип;
			НоваяСтрока.ЛокальноеИмя	= СвойствоТипаXDTO.ЛокальноеИмя;
			НоваяСтрока.Существует		= Ложь;
			НоваяСтрока.НеОбязательное	= СвойствоТипаXDTO.НижняяГраница = 0;
		КонецЦикла;
		//Проверяем наличие свойств
		Для Каждого Дочерний Из УзелDOM.ДочерниеУзлы Цикл
			СвойствоТипаXDTO = УзелDOMСвойстваXDTO.Найти(Дочерний.ИмяУзла, "ЛокальноеИмя"); 
			Если СвойствоТипаXDTO <> Неопределено Тогда
				СвойствоТипаXDTO.Существует = Истина;
				ПроверитьУзел(Дочерний, СвойствоТипаXDTO.ТипXDTO);
			Иначе
				ТекстСообщения = "Узел """ + УзелDOM.ИмяУзла + """ содержит недопустимую вложенную секцию """ + Дочерний.ИмяУзла + """";
				ЗарегистрироватьОшибку(Дочерний, ТекстСообщения); 
			КонецЕсли;	
		КонецЦикла;
		ОтсутствующиеСвойства = УзелDOMСвойстваXDTO.НайтиСтроки(Новый Структура("Существует, НеОбязательное", Ложь, Ложь));
		Для Каждого ОтсутствующееСвойство Из ОтсутствующиеСвойства Цикл
			ТекстСообщения = "Отсутствует обязательная вложенная секция";
			ЗарегистрироватьОшибку(УзелDOM, ТекстСообщения); 
		КонецЦикла;	
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ЗарегистрироватьОшибку(УзелДОМ, ОписаниеОшибки)
	
	ПолноеИмяУзла = УзелДОМ.ИмяУзла;
	РодительскийУзел = УзелДОМ.РодительскийУзел;
	Пока РодительскийУзел.ИмяУзла <> "#document" Цикл
		МассивСтрок = Новый Массив;
		МассивСтрок.Добавить(РодительскийУзел.ИмяУзла);
		МассивСтрок.Добавить("\");
		МассивСтрок.Добавить(ПолноеИмяУзла);
		ПолноеИмяУзла = СтрСоединить(МассивСтрок);
		РодительскийУзел = РодительскийУзел.РодительскийУзел;
	КонецЦикла;
	
	ГУИД = Строка(Новый УникальныйИдентификатор);
	
	Атрибут = УзелДОМ.ДокументВладелец.СоздатьАтрибут("Error");
	Атрибут.Значение = СокрЛП(ГУИД);
	УзелДОМ.Атрибуты.УстановитьИменованныйЭлемент(Атрибут);
	
	СтрокаТаблицы = ТаблицаОшибок.Добавить();
	СтрокаТаблицы.ИД = ГУИД;
	СтрокаТаблицы.Реквизит = ПолноеИмяУзла;
	СтрокаТаблицы.Значение = УзелДОМ.ИмяУзла;
	СтрокаТаблицы.Описание = ОписаниеОшибки;
	
КонецПроцедуры

Во вложении обработка визуально отображающая строки XML-файла содержащие некорректные секции. Переход к строке осуществляется по двойному клику на строку таблицы ошибок. Конфигурация должна содержать XDTO-пакет с пространством имен проверяемого XML-файла.

Платформа 8.3.14.

См. также

SALE! 10%

Синхронизация и обмен для ERP 2.5, КА 2.5, УТ 11.5 БП 3.0, Розница, УНФ и других с EnterpriseData (универсальный формат обмена), правила обмена

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен и синхронизацию в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

25080 22572 руб.

12.06.2017    136385    732    291    

393

Перенос данных из УТ 10.3 в УТ 11.5. Переносятся документы (обороты за период), справочная информация и остатки

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 1С:Управление торговлей 11 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.87.x) и УТ 11.5 (11.5.16.x).

28000 руб.

23.07.2020    47409    202    64    

163

Перенос данных из ERP 2 / КА 2 / УТ 11 в БП 3.0. Переносятся документы, начальные остатки и справочники

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в БП 3 | из КА 2 в БП 3 | из УТ 11 в БП 3 | из ЕРП в БП 3 | В продаже с 2019г. | Воспользовались более 176 предприятий! | Сэкономьте время - используйте готовое решение для перехода! | Перенос разработан в формате КД 2 (правила конвертации данных) | Переносятся все возможные виды документов, начальных остатков и нормативно-справочная информация| Можно опционально выгружать каждую пару "номенклатура+характеристика" как отдельную номенклатуру | Есть выгрузка настроек счетов учета и зарплатных данных из ERP / КА 2 | Можно проверить на вашем сервере перед покупкой, обращайтесь!

34650 руб.

15.04.2019    69419    166    141    

112

Перенос данных из УПП 1.3 в БП 3.0. Переносятся документы (обороты за период), справочная информация и остатки

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.226.x) и БП 3.0 (3.0.151.x). Правила подходят для версии ПРОФ и КОРП.

28000 руб.

15.12.2021    20990    137    38    

96

Перенос данных из УПП 1.3 в ERP 2.5, КА 2.5. Переносятся документы (обороты за период), справочная информация и остатки

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:ERP Управление предприятием 2.5 и 1С:Комплексную автоматизацию 2.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.227.x), ERP 2.5 (2.5.16.x), КА 2.5 (2.5.16.x) .

28000 руб.

24.06.2020    61616    44    27    

75

Перенос данных из ERP 2 / КА 2 в ЗУП 3. Переносятся остатки, документы и справочники

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Воспользовались более 79 предприятий! | Предлагаем приобрести готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | В продаже с 2020г. | Оперативно обновляем правила до актуальных релизов 1С | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

43450 руб.

03.12.2020    34761    83    58    

81

[ED2] Обмен УПП 1.3, КА 1.1, УТ 10.3 с EnterpriseData (универсальный формат обмена), обработка

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 Платформа 1C v8.2 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием Россия Платные (руб)

Регулярный обмен, выгрузка, перенос из КА 1.1, УПП 1.3, УТ 10.3 для обмена с любыми конфигурациями, поддерживающими обмен в формате EnterpriseData (КД3) - БП 3.0, ERP, КА 2, УТ 11, Розница 2, УНФ 1.6 и другими. Правила для старых и доработанных конфигураций не требуют синхронного обновления и совместимы с новыми и будущими конфигурациями. Обмен по расписанию, через папку, FTP, почту.

14580 руб.

18.02.2016    183539    564    508    

509

Перенос данных из БП 3.0 в УНФ 3.0 / УНФ 1.6. Переносятся остатки, документы и справочная информация

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

В продаже с 2018г. | Воспользовались более 41 предприятия! | Правила конвертации (КД 2) для переноса данных из БП 3 в УНФ | Переносятся все виды документов, начальные остатки и вся возможная справочная информация | Есть фильтр по организациям | Оперативно обновляем на новые релизы | Оказываем техподдержку | В комплект файлов входит инструкция, авторская версия обработки "Универсальный обмен...", актуальные правила переноса данных и архив старых версий переноса | Учет в БП 3 должен быть корректным, некорректные данные не переносятся | Можно бесплатно проверить на вашем сервере до покупки!

45650 руб.

10.07.2018    68334    41    124    

46
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. renmy 93 06.09.22 15:41 Сейчас в теме
Статья супер. Автору большое спасибо.

Пришлось немного переделать по себя.
1. В моей схеме типы определяются в свойствах. Получение типа сделал через корневые свойства.
//Получаем тип корневого узла
//ТипОбъектаXDTO = ФабрикаXDTO.Тип("http://www.MyURL", "MyObject");
ТипОбъектаXDTO = ФабрикаXDTO.Пакеты.Получить("ИмяПакета").КорневыеСвойства.Получить("ИмяУзла").Тип;

2.Выводились атрибуты в ошибку "Отсутствует обязательная вложенная секция"
Добавил проверку атрибутов перед кодом:
ОтсутствующиеСвойства = УзелDOMСвойстваXDTO.НайтиСтроки(Новый Структура("Существует, НеОбязательное", Ложь, Ложь));


//Исключаем существующие атрибуты из отсутствующих
Для Каждого Дочерний Из УзелDOM.АтрибутыЦикл
	СвойствоТипаXDTO = УзелDOMСвойстваXDTO.Найти(Дочерний.ЛокальноеИмя, "ЛокальноеИмя"); 
	Если СвойствоТипаXDTO <> Неопределено Тогда
		СвойствоТипаXDTO.Существует = Истина;
	КонецЕсли;	
КонецЦикла;
Показать
Оставьте свое сообщение