<?php // Полная загрузка сервисных книжек, создан 2024-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='\
как ведет себя система с ИРДБ?
(1) С ИРБД не тестил, дабы такой задачи не ставилось.
есть вопрос по поводу объединения уже рабочей базы с даными по изменениями от автора обработкиhttp://infostart.ru/public/19364/?PAGEN_1=1#comm339629
Не пропадут ли уже существующие данные в базе по изменениям при простом объединении?
(3) Простым объединением конфигураций данные не пропадут, но работать будет неправильно. Для этого потребуется сделать некую конвертацию.
Вот умница. Спасибо.
(4) Можно поподробнее про конвертацию?
(6) Выложил инструкцию и обработку по конвертации данных из старой версии.
Здравствуйте. Объединил Вашу конфу со своей и выходит ошибка с ГлТекущим Пользователем??? Что можно сделать? 8.1.13.41 Управление торговлей 10.2.6.4
(8) Возможно при объединении конфигураций не сняли галочку со свойств конфигурации.скриншот
включить интелект!!! 😀
почему галочка не стоит….
Спасибо. На платформе 8.2 работает прекрасно.
Делал свою такую же , только на основании регистра сведений…Прошло 3 месяца — база стала жутко тормозить, регистр максимально оптимизирован, попробуем со справочником, спасибо!
+ поставлю, только не понятно
(0) а вот это зачем?
>>Справочник ЖурналРегистрацииИзмененияОбъектов
(13) 1. ЖурналРегистрацииИзмененияОбъектов.СсылкаНаОбъект имеет тип «Строка», для того чтобы была возможность удалять объекты БД.
2. Галочка «Включить интеллект» помогает более наглядно просматривать ТЧ объекта, когда рядом располагается СтрокаДобавлена, СтрокаУдалена с одним номером строки.
3. Для настройки объектов понадобится добавить в конфигуратор дополнительный справочник или регистр.
не получается объединится с бухией 8.0 — пишет о несовместимости структур — не могли бы выложитьвыслать исходники?
(15) конечно не объединится, она написана на 8.1.
а что вы понимаете под исходниками?
(16) куски текста кода, которые можно было бы по аналогии добавить в 8 конфигурацию
(17) Советую вам найти платформу 8.1 и посмотреть конфигурацию, так будет проще
Классная штука, плюсую обоим
Люди, не работает ссылка на скачивание — Parse error: syntax error, unexpected ‘:’ in /usr/local/www/data/bitrix/stack_cache/MYSQL/b_iblock/30/306 004069f336106238000efc8c322b9.php on line 5
Может кто-нибудь скинуть на fir@ya.ru? Заранее благодарен. Очень хочется попробовать сие чудо 🙂
Выходит ошибка записи в таблицу журнала изменений т.к. число строк превышает 99999.
почему так много строк, считаем. Есть документ в который выводится 8000 строк и заполняется около 20 реквизитов строки. Получаем 8000строк*20 реквизитов получаю как минимум 160000. Исправьте ошибку, сделайте ограничение на 99999 а потом новая запись журнала изменений на оставшиеся.
(21) Понял, будет время исправлю, тем более нашел еще одну ошибку.
Автору СПАСИБО!!!!
(23) Спасибо не булькает 🙂
(24) Попробую потестировать в своем стакане 😉
Хорошая штука, только вот с удалением помеченных объектов проблемка или я чего то не увидела….
Внес изменения, но когда все начинают работать (примерно 15 человек) начинаются ошибки транзакций, не может завершить сессию. Я бы смирился с тем что все стало медленнее, но такие ошибки мешают работать пользователям. Где то в комментах писали что со справочниками таких проблем быть не должно. Идея то хорошая — можно отслеживать что изменилось в документе и табличной части. Посоветуйте что-нибудь.
ПС. База sql.
(26) объекты помеченные на удаление должны без проблем удаляться
(27) работает на нашем предприятии Журнал изменений уже месяцев 8, ошибки транзакций бывают но редко, и скорее всего не из-за этого справочника.
А какой у вас стоит SQL?
Ошибка указывает на код общего модуля Журнала регистрации.
Поторопился закомментировать код, поэтому не могу сказать конкретно на какой код ругался.
2005 sql
я имела ввиду что если объект помечают на удаление , записи журнала не помечаются и помеченные на удаление объекты не удаляются
(31) объекты помеченные на удаление должны без проблем удаляться, т.к. в справочнике «ЖурналРегистрацииИзмененияОбъектов» хранятся не сами объекты, а ссылки на эти объекты в строковом виде.
ну у меня не последняя версия, а какая то одна из первых:)
Что за дата ‘20.10.2010’?
А удаления объектов фиксируются? Потому что на поиск журнала регистрации сподвигла именно задача поиска виновного в удалении объектов.
Можно настроить журнал так, что бы отслеживались еще и изменения в заданном регистре сведений?
(36) К сожалению нет, ибо изначально такой задачи не ставилось.
Справочники часто ссылаются на регистры сведений,а изменения в них не фиксируются. Интересуют естественно непериодические регистры сведений. Было бы логично дописать данный функционал. Система стала бы завершенее что ли.
У меня вопрос к разработчику.
В некоторых ситуация возникает следующая ошибка:
{Обработка.ИсторияИзмененияОбъектов_AEMZ.Форма.Форма(113)}: Ошибка при вызове метода контекста (ЗначениеИзСтрокиВнутр): Ошибка преобразования
НовРеквТЧ.ПослеИзменения = ЗначениеИзСтрокиВнутр(СтрокаРеквТЧ.НовоеЗначение); // alexer 28.12.09
по причине:
Ошибка преобразования
по причине:
Ошибка формата потока
Чем это может быть вызвано??? Если не затруднит, вышлите ответ на почту: zel_maks@mail.ru
(40) знаю об этой ошибке, да нет времени поправить
дело в том, что эта ошибка возникает если изменен реквизит с типом строка неограниченной длины, и количество символов превышает максимально возможное количество в Журнале изменений
(40) как можно вылечить?
(41)+ В том поле используется составной тип данны, что мешает присвоить строке неограниченную длину, но в приципе я же могу постаить длину «999» вместо «100» и должно прокатить?!
(42) Должно помочь.
(43) А не помогло!!! Поставил длину в «500» символов и все-равно ошибка в строке с длиной около 100 символов. В итоге просто поставил обработчик появления ошибки (исключительной ситуации) и если такая возникает, то просто в ручную выделяю подстроку из строки и записываю в нужное поле — вроде работает!
(44) к старым записям не поможет, нужно еще обработку писать, чтоб добавляла недостающие закрывающие скобки
(44) ААА…вон в чем дело…ясно! Ну в принципе моя заплатка будет работать для старых записей, а новые, по идее, теперь нормально будут создаваться. так что все ОК 🙂
скачал, подключил. есть поправки-мнение:
1е — зачем используется конструкция
…
ОбъектПустаяСсылка = ОбъектМенеджер.ПустаяСсылка();
Если ОбъектПустаяСсылка = Источник.Ссылка Тогда
…
почему просто не «Источник.ЭтоНовый()» ???
2е — в этом самом месте нужно еще проверить
«Источник.ПолучитьСсылкуНового().Пустая()» и использовать ее если есть,
и только если она пустая устанавливать ссылку нового, иначе если в объекте уже она установлена и использована в других связанных объектах сами понимаете что будет…
Данный вариант ещё не проверял, т.к. у себя использовал вариант с записью в ЖурналРегистрацииСобытий. Но прочитав комментарии встал вопрос:
В Торговых конфигурациях зачастую существует «Законный» поток изменений задним числом. При этом, в конечном результате изменяются складские и свободные остатки. Фактически выявляется только Номенклатура, по которой произошли существенные изменения. Собственно из этих предпосылок и начинается поиск: кто когда и где внёс изменения в документы, приведшие к изменению остатков…
Насколько я понял из описания, запись справочника соответствует контролируемому объекту и следовательно для поиска изменений влияющих на остатки приходится строить выборку по всем табличным частям?
Как идею, предлагаю дополнить ТЧ изменений категоризацией характера изменений (например выделить в отдельную категорию события влияющие на Остатки; влияющие на Взаиморасчёты; влияющие на Резервы и т.п.). Категорию можно использовать для дополнительной фильтрации.
Изменения в порядке строк табличной части мало кого интересуют, гораздо важнее фиксировать изменения количественных показателей для набора «Измерений»…
Мой плюсик юбилейный :). Можно даже обработку было не делать, а сделать форму списка справочника, было бы еще меньше изменений. А вообще прикольно
А как бороться с «объект не найден» после того, как удалил помеченные на удаление объекты? Может, сохранять наименование?
Спасибо большое автору! Журнал встроили в базу, все пока отлично работает) Пользователи довольны.
Хорошая задумка и реализация. Уже ставил в одну базу, но там мало пользователей и движений. Сейчас хочу поставить большую базу: около 30 пользователей и каждый строчит документы. Посмотрим как будет справляться на таком объеме данных. Честно говоря думаю что будут тормоза…
Прикольная штучка. Но есть одно но… Нет отчетов по которым можно собирать данные и сравнивать. А в таком виде оперативно получить информацию об изменения при больших объемах информации весьма проблематично. А как из этого счастья сделать отчет как-то пока не придумал 🙁
Внедрили, пользуемся. Спасибо!
Тоже получил ошибку
Исправил в табличной части «Изменения» реквизиты «НовоеЗначение» и «СтароеЗначение». Поставил неограниченную длину. Только вот интересует, как это скажется на базе при большом объеме данных? Или лучше будет поставить все таки ограниченную строку в 500 или 1000 символов ?
Неплохая штукенция. Только довольно громоздкая. Ставил себе на УТ — периодически вылетал журнал с ошибкой «Ошибка формата потока». И при изменении документа свыше скольки-то тысяч строк табличной части (не помню точно) запись в журнал вылетала с ошибкой. Приходилось брать конструкцию записи в попытку исключение.
Здравствуйте! Как обстоят дела с удалением объектов, в том числе, непосредственным. Ваши доработки системы помогают обработать такие ситуации?
Все уже сам посмотрел. Удалять дает без проблем. Но появляются записи «<Объект не найден>». Непосредственное удаление никак не обрабатывается
Для того чтобы получить результат, надо загружать ранее выгруженный журнал регистрации?
(60) anton-1c,
если я правильно понимаю вопрос, то записи в журнале регистрации появляются после начала применения этой подсистемы, никакого отношения к типовому журналу регистрации от 1С эта подсистема не имеет
Добавил реквизит «Представление ссылки» для хранения представления ссылок объектов. Что бы потом можно было отследить что же это за <Объект не найден>. Вообще разработка — классная вещь. Спасибо автору за это!
Спасибо, а где описан порядок установки ?
+(64) И как сделать, что б лог велся только по конкретному объекту ?
» Добавил обработку ЖурналИзмененияОбъекта.epf, позволяет просматривать изменения объекта из самого объекта, подключается как внешняя печатная форма (см. файлы).» — цэ
Как просмотривать истрию изменений из самого объекта ?
(+66) И как сделать отбор по одному объекту ?
+(67) Со всеми вопросами разобрался. Внедрил в конфигурацию. Все работает на пять баллов. Рекомендую
половина записей — Объект не найден, что с этим делать? Отвественный всегда — Администратор и все чеки ККМ
(69) ScRatch,
1.Объект не найден — означает, что были удалены объекты помеченные на удаление
2.Полагаю, что все пользователи входят в 1С под одной учеткой — Администратор
это чеки ккм из розницы, они видимо каждый день после закрытия смены удаляются из УТ, как сделать, чтобы оставалось описание объекта после удаления?
upd в плане обмена сделал чтобы они не удалялись, а только устанавливалась пометка удаления
Спасибо, обработка полезная нужная, +
Плюс, очень понравилось давно хотел что то такое, но вот да, как и писалось выше не хватает отчета…
эх, не работает с 8.2.15.301 (
нет ли возможности конвертнуть? спасибо
(0)
всё хорошо, но есть одно НО!
это даже не к самой системе, а к оформлению…
когда файл создается в виде конфигурации или базы данных, то надо, помимо самой системы, в конфигурации создавать ещё и как минимум двух пользователей — одного с полными правами, а второго без прав, кроме «пользователь».
так будет видно какие права выставлять на объектах системы, если перенос происходит «КопиПастом»
(к примеру из 8.1 в 8.2), а то пришлось самому думать дать пользователю право изменять справочник «ЖурналРегистрации» или хватит с него права добавления… 🙂
З.Ы. в любом случае плюс за такое решение. (и предшественникам тоже)
попробуем, интересно как будет работать когда у нас все 70-90 пользователей сразу начнут работать…
А что нибудь, что фиксирует изменения в регистрах сведений существует? Или есть возможность доработки существующих?
У нас регистр сведений должен находится под постоянным контролем так как в него попадают на некоторое время данные, которые потом используются для расчетов с контрагентами.
По многочисленным просьбам, добавил возможность настройки состава объектов для контроля
http://infostart.ru/public/151285/
спасибо. отличная вещь.
поясните, пожалуйста, такой момент (непринципиальный, конечно, чисто из любопытства)
почему произведено вот это изменение
// Если НЕ РольДоступна(«УправлениеРегистрациейИзменений») Тогда // alexer— 29.12.09
Если НЕ ИмяПользователя() = «ИмяПользователя» Тогда // alexer+++ 29.12.09
чем проверка по роли «хуже»? или просто так захотелось?
Здравствуйте, коллеги
Понадобилось решить ту же задачу. Взял эту разработку за основу, посмотрел «тюнинг» от SAS99 и вот что у меня получилось:
1. Дополнительно к СтароеЗначение и НовоеЗначение вернул СтароеЗначениеСсылка,НовоеЗначениеСсылка. Причину замены ссылок на строковый УИД понимаю (дабы дать возможность удаления объектов), но … так удобнее строить отчеты и проводить анализ
Изменение небольшое и банальное, находится в процедуре РегистрацияИзмененийСделанныхВОбъектах.ДобавитьЗаписьВЖурналИзменений() — так что каждый может сам решить — надо оно ему или нет и отредактировать процедуру без нарушения всего механизма в целом
2. Сделал настройку набора отслеживаемых объектов. Идея «тюнинга» от SAS99, но одним реквизитом «отслеживать» для всего объекта (справочника или документа) у него и ограничилось, так что …несерьезно это как то (хотя за идею и форму справочника настроек — спасибо).
Сделал полную настройку — как реквизитов шапки, так и реквизитов табличных частей
3. Ввел понятие «информационный реквизит». Смысл в следующем — допустим, мы изменили реквизит табличной части Количество. Зарегистрируется запись «изменился реквизит Количество с А на Б в строке X документа Y». Такая запись от человека, анализирующего изменения, однозначно требует дополнительных уточнений, так как не очень то информативна.
Зато запись «Номенклатура:Яблоко, Количество изменилось с А на Б. строка X. Документ Y» уже более информативно и может даже не потребовать дополнительной детализации.
Информационный реквизит — реквизит, который вносится в журнал, дополняя информацию об изменении отслеживаемых реквизитов.
Настраивается в том же СправочникеНастроек. Как для реквизитов Шапки так и для ТабличныхЧастей
4. Добавил настройку ключевых полей.
В алгоритме alexer строки сверяются по всем реквизитам, имеющим непримитивный тип. в результате, например, при смене в строке ТЧ реквизита «Страна» имеем полный комплект «Строка удалена» + «Строка добавлена». Особенно в сочетании с настройкой отслеживаемых объектов (контроль реквизита «Страна», у примеру, нас не интересует) выглядит ужасно неудобно.
Добавил в Настройки признак реквизита ТЧ «Ключевое». Если ключевые поля отмечены — сверка строк идет по ключевому набору, если нет — по алгоритму alexer. В вышеприведенном случае при указании ключевого поля «Номенклатура» будем иметь запись в журнале «строка изменена»
5. «Наследственность». Механизм alexer’а дополнен, а не кардинально изменен — при замене необходимо лишь заполнить справочник «Настройки» — при указании всех галок «Отслеживать» без изменения прочих (Информационный реквизит, Ключевой реквизит) механизм будет работать абсолютно точно так же как исходный
// ах да. еще нужно будет подправить п.1, если идея с хранением ссылок на объекты бд мешает
Сейчас буду тестировать на УТ 10.3
Если нужно (и можно) — выложу здесь этот очередной «тюнинг»
Давно использую этот механизм.
Работает как часы.
НО с недавнего времени встала необходимость отслеживать изменения в контактной информации в контактных лицах контрагентов. А информация эта храниться в отдельном регистре сведений и не регистрируется.
Может кто-то пробовал прикрутить регистрацию изменений в регистрах сведений ?
Надо будет глянуть и оценить. Ставлю плюсик авансом, что бы не забыть 🙂
Спасибо
Спасибо, опробую.
Скажите плиз на УПП платформа 8.2 заработает?
(87) z8491, На любой конфигуации под обычным приложением
При попытки объеденить пишит несовместимая конфигурация (
Точнее Cтpуктуpa кoнфигуpaции нecoвмecтимa c тeкущeй вepcиeй пpoгpaммы.
попробуйте открыть сначала файл cf в конфигураторе и переконвертировать его
(91) alexer, да спасибо, уже допер, но все равно спасибо за подсказку
Автор подскажите каствомк будет проходить работа с большими базами да них на SQL и огоромным количеством пользователей. Подвисать не будет. А можно как то организовать хранение етой базы в отдельной базе. Зарание спасибо за ответ.
(93) dyak84, Реализовывал подобный проект, когда часть журнала хранится в самой базе, например за год, а остальная часть хранится в другой базе отведенной специально для журнала событий, и при необходимости просмотра старых логов происходит подключение к архивной БД по OLE. Для очищения рабочей базы, примерно раз в квартал, делается переброска данных в базу логов из рабочей базы за некий период. По поводу подвисания, все зависит от мощности сервера.
а как настроить изменения каких объектов должны записываться в журнал? все объекты, которые были созданы после установки — не отражаются в журнале..
(94) Много уважаемый alexer Думал справится Сам с идеей архивации справочника Журналрегистрации при больших обэмах даных, но увы выгрузку с последующим удалением из основной базы настроил но вот как заставить адекватно и вразумительно просматривать записи в архивной базе ето как то никак не получается. Получается следующая картинаПодскажите пожалуйста как ето дело довести до ума. Зарание спасибо за ответ
(96) dyak84,
Я разделил ТЗ истории на две таблицы: таблица текущей базы и таблица архива, и подключаю архив по необходимости.
Судя по скриншоту, Вы не преобразовываете строковую ссылку в значение — функция ЗначениеИзСтрокиВнутр().
(97)По сути не все получается преобразовать ошибочка не дает ето зделать
Форма.УправлениеЖурналом.Форма(56)}: Ошибка при вызове метода контекста (ЗначениеИзСтрокиВнутр)
Стр.НовоеЗначение = Строка(ЗначениеИзСтрокиВнутр(стр.НовоеЗначение ));
по причине:
Ошибка преобразования
по причине:
Ошибка формата потока
Подскажите как решить етот вопрос
Обработка использую во многих местах работает отлично.
Но есть магазин с РИБ. Решил дописать чтоб можно было видеть с какого узла пришли изменения.
Добавил еще реквизит в справочник, изменил обработку чтоб дописывала в реквизит.
При дописывании еще подумал зачем условия отсекающие если обмен?
Обновил конфу. Сделал обмен.
На следующий день произошел FAIL.
При получении нового элемента через обмен записывался в журнал, но ГУИД стали разные.
Долго разбирался. Оказалось что из-за моей дописки.
Чтоб не наступали на грабли.
(98) dyak84,
Обнаружил такую же ошибку.
{Обработка.ИсторияИзмененияОбъектов_AEMZ.Форма.Форма.Форма(77)}: Ошибка при вызове метода контекста (ЗначениеИзСтрокиВнутр)
РеквШапки.ДоИзменения = ЗначениеИзСтрокиВнутр(СтрокаРеквШапки.СтароеЗначение); // alexer 28.12.09
по причине:
Ошибка преобразования
по причине:
Ошибка формата потока
Насколько понял из кода, ошибка возникает из-за того что реквизиты «СтароеЗначение» и «НовоеЗначение» имеют длину всего 100 символов и когда изменяемый реквизит в документе (справочнике) длиной больше 100 символов, то возникает вот такая проблема, т.к. обрезается служебная закрывающая кавычка.
Вывод — либо обрезать строку перед записью на несколько символов, нужных для служебных символов, либо увеличивать длину реквизита до нужной длины либо сделать вообще неограниченной длины.