<?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='\
В Вашей статье совсем не прозвучала тема о полезности задачи. А между тем, я такую решал в след. проблеме:
— импортировал товары их файла. Поиск велся по коду/ артикулу / штрих-коду и т.д.
А наименования в файле только похожи на наши в базе.
— потом нужно показать результат пользователю оба наименования этими двумя колонками.
— т.к. строк много, вот тут и нужно сравнить оба наименования и цветом/ значком показать степень различия.
Мой алгоритм был простым: по количеству совпадающих слов. Так что накоплю денег и скачаю для спортивного интереса.
(1) Спасибо за комментарий. Действительно, функцию можно использовать для таких вещей как автоматическое сопоставление номенклатуры предприятия и номенклатуры поставщика в той же ERP.
(1) успешно решается применением StrMatch.dll (работает и в 8-ке)
— работает
(1),(2) обработки с такими возможностями уже есть на ИС для 8-ки, поищите.
(2)
(3)
В данном решении используется StrMatch.dll?
я помню что StrMatch.dll не работает на 64x
(4) Нет, я не использовал внешние компоненты.
Данная обработка написана с учетом того, что в конфигурации есть БСП, управляемые формы.
Скачал. В УПП не открывается, т.к. БСП нет
(6) Спасибо за замечание. Добавил вариант обработки без использования БСП.
Алгоритм Левенштейна на 1С давно сделан
(8) Этот пост не видел, видимо плохо искал. Тем лучше, что теперь у нас есть 2 алгоритма и «Расстояние Левенштейна» и «Расстояние Дамерау-Левенштейна» (дополненный Дамерау операцией перестановки букв).
БСП — это что?
(10) В данном случае оформление внешней обработки для возможности встраивания в справочник «Дополнительные Отчеты и Обработки», который принадлежит Библиотеке Стандартных Подсистем.
А есть ли алгоритмы учитывающие перестановку слов?
(12) На самом деле этот алгоритм можно доработать и под перестановку слов. Его суть заключается в том, что изначально создается «словарь» (каталог), уникальных символов из двух наборов данных — строка, которую надо сравнить и строка с которой идет сравнение. Раньше коды символов были в кодировке ASCII (досовской IBM866), что наталкивало программистов на простое решение — создать массив из 256 элементов, где индекс будет равен коду символа. С появлением unicode, utf-8 и utf-16 (которую использует 1С) алгоритм потребовалось немного видоизменить, т.к. возможных символов стало несколько десятков тысяч. Соответственно один символ уже не занимает фиксированное количество байт и может иметь вариативный размер. Но весь их набор на самом деле не нужно держать в памяти. Достаточно, чтобы в словаре были перечислены все уникальные значения из двух строк. Таким образом можно сделать 2 словаря и 2 проверки. Первый словарь — набор уникальных символов, второй словарь — набор уникальных слов. Таким образом первая проверка даст процент похожести двух строк в разрезе символов и их перестановок, а вторая проверка в разрезе слов и их перестановок. Два значения результата можно привести к какому-то общему.