Эх… МоментВремени() !




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

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

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

<?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='\

64 Comments

  1. dvv01

    > На мой взгляд, правильно так :

    «Но есть особенность — документы разного типа , записанные в одну и ту же секунду, располагаются в произвольном порядке, а не в порядке их физического создания (как было в 7.7). Документы же одного типа располагаются в порядке их физического создания.»

    У меня получалось так:

    Если время создания одинаково и документы разных типов то:

    — по временной шкале они сортируются по порядку расположения в деоеве метаданных (если конфа не менялась, то по алфавиту) — обращали внимание при обновлении на настройку режима «порядок объектов». В связи с чем может иметь смысл в конфигурации сдвинуть «Переоценку товаров в рознице» в самое начало до документов перемещения, оприходования, поступления или возврата дабы не нарываться на ошибки «Нет цен АТТ» при перепроведении.

    Reply
  2. Ish_2

    (1) Не знал этого. Явного описания от «1с» этого факта нигде не нашёл.

    Нужно пробовать.

    Reply
  3. AnryMc

    (0) IMHO — для распределения разных документов на оси времение есть ПОСЛЕДОВАТЕЛЬНОСТЬ

    Reply
  4. Ish_2

    (3) При чем тут «последовательность» ?

    «КорректировкаДолга» и «РеализацияТоваровУслуг», приведенные в теме в качестве примера, принадлежат одной последовательности «Взаиморасчеты». И ЧТО ? От чего это спасает ?

    Reply
  5. Alias

    Простите, но мне кажется лучше оставить изначальную формулировку без изменений….

    Разных типов, одинаковых типов — неважно. Документы, созданные в одну секунду, располагаются в произвольном порядке независимо от типа. Другое дело что единожды созданные (расположившись на оси времени) они будут сохранять этот порядок всегда, пока ГУИД останется неизменным.

    Получение уникального идентификатора гарантирует только его уникальность, но не возрастание.

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

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

    В конце концов, проверьте сами — создайте не 10, а 1.000.000 документов в одну секунду и посмотрите, по порядку они будут идти или нет. Если по порядку — попробуйте в другой базе, увеличьте число документов, и т.д.

    На закуску процитирую слова Бориса Нуралиева:

    «Механизм генерации ссылок обеспечивает только их уникальность. Возрастающая последовательность при их генерации не обеспечивается.»

    Всё сказано вполне чётко, не правда ли?

    p.s. Думаю, не стОит напоминать что момент времени — это время + ссылка, то есть если так будет проще, время + тип документа + уид

    Reply
  6. Ish_2

    (5) В таких случаях нужно обязательно указывать ссылку.

    Тем не менее звучит убедительно.

    Если предположить , что пост (1) верен , то из него вытекает ,

    что меняя порядок расположения документа в конфигурации — мы «скачком» меняем «старшие разряды» вновь создаваемых ссылок. И тогда получается , что созданный позднее (после изменения порядка в конфигурации) документ по значению ссылки возможно будет меньше ссылки ранее созданного документа.

    Reply
  7. Alias

    (6)

    http://partners.v8.1c.ru/forum/thread.jsp?id=279626#279626

    имеющие уши, да услышат 🙂 имеющие доступ к партнёрскому форуму — или знают, или найдут.

    По поводу изменения порядка в конфигурации — не уверен. Мне кажется тип документа (та часть ГУИДа которая определяется типом) определяется в момент добавления объекта в конфигурацию и потом не меняется (при доработках, по крайней мере).

    А про тот идентификатор, который 1С примерно называет ГУИДом, можно сказать ещё много чего. Например, та самая «хронологическая последовательность» в пределах одной секунды, о которой говорит автор, легко и непринуждённо может быть сбита, если ГУИД создать программно (УстановитьСсылкуНового()). См. например ветку http://partners.v8.1c.ru/forum/thread.jsp?id=839888#839888, я там тоже писал про это.

    P.S. ещё одна цитата от 1С:

    «Никакой информации о принадлежности к конкретной ИБ, типу объекта, сессии и др. в GUID нет.»

    так что не стройте иллюзий. Сто раз получится хронология в секунде, а на сто первый нет. И какой толк тогда будет в том что «а до этого прекрасно работало!»…

    Reply
  8. Ish_2

    (7)В текст темы внесены изменения.

    Reply
  9. Ish_2

    (7) Кстати , а «1с» признает такую неопределенность взаимного расположения документов на оси времени в пределах одной секунды существенным недостатком платформы 8 ?

    Действительно , определяя остатки на МоментВремени документа , мы всегда должны учитывать неопределенность : возможно, данные в эту секунду по некоторым документам не попали в запрос, хотя созданы они были «физически» раньше. Мы запросто можем «попасть» на отрицательные остатки !

    Ситуация , описанная в теме : «КорректировкаДолга» в последнюю секунду месяца не может учесть долг по документу «РеализацияТоваровУслуг» , записанного в ту же секунду — очень похожа на «косяк».

    Reply
  10. Alias

    (9) Существенным недостатком не признают. «Это не является ошибкой, так как именно такое проектное решение было принято» (с)

    Ситуация «конца месяца», когда много различных документов вводятся с временем 23:59:59, является особенностью работы системы, которую нужно учитывать.

    Рекомендуемым способом «является установка у документов программным способом времени соответствующего желаемому порядку» (с).

    Проще говоря, если какой-то документ гарантированно должен стоять раньше другого, единственный способ достичь этого со 100%-ной вероятностью — установить у него дату с меньшим временем. 23:59:58, например.

    Reply
  11. Ish_2

    (10)

    «Это не является ошибкой, так как именно такое проектное решение было принято» (с)

    Мммм.. Согласен, это сильно.

    Отсюда следует , что поведение документа «КорректировкаДолга» в типовой БП 2.0 как раз не учитывает такой особенности платформы.

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

    Reply
  12. Alias

    (11)

    >два расходных документа проведенные в одну секунду непредсказуемо расположены на оси времени относительно друг друга

    Будучи единожды созданными, они займут своё положение на оси времени и непредсказуемо относительно друг друга никак скакать уже не будут (ну в смысле в пределах одной секунды). То есть один всегда будет предсказуемо раньше другого, хоть сейчас, хоть через год, хоть после выгрузки-загрузки и т.д.

    В случае описанного поведения «Корректировки долга» (впрочем, на его месте мог быть и другой документ) мне кажется это не документ не учитывает поведения платформы, а тот человек, который этот документ создаёт 🙂

    С отрицательными остатками непонятен вопрос. Если абстрагироваться от проблемы одной секунды, появление отрицательных остатков может случиться при любой работе задним числом. Если мы сначала провели один документ в 10:00, а потом другой в 9:00. Граница корректной последовательности в этом случае будет стоять на позиции 9:00. Для восстановления корректной последовательности документ за 10:00 должен быть перепроведен.

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

    Reply
  13. Ish_2

    (12)

    В случае описанного поведения «Корректировки долга» (впрочем, на его месте мог быть и другой документ) мне кажется это не документ не учитывает поведения платформы, а тот человек, который этот документ создаёт

    Ситуация. Бухгалтеру нужно зачесть авансы в конце текущего месяца. Он начинает делать «КорректировкуДолга» для определенного контрагента. Этот документ должен быть проведен именно в текущем месяце .

    И получает примерно следующее сообщение : «Долг по указанному документу не может учтен…». Хм.. обязательно расскажу ей , что она просто не понимает , чего делает в БП2.0.. или что-нибудь про гуид и одну секундычку..

    По отрицательным остаткам.

    Два оператора в 11:00:00 в пределах одной секунды проводят документы (каждая свой) по расходу товара «ТоварN» (его текущий остаток- 10 шт.). Первый по времени оператор ставит на расход 6 шт. Второй по времени — 5 шт.

    Перед проведением документа вторым оператором реально осталось — 4 шт.

    Начинается проведение , делается запрос на момент времени второго документа и получаем в результате запроса 10 шт ( второй документ по моменту времени в пределах одной секунды вполне может быть меньше чем первый).

    Получили отрицательный остаток. Где здесь «заднее число» ?

    Reply
  14. cool.vlad4

    1С не могла сделать иначе,…свобода которую они дают, имеет и отрицательные стороны, нужно контроль брать на себя.

    Reply
  15. Ish_2

    (12) Я извиняюсь. Разумеется,»Оперативное проведение» выключено.

    Reply
  16. awa
    Reply
  17. Alias

    (13)

    > Где здесь «заднее число»?

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

    Когда происходит работа в оперативном режиме, платформа сама контролирует время и создаёт новый документ с приращением +1 секунду, если необходимо.

    Если работа неоперативная (то есть оба пользователя установили одно и то же время 11:00, и при проведении оно автоматически не изменилось), сразу появляется вероятность «работы задним числом».

    Я же говорю, в этом смысле нет разницы одна там секунда или разные. Это две грани одного и того же явления — неоперативного проведения документов. Разное время у документов или одинаковое — может случиться «заднее число». Только если время разное, мы однозначно сразу можем понять будет оно или нет, а в случае одинакового времени — как повезёт. Может случиться, а может и нет, если документы случайно встанут в правильном порядке.

    Reply
  18. Ish_2

    (17) Ок.

    Reply
  19. Ish_2

    (16) Прочитал мельком.

    Интересно. Вполне стоит оформить отдельной статьёй.

    Reply
  20. Ish_2

    (16)

    Много раз встречал утверждение, что 1С не генерит каждый раз новый GUID, а использует один раз сгенеренный в начале сеанса GUID, а потом просто прибавляет каждый раз по единичке, когда нужен новый GUID. Именно поэтому, документы одного типа с временем в пределах одной секунды и созданные в одном сеансе располагаются в порядке их создания. Никаких других гарантий быть не может. Например, если провести эксперимент, что строго по очереди из двух соединений с базой создавать документы одного вида в одной секунде, то фактически, в силу выше описанной особенности создания GUID в 1C, окажется, что сначала идут все документы, созданные в одной сессии, а потом, все документы в другой сессии.

    Отсюда вытекает , что если в первой сессии ссылки для документа начинаются с N , то во второй сессии

    ссылки должны начинаться с N+M.

    Вопрос : если количество созданных документов в первой сессии очень велико , то тогда в первой сессии мы можем достигнуть значения N+M , т.е. получаем дублирование ссылок в первой и второй сессии.

    Я правильно всё понял ?

    Reply
  21. awa

    (20) Теоретически да. Но GUID — это 128-битное число, и, как я понимаю, механизм генерации GUID сделан так, чтобы M было очень большим. Таким большим, что столько документов в базе просто не бывает. Но на самом деле, реальных познаний в алгоритме генерации GUID у меня нет. Остается только надеяться, что 1С это учла и проверила.

    Reply
  22. Ish_2

    (21) Понимаю , что это всего лишь предположения. Тем не менее.

    Ежедневное количество К открываемых сессий может быть большим. Для каждой сессии мы с большим запасом должны определить некоторое M. И тогда для последней сессии получим начальное значение счетчика К*М .

    Отсюда и сомнение : Не исчерпаем ли мы достаточно быстро всю «емкость» ссылок ?

    Вероятно , нам неизвестен какой-то нюанс в назначении ссылок.

    Reply
  23. awa

    (22) 128-битное число — это ОЧЕНЬ большое число!

    Википедия про UUID

    Общее количество уникальных ключей UUID составляет 2#k8SjZc9Dxk128 = 256#k8SjZc9Dxk16 или около 3.4 × 10#k8SjZc9Dxk38. Это означает, что генерируя 1 триллион ключей каждую наносекунду, перебрать все возможные значения удастся лишь за 10 миллиардов лет.

    Но, если мы все же внезапно сгенерируем существующий GUID, то мы просто получим ошибку при записи в базу данных из-за неуникальности индекса. Эту ситуацию можно искусственно воспроизвести с помощью УстановитьСсылкуНового().

    Reply
  24. DoctorRoza

    23ч.59м.59с. .. спать нужно, а не документы проводить .. 😀

    Reply
  25. Ilyabaykov

    Не забываем про журналы, если режим времени текущее или последним, то документ гарантированно встанет за последним документом, принадлежащим данному журналу, даже если они разных типов. Однако так-же не забываем, что много документов на 23:59:59 это потенциальный источник ошибок.

    Reply
  26. Ish_2

    (25)

    Правильно ли я понял , что все пред. утверждения к Журналам и СпискамДокументов не относятся.

    Другими словами, при неоперативном проведении, в журнале или в форме списка документов — записанные в одну секунду документы будут располагаться в сверхточно — хронологическом порядке их создания ? Так ?

    Reply
  27. Lara.Builova

    (12) >> При первичном создании базы из конфигурации объекты получают номера в порядке расположения их в конфигурации. Эти номера не изменяются при дальнейших изменениях базы.

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

    Возможно ли объяснить потерю данных в случае обновления базы с помощью метода «загрузить конфигурацию из файла», когда сфшник подготовлен в другой базе и там в конфигураторе изменен порядок следования объектов в дереве (добавили новый и для удобства выстроили по алфавиту)?

    Reply
  28. Ilyabaykov

    (26) Документы будут располагаться так, как вы их расположите 🙂 Если нам надо, что-бы документ располагался в конце дня, или начале дня, в рамках журналов, которым он принадлежит, то сделать это мы можем, но не установкой времени при помощи Дата = ‘20110131235959’ а используя метод «УстановитьВремя». Работает естественно только в рамках журнала, которому принадлежит документ.

    Для документов, никак не связанных (последовательностями или журналами) расположить в «правильной» для нас последовательности довольно сложно, но здесь нас выручает блокировка данных! да, не смейтесь, если-бы первый оператор из примера в (13) заблокировал «свои» остатки, то второй оператор ждал-бы завершения проведения его документа и увидел-бы уже правильные остатки.

    Вообще странная дискуссия — какой документ раньше, тот, который на 23:59:59 или тот, который на 23:59:59 🙂

    Если такие проблемы возникают это должно решаться четким пониманием какой документ должен быть на каким и соответственно распределять их по шкале времени, но не в пределах одной несчастной 23:59:59 а например 23:59:57 и 23:59:58.

    Reply
  29. Ish_2

    (28) Нет слов.

    Reply
  30. Ilyabaykov

    (29) Что именно вызвало у Вас немоту? на самом деле по поводу размещения документов в пределах одной секунды совершенно прав awa в (16) и с этим ничего не поделаешь, так реализовано в платформе. А я лишь хотел сказать, что если последовательность документов сильно критична для системы, система-же и должна контролировать правильность ввода. Например закрытие месяца — только на 23:59:59 и только его. а переоценку товаров — только в начало дня.

    Касательно непредсказуемости распределения документов в пределах одной секунды — документы, заняв позицию на временной оси один раз, со своего места уже не уйдут, разве что у ранее созданного документа не поменяют время и он вклинится перед «нашим» документом (GUID меньше).

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

    Reply
  31. awa
    Reply
  32. cool.vlad4

    (31) 😀 побольше бы таких оффтопов

    Reply
  33. Ish_2

    (31) Прочитал , почесал в затылке.

    Признайся , Валера, такая аналитика не может быть профессией.

    А может быть только — хобби.

    Reply
  34. Lara.Builova

    (31) Я ломаю голову над одной проблемой, когда у меня пропали не только данные, но и реквизиты в конфигураторе.

    База была в таком состоянии, что работать у клиентов на их медленных машинах было невозможно.

    Частично снята с поддержки, обновления делались путем кусочного вставления того, что прог считал необходимым из разных релизов. Основная конфигурация состояла из такой вот мозаики. Конфигурация поставщика тоже не соответствовала номеру релиза, вытащенного определенного Вашей програмкой Tool_1CD, то есть тоже умудрились ее покромсать. Задача была поднять последовательно все релизы (примерно 10), убрать все хвосты, обычно удаляемые сфу-шником, ненужные с определенного релиза реквизиты (типа удалитьПодразделение). Делалось это на копии базы дома, проверены были все добавленные предыдущими прогами объекты — все на месте, данные на месте. При замене конфигурации у клиентов некоторые реквизиты улетели, причем те, что были воткнуты и в конфу поставщика.

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

    Reply
  35. awa

    (33) Да, Игорь, это не профессия, мне за это не платят ))

    (34) Все-таки я думаю, что причина в

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

    как я говорил выше, при такой вставке мы получаем внутренние GUID объектов, не совпадающие с конфигурацией поставщика. И в дальнейшем избавиться от этих неправильных GUIDов практически невозможно — при обновлении путем «сравнить и объединить» даже с конфигурацией поставщика остаются неправильные GUID. Способ заменить эти GUID на правильные: 1) загрузить конфигурацию без сравнения. Данные будут потеряны; 2) Создать новую базу из конфигурации поставщика, и данные туда перенести из старой базы.

    А вообще, 1С не предоставляет нормальных средств для отслеживания таких ситуаций, на партнерском форуме вроде даже ветка была, где просили сделать возможность при сравнении/объединении выбрать вариант «для объектов, сопоставленных по имени взять GUID из новой базы». Однако ж, воз и ныне… ))

    Reply
  36. Lara.Builova

    (35) Спасибо за ответы.

    Reply
  37. Ish_2

    (35) Ну , раз хобби — давай «хоббировать». И проверим предположение в (16):

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

    Проведем простейшее исследование для клиент-серверного варианта 8.2(MSSQL).

    Создадим в хронологическом порядке 3 сессии : Сессия А,Сессия В, Сессия С.

    В каждой из сессий будем записывать документы с одинаковым временем 30.04.2011 23:59:59 и префиксами соответсвующими названию сессии (префиксы СессияА,СессияВ,СессияС).

    Экперимент № 1.

    В каждой из сессий запишем документы в следующем хронологическом порядке :

    СессияА1,СессияС1,СессияВ1. В журнале они будут располагаться в следующем порядке :

    СессияА1,

    СессияС1,

    СессияВ1.

    Другими словами , «как ввели — так и получили».

    Хотя сессия С была создана позже Сессии В — тем не менее мы получили , что ссылка в сессии С меньше ссылки в сессии В. Отсюда следует , что фраза в (16) о «сгенеренном в начале сеанса GUID» — неверна.

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

    Эксперимент № 2.

    Все последующие записанные документы (каждый в своей сессии) располагались каждый в своём диапазоне в строго хронологическом порядке (по возрастанию ссылок), что в целом подтверждает предположение (16). См . рисунок.

    Думаю также , что предложение в (5) создавать множество документов в одном сеансе для того , чтобы «сбить» последовательность возрастания ссылок смотрится малоперспективным. Действительно, хронологическое невозрастание ссылок документов легко достигается при использовании нескольких сеансов.

    Reply
  38. awa

    (37) Спасибо большое, что провел эксперимент, результат которого я предсказал в (16)!

    Скорее всего ты прав, и 1С генерит первый GUID не в начале сеанса, а в момент, когда он понадобится первый раз в сеансе. Это логично. Но дело в том, что как устроена генерация GUID, мы не знаем. Предположу, что, в эксперименте ты все три сессии открыл на одном компьютере, и поэтому, так как GUID для каждой сессии 1С получала на одном компьютере, с не очень большим промежутком времени между их получением, есть зависимость между временем получения GUID и их сортировкой в базе. И поэтому ты получил именно такой порядок:

    СессияА1,

    СессияС1,

    СессияВ1.

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

    Но, если сессии открывать на разных компьютерах, или на одном компьютере, но через большие промежутки времени, вполне вероятно, что и эта зависимость пропадет. Да и в рамках одной сессии, где гарантия, что, в 1С нет какого-нибудь счетчика, и что, например, после 1000 раз прибавления к GUID по единичке, 1С не возьмет, и не сгенерит совсем новый GUID? Это знают только разработчики 1С.

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

    Reply
  39. Ish_2

    (38) Конечно, все три сессии были созданы на одном компьютере с интервалом 20-30 сек.

    Проведем более содержательный тест : в каждой сессии А и С одновременно запускаются процедуры записи 100 000 документов с одной датой-временем. Узнаем возможны ли разрывы в расположении документов в журнале или документы из каждой сессии будут располагаться строго в «своем» диапазоне(диапазоне своей сессии).

    Reply
  40. Ish_2

    (38) Экперимент был следующий : даны три сессии А,В,С (запущены в каком-то произвольном порядке).

    В каждой сессии с интервалом в 4-5 сек. запускается процедура создания и записи 10 000 документов «реализацияТоваровУслуг» с соответсвующим букве сессии комментарием (например, первый созданный в сессии А документ имеет комментарий А1 и т.д.)

    Результат выполнения трех процедур в разных сессиях наблюдаем в списке документов «РеализацияТоваровУслуг».

    Получили документы в следующем порядке :

    С1 ..С32

    А1 ..А32

    В1 ..В32

    А33 ..А224

    В33 ..В96

    А225..А228

    В97 ..В160



    С33..С96

    … и т.д. до С10000,В10000,А10000.

    О закономерности тут судить трудно. Но.

    На данный момент имеем , что предположение в (16) неверно.

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

    Желательно , конечно, чтобы кто-то еще повторил этот эксперимент.

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

    Reply
  41. awa

    (40) Очень похоже, что счетчик, про который я говорил в (38), равен 32. Т.е. 1С генерит уникальный GUID, скорее всего с помощью вызова WinAPI-функции UuidCreate, и затем использует данный GUID для получения 32 последовательных значений, прибавляя каждый раз по единичке. Потом снова генерит новый GUID, и получает новый блок из 32 последовательных GUID, и т.д.

    Проверить это можно посмотрев сами GUID в базе. Если база файловая, то проще это сделать с помощью Tool_1CD, только надо отключить опцию «Отображать Binary(16) как GUID».

    Правда, блок А225..А228 выбивается из предположения про счетчик на 32.

    Reply
  42. Ish_2

    (41)А225..А228. Конечно, это опечатка.

    Правильно А225…А288 (64 документа) .

    Reply
  43. Ish_2

    (41) И вот ещё что. Как и ожидалось , в каждой сессии обеспечивается возрастание ссылок.

    Другими словами , если сделать отбор в списке документов по комментарию начинающемуся с «А»,

    то все документы в списке расположены в строгом порядке их создания :

    А1,А2,А3,…..А9999, А10000.

    Аналогично для «В» и «С».

    Контроль осуществлялся с помощью простейшей процедуры :

    Выборка = Документы.РеализацияТоваровУслуг.Выбрать(НачалоДня(Дата(2011,8,31)),КонецДня(Дата(2011,8,31)));
    Пред = 0;
    Пока Выборка.Следующий() Цикл
    Если Найти(Выборка.Комментарий,»С»)=0 Тогда
    Продолжить;
    КонецЕсли;
    Строка =  СтрЗаменить(Сред(Выборка.Комментарий,2),Символы.НПП ,»»);
    Число = Число(Строка);
    Если Число > Пред Тогда
    Пред = Число;
    Иначе
    Сообщить(«***********»+ Выборка.Комментарий);
    КонецЕсли;
    КонецЦикла;  

    Показать

    Reply
  44. Ish_2

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

     НачатьТранзакцию();
    Для н=1 по 10000 Цикл
    Объект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
    Объект.Дата = Дата(2011,8,31,23,59,59);
    Объект.Комментарий = «А»+н; // В обработке для второй сессии использовалось «В»,
    //Для третьей сессии «С».
    Объект.Записать(РежимЗаписиДокумента.Запись);
    Если н%1000=0 Тогда
    ЗафиксироватьТранзакцию();
    Сообщить(» «+н);
    НачатьТранзакцию();
    КонецЕсли;
    КонецЦикла;
    ЗафиксироватьТранзакцию();

    Показать

    Reply
  45. maxx

    Тема увлекательная, но не интересная мне с точки зрения работы прикладного решения, т.к. куча документов в одну секунду думаю в 99% процентах случаях — это неверная ситуация, т.е. не реальная. Если документы (точнее движения) в одну секунду критичны,то лучше от этого изначально избавляться на вводе данных, например, регистрируя связанные документы в регистре сведений с периодичностью в секунду, тогда платформа не даст вводить такие документы, а там уже или пользователь пусть думает или алгоритм придумывать чтобы секунды были разные.

    Reply
  46. Ish_2

    (45) Вообщем-то , конечно, подробно копать в механизме генерации ссылок смысла мало. Но ведь хобби..

    Да и началось всё с простого практического вопроса : почему в типовой БП20 документ «КорректировкаДолга» не закрывает авансы по другому документу.

    Reply
  47. puzano-v

    Отличие 1с8 от 1с7 в том, что доступ к документам в 1с7 ведется через общий журнал, который отсутствует в 1с8.

    поэтому документы на последней секунде располагаются в любом порядке (очивидно).

    Для убедительности зайдите на сервер и посмотрите текст запроса 1с по отбору документов для 1с7 и 1с8.

    ( сложных запросов писать не надо ).

    Reply
  48. Ish_2

    (47) Мы все люди со своими странностями и тараканами. Ничего дурного в этом нет.

    К сожалению , ни слова не понял — о чём это ?

    Но с уважением и пониманием отношусь к попыткам хоть как-то изъясниться в (47).

    Reply
  49. AlexO

    Так и что решили?

    1С умыла руки — «мы так решили, и следите за своими остатками сами», тут еще про свободу какую-то в 1с говорили.. это совсем смешно: «свобода в 1с!».

    Одни рамки и ограничения. А также узость мышления создателей платформы и их методологов.

    Таким образом — проблема разновидных доков в одной секунде нерешаема? и создаются они случайным образом?

    «Мы решили, что будет хаос — разгребайте сами»?

    Reply
  50. Ish_2

    (49)

    Одни рамки и ограничения. А также узость мышления создателей платформы и их методологов.

    Полегче на поворотах.

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

    У Вас он есть ? Давайте обсудим.

    Мой же взгляд , на эту проблему менялся от «очевидного косяка платформы» до «неприятного следствия вполне осознанного решения разработчиков платформы». Дело в том, что любой механизм упорядочивания документов на временной оси не будет лишен недостатков. Судя по всему, существующий вариант механизма разработчики сочли наименьшим злом. Грубо говоря , предлагается убойный по простоте подход :

    » не создавай кучу документов в одну секунду !»

    Reply
  51. AlexO

    (50) >> Полегче на поворотах.

    это бы 1с-у скажите ))

    а то учет учетом, но такие перлы вылазят постоянно…

    >> нужно как минимум предложить свой безупречный механизм упорядочивания документов на временной оси

    а его и не нужно предлагать — все уже изобретено: все ОС позволяют получить и учесть доли секунды, так почему 1С привязалась к секунде? И это не «подход : » не создавай кучу документов в одну секунду !», а ограничение платформы, т.к. создать «кучу документов в одну секунду» норовит сама платформа, а не оператор.

    Кто создает в 1 сек несколько документов — платформа или умысел?

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

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

    Да много чего можно было сделать.

    А главное — можно было в принципе не допускать такого события.

    Но обработка и отслеживание ошибок — далеко не самая сильная сторона 1С.

    Reply
  52. jobkostya1c8

    Очень полезная статья. Изучая суть момента времени Попутно возникает следующий вопрос: если введены несколько документов одного типа в одну и туже секунду как программно изменить их место расположение, т.е. поменять момент времени. Задача в частности сводится к тому, чтоб программно записать новый документ ОперацияБух позади регламентной операции без ее перепроведения, время которой как раз составляет последнюю секунду месяца.

    Reply
  53. AlexO

    (52) kostyaomsk,

    никак.

    Никакого механизма отслеживания и распределения в определенном порядке в базе в 1с нет.

    Вы можете поменять в МоментеВремени объекта только время. Вот этим и рулите.

    Да. еще можете извернуться и УИД поменять. Но оно вам вам нужно?

    Reply
  54. Ish_2

    (52) Сам я не знаю , как это корректно и легально сделать.

    А Вы попробуйте !

    И потом напишите как заменили ссылки и что получилось.

    Я почитаю с удовольствием.

    Reply
  55. red80

    >> Но есть особенность — документы разного типа , записанные в одну и ту же секунду, располагаются в произвольном порядке, а не в порядке их физического создания (как было в 7.7). Документы же одного типа располагаются в порядке их физического создания.

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

    Reply
  56. red80

    Еще:

    В запросе можно сравнивать .МоментВремени (!), но в агрегатных функциях использовать нельзя.

    Reply
  57. BraunAlex

    Из справки 1С

    «Последовательности

    Последовательности предназначены обеспечения проведения документов в непрерывной хронологической последовательности. Последовательность может иметь измерения, в разрезе которых можно контролировать и поддерживать последовательность проведения документов. Существует также доступ к записям регистрации отдельных документов в последовательности.
    » ©

    Reply
  58. jobkostya1c8

    (53) AlexO, в итоге учитывая весь опыт в общем «не надо так внедрять». Только два выхода:

    1. Оставлять интервал между документами (10 секунд) и в конце тоже 10 секунд «на крайний случай». На это был целый лист служебной записки. Так сказать внутренние стандарты фирмы для разработки

    2. Можно создать в конфигурации новый документ только для подобных случаев чтоб он точно записывался последним. Для этого необходимо лезть в механизмы хранения файлов чтоб понять как сортируются ссылки (например понять что сравнивает встроенная функция «МоментВремени().Сравнить(<ДокСсылка>)». Ну это уже если совсем крайний случай.

    Reply
  59. AlexanderKulikov

    Давайте проведем эксперимент. Создадим простой запрос в 1С с выбором остатков и посмотрим в профайлере на запрос к SQL. Мы увидим там кроме всего прочего такой фильтр (который отсекает движения «не раньше» текущего документа)



    WHERE (T4._Period > @P3 OR T4._Period = @P4 AND (T4._RecorderTRef > @P5 OR T4._RecorderTRef = @P6 AND T4._RecorderRRef >= @P7)) ….

    в качестве P3 и P4 устанавливается время документа (например ‘4015-08-20 10:42:14’)

    в качестве P5 и P6 устанавливается тип документа binary(4) ( например 0x0000000C)

    в качестве P7 устанавливается ссылка (идентификатор) документа binary(16) ( например 0x83C0AC220BDCDC1D11E52B74AC06CBD9)

    Таким образом мы видим что

    1. Сравнивается время

    2. Если время одинаковое — сравнивается тип

    3. Если тип одинаковый — сравнивается ссылка

    Естественно, тип и ссылка при изменении документа не меняются. То есть, документ при первоначальной записи в базу данных имеет свое ПРЕДОПРЕДЕЛЕННОЕ место на оси времени внутри секунды.

    Reply
  60. Ish_2

    (59) AlexanderKulikov,

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

    Таким образом мы видим что

    1. Сравнивается время . ———-Ок

    2. Если время одинаковое — сравнивается тип — ОК

    3. Если тип одинаковый — сравнивается ссылка ——ОК

    Ну, понятно, конечно. И ?

    Что нового дало нам Ваше исседование ? Вывод- то какой ?

    Reply
  61. AlexanderKulikov

    Да, собственно, одной строкой кода показал как это происходит в запросе. Лично мне — так проще.

    Reply
  62. SoDm
    На закуску процитирую слова Бориса Нуралиева:

    «Механизм генерации ссылок обеспечивает только их уникальность. Возрастающая последовательность при их генерации не обеспечивается.»

    Вы уверены, что это слова Бориса Нуралиева, а не Сергея Нуралиева?

    Reply
  63. timeforlive

    Первый посткриптум к статье.

    Опечатка:

    Постскриптум

    Reply
  64. Ish_2

    (63) Да, ошибка. Спасибо.

    Пусть останется как есть.

    Reply

Leave a Comment

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