HTML - это просто: Программное формирование HTML документа, содержащего ссылки на объекты БД

16.06.15

Разработка - Работа с интерфейсом

В данной статье рассматривается способ программного формирования HTML документа, содержащего ссылки на объекты базы данных, такие как справочники, документы и т.д. Показан пример построения обработчика события OnClick ПоляHTMLДокумента, для обработки клика на html -ссылке.

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

Наименование Файл Версия Размер
ФормиированиеHTML.rar
.rar 8,62Kb
10
.rar 8,62Kb 10 Скачать

Предисловие

Однажды, дописывая обработку, создающую и модифицирующую, не суть важно какие документы, я подумал, что неплохо было бы вывести для пользователя некое резюме:

"Создан документ такой-то"

"Изменен документ такой-то" и т.д.

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

То, что в форме есть элемент управления именуемый ПолеHTMLДокумента я конечно знал, но вот представилась возможность познакомиться с ним поближе. Было решено реестр обработанных документов выводить в виде html документа содержащего ссылки на эти самые документы, а по клику на ссылке открывать форму соответствующего документа. Здесь мне многие могут возразить: "А почему бы для этих целей не использовать обычный макет, выводимый в табличный документ, а для открытия документов использовать расшифровку? И чем Ваш способ лучше?" Отвечаю: Конечно можно использовать, и мой способ ничем не лучше. Он просто другой. Ведь у хорошего программиста  для решения одной задачи должно быть в арсенале несколько инструментов :)

Итак, перейдем от слов к делу, в рамках данной статьи рассмотрим следующую задачу: Сформировать html-документ, содержащий ссылки на элементы справочника номенклатура, по клику требуется открывать форму соответствующего элемента.

Создаем новый отчет, его форму, на форме размещаем элемент управления ПолеHTMLДокумента.

Текст модуля формы:


Процедура ДобавитьТекстHTML(ТекстHTML, Элемент);
   
// Ссылку будем формировать хитро:
    // Предполагаем что символ "-" не входит в имена объектов метаданных,
    // учавствующих в формировании html
    // Тогда ссылка будет иметь следующий вид:
    // Номенклатура-d341d377-b3b1-11dc-a100-0011d85708ff
    // Передавать нашу ссылку будем через атрибут id
   
СсылкаНаЭлемент = Элемент.Метаданные().Имя+"-"
   
+Элемент.Ссылка.УникальныйИдентификатор();
   
ТекстHTML.ДобавитьСтроку("<A id=""" + СсылкаНаЭлемент + """ href= """
   
+ Элемент + """ >"+Элемент+"</A><BR>");
КонецПроцедуры

Процедура
ДействияФормыСформировать(Кнопка)
   
Запрос = Новый Запрос("
    |ВЫБРАТЬ
    |    Номенклатура.Ссылка
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура"
);
   
ТекстHTML = Новый ТекстовыйДокумент;
   
Выборка = Запрос.Выполнить().Выбрать();
    Пока
Выборка.Следующий() Цикл
       
ДобавитьТекстHTML(ТекстHTML, Выборка.Ссылка);
    КонецЦикла;
ЭлементыФормы.ПолеHTMLДокумента.УстановитьТекст(ТекстHTML.ПолучитьТекст());
КонецПроцедуры

Ну вот html мы сформировали, теперь что бы ссылки "ожили" надо написать обработчик события OnClick элемента управления ПолеHTMLДокумента.

Процедура ПолеHTMLДокументаonclick(Элемент, pEvtObj)
   
htmlElement = НайтиСсылку(pEvtObj.srcElement);
   
// Анализируем если произошло нажание не ссылку
   
Если htmlElement <> Неопределено Тогда
       
// Если у ссылки есть идентификатор
       
Если СокрЛП(htmlElement.id) <> "" Тогда
           
// Получаем ссылку из атрибута id
           
СсылкаНаЭлемент = htmlElement.id;
           
Разделитель = Найти(СсылкаНаЭлемент,"-");
            Если
Разделитель > 0 Тогда
               
// Получаем тип элемента
               
ТипЭлемента = Лев(СсылкаНаЭлемент,Разделитель-1);
               
// Получаем УникальныйИдентификатор
               
ГУИД = Сред(СсылкаНаЭлемент,Разделитель+1);
               
Справочники[ТипЭлемента].ПолучитьСсылку(Новый УникальныйИдентификатор(ГУИД)).ПолучитьФорму().Открыть();
            КонецЕсли;
           
// Отказ от стандартной обработки клика
           
pEvtObj.returnValue = Ложь;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Функция
НайтиСсылку(Элемент)
   
Врем = Элемент;
    Пока
Врем <> Неопределено Цикл
        Если
НРег(Врем.tagName) = "a" Тогда
            Возврат
Врем;
        КонецЕсли;
       
Врем = Врем.parentElement;
    КонецЦикла;
    Возврат Неопределено;
КонецФункции

Всё можно пробовать! см. Рис.1

Заключение

Обратите внимание что ссылку я формировал следующим образом:

<ИмяОбъектаМетаданных>-<УникальныйИдентификатор> это сделано для того, чтобы в обработчике можно было определить к какому объекту метаданных относится данный УникальныйИдентификатор, потому что имея ТОЛЬКО УникальныйИдентификатор невозможно определить к какому объекту метаданных он относиться. Точнее возможно, но уж слишком долго и неудобно - путем перебора всех метаданных в цикле, для каждого объекта метаданных выполнять попытку <ОбъектМетаданных>.ПолучитьСсылку(Новый УникальныйИдентификатор(НашУникальныйИдентификатор))

Хотя в нашем примере только один справочник, и указывать его вид было необязательно, и так понятно что это УникальныйИдентификатор элемента справочника Номенклатура, но вдруг Вам потребуется работать с несколькими справочниками, вот тут то мой способ задания ссылки Вам и пригодится.

P.S. Платформа 8.2 имеет встроенный механизм работы со ссылками на объекты БД и данная задача наверняка упростится, но это уже другая тема.

P.P.S. Как выяснилось, в ходе обсуждения этой статьи, существует и более простой способ формирования ссылки на объект БД. Выкладываю пример кода, в котором ссылка формируется по методу о котором написал в форуме Saint:


Источник: http://www.obrabotki.com/1s-create-html-1/

http://www.obrabotki.com/1s-create-html-2/

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    121603    670    389    

711

SALE! 25%

Infostart PrintWizard

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

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

18000 15300 руб.

06.10.2023    7261    21    6    

39

SALE! 20%

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

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

10000 8000 руб.

10.11.2023    3504    11    1    

33

SALE! 30%

PowerTools

Инструментарий разработчика Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

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

3600 2520 руб.

14.01.2013    177725    1073    0    

849

Многопоточность. Универсальный «Менеджер потоков» 2.1

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Восстановление партий или взаиморасчетов, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

5000 руб.

07.02.2018    99338    239    97    

296

Богатый редактор картинок, хранимых в базе, с возможностью РИСОВАНИЯ. Редактор внешних файлов картинок. Объект, расширяющий возможности работы с картинками из встроенного языка (Три в одном) + Обработка «Стандартизация картинок»

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработка предназначена для редактирования картинок в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Также обработка может быть использована из встроенного языка как объект для редактирования картинок. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Данная обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    61793    43    59    

80

[Расширения] Динамическое управление видимостью и доступностью элементов форм (УФ) (8.3.6+)

Работа с интерфейсом Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Механизм «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

5000 руб.

14.01.2016    54397    16    21    

42

Управление дашбордами

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    16695    21    4    

35
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Saint 20.02.10 20:54 Сейчас в теме
Слишком сложное формирование ссылки объекта. Достаточно пары фукнций ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр(). А событие onclick можно обработать проще:
// Отказ от стандартной обработки клика.
pEvtObj.returnValue = Ложь;

Если ВРег(pEvtObj.srcElement.tagName) = "A" Тогда
	
	СсылкаТекст = Сред(pEvtObj.srcElement.href, 4);
	Ссылка = ЗначениеИзСтрокиВнутр(СсылкаТекст);
	Если Ссылка.Пустая() Или Ссылка.ПолучитьОбъект() = Неопределено Тогда
		
		Предупреждение("Выбранный объект был удалён.",, "Объект удалён");
		Возврат;
		
	Иначе
		ОткрытьЗначение(Ссылка);
	КонецЕсли;
	
КонецЕсли; 
Показать
🅵🅾️🆇; MCitrus; awa; Новенький; Ish_2; artbear; +6 Ответить
2. ll13 1047 20.02.10 21:30 Сейчас в теме
(1) Ваш вариант неработоспособен, у меня была первая мысль сделать именно так как Вы написали, но наступил на грабли.
ЗначениеВСтрокуВнутр() возвращает строку вида {"#",e18d5670-dd2f-4528-8897-d3f07ca77f21,37:a1050011d85708ff11dcb5e99d48b4a8} в html тег вы её не запихнете, точнее запихнете, но обратно не получите. Если у Вас есть работоспособная обработка формирующая и обрабатывающая ссылки с помощью
ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() выложите плиз.
3. пользователь 20.02.10 21:38
Сообщение было скрыто модератором.
...
4. пользователь 20.02.10 21:52
Сообщение было скрыто модератором.
...
13. WKBAPKA 214 21.02.10 12:14 Сейчас в теме
2(2): строку легко можно преобразовать к удобочитаемому виду... хотя с другой стороны, зачем козе боян, если можно сделать так как в статье )
12. WKBAPKA 214 21.02.10 12:13 Сейчас в теме
2(1): + 1 первое что в голову пришло при чтении статьи
24. yku 372 18.03.10 22:43 Сейчас в теме
(1),(2) и др. Ну что вы велосипед изобретаете? ведь есть же в типовой УТ в форме задачи пользователя:
" + ?(ТипЗнч(Содержимое) = Тип("Строка"), СтрЗаменить(Содержимое, Символы.ПС, ""), "" + Строка(Содержимое) + "") + "</td>

то бишь они берут просто ЗначениеВСтрокуВнутр() и запихивают в id, где он прекрасно сохраняется :).
25. Saint 18.03.10 23:25 Сейчас в теме
(24) А у тебя проблемы с изобретением велосипедов? Описанный тобой способ является не более чем ещё одним способом решения указанного вопроса и не сильно отличается от предложенного мной варианта. К тому же мной этот вариант был придуман ещё тогда, когда в типовой об этом, скорее всего, нервно курили. Так что тут ещё вопрос, кто изобретает велосипед.
26. yku 372 19.03.10 00:12 Сейчас в теме
(25) ого - немного ошарашен тоном. Предложенный вами вариант (в том виде, в каком он здесь опубликован) все-таки не работоспособен из-за наличия символа "#" в получаемой строке. И хоть это ограничение обходится за десять секунд, но обходить-то его надо. Так что вариант из типовой - легче. А существенных отличий действительно нет.

О "велосипеде" было к слову. Сожалею, что это вас "задело".
27. ll13 1047 19.03.10 00:25 Сейчас в теме
(26) Оба варианта, которые опубликованы в статье полностью работоспособны, 2-ой вариант который предложил saint наиболее простой и универсальный. Специально замечу что символ "#" нисколько не мешает ему работать ;)
29. yku 372 19.03.10 00:36 Сейчас в теме
(27) хм. а у меня мешает :(. Нет, серьезно. 1с стопорится при получении значения href. Пропадают все символы до #. Причем, если до последнего символа "#". То есть, если завернуть во всякие структуры, массивы и проч - теряется. может, от версии IE зависит?
30. ll13 1047 19.03.10 00:38 Сейчас в теме
(29) Всё дело в волшебных пузырьках :D , а точнее в префиксе "v8:"
31. yku 372 19.03.10 00:40 Сейчас в теме
(30) да ставлю я его. проверил на другом компе - нормально. что за магия? или просто спать пора?
32. Saint 19.03.10 01:16 Сейчас в теме
(31) Фиг его знает. Вариант нормально работал на IE, начиная с версии 6. Тем более что у меня используется не простой HTML, а преобразование XSL. И проблем не возникало никогда. Так что спать! :D
sergmorozov; +1 Ответить
28. Saint 19.03.10 00:30 Сейчас в теме
(26) Меня это не задело. Просто не нужно утверждать, что типовая - это круто и только там может быть правильное решение. И прежде чем утверждать, что вариант не рабочий, это не мешало бы для начала проверить. МОЙ вариант у меня работает уже года эдак 4. Почему мне не мешает символ "#"?
38. 🅵🅾️🆇 522 13.03.18 17:18 Сейчас в теме
(1) Прошу прощения за некропостинг, но вот кратенькая адаптация под УФ
&НаКлиенте
Процедура СписокПрисутствующихСотрудниковПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
	Если ДанныеСобытия.Anchor = Неопределено Или ВРег(ДанныеСобытия.Anchor.tagName) <> "A" Тогда Возврат КонецЕсли;
	СтандартнаяОбработка	= Ложь;
	Ссылка	= ПолучитьСсылкуСотрудникаИзСтрокиВнутр(Сред(ДанныеСобытия.Href, 4));
	Если Ссылка.Пустая() Тогда Сообщить("Ошибка получения ссылки сотрудника."); Возврат КонецЕсли;
	ОткрытьЗначение(Ссылка);
КонецПроцедуры // СписокПрисутствующихСотрудниковПриНажатии()

&НаСервереБезКонтекста
Функция ПолучитьСсылкуСотрудникаИзСтрокиВнутр(Строка)
	Попытка 
		Ссылка	= ЗначениеИзСтрокиВнутр(Строка);
		Если Ссылка.ПолучитьОбъект() = Неопределено Тогда 
			Возврат ПредопределенноеЗначение("Справочник.Сотрудники.ПустаяСсылка");
		Иначе
			Возврат Ссылка;
		КонецЕсли;
	Исключение 
		Возврат ПредопределенноеЗначение("Справочник.Сотрудники.ПустаяСсылка");		
	КонецПопытки;
КонецФункции // ПолучитьСсылкуСотрудникаИзСтрокиВнутр()
Показать
5. Saint 20.02.10 22:04 Сейчас в теме
Отвечаю на удалённое сообщение.
Во первых я с тобой водку не пил

Это точно, ибо я спиртное не употребляю. :D
По русски понимаешь ? Пишу ещё раз: Если есть работоспособный вариант выложи его.

Я по-русски понимаю. А ты? Весь смысл обработки я тебе уже написал. Добавлю ещё раз замечание из своего удалённого ответа: сделай
"v8:" + ЗначениеВСтрокуВнутр(ТвояСсылка)

и будет тебе счастье.
6. Abadonna 3958 20.02.10 22:11 Сейчас в теме
Тон не сбавите - буду все посты удалять.
8. Saint 20.02.10 22:19 Сейчас в теме
(6) У меня нормальный тон. Если человек не понимает шуток - тогда прошу прощения.
9. Abadonna 3958 20.02.10 22:21 Сейчас в теме
(8) Ну вот и славненько. ;)
7. maxp77 20.02.10 22:18 Сейчас в теме
Мой подход к решению:
стрOpenOrganization = "OpenInsuranceOrganization";
ОрганизацияИд	= Строка(МенеджерЗаписи_Пациент_Контакты.Контакт.Владелец.УникальныйИдентификатор());
ОрганизацияКонтакта	= "какое-то описание";
/////////////////////////////
// это кусок HTML
|			<P id=ОрганизацияКонтакта style=""DISPLAY:inline"">"+ОрганизацияКонтакта+"</P>
////////////////////////////
Процедура ПолеHTMLДокументаOnClick(Элемент, pEvtObj, Форма) Экспорт
	
	ЭлементHTML = НайтиЭлемент(pEvtObj.srcElement, "A");
	Если ЭлементHTML = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭлементHTML.id = "Команда" Тогда
		Попытка
			Форма.ВыполнитьКомандуФормы(ЭлементHTML.pathname, ЭлементHTML.target);
		Исключение
			// в случае неверной или недоступной по правам команды ничего не делаем
		КонецПопытки;
		pEvtObj.returnValue = Ложь;
		
	КонецЕсли;
	
КонецПроцедуры
//////////////////////////
Процедура ВыполнитьКомандуФормы(Команда, Значение) Экспорт

	Если Не ЗначениеЗаполнено(МенеджерЗаписи_Пациент_Контакты.Контакт) Тогда
		Возврат;
	КонецЕсли;

	Если Команда = "OpenInsuranceOrganization" Тогда

		Если Не ПустаяСтрока(Значение) Тогда
			ВыбранныйСправочник	= XMLЗначение(Тип("СправочникСсылка.Страховщики"), Значение);
			ВыбранныйСправочник.ПолучитьФорму(, ЭтаФорма, ЭтотОбъект).Открыть();
		КонецЕсли;

	КонецЕсли;

КонецПроцедуры

Показать
11. Saint 20.02.10 22:22 Сейчас в теме
(7) Мне кажется, что мой вариант проще и универсальнее. Но это уже дело хозяйское. ;)
10. maxp77 20.02.10 22:22 Сейчас в теме
///туда
Строка(___.УникальныйИдентификатор());
///оттуда
XMLЗначение(Тип("СправочникСсылка.___"), Значение);
14. WKBAPKA 214 21.02.10 12:17 Сейчас в теме
А вот это
Если СокрЛП(htmlElement.id) <> "" Тогда

можно переписать вот так:
Если Не ПустаяСтрока(htmlElement.id)  Тогда


лучше смотриться

но идея интересная, за статью +

ПЫСЫ: вы уже и поругаться тут успели :D
15. shestopalovpro 152 23.02.10 09:20 Сейчас в теме
Люди подскажите, а есть более универсальный вариант обработки onclick... Данный пример заточен под справочники...Конечно труда не составляет переделать его под другие объекты метаданных...Но может есть более универсальный способ...Например, работать, как со справочниками так и с документами...
16. Saint 23.02.10 09:25 Сейчас в теме
(15) Смотри мои 1 и 5 ответы. Изложенный в них способ универсален.
17. shestopalovpro 152 23.02.10 10:21 Сейчас в теме
(16) Извини не могу разобраться! Приведенный код не работает! Может есть рабочий примерчик!!Буду рад!!
18. Saint 23.02.10 11:31 Сейчас в теме
(17) Приведенный код работает. Делать примерчик времени пока нет.
19. ll13 1047 24.02.10 10:47 Сейчас в теме
(17) Выложил рабочий пример, по методу saint'а, см. статью
shestopalovpro; Saint; Ish_2; +3 Ответить
21. shestopalovpro 152 25.02.10 05:30 Сейчас в теме
(19) Большое спасибо!! Будемс работать!!
20. pavel_pss 289 24.02.10 21:50 Сейчас в теме
Эх, чувак, где ты был раньше :) . Но все равно полезно
22. profes 41 25.02.10 09:38 Сейчас в теме
[+] За освоение новых технологий V8 :)
23. Жарков 27.02.10 12:11 Сейчас в теме
Спасибо, буду использовать. Хорошая идея.

По оформлению статьи - чтобы правильно выводился код, несмотря на наличие HTML-тегов можно использовать тег CODE вместо картинок. Тогда и пользователям легче использовать будет.
33. O-Planet 6431 29.03.10 09:40 Сейчас в теме
Это все замечательно... Но вот реально что хочется, так это работать внутри html с объектами 1С, как с объектами именно, т.е. обращаться к их реквизитам, изменять их при необходимости и т.д. На javascript... Эх... :(
34. O-Planet 6431 29.03.10 09:41 Сейчас в теме
Поясню... Передаю, скажем, список в html, там сортирую, и он в 1С соотвественно отсортирован...
35. Saint 29.03.10 10:08 Сейчас в теме
(34) Мда... А что мешает передать уже отсортированный средствами 1С список? HTML как бы немного не предназначен для таких операций.
36. Muhin555 24 26.03.11 00:48 Сейчас в теме
А нет ли примерчика, где бы обрабатывались Checkbox-ы в теле HTML документа и значения их передавались бы в 1С????
37. PerlAmutor 129 28.07.17 12:28 Сейчас в теме
удалено.
Промазал с темой.
Оставьте свое сообщение