Кто и что изменял в документе




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

57 Comments

  1. CheBurator

    Антон! а прокомментируйте, плиз, — ловит ваша разработка протое изменение порядка строк (считаем что это не изменение), добавление строк, удаление строк? Прокомментируйте чуть подробнее.. в каком формате хранится, как логгируется?

    Reply
  2. antonrost

    Исправил

    вместо

    ТЗ.Автор = глПользователь;

    теперь

    ТЗ.Автор = ?(ПустоеЗначение(ПолноеИмяПользователя())=0,ПолноеИмяПользователя(),ИмяПользователя());

    Reply
  3. antonrost

    1. Хранится в виде файла: «ЗначениеВФайл(ИмяФайла, ТаблицаИзменений)»

    При этом файлы имеет вид: КаталогБазыLogВидДокументаВнутреннийНомерДокументаНомерИ­зменения.txt

    (Например: D:БазыТоргDemoDBLogПоступлениеТМЦ3470002.TXT)

    2. Изменение порядка строк в данной версии не отслеживается, но очень легко добавить. Достаточно в сравниваемые таблицы (до и после изменений) добавить колонку с номером строки.

    3. Добавление и удаление строк отслеживается. Принцип просмотра изменений ТЧ следующий (он, кстати, продемонстрирован в скриншотах): если есть измененная строка, то в результатах мы увидим ДВЕ СТРОКИ. Одна со знаком «-» (то, что было до изменения), вторая со знаком «+» (то, что стало). Измененные реквизиты выделены цветом. Для удобства сравнения рекомендуется отсортировать таблицу по ключевым реквизитам (например, по номенклатуре) двойным щелчком по наименованию колонки. Соответственно, если количество строк изменилось, то будет ТОЛЬКО строка с минусом (если строку удалили), или ТОЛЬКО строка с плюсам, если строку добавили.

    Reply
  4. antonrost

    При снятии флажка «Только измененные реквизиты», в отчет выведутся ВСЕ реквизиты документа. Измененные также останутся выделенными цветом.

    Reply
  5. antonrost

    Если у кого-то есть необходимость отслеживать изменение порядка строк — говорите. Добавлю через некоторое время.

    Reply
  6. antonrost

    70 человек скачали, никто не оценил. Вывод: кг/ам ???

    Reply
  7. Abadonna

    Совсем недавноя делал подобную штуку. Умудрился запихать весь документ в одну «плоскую» ТЗ из 4 колонок. Т.е. в этой 4-х колоночной ТЗ хранятся разом и общие, и реквизиты шапки, и все строчки документа.

    Если интересно — могу намылить.

    Примечание: а т.к. у нас всё равно SQL стоял, я завел «боковую» базу

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

    Контрагенты! Вот где они, гады, творят, что хотят, а потом отпираются 😉

    Reply
  8. antonrost

    И у меня тоже одна ТЗ. Только колонок пять :).

    Reply
  9. wadus

    Внедрил в свою конфигурацию. Шеф в восторге (неописуемом).

    Вопрос: можно тоже самое, но для справочников?

    Reply
  10. CheBurator

    Изменения пишутся в какой файл? текстовый? xml?

    или как еще…? в принципе, нормально, вопрос с типом файла выясню — может поставлю вместо своей…

    Reply
  11. antonrost

    Применяется метод «ЗначениеВФайл».

    Минус — на больших конфигурациях «жрет» дисковое пространство. Есть идея архивировать каждый документ. Нет времени. 🙂

    Со временем приделаю и справочники.

    Reply
  12. antonrost

    Вернее, на больших базах…

    Reply
  13. Denisыч

    Очень хорошая разработка. Хотелось бы еще изменения справочников увидеть. Когда можете сделать?

    Reply
  14. antonrost

    Банально не хватает времени 🙁

    Reply
  15. lustin

    +1

    Reply
  16. glavbukh

    +1. Присоединяюсь к Denisыч : «Ну когда же…»?

    Reply
  17. antonrost

    Скоро. Для себя сделал — тестирую.

    Reply
  18. gubsky

    ну и что там на счет справочников? как тема движется?

    Reply
  19. antonrost

    Выложил новую версию (документы + справочники). Описание внутри архива. Извиняюсь, если не очень подробное.

    Если что-то неработает — обращайтесь, разберусь.

    Reply
  20. infossa

    (19) обработка интересная и полезная

    (7) также интересует вариант для SQL Server

    если можно , то выложите здесь также свой вариант

    Reply
  21. mdzen

    Интересно. Сравню со своей….

    Reply
  22. mdzen

    В принципе неплохо как идея.

    Только есть небольшое неудобство — доки в среднем 100 — 150 позиций занимают 56-80 кб. , за день лепят до 100 документов — по минимуму за день отожрет 56 — 80Mb если нет изменений, а если хоть по разу поменяют это еще 56-80 Mb , итого — 112 — 160 Мб ( т.е. полтора гига за 10 дней), а если надо логи за год-полтора иметь?

    Для организаций с небольшим документо-потоком решение отличное ( потому +1)

    Reply
  23. Polukuzov

    Я переделал процедуру хранения изменений(изменения по одному документу храняться в виде архива.zip и при надобности распоковывается во временную папку добавляется и снова упаковывается) при этом достигается экономия по месту хранения в 5-6 раз, а это уже что-то. А так вообще вещь нужная правда слегонца громоздкая. Много места занимает хранение в ввиде «ЗначениеВСтрокуВнутр» там куча скобок,кавычек и пробелов, но писать свою процедуру хранения как-то совсем неохота. Автору риспект +1

    Reply
  24. antonrost

    Теперь корректно работает в распределенных базах.

    Reply
  25. Mario Bro

    я не програмист 1С но нам в фирму очень нужна подобная вещь, скачал, дак на работе блин даже ЗИП-аврхиваторов нету блин:(

    Reply
  26. antonrost

    давай адрес — вышлю

    Reply
  27. Mario Bro

    Разархивировал но там как я понял документы уже для внедрения в 1С, надо будет программиста нашего загрузить

    Reply
  28. Mario Bro

    А нет чё нить типа презентации данной функции)))

    Reply
  29. antonrost

    Скриншоты не подходят ?

    Reply
  30. Mario Bro

    antonrost

    В 1С 7.7 есть получается и базовый журнал регистрации? у нас просто есть какой то но он уж очень долгий и там не очень то легко что то увидеть в разрезе таблицы

    Reply
  31. Fedorenko

    Попробовал на документе Реализация в Торговля и Склад 7.7. Обработка «Просмотр изменений в документах и справочниках.ert» пишет ошибку:

    Стр = ЗначениеВСтрокуВнутр(СоздатьОбъект(Шаблон(«[ТекТип].[ТекВид]»)));

    {E:TORGEXTFORMSПРОСМОТР ИЗМЕНЕНИЙ В ДОКУМЕНТАХ И СПРАВОЧНИКАХ.ERT(144)}: Неудачная попытка создания объекта.

    Обработка «ПРОСМОТР ИЗМЕНЕНИЙ.ERT» выдает ошибку: ВидЭлемента = Конт.Вид();

    {E:TORGEXTFORMSПРОСМОТР ИЗМЕНЕНИЙ.ERT(230)}: Значение не представляет агрегатный объект (Вид).

    Reply
  32. antonrost

    (31) Загляни в личные сообщения.

    Reply
  33. antonrost

    Глючила функция «Шаблон». Исправил.

    Reply
  34. GenTay

    Идея очень хорошая, но оценить не могу, т.к. теже ошибки что и у сообщ. № 31

    Reply
  35. GenTay

    И еще при проводке сообщает {D:ПАПКА ОБМЕНАПРОБАEXTFORMSРЕГИСТРАЦИЯ ИЗМЕНЕНИЙ.ERT(36)}: Функция не обнаружена (глРазложить)

    Reply
  36. antonrost

    Последнюю ошибку исправил, обновил. Предыдущие тоже вроде исправлял. Если не получится — пишите, разберемся.

    Reply
  37. GenTay

    Осталось

    Конт = Форма.Параметр;

    ВидЭлемента = Конт.Вид();

    {Обработка.РегистрацияИзменений.Форма.Модуль(230)}: Значение не представляет агрегатный объект (Вид)

    Reply
  38. GenTay

    Пардон, плз. Это у меня глюки. Все заработало, но когда прошу показать изменения, выдает что-то про точку актуальности, но 1с бух нет оперативных итогов!

    Reply
  39. antonrost

    Сейчас исправлю.

    Reply
  40. antonrost

    Исправлено.

    Reply
  41. GenTay

    Просто супер!!!!!

    Reply
  42. GenTay

    Привет! Не хочу надоедать, но какой-то конфуз у меня. Вчера все поставил, все работало. А сегодня не работает, причем в папке «log» создает ссылки, в отчете «просмотр изм в доках и спр» выдает в вверху,ну к примеру, «прих.накл». Но перечень изменений зась. Пишет «0 строк». Изменения были.Вчерашние изменения пожалуйста, сегодняшие ни как. Я глянул код, китайская грамота на русском языке, учебник квантовой физики. Что бы это значило?

    Reply
  43. antonrost

    Напиши на мыло a.yuhlin@empils.ru

    Reply
  44. korpas

    Обновил файлы на новую версию. При попытке посмотреть изменения вылетают следующие ошибки:

    КодВида = СЗ.ПолучитьЗначение(2);

    {\…EXTFORMSПРОСМОТР ИЗМЕНЕНИЙ В ДОКУМЕНТАХ И СПРАВОЧНИКАХ.ERT(119)}: Индекс не входит в границы списка значений.

    КодЭл = СЗ.ПолучитьЗначение(3);

    {\…EXTFORMSПРОСМОТР ИЗМЕНЕНИЙ В ДОКУМЕНТАХ И СПРАВОЧНИКАХ.ERT(120)}: Индекс не входит в границы списка значений.

    КодБазы = СЗ.ПолучитьЗначение(4);

    {\…EXTFORMSПРОСМОТР ИЗМЕНЕНИЙ В ДОКУМЕНТАХ И СПРАВОЧНИКАХ.ERT(121)}: Индекс не входит в границы списка значений.

    Таблица документов не заполняется. В старой версии все работает.

    Reply
  45. antonrost

    (45) Боюсь, что совместимость не предусмотрена 🙁 , т.е. новый просмотрщик показывает только новые изменения.

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

    Reply
  46. korpas

    (46)

    1) Сильно изменился формат хранения? Заметил пару новых функций, в остальное не внедрялся…

    2) У меня был случай, что обработка показывала изменения человеком, который их в это время не делал, а делал другой человек. Я думал, что это связано с открытием одного документа двумя пользователями: одним на редактирование, вторым на просмотр, но воспроизвести такую ситуацию не смог. Возможны ли вообще случаи, что обработка покажет другого пользователя, не делавшего изменения?

    3) Как можно правильно перейти на новую версию обработки? Удалить Папку Log? Тогда в нее будут записываться изменения уже новой обработки?

    Reply
  47. antonrost

    (47)

    1. Изменился только формат имени файла.

    2. Если документ изменен программно, то в LOG изменения будут добавлены при первом открытии документа и припишутся тому, кто его открыл. Чтобы такого не происходило, надо после Док.Записать() вызывать глРегистрацияИзменений().

    3. Если есть возможность очистить log, проще всего так и сделать.

    Reply
  48. Ekstrem13

    Почему нет периода дат. Мне например нужно видеть изменения за конкретный квартал а не все

    Reply
  49. rosalin

    Антон,

    Приветствую, скачал вашу обработочку отличная вещь внес изменения

    в ГМ

    но не могу сделать что бы работала кнопка

    по обработке «Просмотр изменений в документах и справочниках», все

    показывает

    а вот кнопка с формулой

    ОткрытьФорму(«Отчет#», ТекЭлемент, КаталогИБ()+»ExtFormsПросмотр изменений.ert»);

    ругаеться типа

    ОткрытьФорму(«Отчет<<?>>

    Пропущен символ ‘»‘ (двойная кавычка)

    ОткрытьФорму(«Отчет<<?>>

    Ожидается символ ‘)’

    Помогите плиз

    Reply
  50. rosalin

    еще ругаеться

    ВидЭлемента = Конт.Вид();

    {W:ARCHIVE1903EXTFORMSПРОСМОТР ИЗМЕНЕНИЙ.ERT(195)}: Значение не представляет агрегатный объект (Вид)

    Reply
  51. tanekQ

    Интересная вещица! А главное столько лет поддерживается и, соответственно, совершенствуется! Автору БОЛЬШОЙ плюс!

    Reply
  52. grayglobus

    Вещь интересная и нужная, опробую на постоянном клиенте, бо про некоторые реквизиты сам писал

    Reply
  53. lees

    Для моей самописной небольшой базы объемом 1,5 ГБ хорошее решение задачи поиска виновных, спасибо большое

    Reply
  54. merlin1975

    Здравия!

    Посмотрел Вашу обработку. Интересно. Начал пробовать. Внес изменения в глобальный модуль, встроил отчеты ПросмотрИзменений и РегистрацияИзменений. Немного из-за этого подправил код (на открытие встроенных отчетов).

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

    И, при выборе на главной форме «Справочник» (я менял только один документ) — обработка впадает в ступор. Видимо ищет того, чего нет… Это у меня что-то плохо отрабатывает или сама обработка?

    Благодарю.

    Reply
  55. merlin1975

    (7)Можно получить Ваш вариант обработки?

    Reply
  56. merlin1975

    (23)Можно Вашу версию «пощупать»?

    Reply
  57. antonrost

    (55)

    Писал эту обработку 13 лет назад, вообще не помню как там что работает )))

    1. Если в ТЧ показывать только измененные колонки, то может быть не видно ключевых, необходимых для понимания к чему относится данная строка. Например — не будет видно Номенклатуры, неудобно разбираться. Но при желании можно и скрыть их — кто мешает?

    2. Не понял сути вопроса.

    Reply

Leave a Comment

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