Аттестация "1С:Специалист" > Аттестация "1С:Специалист" ЗУП
ЗУП 3.0 Специалист Билет 5
mkanaev:
Модуль документа "Индивидуальные тренировки":
--- Код: ---Процедура ОбработкаПроведения(Отказ, Режим)
Если Константы.ВидВремени_ИндивидуальныеТренировки.Получить().Пустая() Тогда
СообщениеПользвателю = Новый СообщениеПользователю;
СообщениеПользвателю.Текст = "Не установлена константа ""ВидВремени_ИндивидуальныеТренировки""";
СообщениеПользвателю.Сообщить();
Отказ = Истина;
КонецЕсли;
Если Константы.Показатель_ОкладПоДолжности.Получить().Пустая() Тогда
СообщениеПользвателю = Новый СообщениеПользователю;
СообщениеПользвателю.Текст = "Не установлена константа ""Показатель_ОкладПоДолжности""";
СообщениеПользвателю.Сообщить();
Отказ = Истина;
КонецЕсли;
Если Отказ Тогда
Возврат;
КонецЕсли;
Движения.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Записать();
ТаблицаДанные = Данные.Выгрузить(Новый Массив);
Для Каждого СтрокаДанные Из Данные Цикл
Если СтрокаДанные.НачалоПериода > СтрокаДанные.КонецПериода Тогда
СообщениеПользвателю = Новый СообщениеПользователю;
СообщениеПользвателю.Текст = "В строке номер: " + Строка(СтрокаДанные.НомерСтроки) + " не верно указан период";
СообщениеПользвателю.Сообщить();
Отказ = Истина;
Продолжить;
КонецЕсли;
НачалоПериода = СтрокаДанные.НачалоПериода;
Пока Год(НачалоПериода) <> Год(СтрокаДанные.КонецПериода)
Или Месяц(НачалоПериода) <> Месяц(СтрокаДанные.КонецПериода)
Или День(НачалоПериода) <> День(СтрокаДанные.КонецПериода) Цикл
СтрокаТаблицыДанные = ТаблицаДанные.Добавить();
СтрокаТаблицыДанные.сотрудник = СтрокаДанные.Сотрудник;
СтрокаТаблицыДанные.НачалоПериода = НачалоПериода;
СтрокаТаблицыДанные.КонецПериода = КонецДня(НачалоПериода);
НачалоПериода = НачалоДня(НачалоПериода + 60*60*24);
КонецЦикла;
СтрокаТаблицыДанные = ТаблицаДанные.Добавить();
СтрокаТаблицыДанные.сотрудник = СтрокаДанные.Сотрудник;
СтрокаТаблицыДанные.НачалоПериода = НачалоПериода;
СтрокаТаблицыДанные.КонецПериода = СтрокаДанные.КонецПериода;
КонецЦикла;
Если Отказ Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТаблицаДанных", ТаблицаДанные);
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("Показатель_ОкладПоДолжности", Константы.Показатель_ОкладПоДолжности.Получить());
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.Текст = "ВЫБРАТЬ
| Док.Сотрудник,
| Док.НачалоПериода,
| Док.КонецПериода
|ПОМЕСТИТЬ Данные
|ИЗ
| &ТаблицаДанных КАК Док
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВЗ.Сотрудник КАК Сотрудник,
| ВЗ.День КАК День,
| ВЗ.НачалоПериода,
| ВЗ.КонецПериода,
| РАЗНОСТЬДАТ(ВЗ.НачалоПериода, ВЗ.КонецПериода, СЕКУНДА) / (60 * 60) КАК Часов,
| МАКСИМУМ(ВЫБОР
| КОГДА ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Период ЕСТЬ NULL
| ТОГДА ЕСТЬNULL(СтавкиПоДолжности.Сумма, 0)
| ИНАЧЕ 0
| КОНЕЦ) КАК Показатель
|ИЗ
| (ВЫБРАТЬ
| Данные.Сотрудник КАК Сотрудник,
| НАЧАЛОПЕРИОДА(Данные.НачалоПериода, ДЕНЬ) КАК День,
| Данные.НачалоПериода КАК НачалоПериода,
| Данные.КонецПериода КАК КонецПериода,
| МАКСИМУМ(КадроваяИсторияСотрудников.Период) КАК ПериодСрезаДоожности
| ИЗ
| Данные КАК Данные
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
| ПО Данные.Сотрудник = КадроваяИсторияСотрудников.Сотрудник
| И (КОНЕЦПЕРИОДА(Данные.НачалоПериода, ДЕНЬ) >= КадроваяИсторияСотрудников.Период)
| И (КадроваяИсторияСотрудников.ГоловнаяОрганизация = &Организация)
|
| СГРУППИРОВАТЬ ПО
| Данные.Сотрудник,
| НАЧАЛОПЕРИОДА(Данные.НачалоПериода, ДЕНЬ),
| Данные.НачалоПериода,
| Данные.КонецПериода) КАК ВЗ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
| ПО ВЗ.Сотрудник = КадроваяИсторияСотрудников.Сотрудник
| И ВЗ.ПериодСрезаДоожности = КадроваяИсторияСотрудников.Период
| И (КадроваяИсторияСотрудников.ГоловнаяОрганизация = &Организация)
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтавкиПоДолжности КАК СтавкиПоДолжности
| ПО (ВЫБОР
| КОГДА КадроваяИсторияСотрудников.ДействуетДо = ДАТАВРЕМЯ(1, 1, 1)
| ИЛИ КадроваяИсторияСотрудников.ДействуетДо > ВЗ.День
| ТОГДА КадроваяИсторияСотрудников.Должность
| ИНАЧЕ КадроваяИсторияСотрудников.ДолжностьПоОкончании
| КОНЕЦ = СтавкиПоДолжности.Должность)
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников КАК ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников
| ПО ВЗ.Сотрудник = ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Сотрудник
| И (ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Организация = &Организация)
| И (ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Показатель = &Показатель_ОкладПоДолжности)
| И (ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Период МЕЖДУ НАЧАЛОПЕРИОДА(ВЗ.День, ДЕНЬ) И КОНЕЦПЕРИОДА(ВЗ.День, ДЕНЬ))
|
|СГРУППИРОВАТЬ ПО
| ВЗ.Сотрудник,
| ВЗ.День,
| ВЗ.НачалоПериода,
| ВЗ.КонецПериода,
| РАЗНОСТЬДАТ(ВЗ.НачалоПериода, ВЗ.КонецПериода, СЕКУНДА) / (60 * 60)
|ИТОГИ
| СУММА(Часов),
| МАКСИМУМ(Показатель)
|ПО
| Сотрудник,
| День
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Док.НомерСтроки,
| МАКСИМУМ(ВЫБОР
| КОГДА ПериодыГрупповыхТренировок.Сотрудник ЕСТЬ NULL
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ) КАК ЕстьПересечение
|ИЗ
| Документ.ИндивидуальныеТренировки.Данные КАК Док
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ИндивидуальныеТренировки.Данные КАК Док1
| ПО (Док1.Ссылка = &Ссылка)
| И Док.НомерСтроки <> Док1.НомерСтроки
| И Док.Сотрудник = Док1.Сотрудник
| И (Док.НачалоПериода < Док1.НачалоПериода
| И Док.КонецПериода > Док1.НачалоПериода
| ИЛИ Док.НачалоПериода < Док1.КонецПериода
| И Док.КонецПериода > Док1.КонецПериода
| ИЛИ Док.НачалоПериода > Док1.НачалоПериода
| И Док.КонецПериода < Док1.КонецПериода)
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПериодыГрупповыхТренировок КАК ПериодыГрупповыхТренировок
| ПО Док.Сотрудник = ПериодыГрупповыхТренировок.Сотрудник
| И (Док.НачалоПериода < ПериодыГрупповыхТренировок.НачалоПериода
| И Док.КонецПериода > ПериодыГрупповыхТренировок.НачалоПериода
| ИЛИ Док.НачалоПериода < ПериодыГрупповыхТренировок.КонецПериода
| И Док.КонецПериода > ПериодыГрупповыхТренировок.КонецПериода
| ИЛИ Док.НачалоПериода > ПериодыГрупповыхТренировок.НачалоПериода
| И Док.КонецПериода < ПериодыГрупповыхТренировок.КонецПериода)
|ГДЕ
| Док.Ссылка = &Ссылка
| И (НЕ Док1.Ссылка ЕСТЬ NULL
| ИЛИ НЕ ПериодыГрупповыхТренировок.Сотрудник ЕСТЬ NULL )
|
|СГРУППИРОВАТЬ ПО
| Док.НомерСтроки";
Результат = Запрос.ВыполнитьПакет();
ВыборкаПроверка = Результат[2].Выбрать();
Пока ВыборкаПроверка.Следующий() Цикл
СообщениеПользвателю = Новый СообщениеПользователю;
Если Не ВыборкаПроверка.ЕстьПересечение Тогда
СообщениеПользвателю.Текст = "Не верно указан период в строке номер: " + Строка(ВыборкаПроверка.НомерСтроки);
Иначе
СообщениеПользвателю.Текст = "Не верно указан период в строке номер: " + Строка(ВыборкаПроверка.НомерСтроки) + " в это время есть групповое занятие";
КонецЕсли;
СообщениеПользвателю.Сообщить();
Отказ = Истина;
КонецЦикла;
Если Отказ Тогда
Возврат;
КонецЕсли;
ВыборкаСотрудников = Результат[1].Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаСотрудников.Следующий() Цикл
ЗначениеПоказателя = 0;
НачалоПериода = Неопределено;
ВыборкаДень = ВыборкаСотрудников.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаДень.Следующий() Цикл
Движение = Движения.ДанныеОперативногоУчетаРабочегоВремениСотрудников.Добавить();
Движение.Период = ВыборкаДень.День;
Движение.Сотрудник = ВыборкаСотрудников.Сотрудник;
Движение.ПериодРегистрации = НачалоМесяца(ВыборкаДень.День);
Движение.ВидУчетаВремени = Константы.ВидВремени_ИндивидуальныеТренировки.Получить();
Движение.ВидДанных = Перечисления.ВидыДанныхУчетаВремениСотрудников.ДополнительноеВнутрисменноеВремя;
Движение.Часы = ВыборкаДень.Часов;
Если ЗначениеПоказателя = 0 Тогда
ЗначениеПоказателя = ВыборкаДень.Показатель;
НачалоПериода = ВыборкаДень.День;
Продолжить;
КонецЕсли;
Если ЗначениеПоказателя <> ВыборкаДень.Показатель И Не ЗначениеПоказателя = 0 Тогда
Движение = Движения.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Добавить();
Движение.Период = НачалоПериода;
Движение.Сотрудник = ВыборкаСотрудников.Сотрудник;
Движение.Организация = Организация;
Движение.ФизическоеЛицо = ВыборкаСотрудников.Сотрудник.ФизическоеЛицо;
Движение.Показатель = Константы.Показатель_ОкладПоДолжности.Получить();
Движение.Значение = ЗначениеПоказателя;
Движение.ДействуетДо = ВыборкаДень.День;
ЗначениеПоказателя = ВыборкаДень.Показатель;
НачалоПериода = ВыборкаДень.День;
Продолжить;
КонецЕсли;
КонецЦикла;
Если Не ЗначениеПоказателя = 0 Тогда
Движение = Движения.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Добавить();
Движение.Период = НачалоПериода;
Движение.Сотрудник = ВыборкаСотрудников.Сотрудник;
Движение.Организация = Организация;
Движение.ФизическоеЛицо = ВыборкаСотрудников.Сотрудник.ФизическоеЛицо;
Движение.Показатель = Константы.Показатель_ОкладПоДолжности.Получить();
Движение.Значение = ЗначениеПоказателя;
КонецЕсли;
КонецЦикла;
Если Не Отказ Тогда
Движения.ДанныеОперативногоУчетаРабочегоВремениСотрудников.Записывать = Истина;
Движения.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.Записывать = Истина;
КонецЕсли;
КонецПроцедуры
--- Конец кода ---
mkanaev:
Отчет СКД:
--- Код: ---ВЫБРАТЬ
НАЧАЛОПЕРИОДА(ВЗ.ПериодДействияНачало, МЕСЯЦ) КАК Месяц,
ВЗ.Сотрудник,
ВЗ.ПериодДействияНачало КАК ПериодСреза,
0 КАК ЧасовПоГрафикуДежурства,
ВЫБОР
КОГДА ВЗ.ВидРасчета = &Оклад
ТОГДА ВЗ.Результат
ИНАЧЕ 0
КОНЕЦ КАК Начислено_Дежурство,
ВЫБОР
КОГДА ВЗ.ВидРасчета = &ГрупповыеЗанятия
ТОГДА ВЗ.Результат
ИНАЧЕ 0
КОНЕЦ КАК Начислено_ГрупповыеЗанятия,
ВЫБОР
КОГДА ВЗ.ВидРасчета = &ИндивидуальныеЗанятия
ТОГДА ВЗ.Результат
ИНАЧЕ 0
КОНЕЦ КАК Начислено_ИндивидуальныеЗанятия,
ВЫБОР
КОГДА ВЗ.ВидРасчета = &Оклад
ТОГДА ВЫБОР
КОГДА ВЗ.ОтработаноЧасов ЕСТЬ NULL
ТОГДА ВЗ.ОтработаноЧасов_ИндивидуальныйГрафик
ИНАЧЕ ВЗ.ОтработаноЧасов
КОНЕЦ
ИНАЧЕ 0
КОНЕЦ КАК Часов_Дежурство,
ВЫБОР
КОГДА ВЗ.ВидРасчета = &ГрупповыеЗанятия
ТОГДА ВЫБОР
КОГДА ВЗ.ОтработаноЧасов ЕСТЬ NULL
ТОГДА ВЗ.ОтработаноЧасов_ИндивидуальныйГрафик
ИНАЧЕ ВЗ.ОтработаноЧасов
КОНЕЦ
ИНАЧЕ 0
КОНЕЦ КАК Часов_ГрупповыеЗанятия,
ВЫБОР
КОГДА ВЗ.ВидРасчета = &ИндивидуальныеЗанятия
ТОГДА ВЫБОР
КОГДА ВЗ.ОтработаноЧасов ЕСТЬ NULL
ТОГДА ВЗ.ОтработаноЧасов_ИндивидуальныйГрафик
ИНАЧЕ ВЗ.ОтработаноЧасов
КОНЕЦ
ИНАЧЕ 0
КОНЕЦ КАК Часов_ИндивидуальныеЗанятия
ПОМЕСТИТЬ Данные
ИЗ
(ВЫБРАТЬ
Начисления.Регистратор КАК Регистратор,
Начисления.НомерСтроки КАК НомерСтроки,
Начисления.Сотрудник КАК Сотрудник,
Начисления.ВидРасчета КАК ВидРасчета,
Начисления.ПериодДействияНачало КАК ПериодДействияНачало,
Начисления.ПериодДействияКонец КАК ПериодДействияКонец,
Начисления.Результат КАК Результат,
СУММА(ЕСТЬNULL(ГрафикиРаботыПоВидамВремени.ДополнительноеЗначение, 0)) КАК ОтработаноЧасов_ИндивидуальныйГрафик,
Начисления.ОсновноеЗначениеФактическийПериодДействия КАК ОтработаноЧасов
ИЗ
РегистрРасчета.Начисления.ДанныеГрафика(
ГоловнаяОрганизация = &Организация
И ВидРасчета В (&Оклад, &ГрупповыеЗанятия, &ИндивидуальныеЗанятия)) КАК Начисления
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.Начисления.ФактическийПериодДействия(
ГоловнаяОрганизация = &Организация
И ВидРасчета В (&Оклад, &ГрупповыеЗанятия, &ИндивидуальныеЗанятия)) КАК ФактическийПриодДействия
ПО Начисления.Регистратор = ФактическийПриодДействия.Регистратор
И Начисления.НомерСтроки = ФактическийПриодДействия.НомерСтроки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ГрафикиРаботыПоВидамВремени КАК ГрафикиРаботыПоВидамВремени
ПО (ГрафикиРаботыПоВидамВремени.ГрафикРаботы = ФактическийПриодДействия.ГрафикРаботы)
И (ГрафикиРаботыПоВидамВремени.ВидУчетаВремени = ФактическийПриодДействия.ВидУчетаВремени)
И (ГрафикиРаботыПоВидамВремени.Дата МЕЖДУ ФактическийПриодДействия.ПериодДействияНачало И ФактическийПриодДействия.ПериодДействияКонец)
И (НЕ ГрафикиРаботыПоВидамВремени.ВремяВЧасах)
И (ТИПЗНАЧЕНИЯ(ФактическийПриодДействия.ГрафикРаботы) = ТИП(Справочник.Сотрудники))
ГДЕ
Начисления.ПериодДействияНачало МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
Начисления.Регистратор,
Начисления.НомерСтроки,
Начисления.Сотрудник,
Начисления.ВидРасчета,
Начисления.ПериодДействияНачало,
Начисления.ПериодДействияКонец,
Начисления.Результат,
Начисления.ОсновноеЗначениеФактическийПериодДействия) КАК ВЗ
ОБЪЕДИНИТЬ
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(ВЗ.ПериодДействияНачало, МЕСЯЦ),
ВЗ.Сотрудник,
ВЗ.ПериодДействияНачало,
ВЫБОР
КОГДА ВЗ.ЧасовПоНорме ЕСТЬ NULL
ТОГДА ВЗ.ЧасовПоНорме_ИндивидуальныйГрафик
ИНАЧЕ ВЗ.ЧасовПоНорме
КОНЕЦ,
0,
0,
0,
0,
0,
0
ИЗ
(ВЫБРАТЬ
Начисления.Регистратор КАК Регистратор,
Начисления.НомерСтроки КАК НомерСтроки,
Начисления.Сотрудник КАК Сотрудник,
Начисления.ВидРасчета КАК ВидРасчета,
Начисления.ПериодДействияНачало КАК ПериодДействияНачало,
Начисления.ПериодДействияКонец КАК ПериодДействияКонец,
Начисления.ОсновноеЗначениеНормаПериодДействия КАК ЧасовПоНорме,
СУММА(ЕСТЬNULL(ГрафикиРаботыПоВидамВремени.ДополнительноеЗначениеНорма, 0)) КАК ЧасовПоНорме_ИндивидуальныйГрафик
ИЗ
РегистрРасчета.Начисления.ДанныеГрафика(
ГоловнаяОрганизация = &Организация
И ВидРасчета = &Оклад) КАК Начисления
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ГрафикиРаботыПоВидамВремени КАК ГрафикиРаботыПоВидамВремени
ПО Начисления.ГрафикРаботы = ГрафикиРаботыПоВидамВремени.ГрафикРаботы
И Начисления.ВидУчетаВремени = ГрафикиРаботыПоВидамВремени.ВидУчетаВремени
И (ГрафикиРаботыПоВидамВремени.Дата МЕЖДУ Начисления.ПериодДействияНачало И Начисления.ПериодДействияКонец)
И (НЕ ГрафикиРаботыПоВидамВремени.ВремяВЧасах)
И (ТИПЗНАЧЕНИЯ(Начисления.ГрафикРаботы) = ТИП(справочник.Сотрудники))
ГДЕ
Начисления.ПериодДействияНачало МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
Начисления.Регистратор,
Начисления.НомерСтроки,
Начисления.Сотрудник,
Начисления.ВидРасчета,
Начисления.ПериодДействияНачало,
Начисления.ПериодДействияКонец,
Начисления.ОсновноеЗначениеНормаПериодДействия) КАК ВЗ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Данные.Сотрудник,
Данные.ПериодСреза
ПОМЕСТИТЬ ТаблицаСреза
ИЗ
Данные КАК Данные
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЗНАЧЕНИЕ(Справочник.Сотрудники.ПустаяСсылка) КАК Сотрудник,
ДАТАВРЕМЯ(1, 1, 1) КАК ПериодСреза,
ЗНАЧЕНИЕ(Справочник.Должности.ПустаяСсылка) КАК Должность
ПОМЕСТИТЬ Представления_Должности
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Данные.Месяц,
Данные.Сотрудник,
Представления_Должности.Должность,
СУММА(Данные.ЧасовПоГрафикуДежурства) КАК ЧасовПоГрафикуДежурства,
СУММА(Данные.Начислено_Дежурство) КАК Начислено_Дежурство,
СУММА(Данные.Начислено_ГрупповыеЗанятия) КАК Начислено_ГрупповыеЗанятия,
СУММА(Данные.Начислено_ИндивидуальныеЗанятия) КАК Начислено_ИндивидуальныеЗанятия,
СУММА(Данные.Часов_Дежурство) КАК Часов_Дежурство,
СУММА(Данные.Часов_ГрупповыеЗанятия) КАК Часов_ГрупповыеЗанятия,
СУММА(Данные.Часов_ИндивидуальныеЗанятия) КАК Часов_ИндивидуальныеЗанятия
ИЗ
Данные КАК Данные
ЛЕВОЕ СОЕДИНЕНИЕ Представления_Должности КАК Представления_Должности
ПО Данные.Сотрудник = Представления_Должности.Сотрудник
И Данные.ПериодСреза = Представления_Должности.ПериодСреза
СГРУППИРОВАТЬ ПО
Данные.Месяц,
Данные.Сотрудник,
Представления_Должности.Должность
--- Конец кода ---
серж:
--- Цитата: mkanaev от Апрель 05, 2016, 09:55:32 am ---7. Создал документ "ИндивидуальныеТренировки". Документ формирует движения в регистр накопления "ДанныеОперативногоУчетаРабочегоВремениСотрудников"
--- Конец цитаты ---
Круто, запись в этом регистре вытесняет все прочие виды времени. Это означает, что записав 1 час времени персональной тренировки в этот регистр, явка сотрудника в этот день тоже будет 1 час, с соответствующим уменьшением з/п при расчете.
Такие решения прокатывают на экзамене ?
alsygaev:
Всем привет. Предлагаю свое решение билета 5 без отчета. Решение выполнено на релизе 3.1.7.128. Прошу покритиковать.
VAAngelov:
Прикладываю свое переработанное решение на основе решения пользователя mkanaev. И прикладываю описание решения(пользователь mkanaev)
Навигация
Перейти к полной версии