Все публикации

БСП
Разработки

Live template в стиле PHPStorm

Позволяет управлять последовательностью перехода к местам вставки при применении шаблона
vigor 10 2
Бесплатно

Високосный ли год?

Полное правило для определения високосного года по григорианскому календарю
Функция Високосный(Год) Экспорт
	
	Если Год % 400 = 0 Тогда
		Возврат Истина;
		
	ИначеЕсли Год % 100 = 0 Тогда
		Возврат Ложь;
		
	ИначеЕсли Год % 4 = 0 Тогда
		Возврат Истина;
	Иначе
		Возврат Ложь;
	КонецЕсли; 
		
КонецФункции

Открыть форму списка с отбором по доп.свойству / доп.реквизиту

Baiji 29 2

&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
	
	ФиксированныеНастройки = Новый НастройкиКомпоновкиДанных;
	ЭлементОтбора = ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); 
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка.[Это приложение (Договоры)]");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ЭлементОтбора.Использование = Истина;
	ЭлементОтбора.ПравоеЗначение = Истина;
	
	ФиксированныеНастройки = Новый Структура("ФиксированныеНастройки", ФиксированныеНастройки);
	
	ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаСписка", ФиксированныеНастройки, ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно, ПараметрыВыполненияКоманды.НавигационнаяСсылка);
	
КонецПроцедуры

Синтакс-помощник БСП

Синтакс-помощник БСП - cправочник по библиотеке стандартных подсистем. В состав справочника входит описание экспортных процедур и функций, размещенных в областях кода ПрограммныйИнтерфейс БСП.
prog1c 138 7 7
1 800 руб.

Загрузить картинку из интернета асинхронно

Загрузить картинку из интернета асинхронно и отобразить её на форме в реквизите типа "Строка" НаКлиенте Асинх Процедура ЗагрузитьКартинку(Команда) URL = ; // здесь надо задать URL-адрес картинки ВремФайл = ПолучитьИмяВременногоФайла(); Ждать Копи...

Функция ВремяГода(мес)

Возвращает время года по номеру месяца Функция ВремяГода(мес) Если мес = 12 ИЛИ мес = 2 Тогда Возврат Зима; ИначеЕсли мес = 5 Тогда Возврат Весна; ИначеЕсли мес = 8 Тогда Возврат Лето; Иначе Возврат Осень; КонецЕсли; КонецФункци...

кнПерезапустить_Нажатие

9815 28 2
Процедура кнПерезапустить_Нажатие(Кнопка)
    Для каждого МетаФорма Из ЭтаФорма.Метаданные().Формы Цикл
        ТекФорма = ПолучитьФорму(МетаФорма);
        Если ТекФорма.Открыта() Тогда
            ТекФорма.Закрыть();
            Если ТекФорма = ЭтаФорма Тогда
                Если Найти(Строка(ТипЗнч(ЭтотОбъект)), "Внешняя обработка объект:") = 1 Тогда
                    ВнешниеОбработки.Создать(ЭтотОбъект.ИспользуемоеИмяФайла).ПолучитьФорму(МетаФорма.Имя).Открыть();
                Иначе
                    ВнешниеОтчеты.Создать(ЭтотОбъект.ИспользуемоеИмяФайла).ПолучитьФорму(МетаФорма.Имя).Открыть();
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Шаблон юнит-теста

#Область ОписаниеПеременных

Перем КонтекстЯдра;              // Фреймворк тестирования
Перем Утверждения;               // Ассерты
Перем Данные;                    // Плагин данных
Перем УтвержденияПроверкаТаблиц; // Плагин проверки таблиц

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс

#Область СобытияФреймворкаТестирования

Процедура Инициализация(КонтекстЯдраПараметр) Экспорт
	
	КонтекстЯдра              = КонтекстЯдраПараметр;
	Утверждения               = КонтекстЯдра.Плагин("БазовыеУтверждения");
	Данные                    = КонтекстЯдра.Плагин("Данные");
	УтвержденияПроверкаТаблиц = КонтекстЯдра.Плагин("УтвержденияПроверкаТаблиц");
	
КонецПроцедуры

Процедура ЗаполнитьНаборТестов(НаборТестов, КонтекстЯдраПараметр) Экспорт
	
	КонтекстЯдра = КонтекстЯдраПараметр;
	
	НаборТестов.Добавить("Тест_ДолженПроверить");
	
КонецПроцедуры

// BSLLS:PairingBrokenTransaction-OFF
// BSLLS:BeginTransactionBeforeTryCatch-OFF
// BSLLS:WrongUseOfRollbackTransactionMethod-OFF

Процедура ПередЗапускомТеста() Экспорт
	НачатьТранзакцию();
КонецПроцедуры

Процедура ПослеЗапускаТеста() Экспорт
	Если ТранзакцияАктивна() Тогда
		ОтменитьТранзакцию();
	КонецЕсли;
КонецПроцедуры

// BSLLS:PairingBrokenTransaction-ON
// BSLLS:BeginTransactionBeforeTryCatch-ON
// BSLLS:WrongUseOfRollbackTransactionMethod-ON

#КонецОбласти

#Область Тесты

Процедура Тест_ДолженПроверить() Экспорт
	
	// Дано
	
	// Когда
	
	// Тогда
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

Шаблон http-сервиса

9815 28 2
#Область ОбработчикиСобытий

Функция ЛицензииДоступны(Запрос)
	
	Ответ = Новый HTTPСервисОтвет(200);
	ДобавитьЗаголовкиДанных(Ответ);
	Результат = Результат();
	Ответ.КодСостояния = Результат.КодСостояния;
	Ответ.УстановитьТелоИзСтроки(Результат.ТекстСостояния);
	Возврат Ответ;
	
КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Процедура ДобавитьЗаголовкиДанных(Ответ) Экспорт
	
	Заголовки = Ответ.Заголовки;
	
	Заголовки.Вставить("Accept", "application/json");
	Заголовки.Вставить("Accept-Charset", "utf-8");
	Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");	
	Заголовки.Вставить("Cache-Control", "no-cache");
	
КонецПроцедуры

Функция Результат()
	
	Попытка
		ТекстСостояния = НаличиеЛицензийТекст();
		КодСостояния = 200;
	Исключение
		ТекстСостояния = "";
		КодСостояния = 500;
	КонецПопытки;
	
	Возврат Новый Структура("ТекстСостояния, КодСостояния", ТекстСостояния, КодСостояния);
КонецФункции

Функция НаличиеЛицензийТекст()
	
	УстановитьПривилегированныйРежим(Истина);
	ЗакрытьПрограмму = Ложь;
    торо_СЛКСервер.ПроверитьЛицензииПередНачаломРаботыСистемы(ЗакрытьПрограмму);
    
	Структура = Новый Структура;
	Структура.Вставить("LicenseAvailable ", Формат(НЕ ЗакрытьПрограмму, "БЛ=false; БИ=true"));
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, Структура);
	Текст =  ЗаписьJSON.Закрыть();
	
	Возврат Текст;
КонецФункции

#КонецОбласти

Использование в Мобильном Приложении (Андроид) сканера ШтрихКодов с компонентой Драйвер1СУстройствоВводаNative от 1С

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

Передача параметров и отбора в общую форму отчета

НаКлиенте Процедура ОписьНаСтройку(Команда) КомпоновщикНастроек = ПолучитьКомпоновщикНастроек(); Настройки = КомпоновщикНастроек.Настройки; КомпоновкаДанныхКлиентСервер.УстановитьПараметр(Настройки, ДатаКонца, ТекущаяДата()); ПараметрыОткрытия = Нов...
RomanVG 122 1 6 1

Показать подтверждение закрытия Формы

Вариант 1. Будет выведено сообщение "Закрыть форму?" и 2 кнопки "Да/Нет". У формы нужно добавить реквизит, например "ЗакрытьФормуБезПодтверждения", содержащий в себе признак того, нужно выводить предупреждение или нет. НаКлиенте Процедура ПередЗакрытием(От...
RomanVG 122 1 6 1

Конвертировать объект в структуру

Возвращает структуру реквизитов объекта или ссылки, включая стандартные реквизиты и реквизиты табличной части. Можно использовать, если необходимо, например, эмулировать вызов метода, использующего объект формы.
Nerich 22 2
// Возвращает структуру реквизитов объекта или ссылки, включая стандартные реквизиты и реквизиты табличной части.
// Можно использовать, если необходимо, например, эмулировать вызов метода, использующего объект формы.
//
// Параметры:
//  ВходящийОбъект - ЛюбаяСсылка или ЛюбойОбъект
// 
// Возвращаемое значение:
//  Структура
//
Функция КонвертироватьОбъектВСтруктуру(ВходящийОбъект)

   СтруктураОбъекта = Новый Структура;

   СтандартныеРеквизитыОбъекта = ВходящийОбъект.Метаданные().СтандартныеРеквизиты;
   Для Каждого СтандартныйРеквизит Из СтандартныеРеквизитыОбъекта Цикл
       СтруктураОбъекта.Вставить(СтандартныйРеквизит.Имя, ВходящийОбъект[СтандартныйРеквизит.Имя]);
   КонецЦикла;

   РеквизитыОбъекта = ВходящийОбъект.Метаданные().Реквизиты;
   Для Каждого Реквизит Из РеквизитыОбъекта Цикл
       СтруктураОбъекта.Вставить(Реквизит.Имя, ВходящийОбъект[Реквизит.Имя]);
   КонецЦикла;

   ТЧ = ВходящийОбъект.Метаданные().ТабличныеЧасти;
   Для Каждого ТаблЧасть Из ТЧ Цикл
       ТЗ = ВходящийОбъект[ТаблЧасть.Имя].Выгрузить();
       Массив = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТЗ);
       СтруктураОбъекта.Вставить(ТаблЧасть.Имя, Массив);
   КонецЦикла;

   Возврат СтруктураОбъекта;

КонецФункции

Отправка писем с приложением эксель для БП

Отправка сформированного табличного документа в формате эксель для БП
Vitor 13 1 1
Процедура СформироатьТабДок()
	ТабДок = Новый ТабличныйДокумент;  
	ОблШапка = Макет.ПолучитьОбласть("Шапка");
	ТабДок.Вывести(ОблШапка);
	ПотокВПамяти = Новый ПотокВПамяти();
	ТабДок.Записать(ПотокВПамяти, ТипФайлаТабличногоДокумента.XLSX); 
	ДвоичныеДанные = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
	Тема = "Тема от: "+Строка(Формат(ТекущаяДата()-86400, "ДФ=dd.MM.yyyy"));
	ТекстПисьма = "";
	ОтправитьEmail("Адрес отправки", , Тема, ТекстПисьма, ДвоичныеДанные, "Имя отправителя");
КонецПроцедуры   

&НаСервере
Процедура ОтправитьEmail(АдресПочты, Копия = Неопределено, Тема, ТекстПисьма, Вложение = Неопределено, ИмяОтправителя) 
	Профиль  = Новый ИнтернетПочтовыйПрофиль;
	Профиль.АдресСервераIMAP = "imap.mail.ru";
	Профиль.АдресСервераSMTP = "smtp.mail.ru";
	Профиль.ПортSMTP = 465;
	Профиль.ПортIMAP = 993;
	Сообщение = Новый ИнтернетПочтовоеСообщение;
	Профиль.Пользователь = "Пользователь";
	Профиль.Пароль = "Пароль";
	Профиль.ПользовательSMTP = "ПользовательSMTP";
	Профиль.ПарольSMTP = "ПарольSMTP";
	Сообщение.Отправитель.Адрес = "Адрес";
	Сообщение.ИмяОтправителя = ИмяОтправителя;
	Профиль.ИспользоватьSSLSMTP = Истина;
	Сообщение.Получатели.Добавить(АдресПочты);
	Сообщение.Тема = Тема;
	Сообщение.Тексты.Добавить(ТекстПисьма, ТипТекстаПочтовогоСообщения.ПростойТекст); 
	Если Вложение <> Неопределено тогда                           
		Тема = Тема+".xlsx";
		Сообщение.Вложения.Добавить(Вложение,Тема);
	КонецЕсли;
	Почта = Новый ИнтернетПочта;
	Попытка
		Почта.Подключиться(Профиль); 
		Почта.Послать(Сообщение);
		Почта.Отключиться();
	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
КонецПроцедуры

Сколько процентов число от числа

Возвращает сколько процентов число от числа
SeiOkami 521 5 12 15
// Сколько процентов число от числа
// Источник: https://github.com/SeiOkami/CollectionMethodsOneS/issues/151
// 
// Параметры:
//  Число - Число
//  ОтЧисла - Число
//  ОкруглятьДо - Число - Количество знаков округления, 0 - не требуется
// 
// Возвращаемое значение:
//  Число
//
// Пример:
//  Процент = СколькоПроцентовЧислоОтЧисла(10, 100);  // 10
//  Процент = СколькоПроцентовЧислоОтЧисла(9, 69, 2); // 13.04
//
Функция СколькоПроцентовЧислоОтЧисла(
	Знач Число, Знач ОтЧисла, Знач ОкруглятьДо = 0) Экспорт
	
	Если ОтЧисла = 0 Тогда
		Возврат 0;
	КонецЕсли;
	
	Результат = (Число / ОтЧисла) * 100;
	
	Если ОкруглятьДо > 0 Тогда
		Результат = Окр(Результат, ОкруглятьДо);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Копия массива

Возвращает копию массива с указанием числа элементов и начального индекса В коде есть две реализации метода: 1. КопияМассиваНаполнением - Создает пустой массив и наполняет его циклом из оригинала 2. КопияМассиваУдалениемЛишних - Создает полную копию и удаления лишние элементы А так же метод КопияМассива, который в зависимости от числа объектов массива сам выбирает один из методов
SeiOkami 521 5 12 15

// Возвращает копию массива с указанием числа элементов и начального индекса
// Внутри есть определение метода копирования
// Источник: https://github.com/SeiOkami/CollectionMethodsOneS/issues/150
// 
// Параметры:
//  Массив - Массив из Произвольный
//  НачальныйЭлемент - Число - Индекс начального элемента
//  ЧислоЭлементов - Число - Число выбираемых элементов, 0 - все оставшиеся
//  МетодКопирования - Число - 0 - определять автоматически, 1 - наполнение циклом, 2 - удаление лишних
// 
// Возвращаемое значение:
//  Массив из Произвольный
//
// Примеры:
//  ИсходныйМассив = СтрРазделить("1,2,3,4,5", ",");
//  Результат = КопияМассива(ИсходныйМассив, 1, 3); //"2,3,4"     - Три элемента с индекса 1
//  Результат = КопияМассива(ИсходныйМассив, 1);    //"2,3,4,5"   - Все элементы с индекса 1
//  Результат = КопияМассива(ИсходныйМассив, 0, 2); //"1,2"       - Первые 2 элемента
//  Результат = КопияМассива(ИсходныйМассив);       //"1,2,3,4,5" - Полная копия массива
//  
Функция КопияМассива(Знач Массив, Знач НачальныйЭлемент = 0, Знач ЧислоЭлементов = 0, Знач МетодКопирования = 0) Экспорт
	
	ВсегоЭлементов = Массив.Количество();
	
	Если МетодКопирования = 0 Тогда
	
		//Если массив меньше, то нет принципиально разницы в скорости
		//TODO: Определить экспериментально идеальное значение
		МинимальнаяДлинаМассиваДляПоискаМетода = 10;
		Если ВсегоЭлементов > МинимальнаяДлинаМассиваДляПоискаМетода Тогда
		
			Если ЧислоЭлементов = 0 Тогда
				ЧислоЭлементов = ВсегоЭлементов - (НачальныйЭлемент + 1);
			КонецЕсли;
			
			Если ЧислоЭлементов = 0 Тогда
				Возврат Новый Массив;
			Иначе
				ПроцентНужных = (ЧислоЭлементов / ВсегоЭлементов) * 100;
				Если ПроцентНужных > 90 Тогда
					МетодКопирования = 2; //Легче скопировать весь большой массив и удалить лишние элементы
				Иначе
					МетодКопирования = 1; //Легче взять нужные элементы из большого массива
				КонецЕсли;
			КонецЕсли;
		
		Иначе
			
			МетодКопирования = 1; //Устроит любой метод
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если МетодКопирования = 1 Тогда
		КопияМассива = КопияМассиваНаполнением(Массив, НачальныйЭлемент, ЧислоЭлементов);
	Иначе
		КопияМассива = КопияМассиваУдалениемЛишних(Массив, НачальныйЭлемент, ЧислоЭлементов);
	КонецЕсли;
	
	Возврат КопияМассива;
	
КонецФункции

// Возвращает копию массива с указанием числа элементов и начального индекса
// Создает полную копию и удаления лишние элементы
// Эффективен, когда нужно взять бОльшую часть большОго массива
// Источник: https://github.com/SeiOkami/CollectionMethodsOneS/issues/150
// 
// Параметры:
//  Массив - Массив из Произвольный
//  НачальныйЭлемент - Число - Индекс начального элемента
//  ЧислоЭлементов - Число - Число выбираемых элементов, 0 - все оставшиеся
// 
// Возвращаемое значение:
//  Массив из Произвольный
//  
// Примеры:
//  ИсходныйМассив = СтрРазделить("1,2,3,4,5", ",");
//  Результат = КопияМассива(ИсходныйМассив, 1, 3); //"2,3,4"     - Три элемента с индекса 1
//  Результат = КопияМассива(ИсходныйМассив, 1);    //"2,3,4,5"   - Все элементы с индекса 1
//  Результат = КопияМассива(ИсходныйМассив, 0, 2); //"1,2"       - Первые 2 элемента
//  Результат = КопияМассива(ИсходныйМассив);       //"1,2,3,4,5" - Полная копия массива
Функция КопияМассиваУдалениемЛишних(Знач Массив, 
	Знач НачальныйЭлемент = 0, Знач ЧислоЭлементов = 0) Экспорт
	
	КопияМассива = Новый Массив(Новый ФиксированныйМассив(Массив));
	
	Пока НачальныйЭлемент > 0 Цикл
		КопияМассива.Удалить(0);
		НачальныйЭлемент = НачальныйЭлемент - 1;
	КонецЦикла;
	
	Если ЧислоЭлементов > 0 Тогда
		ЭлементовКУдалению = КопияМассива.Количество() - ЧислоЭлементов;
		Пока ЭлементовКУдалению > 0 Цикл
			КопияМассива.Удалить(КопияМассива.ВГраница());
			ЭлементовКУдалению = ЭлементовКУдалению - 1;
		КонецЦикла;
	КонецЕсли;
	
	Возврат КопияМассива;
	
КонецФункции

// Возвращает копию массива с указанием числа элементов и начального индекса
// Создает пустой массив и наполняет его циклом из оригинала
// Эффективен, когда нужно взять несколько элементов из оригинального большого массива
// Источник: https://github.com/SeiOkami/CollectionMethodsOneS/issues/150
// 
// Параметры:
//  Массив - Массив из Произвольный
//  НачальныйЭлемент - Число - Индекс начального элемента
//  ЧислоЭлементов - Число - Число выбираемых элементов, 0 - все оставшиеся
// 
// Возвращаемое значение:
//  Массив из Произвольный
//  
// Примеры:
//  ИсходныйМассив = СтрРазделить("1,2,3,4,5", ",");
//  Результат = КопияМассива(ИсходныйМассив, 1, 3); //"2,3,4"     - Три элемента с индекса 1
//  Результат = КопияМассива(ИсходныйМассив, 1);    //"2,3,4,5"   - Все элементы с индекса 1
//  Результат = КопияМассива(ИсходныйМассив, 0, 2); //"1,2"       - Первые 2 элемента
//  Результат = КопияМассива(ИсходныйМассив);       //"1,2,3,4,5" - Полная копия массива
Функция КопияМассиваНаполнением(Знач Массив, 
	Знач НачальныйЭлемент = 0, Знач ЧислоЭлементов = 0) Экспорт
	
	Если ЧислоЭлементов = 0 Тогда
		ЧислоЭлементов = Массив.Количество() - НачальныйЭлемент;
	КонецЕсли;
	
	КопияМассива = Новый Массив(ЧислоЭлементов);
	
	ИндексКопии = 0;
	ИндексМассива = НачальныйЭлемент;
	
	Пока ИндексКопии < ЧислоЭлементов Цикл
		
		КопияМассива[ИндексКопии] = Массив[ИндексМассива];
		
		ИндексМассива = ИндексМассива + 1;
		ИндексКопии = ИндексКопии + 1;
		
	КонецЦикла;
	
	Возврат КопияМассива;
	
КонецФункции

Построчный обход макета

Построчный обход макета
BobrAl 4 1
	Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет");
	Для Стр=1 По Макет.ВысотаТаблицы Цикл		
		Код=Макет.Область(Стр, 1).Текст; 
	КонецЦикла;

Запуск внешнего отчета в сформированном виде

Отчет находится по наименованию, указывается нужный вариант отчета.
RomanVG 122 1 6 1
&НаКлиенте
Процедура ИнформацияПоЗданиям(Команда)

	ВнешнийОтчетОбработкаДляОткрытияСсылка = ПолучитьСсылкуНаВнешнийОтчетОбработкуПоИмениНаСервере("Информация по зданиям");
	Если Не ЗначениеЗаполнено(ВнешнийОтчетОбработкаДляОткрытияСсылка) Тогда
		Сообщить("Отчет не найден");
		Возврат;
	КонецЕсли;
    
    ИмяОбработкиСлужебное = ДополнительныеОтчетыИОбработкиВызовСервера.ПодключитьВнешнююОбработку(ВнешнийОтчетОбработкаДляОткрытияСсылка);
    
    ПараметрыФормы = Новый Структура;
    
    ПараметрыФормы.Вставить("КлючВарианта", "Основной");
    ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
    
    ОткрытьФорму("ВнешнийОтчет." + ИмяОбработкиСлужебное + ".Форма", ПараметрыФормы, ЭтаФорма);

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

&НаСервереБезКонтекста
Функция ПолучитьСсылкуНаВнешнийОтчетОбработкуПоИмениНаСервере(ИмяОтчетаОбработки)
    Возврат Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(ИмяОтчетаОбработки).Ссылка;
КонецФункции

Добавление команды в общую форму отчета на БСП

В общем модуле ВариантыОтчетовПереопределяемый, в процедуре НастроитьВариантыОтчетов добавляем Процедура НастроитьВариантыОтчетов(Настройки) Экспорт ВариантыОтчетов.НастроитьОтчетВМодулеМенеджера(Настройки, Метаданные.Отчеты.тдс_ОтчетПоДебиторскойЗадолжен...
RomanVG 122 1 6 1

Преобразование отчета на СКД в таблицу значений на табличном документе

Иногда с отчетами удобнее (или быстрее) работать в MS Excel, например, когда необходимо связать несколько разных отчетов. Если отчеты выводятся с группировкой, то связать их бывает проблематично. Если у отчета нет своей формы, то можно применить такое унив...
RomanVG 122 1 6 1