<?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='\
Внятно и полезно 😎
Хорошая статья!
Хорошая статья. Единственное дополнение: при реальном использовании обёрток возможно более удобным будет оформить их в отдельном общем модуле. Типа эмуляция класса. 😀
(3) Спасибо. Надо подумать как это поудобнее оформить.
(0) Жаль в VBS регулярные выражения кастрированы…
(5) Я свою компоненту набросал для использования нетовских регулярных выражений из 1с-ки.
(6) главное чтобы без NET 😉
(7) У меня НЕТ везде стоит, так что на счет этого не беспокоюсь вообще.
(8) меня больше беспокоит где он не стоит 😀
Из минусов обязательно нужно упомянуть возможность зависания при использовании сложных шаблонов. Отладчик RegExBuddy в таких ситуациях пишет о невозможности получить результат за разумное число итераций.
RegExBuddy — платная только?
А где книжечку с «обложки» публикации скачать можно? 🙂
Из минусов я бы отметил еще ограниченность регэкспов в VBS (тут об этом уже упоминалось), нет «просмотра назад» в частности, что меня очень огорчило, когда я писал свой обфускатор…
(0) Доступно и понятно. Молодец.
(12) Например на Infanata
(10) Хорошо… я с подобным не сталкивался. Здорово если бы был примерчик такого шаблона с которым зависает
(11) Если хорошо поискать можно найти и «русскую версию» 😉
(12) По сравнению со встроенным языком это как мне кажется не ограниченность
Было бы здорово если бы 1С встроила поддержу RegExp на уровне платформы наконец то за код Лев(Стр,Найти(… можно будет проклинать 🙂
Очень хорошо написано и понятно.
Скачал. Запустил. Получил:
Выполнений: 100 функций на RegExp время: 172 мс
Выполнений: 100 Функции из Бух 1.6 и КОРП 2.0 время: 78 мс
Мне показалось, что должно быть наоборот. Что я делаю не так?
(16) Думаю, что из теста времени надо убрать время на создание ком-объекта.
(17) Ком-объект создается и настраивается при открытии обработки в её модуле. Проверил в отладчике — отрабатывается 1 раз при открытии…
Думал время определяет неправильно. Добавил циклов. Получил:
Выполнений: 1 000 функций на RegExp время: 1 781 мс
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 703 мс
(18) А что за обработка? Дай посмотреть 😉
(19) Вверху страницы «Скачать Пример. Тест. Сравнение скорости…»
+18 Думал из-за конфигурации. Запустил в УПП. Получил:
Выполнений: 1 000 функций на RegExp время: 1 719 мс
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 625 мс
Выполнений: 100 функций на RegExp время: 445 мс
Выполнений: 100 Функции из Бух 1.6 и КОРП 2.0 время: 341 мс
(22) Ну, вот. Хоть и не большой, а перевес в сторону 1С. 🙁
Видимо у меня ПК немного побыстрее и 1С отрабатывает на нем оптимальнее чем RegExp.
(23) А мне кажется, что тут дело в кэшировании… Надо бы тест переделать на рандомную последовательность разбираемой строки…
(24) Вряд ли. В функции 1С строка постоянно режется и результат пишется в ту же переменную. Так не прокэшировать.
Но как вариант можно попробовать и случайный набор строк.
(24), (25) неудачный пример для сравнения получился (слишком простой) поэтому и не акцентировал на нем внимание.
На моей системе выдавал как у Душелова около 400 мс иногда с перевесом в пользу 1С.
Я уже давно сталкивался что 1С быстрее отрабатывает на простых вариантах, поэтому и писал про читаемость
(25) Все таки, думаю, при постоянном вычислении одних и тех же значений 1С-как кэширует.
И я ряд тестов провел, скорость примерно одинаковая, выше/ниже друг друга.
Согласен с (26) надо более сложный пример.
(26) (27) Я «ЗА» тестирование. Но у меня нет более сложного примера. Что вы имеете ввиду?
А функция в 1С могла бы выглядеть так:
Показать
Мне кажется вполне читаемо и работает быстрее. Возможно на более сложном примере будет иначе…
(28) Берем к примеру любой анализ хтмл-кода, к примеру, выбрать весь текст, без тегов и т.п. Думаю, что «в ручном» режиме 1С это будет делать очень долго, именно в этом и есть прелесть регулярных выражений.
Или отобрать все е-мыл адреса в тексте…. Примеров найти можно много, но тут сложность будет в другом — написать аналогичные примеры на языке 1С.
(28) если честно я редко заморачиваюсь на счет скорости в абсолютном виде. Приемлемая вот то слово.
(29) согласен правильные примеры
Найти все GUIDы в тексте
Главная прелесть регуляров то что анализ описывается простым понятным языком.
Мое знакомство с RegExp началось когда мне нужно было разбирать файлы от дистрибьюторов вида:
<RCAgent {1},{Иванов}>
<SalesMen {1}, {ТП}, {1}>
…
причем была обработка, которая обрабатывала файлы, но она делала это очень медленно на файлы 30 Кб уходило по 5 минут. Понятно что она была написана не оптимально, но мне если честно трудно упрекать автора т.к. у меня от многих задач разбора текста «голова съезжала».
Переписал на RegExp оказалось просто и понятно и даже оптимизировать не пришлось разбор файлов по 100 Кб стал занимать 10 сек вместе с записью данных в СУБД. Было правда несколько ошибок, но это из за моего плохого знания языка шаблонов, да и ошибки исправлялись за 1 минуту.
Очень хороший обзор. За примеры кода — отдельное спасибо.
На скоростях не замарачивайтесь — можеть и дольше чем на встроенном языке 1С, но зато понятность и скорость алгоритмизации процеса это компенсирует.
Да, хороший обзор.
Лично я бы код функций оформил по-другому:
1. простой общий модуль — в каждую функции передаем переменную RegExp как первый параметр
т.е. сначала создаем (кеширование), затем используем
в этом случае можно сделать проверку параметра в каждой функции — типа если параметр не заполнен, то создаем его по новой, если заполнен, пропускаем.
2. или создаем отдельную обработку-класс, в модуль которой и записываем весь указанный код, убираем из имен функций строку «РегулярныеВыражения_», добавляем к нужным функциям Экспорт.
и класс почти спокойно можно юзать.
Лично мне как приверженцу ООП нравится второй вариант 🙂
Ну и пример на самом деле хорошо бы поменять 🙂
РазложитьСтрокуВМассив и ПодставитьПараметрыВСтроку нужно изменить, т.к они могут работать неточно 🙂
например, в первый метод передадим в качестве разделителя точку, получим ошибки 🙂
во втором также могут быть проблемы — название функции не очень соответствует выполняемой функции
Насчет примера был неправ.
Даже в этом случае регулярные выражения немного, но выигрывают.
Проблема просто в неоптимальном/неаккуратном коде реализации метода РазложитьСтрокуВМассив 🙂
вместо вычисляющего цикла
Показать полностью
нужно юзать простое
Показать полностью
и результат налицо:
Выполнений: 1 000 функций на RegExp время: 2 516 мс
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 2 906 мс
для 100 функций — время одинаково 🙂
и это на очень простой задаче 🙂 — а на сложных выигрыш будет намного больше
ЗЫ жаль, что код
Показать полностью
не работает, так было бы еще быстрее 🙂
PPS естественно, код функции РегулярныеВыражения_Выполнить также нужно изменить.
(28) Приведенного кода из (34) достаточно для сравнения производительности и тестирования ? 🙂
(34) 🙂
А круче всех в этом сравнении:
Выполнений: 100 Функции из Бух 1.6 и КОРП 2.0 время: 439 мс
Выполнений: 100 функций на RegExp время: 334 мс
Выполнений: 100 функций на яве время: 224 мс
(33) с разделителем точка не будет проблем проверил шаблон «[#k8SjZc9Dxk.]*»
(34) спасибо теперь лучше 😉
(36) класс!!! будем знать самый быстрый вариант
Учел ценные предложения товарища artbear (обновил пример)
1С интерпретатор. Больше строк кода — медленнее работает. Внес изменения в тест. Тест прилагается.
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 641 мс
Выполнений: 1 000 функций на RegExp время: 1 047 мс
Выполнений: 1 000 функций на Ява время: 843 мс
Нужно еще подумать… 🙂
(36) Код на Яве не соответствует требованиям теста — возвращаемое значение не Массив 1С 🙂
нужно в ее конце вставить код
Показать полностью
И результат по тесту из (39)
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 797 мс
Выполнений: 1 000 функций на RegExp время: 1 296 мс
Выполнений: 1 000 функций на Ява время: 2 063 мс
Счас посмотрю код 1С из (39)
ЗЫ лично я для проверки в конце модуля формы сразу вставляю юнит-тест, который и выдал мне ошибку для Явы 🙂
Показать полностью
и сплю спокойно
ОФФ. По (39) мелкий коммент —
ИМХО очень неудачное структурирование кода в одну строку 🙁
читать очень трудно, почти невозможно 🙁
особенно метод РазложитьСтрокуВМассивПодстрокБух16Корп20
остальные-то более тривиальны.
Все таки примеры нужны другие 🙂
Типа тех, что я предложил ниже.
(41) Структурированный код приведен в (28), а в тексте теста используется оптимизированный код. 🙂
В 1 строчку работает в 1.5-2 раза быстрее. О причинах я писал в (39) — 1С интерпретатор.
(43) Про скорость кода в 1 строку согласен
(42) (43)
Можно еще ускорить 🙂
1. в конце модуля добавляем
Показать полностью
2. исправляем метод РазложитьСтрокуВМассивЯва
на следующий
Показать полностью
Получаем результат
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 735 мс
Выполнений: 1 000 функций на RegExp время: 1 859 мс
Выполнений: 1 000 функций на Ява время: 688 мс
счас переделаю код RegExp 🙂
PS юнит-тесты показывают, что код верный — возвращается правильный массив
(44) Нормально!.. Можно еще поковырять 🙂
(44) Ошибочка 🙂
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 641 мс
Количество элементов: 151
Выполнений: 1 000 функций на RegExp время: 1 047 мс
Количество элементов: 151
Выполнений: 1 000 функций на Ява время: 797 мс
Количество элементов: 302 000
(45) На самом деле я немного смухлевал, конечно 🙂
Ведь в (44) на самом деле для Явы всегда возвращается один и тот же массив 🙁 — а в остальных всегда вновь созданный.
К сожалению, у 1С нет метода копирования одного массива в другого или хотя бы конструирования массива по другому массиву.
А выгрузка/загрузка через списокЗначений или таблицуЗначений сильно тормозит 🙁 (фактически время увеличивается в 2 раза)
Остается утешаться тем, что для более сложных задач RegExp поудобнее/помощнее/поудобнее 🙂
(46) Забыл дописать — естественно, в функции Ява нужно добавить резМассив.Очистить() 🙂
У меня юнит-тесты все равно такую ошибку бы не пропустили 🙂
(46) (45) Еще поковырял код 🙂
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 750 мс
Выполнений: 1 000 функций на RegExp время: 1 844 мс
Выполнений: 1 000 функций на Ява время: 344 мс
Вместо Явы, которая не возвращает чистый SafeArray, использую VBScript
в начале модуля
Показать полностью
и в конце модуля
Показать полностью
ЗЫ код 1С также в 1 строчку.
(49) Это не ява, это VBS 🙂 добавляй в тест 😉
Итак, для простой задачи получения массива подстрок из строки по разделителю
получилось вот такое распределение
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 750 мс
Выполнений: 1 000 функций на RegExp время: 969 мс
Выполнений: 1 000 функций на VBScript время: 375 мс
Больше способа ускорить получение данных через RegExp не нашел.
Уже видно, что не такая большая разница между 1С и RegExp — даже для столь простой задачи.
Ну и ВБСкрипт выше всяких похвал 🙂
ЗЫ в последнем варианте реализации regExp загнал практически весь код в ВБСкрипт.
(51) Сделал более «читаемый» текст модуля на 1С. Вот результаты замеров.
Выполнений: 100 Функции из Бух 1.6 и КОРП 2.0 время: 47 мс
Выполнений: 100 функций на RegExp время: 78 мс
Выполнений: 100 функций на VBScript время: 47 мс
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 469 мс
Выполнений: 1 000 функций на RegExp время: 890 мс
Выполнений: 1 000 функций на VBScript время: 406 мс
А вот альтернативные способы получить на 1С-е, не такие быстрые…
или, где Т = Новый ТекстовыйДокумент;
(53) Вот и я говорю об альтернативном коде и довольно быстром…
(54) Интересный вариант 🙂
А почему у тебя в (52) разница не такая большая ?
у меня на твоем тесте
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 625 мс
Выполнений: 1 000 функций на RegExp время: 1 000 мс
Выполнений: 1 000 функций на VBScript время: 407 мс
т.е. ЗначениеИзСтрокиВнутр и рядом с ВБ не стоит 🙂
(55) Наверное зависит от ПК, ОС и другого установленного ПО. У меня дома почему-то 1С немного медленее шевелится, хотя ПК почти одинаковые (дома RAID побольше 🙂 ).
(56) Кстати, меня давно интересует вопрос — почему 1С функцию РазложитьСтрокуВМассив не реализует как встроенную/штатную.
Ведь у 1С на этой функции достаточно много построено 🙂
Кстати, твой код в (52) уже не имеет никакого отношения к Бух 1.6 и КОРП 2.0 🙂
Я думаю, что надо заводить отдельную ветку с поисками и оптимизацией алгоритмов штатных, 1С-ных универсальных методов.
(58) Хорошая идея.
http://infostart.ru/public/64770/
Завел новую ветку
(57) Функция ЗначениеЗаполнено() появилась тоже сравнительно недавно. Может быть в 8.3 сделают. 🙂
В 7.7 у меня все построено на списках значений (динамических массивов нет) и используется приблизительно вот такой код:
Т.е. кое что по разбору строк в списки раньше было, но со временем об этом забыли…
Ну, я тоже к этому не имею непосредственного отношения 🙂
(60) это уже ОФФ 🙂
В 77 нужно хотя бы просто загружать ВК 1С++ — создание объектов будет супербыстрым, в штатной 1С оно очень-очень медленно.
Лично проверял и делал код в 1С++ 🙂
(0) Предполагаю, что в п. 6. Заключение есть ссылка на меня. Можно поправить ник или это так задумано?
(63) Извини поправлю 🙂
Суперски!!! Регулярные выражения очень помогаюТ!!! не Хочется каждый раз писать одно и тоже )
Автор — СПАСИБО за подробное изложение!
Выполнений: 100 Функции из Бух 1.6 и КОРП 2.0 время: 47 мс
Выполнений: 100 функций на RegExp время: 78 мс
Выполнений: 100 функций на VBScript время: 47 мс
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 469 мс
Выполнений: 1 000 функций на RegExp время: 890 мс
Выполнений: 1 000 функций на VBScript время: 406 мс
хорошая статья, жаль нет примеров, как заменить одну строку на другую, но буду копать.
Может быть на РегЭксп так долго, потому что каждый раз объект создаете? Попробуйте его один раз создавать.
Ссылкаhttp://www.script-coding.info/WSH/RegExp.html битая…
http://www.script-coding.com/WSH/RegExp.html#3.1 .
Вместо нее рекомендую:
С фразы: «основное достоинство RegExp это читаемость»
чуть со стула не упал 🙂
например, чё за? ‘#k8SjZc9Dxk\s*((?:(?:(?:»[#k8SjZc9Dxk»]»)*)|(?:[#k8SjZc9Dxk/]*)|(?:[#k8SjZc9Dxk/]+/))*)(//.*)?\s*$’
и это ведь достаточно примитивный RegExp
Ну и за [([wА-яёЁ]+)] хочется кого-то придушить. Почему в Perl’е я могу просто написать w, а в родном виндовом движке — фигушки??!!!
(68) Читаемость относительная. Код еще сложнее. Ну естественно при условии хороших знаний регуляров
(69) Основной прикол регэкспов в том, что написать иной раз проще, чем понять 🙂
Если я всё правильно понимаю, то можно и не спрашивать будет ли конструкция
у меня работать, если сервер 1С располагается на Linux?
(71) Ну да не будет
Там наверно есть другие библиотеки, но подсказать ничего не могу.
(72) Ну да, там есть штатные консольные средства мощные. Ясненько… просто решил уточнить. Спасибо.
Всем привет! Есть обработка по поиску картинок в интернете:http://infostart.ru/public/82682/
в ней как раз основная фишка поиск через регулярное выражение.
Алгоритм простой: из Гугля или Яндекса получаем список картинок и анализируем при помощи регулярного выражения
Если Matches.Count больше нуля — все ОК.
Все работало хорошо до последнего времени, что сломалось не пойму.
Гугл картинки собирает, а скрипт ничего найти не может. Может кто знает в чем проблема?
P.S. Автор разработки отмалчивается.
(74)Присоединяюсь.
Помогите пожалуйста с решением данной проблемы.
У кого-нибудь работает под 8.3.4. ?
При подключении компоненты под 8.3.4.389 падает платформа.
(70)
Some people, when confronted with a problem, think
“I know, I’ll use regular expressions.” Now they have two problems.
©
(76)http://infostart.ru/public/183084/ не пробовали?
(78) andrewks, О сорри, не в ту публикацию написал. Падает под 8.3.4 именно компонента от Орефкова
вот это да, это же джаваскрипт в 1С 🙂