Сравнение табличных документов




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

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

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

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

48 Comments

  1. mailrum2004

    Спасибо. Хорошая обработка. Можно еще вывести отдельной колонкой разницу сумм.

    Reply
  2. Damian

    (1) на досуге прикручу

    Reply
  3. Bacemo

    да. Это лучше, чем штатная 1С Сравнение файлов. Так что + поставил

    Reply
  4. DrAku1a

    Отлично! Теперь не нужно «париться» с ексель-функцией ВПР!

    Reply
  5. Famza

    (0) При сравнении двух файлов mxl из 7.7 выскочило

    {ВнешняяОбработка.СравнениеТабличныхДокументов.МодульОбъекта(213)}: Ошибка при вызове метода контекста (Область)

    Ячейка = ТабДок.Область(«R»+ТекущаяСтрока+»C»+ТекущаяКолонка);

    по причине:

    Область не найдена: R1 000C2

    Пересохранил в 8ке — результат тот же

    Reply
  6. Damian

    (5) совсем забыл, что числа добавляются к строкам с неразрывным пробелом между разрядами 🙂 Сегодня поправлю.

    Reply
  7. Damian

    Добавлена возможность вывода разницы между сравниваемыми колонками числового типа и поправлены некоторые ошибки.

    Reply
  8. fixin

    Молодетс! Давно сам хотел написать такую обработку.

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

    И чтобы могла сравнивать многострочные отчеты, где одна строка данных занимает 2-3 строки (в 1с-стиле, те же карточки счета и т.п.)

    Reply
  9. Damian

    (8) была идея, чтобы сравнивала ячейки не одной строки, а нескольких (для сравнения ОСВ было бы милое дело), но обломался реализовывать.

    Может добавлю, может нет, может кто-то другой добавит и выложит 🙂 Буду только за 🙂

    Reply
  10. VasMart

    WinMerge не подходит?

    Reply
  11. Damian

    (10) WinMerge в своем первозданном виде не умеет сравнивать таблицы подобным образом. Возможно, есть плагины для него, которые реализовывают этот функционал, но я не задавался их поиском.

    Reply
  12. fixin

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

    Смотри, как это работает.

    Есть две таблицы с, например, 5 колонками.

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

    Перебираем ключи из 1, 2, 3 и 4х колонок.

    Ищем такую комбинацию колонок, которая максимально встречается во второй таблице.

    Ну например, есть колонки ФИО Рост Вес Дата

    Я беру сначала ФИО, ФИО не годится, т.к. есть неоднозначные соответствия.

    Я беру ФИО + Рост, но опять же не прокатывает, т.к. есть дубли.

    А вот ФИО + Дата дублей не будет.

    И еще — не мешало бы автосопоставлять колонки.

    Например, по значениям — можно ведь определить, где колонка ФИО, где колонка адреса, где колонка дат и т.п.

    Это еще не ИИ, но интересная тема. Тут бы пользователям помочь — подсказать какие виды таблиц бывают.

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

    Reply
  13. tazmag

    а как насчет dbf

    Reply
  14. Damian

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

    (13), а зачем? для DBF придется указывать имена полей сопоставления и сравнения, следовательно файл надо открыть каким-нить просмотрщиком, тем же Excel… А раз открыли в Excel, почему бы его не сохранить как XLS? Ну и дальше по накатанной 🙂

    Reply
  15. fixin

    (14) озолочение оно требует сил. Чтобы быть Золотым, нужно чтобы юзвери невыносимо Любили. Вот как меня, например. 😉

    Reply
  16. Yashazz

    (8), (9) Ага. Однажды я озверел и сделал такую штуку, мои юзвери все пользуются. А потом 2 года всё собирался причесать и на ИС выложить, но вот, опередили. Сравнение для нескольких строк тоже влом делать оказалось.

    Reply
  17. fixin

    (16) вот видишь, как важно преУСПЕТЬ

    Reply
  18. mailrum2004

    Спасибо за изменения (7). Идея (12) автоматического поиска ключевых колонок очень понравилась. Хорошо еще иметь возможность указывать тип для каждого файла в отдельности, чтобы сравнить *.xls с *.mxl

    Reply
  19. Damian

    (18) для того, чтобы задать параметры чтения файла, его надо открыть и посмотреть на состав колонок и количество строк. Мне кажется, при этом ничего не мешает сохранить MXL в XLS и сравнивать уже файлы одного формата.

    Reply
  20. dyak84

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

    Reply
  21. Famza

    (0), еще было бы неплохо прикрутить просмотр сравниваемых файлов — удобней и номера колонок заполнять будет

    Reply
  22. Famza

    (0), взял две оборотки из 7.7, сохранил в *.mxl и сравнил. Результат:

    1. При выборе в настройках сравнения для файла типа «Число» ячейки обнуляются. Может преобразовать в число хотя бы для файлов 1С?

    2. При последовательном сравнении файлов сопоставление получается такое:

    Reply
  23. Damian

    (22),

    1. Если не удается преобразовать значение ячейки в число (значение содержит нецифровые символы) — возвращается 0.

    2. Последовательное сравнение так и будет работать. Этот режим нормально отработает только при идентичном содержимом колонок сопоставления.

    Reply
  24. Famza

    (23) но ведь колонки в пункте 2 одинаковы — стандартная ОСВ.

    Reply
  25. SvetLanaGil

    Спасибо за обработку! Отличное подспорье в работе.

    Reply
  26. Фред

    На досуге попробую, Кажется, может помочь иногда.))

    Reply
  27. Damian

    (24) Famza, судя по приложенному скрину, во втором файле нет строки «08.4 Приобр. отд. объектов ОС». Последовательное сравнение так и должно отработать. Вообще этот режим сравнения изначально не планировался и в дальнейшем развиваться вряд ли будет. Используйте обычное сравнение, оно даст более качественный результат.

    Обработка обновлена, см. Update 27.09.2012.

    Reply
  28. gull22

    Отличная обработка. Пожелание автору. Не обязательное, и за то чтоесть низкий поклон. Желательно реализовать возможность изменения ширины колонок на закладке «Результат», а то экрана бывает не хватает

    Reply
  29. antares_of

    Очень полезная обработка. Встроенная в 1с обработка «сравнить файлы» тоже это делает, но не дает ни каких возможностей настройки перед выводом. А еще в стандартной я столкнулся с проблемой: когда сравниваю остатки в двух базах УТ, выгружаю в табличный документ всего две колонки с кодом (или названием) и с количеством. Так она мне некоторые позиции сопоставляет с теми у которых совершенно другой код и говорит, что код изменился. Хотя номенклатура с таким кодом (или названием) есть в обеих базах.

    Reply
  30. Vanchez

    Спасибо, очень пригодилась! Для себя добавил галки «Не учитывать регистр» (для колонок сопоставления), «Выводить только разные строки».

    Reply
  31. Famza

    (31) gurtas,

    z ghjcnj cgfvk. n/r / ytn ltytu f j,hf,jnre [jxtncz

    транслит «я просто спамлю т/к / нет денег а обработку хочется». Спам одноозначно

    Reply
  32. VallyD

    Обработка наверное хорошая, но если я правильно поняла, то если сформировать ОСВ по товарам с учетом партий, ничего не получится правильно сравнить. Не поможет ни последовательное, ни обычное сравнение. Так как для разных товаров может быть один партиеобразующий документ, и тогда наступит полная путаница. Пользователь fixin прав, без поиска ключа не обойтись.

    Reply
  33. Damian

    (33) да, не получится вообще нормально сравнить, если отчет построен иерархически, с группировками (не только ОСВ).

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

    Иногда, кстати, быстрее не отчет на коленке набросать, а запрос в консоли — и вывести результат в табличный документ )

    Reply
  34. gull22

    Низкий поклон автору. Выручала экономя время не один раз! Скачал и другим советую.

    Reply
  35. logarifm

    Идея имеется но она узкоприменима!

    Reply
  36. dyak84

    Автор такой маленький вопрос а если сортировка в первом файле от А до Ю, а в другом от Ю до А как в таком случае будет работать ваша обработка. Большие по несколько тисяч строк Ваша обработка обрабативает. Зарание спасибо за ответ

    Reply
  37. Damian

    (37) сортировка файлов не имеет значения, если не используется последовательное сравнение.

    Reply
  38. toss

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

    Reply
  39. gull22

    Беда пришла откуда не ждали. УПП релиз 1.3.40.2 платформа 8.2.18.102. При выборе файла Excel сообщение об ошибке

    {ВнешняяОбработка.СравнениеТабличныхДокументов.МодульОбъекта(1885)}: Ошибка при установке значения атрибута контекста (ActiveConnection)

    axCatalog.ActiveConnection = Connection;

    по причине:

    Произошла исключительная ситуация (0x800a0bb9)

    Reply
  40. Damian

    (39) Первоначально задача стояла вообще, в принципе, определить строки, в которых различаются значения, чтобы сузить область поиска ошибок.

    Раскрашивание и т.п. — это уже мелкие, дорогие сердцу интерфейсные плюшки 🙂

    Может, когда-нибудь попозже и реализую более наглядную заливку.

    (40) Судя по информации, почерпнутой в доверительных беседах с Google, это какой-то бок .NET Framework.

    Файлы Excel читаются при помощи ADODB, и где-то передаются недопустимые, с точки зрения .NET, аргументы.

    Единственное, что могу предложить:

    1. Попробовать запустить на другой машине

    2. Скопировать файлы в чистый табличный документ, сохранить как MXL и сравнивать уже их.

    Reply
  41. SAMIR666

    Отличная Оброботка

    Reply
  42. SlavaVNL

    Еще не проверял, но уже скачал и плюсанул. Всегда пользовался ВПР а тут такое счастие!

    Reply
  43. sonGodv

    Качественная обработка. Жаль нет управляемой формы. Думаю добавить, как-то уже отвык от обычного приложения

    Reply
  44. b-dm

    Хорошая вещица, добронто сделанная, но мне к сожалению не помогла…

    Reply
  45. PavelZnaikin

    её надо УФ переводить

    Reply
  46. Castlevania

    Огромное спасибо! Очень помогла

    Reply
  47. tricolor

    Супер обработка!

    Reply
  48. DomKom

    Гениально, работает, СПАСИБО.

    Reply

Leave a Comment

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