Как быстро разработать красивый отчет, используя Универсальный отчет в прикладных решениях фирмы 1С




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2025-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

99 Comments

  1. CheBurator

    хороший материал!!!

    Reply
  2. d_chekunov

    Большое Спасибо за статью. Как раз собирался разбираться как это устроено. Жаль что плюсануть можно только разок.

    Reply
  3. alex_art

    Хороший материал, но все таки такой отчет по-моему все таки будет быстрее написать через СКД

    Reply
  4. I_G_O_R

    лет бы несколько назад, а так уже СКД

    Reply
  5. wirg

    СКД не очень удобный механизм, универсальные отчеты и построитель лучше

    Reply
  6. larisab

    В 8.1 построитель отчета оставлен для поддержки уже написанных на 8.0 конфигураций, все новые отчеты пишутся с использованием СКД. Тем ценнее статья.

    Reply
  7. larisab

    А еще ценнее была бы статья о том как внести изменения в отчет, построенный с помощью построителя на примере ОтчетСписокКроссТаблица или ОтчетОстаткиИОбороты, так как на них написаны большинство отчетов в стандартных конфигурациях.

    Reply
  8. Gilev.Vyacheslav

    ждем про СКД, а пока ПЛЮС 😀

    Reply
  9. I_G_O_R

    (5) чем интересно построитель лучше ❓

    Reply
  10. mirco

    Бегло ознауомился, попозже почитаю поподробней, но идея понравилась. Да и за потраченное время +

    Reply
  11. Ish_2

    Повторю за всеми , пора переходить на СКД, а так плюс , конечно.

    Reply
  12. Мастер1С

    Спасибо всем откликнувшимся.

    Мое мнение — под 8.1 в стандартных конфигурациях этого хватит.

    Самописные — видимо СКД, как более продвинутая технология.

    Но не загорами 8.2, что там будет — к тому и будем адаптироваться.

    Reply
  13. Serj1C

    Плюс. Но как и говорили выше, это механизм давно минувших дней. Но именно он стал пропотипом существуюшей СКД. Я так думаю.

    Reply
  14. Just

    Все это конечно хорошо, сам так делал и иногда делаю сейчас,

    но как-то я уже писал на форуме, но никто не ответил 😥 ,

    часто бывает отчет по своим рег. и т.п. необходимо распечатать и подписать, кладовщик, бухгалтер, не важно. Так вот как в такой отчет вывести строку для подписей в конце??? Если б не такая вот канитель, то было бы вообще нормально всё.

    Reply
  15. Мастер1С

    (14) А не пробовал после вывода отчета добавить строки из макета отчета? Попробую дома, может получится…

    Reply
  16. Мастер1С

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

    Показывать отчеты под СКД — ломать их мирровозрение. Когда-то это придется сделать, согласен, но не раньше чем необходимо.

    Reply
  17. Just

    (16) а каким образом? фиксированного макета нет у Универ.Отчета, куда добавить строки чтоб вывести их после таблицы, типа

    Директр ____ / <ФиоДир> Кассир _ / <ФиоКассир>

    вот ссылка на форум,

    форум

    никто не подкинул идейки (хотя я думаю народу много прочитало), если есть мысль поделись, а то мне что-то ничего путнего не пришло.

    Reply
  18. Serj1C

    (15) поидее можно нарисовать один раз форму настройки СКД такого вида как она была в УниверсальномОтчете

    (16) пробывал, все получалось

    Reply
  19. Evg-Lylyk

    Уже пройдено, но материал все равно полезный. Есть пожелания к оформлению:

    1. код картинкой не очень хорошо (есть обработка http://www.infostart.ru/public/19856/ )

    2. картинки лучше в формате PNG не будет ухудшения качества и размер будет маленький

    Reply
  20. Just

    (18) как пробывал? подробнее можешь пояснить?

    Reply
  21. Шёпот теней

    … сам отчёт даЁт не верные цифры … на одну номенклатуру, дату, склад :

    номенклатура…колОст….колРез

    болт М14х30……184……….30…. данный отчёт

    болт М14х30……..92………15…. штатный отчёт (происходит удвоение данных)

    … вот …

    за саму статью большое спасибо — четко, ясно, наглядно, ПОНЯТНО …. !

    … ВОТ …

    Reply
  22. Valerich

    За подробное и толковое описание плюс. Но статья действительно устарела. В конфе БП уже давно есть аналог на скд. Заготовка готового отчета называется «ШаблонТиповогоОтчета». Все что там надо сделать — это настроить макет (СКД). Все остальные системы вывода, оформления (кстати в случае простых настроек аналогичны тем что привычны) и прочего уже происаны в конфе.

    Сейчас под рукой нет УТ не могу проверить, но в ЗУПе и в УПП тоже большинство отчетов строится через СКД на базе универсального.

    Reply
  23. Valerich

    (21) Саша, могу тебя уверить — это проблемы составления правильного запроса. Особенно когда начинаешь делать кучу соединений.

    Или если выводишь движения с точностью до регистратора — тогда могут плыть итоги по каждой строке…

    Reply
  24. Шёпот теней

    (23) … понятно … спасибо …

    в целом моё мнение:

    такие отчеты «долгие» и + проблема «переделок» в (17) …

    но «красивы» своей универсальностью и «стандартностью» …

    … ВОТ …

    п.с. … «универсальность» это зло …

    Reply
  25. larisab

    (24) > «проблема «переделок» в (17)»

    Учится надо :). Эти знания проверяются при сдаче на специалиста по УТ, там все билеты с подобными заданиями. Азы…

    Reply
  26. Just

    (22) а что-то в стандартной конфе БП 1,6,20 нет «ШаблонТиповогоОтчета».

    да и в ЗУП и УТ нету тоже

    Reply
  27. Just

    (25)

    Учится надо . Эти знания проверяются при сдаче на специалиста по УТ, там все билеты с подобными заданиями. Азы…

    это Вы о чем? Про какие азы? Что-то я непомню там требования подставить подпись при использовани универ. отчета

    Reply
  28. Just

    а вот при сдаче по платформе, требуется отчеты на СКД делать

    Reply
  29. 4ish

    Спасибо за статью. Все просто и понятно даже для такого новичка, как я. 🙂

    Reply
  30. Valerich

    (26) в БП его кажется удалили в 19 релизе (я у себя оставил).

    В ЗУП и УПП можно смотреть в принципе любой отчет, в котором есть макет СКД — они построены универсально

    Reply
  31. Serj1C

    (20) Все очень просто. В процедуре ОбновитьОтчет после стандартного вывода в табличный документ с ним можно делать что угодно. Например:

    Процедура ОбновитьОтчет() Экспорт
    
    СформироватьОтчет(ТабличныйДокумент);
    
    МакетДоп = ПолучитьМакет(«ДополнительныеОбласти»);
    ТабличныйДокумент.Вывести(МакетДоп.ПолучитьОбласть(«Подвал»));
    
    КонецПроцедуры // ОбновитьОтчет()
    Reply
  32. artbear

    (22) Подобный шаблон и еще несколько полезных шаблонов СКД юзается при автогенерации файлов отчетов СКД в обработке «Универсальная консоль отчетов»

    http://infostart.ru/public/16782/

    рекомендую.

    Новые отчеты создавать очень легко и просто.

    У автора консоли даже есть отдельная статья для новичков, как с помощью его консоли быстро создать удобный файл отчета на базе собственной настройки СКД.

    Reply
  33. acsent

    Не актуально. Сейчас принято делать отчеты на основе «Шаблона типового отчета»

    Reply
  34. WKBAPKA

    2(17): да это действительно большая проблема… это конечно классно, что разработчики типовой УТ себе облегчили нелегкую жисть, а что теперь нам внедренцам делать с этим прекрасным универсальным отчетом х.е.з.

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

    Reply
  35. Merlin12042009

    Прекрасная работа, хорошо бы аналогичную статью почитать по СКД

    Reply
  36. Flashback1979SE

    Плюсанул, так как до сих пор помню, как отчет, который был оценен на 6 часов, я сделал за 15 мину:-). Благо прям перед этим разобрал по полочкам этот объект:-). Была бы эта статья у меня перед глазами, тогда (давно), то и на разбор ушло бы намного меньше. Это поможет в основном начинающим, ну а опытным, как справка, вдруг по запарке забудут что-нить.

    Reply
  37. Just

    (31) где ж ты раньше-то был 🙂 , спасибо

    Reply
  38. MSensey

    Как все сложно-то. СКД рулит, а на 8.2 темболее рулит 😉

    Reply
  39. Vladimir_vk

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

    Reply
  40. ArtemK

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

    Reply
  41. IgorMgn

    Спасибо! Уже пригодилось в доработке типового отчета.

    Reply
  42. DoctorRoza

    Отличная статья! Плюс однозначно. Только есть просьба. Выложите эту статью в формате *.doc или др. текстовом формате. Я начинающий, поэтому для подробного разбора html не очень удобно. Заранее благодарю!

    Reply
  43. Мастер1С

    (42) Давайте мыло, кину

    Reply
  44. DoctorRoza

    (43) DoctorRoza@mail.ru

    😳 😳 😳

    Reply
  45. Мастер1С

    (44) отправил

    Reply
  46. logarifm

    Есть и минуса этого использования, при сложных расчетах колонок, которые нельзя вычислить в запросе в макет к сожалению не попадут, а в другом я всегда это использую уже примерно года два или побольше 🙂

    Reply
  47. defini

    Для начинающих программистов самое то!

    +1 адназначна!

    Reply
  48. JIGIT

    Спасибо! Пригодилось!

    Reply
  49. Мастер1С

    (46) Это верно, вариант «Одного запроса»

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

    Reply
  50. Йожкин Кот

    Хотелось бы добавить, следующее:

    1. Подобным функционалом владеют еще и отчеты ОтчетОстаткиИОбороты, ОтчетСписокКроссТаблица и ОтчетДиаграмма.

    2. Если запрос простой, его текст можно и не писать. Достаточно заполнить спец. макет группировками и показателями и вызвать процедуру УправлениеОтчетами.ЗаполнитьНачальныеНастройкиПоМакету. Как пример, в УТ можно глянуть отчет ПланируемыеПоступленияДенежныхСредств.

    «+» за старания.

    Reply
  51. СветикК

    спасибо

    Reply
  52. AVARY

    Большое спасибо! Наконец-то я «подружился» с отчетами 🙂

    Reply
  53. i.kovtun

    (30)

    На ИТС есть поставка подсистемы «Шаблон типового отчета», за 15 минут можно встроить с поддержкой поставщика в любую конфигурацию.

    Reply
  54. slaviksoft

    автор маладец

    если бы 1С такие описания к своим механизмам делала — жить стало бы легче

    Reply
  55. artbear

    (53) В какой ИТС, например, есть?

    что-то я в своих не нашел?

    Reply
  56. i.kovtun

    Декабрь 2009

    1CItsEXETreport

    Возможно это есть только на партнерском ИТС, но вроде это общедоступная «демка».

    Reply
  57. sergiowood

    Добрый день. С Новым Годом! Можно мне получить на мыло (F_S_S@ukr.net) эту статью в формате *.doc.

    Reply
  58. Swetlana

    Хорошая статья! Спасибо. 🙂

    Reply
  59. sss999

    Вот я начинающий,и мне непонятно,почему из резерва взяли только количество,а не количество и номенклатура,мне непонятно по какому полю будет соединение происходить.

    Reply
  60. sss999

    а понял,сорри затупил,а построитель он что делает макет формирует?

    Reply
  61. IDija

    очень помог. с выбором цен

    Reply
  62. bashhhh

    Как можно изменить представление показателя, если как источник используется регистр накопления.

    Ведь в форме настройки табличное поле Показатели недоступно для редактирования.

    Как пример.

    Ведомость по взаиморасчетам с контрагентами.

    В отборе ставим вид контрагента покупатель — в отчете пишет «Долг покупателя» вместо Начальный остаток

    В отборе ставим вид контрагента поставщик — в отчете пишет «Долг перед поставщиком». вместо Начальный остаток

    Reply
  63. valya977

    Спасибо за хорошую статью

    Reply
  64. Temniy

    Блин круто (Вот это способ) 😀

    Reply
  65. yurikovd

    честное слово выручили!!!Вот только проблема у меня половина учреждений на УТ 10.1, а там как известно —

    Reply
  66. yurikovd

    а где можно почитать поподробнее про УО???

    Reply
  67. Мастер1С

    А что такое УО?

    Reply
  68. vip

    (67) УО — умственно отсталый (с) «Три с половиной дня из жизни Ивана Семёнова — второклассника и второгодника»

    Reply
  69. Мастер1С

    (68) Думаю что в контексте данной статьи это не вариант

    Reply
  70. nafa

    Автору спасибо огромное! За 2 часа по инструкциям в статье сделал отчет, на который иначе ушло бы два дня.

    Reply
  71. max5600

    Скажите пожалуйста. Можно ли просто подключить файл .erf в 1С УТ и пользоваться данным шаблоном, или все по шагам все проделывают как автор написал?

    Reply
  72. madmpro

    У меня есть похожий отчет, только на основе универсального отчета, по регистрам партий (комплексная конфигурация, УПП). Проблема с выводом начальных остатков и расшифровок по документам. При выводе расшифровки строки в режиме период+регистратор и отключения детальных записей — все получается (проверено) кроме начальных остатков. Кто-нибудь поможет решать эту проблему?

    http://files.mail.ru/I4ZLS2

    Reply
  73. lakzn

    (67) Думаю, УО — это универсальный отчет 🙂

    А не подскажете, можно программно задать условное оформление поля? Например, я добавляю дополнительное поле «Дата» :

    УниверсальныйОтчет.ДобавитьДополнительноеПоле(«Регистратор.Дата», ТипРазмещенияРеквизитовИзмерений.Отдельно, 3);

    Как задать, чтобы оно выводилось в формате dd.MM.yyyy (без времени)?

    Reply
  74. flashdancer

    Спасибо огромное за такое пояснение!!! ❗ Все понятно и одновременно ничего лишнего!!!

    Мне очень помогло 😀

    Reply
  75. Tarzan_Pasha

    Статья очень полезная. И пример тоже. В примере исправить ошибку надо в одном месте.

    УниверсальныйОтчет.ДобавитьПоказатель(«СуммаРезерв», «Сумма остаток в резерве», Истина, «ЧЦ=15; ЧДЦ=2», «Сумма», «Сумма»);

    вот такая строчка должная быть. а не

    УниверсальныйОтчет.ДобавитьПоказатель(«ОстатокРезерв», «Сумма остаток в резерве», Истина, «ЧЦ=15; ЧДЦ=2», «Сумма», «Сумма»);

    Reply
  76. toxicoff

    Сделал всё вроде по инструкции, строки, колонки, номенклатура выводится… И получается вроде правильный отчет, да только не заполненый)

    показатели не показывает( почему может быть? может в запросе как то накосячил?

    Reply
  77. wrooom

    Вот вы всё хорошо расписали, а СерииНоменклатуры у вас не выводятся ни как отдельное поле, ни в группировках..

    А как же быть, если нужно отображать остатки в разре серий?

    + если я использую вложенный запрос, необходимо ли внутри вложенного запроса применять конструкции построителя?

    Reply
  78. rujopost

    (76) Точно так же было. Оказалось, что на закладке Итоги слетели настройки. Вероятно, глюк платформы.

    Reply
  79. SuhoffGV

    (72)

    А документы движения показываются или вы их не выводите?

    Сделал по инструкции (ТоварыОрганизацийОстаткиИОбороты), без детальных записей все норм. С детальными записями не выводит документы движения. Тот-же запрос в консоли запросов выбирает нормально.

    Reply
  80. budanil

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

    Reply
  81. vstorozhuk

    Огромное спасибо!!! очень полезная статья)))

    Reply
  82. trad72

    спасибо, материал помог разобраться в стоявшей передо мной проблемой. + однозначно )

    Reply
  83. aleksey51286

    спасибо за публикацию, очень интересно

    Reply
  84. pereligins

    Спасибо за публикацию!!! Очень спасла! Сделал отчет на СКД, но клиенту захотелось чтобы он был на основе универсального, т.к. его сотрудники привыкли к интерфейсу. Пришлось переделать, но долго не мог понять как сделать на основе запроса, а не по одному регистру. Спасибо!

    Reply
  85. vovche

    спасибо, слава богу что я пришел в 1с когда универсальный отчет уже начал отмирать 🙂

    Reply
  86. svetic

    Большое Спасибо за статью, помогла разбираться как это устроено. Но хорошо бы облегчить вот такой момент — часто бывает отчет по своим рег. и т.п. необходимо распечатать и подписать, кладовщик, бухгалтер, не важно. Так вот как в такой отчет вывести строку для подписей в конце???

    Reply
  87. asg1975

    Прямо мини учебник. Быстро понять азы — самое то. Огромное спасибо, сам начинал с данного примера!!!

    Reply
  88. Мастер1С

    (86) svetic,

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

    Reply
  89. puxlichok

    Очень помогло разобраться в сабже. Спасибо)

    Reply
  90. olexandr

    Спасибо, очень хорошая статья — научила пользоваться универсальным отчетом, хотя СКД конечно пофункциональней будет.

    Reply
  91. DragonAgo

    Отличная статья, переписала типовой отчет добавив необходимые для пользователя поля и ограничила по правам видимость этих полей.

    Reply
  92. pmtvv

    за статью, спаибо

    Reply
  93. forse

    Хорошая статья спасибо

    Reply
  94. Landrey

    Отличная статья все по полочкам. Для начинающих в самый раз. +

    Reply
  95. Anton_prezident

    Спасибо,много хорошей информации

    Reply
  96. iksanova

    Хороший пример!

    Reply
  97. ipyu

    Большое спасибо, очень познавательно.

    Reply
  98. Flashill

    (17) Just, тоже как-то нужно было разработать отчет произвольной формы. Думал уже на макетах делать, но разобрался и сделал на СКД. Гриф «Утверждаю», места подписей руководителей и т.п.

    Reply
  99. PrinzOfMunchen

    (15) а вы воспользуйтесь механизмом произвольного отчета. И СКД, и стандарт.

    Reply

Leave a Comment

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