Некоторые особенности настройки периода в СКД




Принцип обмена данными из 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='\

35 Comments

  1. alex_art

    хорошая мысль …. вы думаете СКД дольше 4000-х тясячного года не протянет ? :))))

    Reply
  2. ll13

    (1) Я оптимист и конечно же уверен, что СКД протянет дольше 4000-х тясячного года, да вот беда — максимальная дата которую возвращает функция ДАТАВРЕМЯ — это 31.12.3999 🙁

    то есть ДАТАВРЕМЯ(3999,12,31) вернет 31.12.3999, а вот ДАТАВРЕМЯ(4000,1,1) — уже вызовет ошибку 🙂

    Reply
  3. vvr908

    Спасибо, четко и по делу. Удобно сделать все это в рамках СКД и не заморачиваться на переделку периода в форме отчета.

    Reply
  4. rostova.it@gmail.com

    и на какой ерунде люди только плюсы не рубят….

    Reply
  5. e-tixom

    Не плохо было бы еще научить 1С понимать, что время окончания периода это 23:59:59, а не 00:00:00.

    Reply
  6. ll13

    (5) В СКД, при использовании типа СтандартныйПериод,

    ДатаНачала — имеет время 00:00:00, а ДатаОкончания — 23:59:59

    Учите матчасть 😀

    Reply
  7. e-tixom

    (6)Да уж понятно, что речь идет не о стандартном периоде, не тормозите!

    Reply
  8. ll13

    (7) А…, Вас наверное смущает ДАТАВРЕМЯ(3999,12,31) ?

    Если вы столь щепетильны используйте ДАТАВРЕМЯ(3999,12,31,23,59,59) или КОНЕЦПЕРИОДА(ДАТАВРЕМЯ(3999,12,31), «ДЕНЬ»))

    Reply
  9. e-tixom

    (8) Спасибо, что подсказали!. А смущает не меня, а пользователя, мы ведь собственно для них делаем. 😀

    Reply
  10. Hron

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

    Reply
  11. detec

    Что мешает программисту в закладке «Параметры» указать какое-нибудь значение стандартного периода? Например, прошлый месяц? Оно потом подставляется у пользователя в режиме Предприятие.

    Лично я всегда прописываю дату начала как НАЧАЛОПЕРИОДА(&Период.ДатаНачала, «ДЕНЬ»), и по аналогии — дату конца.

    Reply
  12. ll13

    А что мешает программисту НЕ указывать «какое-нибудь значение стандартного периода? Например, прошлый месяц? » что бы оно потом НЕ подставлялось у пользователя в режиме Предприятие ?

    Reply
  13. artbear

    (0) Что исправил в статье?

    Reply
  14. sant78

    ВЫБРАТЬ

    РеализацияТоваровУслуг.Ссылка КАК Ссылка,

    РеализацияТоваровУслуг.Дата КАК Дата

    ИЗ

    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

    {ГДЕ

    (РеализацияТоваровУслуг.Дата >= &ДатаНач),

    (РеализацияТоваровУслуг.Дата <= &ДатаКон)}

    УПОРЯДОЧИТЬ ПО

    Дата,

    Ссылка

    Это текст запроса, без всяких заморочек.

    ЕСЛИ Пользователь ИДИОТ ТОГДА //и ставит значение ДатаНач больше ДатаКон

    ему пора подумать о смене профессии

    ИНАЧЕ

    Пользователь не зря получает зар. плату

    КОНЕЦЕСЛИ;

    Reply
  15. ll13

    (14)Прочитай статью 15 раз, особенно её вступительную часть, которая касается восприятия информации пользователями …

    Reply
  16. Borunmeert

    Не работает условие, что то не то!

    Reply
  17. Brawler

    Сегодня словил ситуевину на 8.3.6.2076, может и раньше было не знаю, никто не жаловался ибо пока только к 8.3.6 готовлюсь, перелопачивают вешние обработки чтобы работали под БСП 2.3.1.

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

    на 8.3.5 пашет, а на 8.3.6.2076 нет)) с потугами качаю 8.3.6.2100 (инет еле жив), может 1С исправили это дело, а пока наблюдаю сообщение «Не установлено значение параметра «Начало периода»»

    Reply
  18. insurgut

    Та же ерунда, 8.3.5.1482, когда очищаю дату начала — вылетает ошибка:

    Ошибка исполнения отчета
    по причине:
    Параметр не найден «Период.ДатаНачала»
    Reply
  19. insurgut

    Что-то вообще тут ничего не работает, дата окончания пустая — а все равно конец 3999 года не берется…

    Reply
  20. insurgut

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

    Пример запроса СКД:

    ВЫБРАТЬ
    ЧекККМСкидки.СкидкаНаценка,
    ЧекККМСкидки.Ссылка,
    ЧекККМСкидки.Сумма
    ИЗ
    Документ.ЧекККМ.Скидки КАК ЧекККМСкидки
    {ГДЕ
    (ЧекККМСкидки.Ссылка.Дата >= &ДатаНачала),
    (ЧекККМСкидки.Ссылка.Дата <= &ДатаОкончания)}

    Показать

    В параметрах ДатаНачала = &Период.ДатаНачала, а ДатаОкончания = &Период.ДатаОкончания (обращаю внимание, что никаких КонецПериода использовать не надо при использовании стандартного периода).

    Все просто и никаких заморочек.

    Reply
  21. Craig

    (20) insurgut, А вот за пояснение для чего нужны {} скобки отдельное спасибо!!!

    Reply
  22. RomanRomans

    (17) Brawler, пробовал на 8.3.6.2299 — тот же результат ‘Не установлено значение параметра «Конец периода» ‘.

    Причем не заполняется параметр с выражением «&СтандартныйПериод.ДатаОкончания», а параметр с выражением «&СтандартныйПериод.ДатаОкончания» заполняется исправно

    Reply
  23. insurgut

    (22) RomanRomans, платформа тут ни при чем, прочтите мой комментарий

    Reply
  24. killstrike

    То есть скопипастил (источник хоть указал и то дело), а здесь выложил за 2 sm? Однако.

    Reply
  25. premierex

    (0) 3). «Кроме того будем проверять что бы ОкончаниеПериода >= НачалоПериода, и если это не выполняется то будем считать что ОкончаниеПериода не задано, т.е. 2).»

    И что получится? Пользователь захотел сформировать отчет за определенный период позапрошлого года, ошибся в дате окончания (установил меньше даты начала) и сидит, ждёт пока его отчет сформируется за период с позапрошлого года по текущую дату. Безо всяких предупреждений со стороны программы. Тоже, как мне кажется, «неблагодарное это дело, да и неправильное». В СКД есть флаг запрета незаполненных значений, на некорректно заданный период тоже выводится ошибка формирования, так что пару-тройку раз пользователь ошибку «словит», и в дальнейшем уже будет очень внимательно подходить к заполнению параметров отчета.

    Reply
  26. user758181

    Коллеги, приветствую!

    Платформа 8.3.10.2580.

    В СКД отчете имеется запрос с условием по периоду ДатаНачала и ДатаОкончания. В запросе определил условие:

    ТекущиеКадровыеДанныеСотрудников.ДатаУвольнения >= &ДатаНачала
    И ТекущиеКадровыеДанныеСотрудников.ДатаУвольнения <= &ДатаОкончания
    

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

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

    Подскажите где что делаю не правильно.

    Спасибо.

    Reply
  27. user758181

    никто не поможет?

    Reply
  28. Brawler

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

    У вас будет на самом деле все так же три параметра:

    ДатаНачала

    ДатаОкончания

    ДатаОкончанияВычисляемая (невидимый параметр и используется в запросе) вычисляется по формуле похожей как у вас там уже написана и считается от видимого параметра ДатаОкончания

    Reply
  29. user758181

    (28) К сожалению, тут важно использовать стандартный период, с его возможностями интерактивного выбора периода — месяц, квартал,, год и тд.

    Reply
  30. RimidalV

    (27)

    Добавьте условие

    ………

    ИЛИ &ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1))

    Reply
  31. Craig

    (0) Автор — убери пожалуйста из статьи зачеркнутый текст ДАТАВРЕМЯ(3999,12,31). Копипастом пользоваться не удобно.

    Оставь только правильный вариант.

    Reply
  32. user846872

    Гм…

    Или я чего-то не понимаю, или можно просто задать для параметра начала периода не только выражение, но и значение. Например, (1999,01,01). Тогда, если с параметра СтандартныйПериод пользователь уберёт галку, период установится с 1999 по 3999, что будет равносильно варианту «включить всё».

    И никаких проблем с потерей параметров. Вот только что проверил.

    Reply
  33. getnight

    (20) Как оказалось, крайне важно задать эти параметры:

    Если Дата1 и Дата2 поставить Всегда, то, будучи внутри {}, будут ВСЕГДА подтягиваться, даже если

    пустые… следовательно, описанного эффекта не будет.

    Или если СтандартныйПериод поставить Авто, то будет то же самое…

    Reply
  34. insurgut

    (33) само собой — если ставить ВСЕГДА, то это будет аналогично тому, что прописывать условия без фигурных скобок. Вся суть фигурных скобок как раз в необязательности параметра.

    Reply
  35. VKuser514865

    Добрый день, подскажите, пожалуйста, как быть? Если в параметрах Начало и Конец убираю галки, то система выдает то что на скринах, а если оставляю все галки, то отчет то вроде и работает, но периоды приходится выбирать по 2 раза… Как это можно поправить?

    Reply

Leave a Comment

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