1С поиск ссылок на объект программно: Поиск ссылок на объекты в 1С 8.3

Поиск битых ссылок — pro1C8.ru

Главная » Администрирование

Автор nikto323 На чтение 3 мин Просмотров 885 Опубликовано

В результате некорректных загрузок из других информационных баз или удаления объектов без контроля ссылочной целостности в базе 1С могут появляться так называемые «битые ссылки» — ссылки на объекты, которых нет в базе. 1С:Предприятие обладает средствами выявления таких некорректных ссылок.

Содержание

  1. Битые ссылки глазами пользователя
  2. Сервис «Тестирование и исправление информационной базы»
  3. Программный поиск битых ссылок

Битые ссылки глазами пользователя

В режиме предприятия битые ссылки выглядят так:


Внимание!

Следует учесть, что такую же «картинку» пользователь может увидеть и в случае некорректно настроенных ролей.


Ниже описано несколько способов поиска некорректных ссылок на объекты.

Сервис «Тестирование и исправление информационной базы»

Для открытия окна настройки проверки необходимо в конфигураторе выбрать пункт меню Администрирование > Тестирование и исправление.

В открывшемся окне устанавливаем флаг «Проверка ссылочной целостности информационной базы». Данная проверка выполняется только совместно с проверкой логической целостности информационной базы.

Далее выбираем что необходимо сделать при обнаружении битых ссылок:

  • Только тестирование — после анализа будет отображен перечень некорректных ссылок;
  • Тестирование и исправление — можно не только получить перечень некорректных ссылок, но и исправить их: очистить некорректную ссылку или создать объект, соответствующий некорректной ссылке.

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

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

Программный поиск битых ссылок

Программный поиск битых ссылок обладает одним несомненным преимуществом: нет необходимости устанавливать монопольный режим и ограничивать доступ пользователей к базе.

Фирма 1С не предоставляет какой-то универсальной обработки для поиска битых ссылок в пользовательском режиме, поэтому придется «творить» самому. Вот несколько подходов, которые можно использовать:

  • Получение в запросе подчиненного реквизита и сравнение его с NULL. В качестве подчиненного реквизита наиболее рационально использовать ссылку — она есть у всех объектов. В запросе также необходимо учесть, что подчиненный реквизит от пустой ссылки также возвращает NULL.
  • Получение объекта от ссылки при помощи метода ПолучитьОбъект(). Если ссылка битая, то будет возвращено значение Неопределено.
  • Получение представления ссылочного типа и сравнение его со строкой «<Объект не найден>».

// ***** Поиск битых ссылок при помощи запроса *****
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка,
| ПоступлениеТоваровУслуг.Контрагент
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| И ПоступлениеТоваровУслуг.Контрагент.Ссылка ЕСТЬ NULL";

// ***** Определение корректности ссылки при помощи метода ПолучитьОбъект() *****
Если ЗначениеЗаполнено(Док.Контрагент) И Док.Контрагент.ПолучитьОбъект() = Неопределено Тогда
// Значение реквизита Контрагент — битая ссылка
КонецЕсли;

// ***** Определение корректности ссылки путем анализа представления *****
Если Найти(Строка(Док.Контрагент), «<Объект не найден>») > 0 Тогда
// Значение реквизита Контрагент — битая ссылка
КонецЕсли;

Поиск и удаление дублей в системе 1С:Предприятие 8

    B этой стaтьe мы рассмотpим возможность поиcка и удаления дублeй в «1С:Предприятие 8. 3» и «1С:Предприятие 8.2». Проиллюстрируем, как работать с типовой обрабoткой «Поиск и удаление дублей» в системе 1С в виде пошаговой инструкции. А также подробно рассмотрим, как в 1С 8.3 осуществить поиск повторов и как правильно сделать удаление дублей.

    Если в программе 1С не следить за данными, то неизбежно дублированиe информации. Чаще всего это происходит в справочниках «Номенклатуpа» и «Контpагенты».

    Поиск и удаление дублей в «1С:Предприятие 8.2»

    В 1С 8.2 поиск и удаление дублей можно осуществить при помощи обработки с диcка ИТC: «Поиcк и замена данных» (8.2). Эта универсальная обработка, которая позволяет нам менять одни значения на другие, после чего объекты без ссылок помечались на удаление и удалялись обработкoй «Удалениe помеченных объeктов».

    Процесс поиcка и удалeния дублей в 1C 8.2 можно вести отдельными операциями:

  •  Путём фиксирования наличия дубля в программе.
  •  Определением наибольшего количества ссылок на найденную пару.
  •  Обработкой «Поиcк и замена данныx» (объект с меньшим числом ссылок, как правило, замещается найденным дублем с большим количеством ссылок).
  •  Объектом, ссылки на который были замещены, помечался на удаление и физически удалялся из базы 1С 8.2 по обработкe «Удаление помеченныx oбъектов».

    Поиск и удаление дублей в «1С:Пред- приятие 8.3»

    В программный продукт «1С:Бухгалтерия 8. Редакция 3.0» уже встpоен уникальный механизм поискa и устранения дублeй. Это типовая обрабoтка «Поиск и удаление дублей», котоpая подходит для поиcка не толькo в номенклатуpе и контрагентаx, нo и в дpугих справочникаx и документах.

    Типовая обработка в 1С 8.3 «Поиск и удаление дублей» максимально упрощает работу по удалению из базы лишней информации. Причём, по правильному удалению – без нарушений учёта в базе данных!

    Где находится обрабoтка «Поиск и удаление дублей»

    Обработку можно вызвать:

  •  Главное меню/Вcе функции/Обpаботки/Поиск и удаление дублeй.
  •  Раздел Администрирование/Поддержка и обслуживание.
  •  Настроив Панель Навигации раздела Администрирования: настройка Панели Навигации – выбор в доступных командах команды «Поиск и удаление дублей».

    Возможности обpаботки «Поиск и удаление дублей»

   Что нам нужно знать об этой обработке?

  •  Обработка предназначена для поиcка и устpанения дублей во всех cписках прогpаммы 1С (для администраторов программы 1С – должны быть
    Полные права
    ).
  •  Обpаботка позволяет нaйти вхождения вcех продублированных элементов в базе данных 1С и производит замену дублей сcылками на выбpанный «правильный» элемент.

    Как работать с этой обработкой мы пошагово рассмотрим в этой статье.

    Шаг 1. Запуск поиска дублирующих- ся элементов

    Вызываем форму обpаботки «Поиск и удаление дублей».

    Устанавливаем условия выбора элементов поиска:

    1. Выбор справочников или документов, в которых обработка произведёт поиск дубликатов.

    2. Наложение условий отбора выбора, например, не помеченный на удаление, заполненный реквизит ИНН.

    3. Правила поиска дублей: по умолчанию задано совпадение наименований, но можно задать другие. Например, совпадение ИНН или кодов (при первом случае в 1С 8.3) выйдет предупреждение о наличии в базе введённого ИНН, а совпадение кодов из-за заложенной уникальности номеров в 1С большей частью невозможно.

    По нажатию кнопки «Поиск дублей» происходит отбор и сравнение данных по заданным условиям. Если дубли не обнаружены, то выводится соответствующее сообщение: «Не обнаружено дублей по указанным параметрам».

    При обнаружении дублей — выводится перечень дублей. Перечень состоит из 2-х частей: слева — найденные элементы. Справа — информация по выделeнным элементам: количество найденных дублей и cписок документов, в котоpых они использованы.

    Шаг 2. Выбор оригинала

    Один из элементов левой части автоматически программой 1С выбиpается как оригинал.

    Однако, можно выбрать другой элемент, выделив егo, и нажав кнопку «Отметить как оригинал». Дубли в спиcке маркируются флажками.

    Шаг 3. Непосредственно удаление дублей в «1С:Предприятие 8.3»

    Удаление дублей происходит по кнопке «Удалить дубли». Дубли будут помечены на удаление, все их вложения в документах заменяются на выбранный Оригинал. Окончательно удaлить дубли можно обрaботкой «Удаление помеченных объектов» (раздeл Администрированиe/Поддержка и обcлуживание).

    Пример удаления дублeй в справочникe «Банковские счетa»

    Заполняем форму «Поиск и удаления дублей»:

    1. Справочник банковские счета.

    2. Не помечены на удаление.

    3. Сравнивать по наименованию.

    Например, в базе 1С 8.3 есть 3 дубля банковских счетов, посмотрим, как обработка удалит лишние ссылки:

нажимаем на кнопку «Найти дубли». Программа 1С 8.3 нашла все три дубля и предлагает оставить тот объект, у которого больше ссылок. Это разумно, так и делаем;

нажимаем кнопку «Удалить дубли». После выполнения всех действий программа 1С выдаст сообщение об успешном завершении: Все найденные дубли (3) успешно объединены.

    Смотрим справочник «Банковские счета»:

два банковских счёта помечены на удаление. Теперь удаляем их по обработке «Удаление помеченных объектов».

    Будьте внимательны! Обязaтельно сделайте резеpвную кoпию перед удалением дублей, поскольку процедура необратимая. По окончанию удаления дублей сформируйте основные отчёты, выполните экспресс-проверку учёта, тестиpование и испpавление базы.

По материалам Профбух8.ру

   

java. Можно ли увидеть все ссылки на объект во время выполнения?

спросил

Изменено 7 лет, 1 месяц назад

Просмотрено 17 тысяч раз

Есть ли способ увидеть все ссылки на объект во время выполнения?

Я использую Netbeans, существует ли в нем эта функция?

РЕДАКТИРОВАТЬ: Нет проблем с использованием профилировщиков для этого, мне нужно только знать ссылки, неважно как.

  • Java
  • объект
  • netbeans
  • ссылка

7

Хорошо, Netbeans показывает все ссылки на объект.

Сначала запустить проект в режиме отладки CTRL + F5 , после показать загруженные классы Alt + Shift + 4 или Window->Debug->Loaded Classes .

Выберите класс, который хотите просмотреть ссылки, и дважды щелкните по нему.

Приостановить выполнение и есть.

Вверху атрибуты объекта, а внизу все ссылки на него.

2

Если вы сбросите кучу и проанализируете ее, вы найдете все ссылки. Профилировщики, такие как VisualVM и YourKit, могут сделать это за вас.

Однако это невозможно определить динамически. Если вы хотите знать все, что относится к объекту, вы должны поддерживать их коллекцию самостоятельно.

1

В Netbeans вы можете использовать функцию Find Usages , чтобы увидеть, где конкретный класс может упоминаться в конкретном проекте.

В Project Explorer выберите класс и щелкните правой кнопкой мыши > Find Usages .

Результаты выглядят примерно так, как показано на следующем рисунке:

0

Извините, непонятно. Мне нужны ссылки во время выполнения. Все ссылка созданного объекта

К сожалению, в Java такой возможности нет. Но есть способ получать уведомления об отсутствии ссылок на объект во время выполнения.

Решение состоит в том, чтобы создать слабую ссылку на отслеживаемый объект и связать ее с очередью ссылок. Когда больше не будет жесткой ссылки на этот объект, сборщик мусора рано или поздно вспомнит об этом и поставит в очередь слабую ссылку. Вы можете проверить это с помощью isEnqueued().

Если вы предоставите больше информации о своей проблеме, возможно, мы сможем дать больше советов и рекомендаций.

РЕДАКТИРОВАТЬ

Чтобы контролировать все ссылки на объект, вы можете использовать шаблон прокси. Вместо установки ссылок на ваш объект подключения вы создаете прокси-объект, содержащий частный экземпляр объекта подключения. Затем сделайте так, чтобы ваш код вызывал прокси, который будет вызывать сам объект соединения, вместо того, чтобы иметь прямые ссылки на соединение.

Когда вы закончите с объектом соединения, закройте его внутри прокси-объекта. Если другие части кода по-прежнему пытаются получить доступ к этим объектам подключения через прокси, вы сможете обнаружить это в прокси при его вызове.

Это уловка, которую вы можете использовать, чтобы определить, какая часть кода все еще «ссылается» на ваш объект, так сказать.

Надеюсь, это поможет.

3

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Обязательно, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

android — Как бы вы программно искали объект массив по имени объекта в Kotlin

Мне нужно сделать некоторые сложные вещи для приложения, которое я только начал делать, и я не знаю, как бы я сделал много Это. Вот как все работает. У меня есть объект, содержащий «комнаты», которые игрок сгенерировал и исследовал. Каждая из этих «комнат» — это еще один объект, содержащий данные для этой конкретной комнаты, такие как ее местоположение или предметы в этой комнате. В первом объекте также есть один массив, который содержит все объекты «комнаты». Эти объекты будут созданы программно, когда пользователь создаст новую комнату, которую он раньше не посещал, а имя объекта будет создано на основе местоположения комнаты (что я тоже не знаю, как это сделать, но это будущий выпуск).

Первое, что мне нужно сделать, это найти в массиве внутри этого первого объекта под названием «Комнаты» другой объект, имя которого совпадает с местоположением игрока. Это определяется тремя переменными, которые определяют, где находится игрок в сетке комнат. Таким образом, 0, 0, 0 будет начальным местоположением, и, например, если игрок пройдет 1 комнату вправо, 2 комнаты назад и 1 этаж вверх, местоположение игрока будет X: 1, Y: -2, Z: 1. Имя объекта этой комнаты будет «R1_n2_1», поэтому игра будет искать в массиве объект с именем «R1_n2_1» и загружать его, если он будет найден. Но если нет объекта с совпадающим именем, то он создаст новую комнату и добавит данные этой новой комнаты в качестве другого объекта, имя которого соответствует тому, что он искал («R1_n2_1»), а затем новый объект также будет добавлен к массиву, указывающему все эти «комнаты»/объекты (как упоминалось ранее, я выясню это позже).

Что мне нужно, так это то, как я буду искать это имя объекта, программно генерируя имя объекта, которое я ищу, а затем находя объект, имя которого соответствует этому. Например, мой текущий код, который почти наверняка не будет работать, но передает идею, генерирует строку имени объекта, который он ищет, а затем ищет совпадение в массиве. Однако он никогда не найдет это совпадение, потому что ищет строку, а не объект с совпадающим именем.

 класс GameActivity : AppCompatActivity() {
private var exitedFrom = "start" //start; л; р; т; б; туннель; лестница; ?;
частная переменная Xcord: Long = 0
частная переменная Ycord: Long = 0
частная переменная Zcord: Long = 0
переопределить удовольствие onCreate(savedInstanceState: Bundle?) {
    super. onCreate(сохраненныйInstanceState)
    setContentView (R.layout.activity_game)
    полноэкранный()
    сгенерировать комнату ()
}
личное развлечение generateRoom() {
    val room = "R$Xcord"+"_$Ycord"+"_$Zcord"
    если (Комнаты.комнаты.содержит(комната)) {
        //загружаем комнату
        println("комната $найдена")
    } else println("комната $комната не найдена") //результат всегда такой
}
 

Вот мой Объект для всех комнат. Шаблон — это то, что будет клонировано для создания новой комнаты, а R0_0_0 — начальная комната.

 Объект Комнаты {
    шаблон объекта {
    переменная х = 0
    переменная у = 0
    переменная г = 0
    переменная выходаT = ложь
    переменная выходаB = ложь
    переменная выхода L = ложь
    переменная exitR = ложь
    }
    
    объект R0_0_0 { //R(x)_(y)_(z)
    переменная х = 0
    переменная у = 0
    переменная г = 0
    переменная выходаT = истина
    вар выходB = истина
    переменная выхода L = истина
    вар выходR = истина
    }
    переменные комнаты = arrayListOf (Шаблон, R0_0_0)
    
}
 9Обновление 0125 

: Моя первая идея заключалась в том, чтобы буквально вообще не заботиться об имени объекта и искать каждый объект, указанный в массиве, для соответствующих переменных местоположения (x, y, z). Однако это не работает, поскольку, если массив содержит более одного объекта, он не может искать все в массиве на предмет соответствия любой из его переменных. Вот эта функция:

 private fun generateRoom() {
    Rooms.rooms.forEach {
        if(it.x == Xcord && it.y == Ycord && it.z == Zcord) {
            println("Комната найдена")
        }
    }
}
 

Есть ли способ обойти это или я должен сделать что-то еще? Будет ли работать «класс данных» вместо объектов? Я не знаю, как работают классы данных, но они звучат многообещающе. Я уже начал что-то пробовать, но понятия не имею, как это будет работать. Любые другие идеи или рабочие решения были бы очень полезны!
Последний вопрос: можно ли сохранить эти объекты с помощью SharedPreferences или онлайн-баз данных, и если да, то как?

  • андроид
  • массивы
  • котлин
  • object

Сначала я хочу отметить несколько вещей:

  • По возможности следует избегать использования object , которые содержат изменяемое состояние (свойства var или свойства val , ссылающиеся на экземпляры изменяемого класса). Они, как правило, делают код хрупким (легко вносить ошибки), потому что общее состояние можно легко изменить из любого места, и они очень усложняют написание тестового кода. Они также могут вызвать утечку памяти, если вы не будете осторожны с ними.
  • Даже если вы изменили Template и R0_0_0 на классы, они выглядят бессмысленно. У них одинаковые свойства, поэтому они должны быть одного класса. И не имеет смысла иметь координаты в имени класса. Если у вас есть сетка 10x10x10, вы собираетесь вручную определять 1000 классов с одинаковыми свойствами? Вам нужен только один класс, из которого вы создадите неопределенное количество экземпляров во время выполнения.
  • Вы не должны хранить состояние игры в действии. Действия какие-то эфемерные. Если пользователь повернет экран, ответит на звонок, подключит клавиатуру и т. д., экземпляр Activity будет уничтожен, и вы потеряете свои игровые данные. Трудным решением было бы превратить ваши игровые классы в Parcelables и использовать onSavedInstanceState для резервного копирования и восстановления после изменения конфигурации. Простое решение — просто переместить эти свойства, представляющие состояние игры, в ViewModel.
  • Не используйте строки для представления состояния, если можете. Это хрупкий код, где вы можете легко сделать опечатку, и IDE не сможет заранее указать на вашу ошибку. Класс перечисления был бы гораздо более подходящим для представления вашей переменной exitedFrom .

Что касается вопроса, о котором вы спрашиваете, то он естественно подходит для MutableMap. Карта содержит записи по уникальным ключам, и каждый ключ, помещенный в карту, может содержать одно значение (в данном случае экземпляр вашего класса Room). Карты предназначены для очень эффективного поиска значений по ключу, но вы также можете эффективно перебирать их, чтобы найти что-то, если вам нужно сделать это таким образом.

Ключи должны быть членами класса, который правильно реализует hashcode() и equals() , что легко выполняется автоматически с использованием класса данных. В этом случае естественным типом ключа будет класс, представляющий координату. Также важно выбрать неизменяемый ключевой класс, чтобы избежать потенциальных ошибок, поэтому все свойства этого координатного класса должны быть val s.

Итак, соединив все это воедино, я бы исправила ваш код с парой примеров функций, которые отвечают на ваш вопрос о поиске комнат.

 // Классы, представляющие состояние игры:
// Этот класс является неизменяемым и является классом данных, поэтому мы можем безопасно использовать его в качестве ключа карты.
// Когда мы хотим внести изменения, мы используем функцию copy() для создания
// новый экземпляр класса.
класс данных координата(
    знач х: Длинный = 0,
    значение: Длинный = 0,
    значение z: длинное = 0
) {
    // Функции удобства:
    fun moveByX(количество: длинное) = копировать(x = x + количество)
    fun moveByY(количество: длинное) = копия(y = y + количество)
    fun moveByZ(количество: длинное) = копировать(z = z + количество)
}
Класс Комната (координата значения: Координата) {
    переменная выходаT = истина
    вар выходB = истина
    переменная выхода L = истина
    вар выходR = истина
    // Я предполагаю, что вы добавите другие свойства, например наличие лестницы
    // движение вверх и/или вниз и т.  д.
)
// Enum для замены строки, которую вы использовали для отслеживания направления движения
Перечисление класса Движение {
    Start, Left, Right, Top, Bottom, UpLadder, DownLadder
}
 
 класс GameActivity : AppCompatActivity() {
    // Прочтите документацию Android о ViewModels, чтобы понять, почему мы
    // создаем экземпляр таким образом.
    val viewModel: GameViewModel от viewModels()
    переопределить удовольствие onCreate(savedInstanceState: Bundle?) {
        super.onCreate(сохраненныйInstanceState)
        setContentView (R.layout.activity_game)
        полноэкранный()
        // Настраиваем пользовательский интерфейс, который рисует элементы на основе свойств
        // viewModel и вызывает функции viewModel, когда пользователь
        // щелкает материал.
    }
}
 
 класс GameViewModel: ViewModel() {
    var playerCoordinate = Координата()
    private var exitedFrom = Movement.Start
    // Карта, содержащая все комнаты, созданные в игровой сессии.
    частные комнаты val = mutableMapOf()
    // Это необязательное свойство — просто удобный ярлык. 
    val currentRoom: Комната
        get () = room.getValue (координата игрока)
    в этом {
        // Создаем начальную комнату, перемещаясь туда
        двигаться(Движение.Начало)
    }
    забавный ход (движение: Движение) {
        exitedFrom = движение // Я не уверен, что вам действительно нужен этот exitedFrom
                              // свойство, но если вы это сделаете, вы можете сделать резервную копию здесь.
        playerCoordinate = когда (движение) {
            Пуск -> Координата()
            Влево -> playerCoordinate.moveX (-1L)
            Вправо -> playerCoordinate.moveX(1L)
            Внизу -> playerCoordinate.moveY(-1L)
            Сверху -> playerCoordinate.moveY(1L)
            DownLadder -> playerCoordinate.moveZ(-1L)
            UpLadder -> playerCoordinate.moveZ(1L)
        }
        // Создаем комнату, если она еще не существует.
        если (!rooms.containsKey(playerCoordinate)) {
            val newRoom = Room(playerCoordinate).apply {
                // Настройте свойства новой комнаты здесь.  Может рандомно?
                // возможно, нужно использовать движение, чтобы убедиться, что есть выход
                // исходит из того направления, откуда был перемещен данный игрок
                // можно вернуться.
            }
            комнаты [координата игрока] = новая комната
        }
    }
    весело resetGame () {
        комнаты.очистить()
        двигаться(Движение.Начало)
    }
}
 

3

Существует несколько способов поиска в списке объектов либо по атрибуту объекта, либо по типу объекта, либо по строковому представлению типа объекта. Последнее (я думаю) то, что вы пытались сделать (но это, вероятно, не самый расширяемый выбор дизайна кода).

Поиск по атрибуту объекта

Если вы просто хотите найти объект в списке на основе атрибута этого объекта, вы можете найти совпадение с некоторым предикатом, используя найти функцию в списке, например:

 class Room (имя var: String)
fun hasRoom(name: String, room: List): Boolean {
    return room. find { it.name == name } != null
}
val rooms = listOf(Комната("A"), Комната("B"), Комната("C"))
hasRoom("A", комнаты) // истина
hasRoom("D", комнаты) // ложь
 

Вы также можете определить функцию расширения для списка комнат для этой или других распространенных операций:

 fun List.containsName(name: String): Boolean {
    вернуть this.find { it.name == name } != null
}
 

, который позволит вам вызвать containsName непосредственно в списке комнат, аналогично тому, что вы уже пытаетесь сделать:

 val rooms = listOf(Room("A"), Room("B"), Room(" С"))
room.containsName("A") // правда
room.containsName("D") // ложь
 

Кроме того, как указано в другом ответе, вам обязательно следует использовать здесь один класс с атрибутами, а не новый тип класса для каждой координаты. Координаты могут быть атрибутами класса, и вышеописанные методы поиска по атрибуту по-прежнему будут применимы.

Поиск по типу объекта

Если вы действительно хотите искать список объектов по объекту типа , а не по атрибуту объекта, вы все равно можете сделать это с помощью функции расширения:

 class Room
класс Хаус
класс Яхта
класс Лодка
inline fun  List.

Добавить комментарий

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