"Чистка" базы БП после удаления организации(ий)




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

27 Comments

  1. Alav

    А без ошибок нельзя выложить?

    //почистим настройки пользователей
    Набор = РегистрыСведений.НастройкиПользователей.СоздатьНаборЗаписей();
    Для каждого УдаляемаяОрг Из масОрг Цикл
    Набор.Отбор.Настройка.Установить(ПланыВидовХарактеристик.НастройкиПользователей.ОсновнаяОрганизация);
    Набор.Прочитать();
    Для каждого СтрокаНабора Из Набор Цикл
    СтрокаНабора.Значение = Справочники.Организации.ПустаяСсылка();
    КонецЦикла;
    Набор.Записать(Истина);
    КонецЦикла;
    

    Показать

    И где здесь условие на удаляемые организации?

    Reply
  2. Sharloc

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

    Reply
  3. almas

    Спасиб. Маненько не доработана. Так например не очистит регистры с сложным Типом измерения . И ПодразделенияОрганизаций Не зачистит. в Понедельник свою версию выложу. Физлиц не по торкает. А так ОК. Я на ЗиУП работаю, потому столько внимания нюансам.

    Reply
  4. joghurt

    Извините за тупость.

    А как этой прогрой пользоваться?

    Reply
  5. NataliH

    Спасибо.получилось не всё, может я чего накосячила.

    Reply
  6. drfox

    Добрый день, а заодно с сотрудниками она физ.лиц не поудаляет?

    Reply
  7. drfox

    {Справочник.ВнешниеОбработки.Форма.ФормаЭлемента(189)}: Ошибка при вызове метода контекста (Создать): Ошибка при выполнении файловой операции ‘F:!SHARE!Обработки8BONUS_OrgMetla.epf’

    чего не так то? 1с 8.1 БП 2.0? хелп… срочно нужно базы разделить…

    Reply
  8. habum

    Добрый день! Использовал при разделении баз, все получилось. Спасибо.

    Reply
  9. Old Daemon

    Интересно, отработает ли отконверченная в 8.2 ? Попробую, отпишусь.

    Reply
  10. Old Daemon

    Чота нифига, написало {Форма.Форма.Форма(238)}: Поле объекта не обнаружено (УдалитьПраваДоступаПользователей)

    Набор = РегистрыСведений.УдалитьПраваДоступаПользователей.СоздатьНаборЗаписей();

    Reply
  11. svetic

    Использую при разделении баз, все получается отлично. Спасибо.

    Reply
  12. aysh

    Спасибо, обработка пригодилась!

    Reply
  13. Sharloc

    (10) Old Daemon,

    Проверьте на версии 1.10, там эта ошибка была исправлена.

    Reply
  14. Ariko-sv

    (4) joghurt, На удаление организацию пометьте и запустите обпаботку

    Reply
  15. Ariko-sv

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

    Reply
  16. Diversus

    (0) Обработку не смотрел т.к. сейчас не нужно, но когда то делал, что то подобное.

    Я использовал следующую схему в своей обработке:

    — Помечал на удаление организацию, все документы которой необходимо удалить

    — Искал по ссылкам все, на что ссылается эта организация (благо есть функция НайтиПоСсылкам) и помечал на удаление

    — Помечал на удаление все элементы справочников, которые могут принадлежать этой организации (зачем, станет понятно дальше) (Номенклатура, Места хранения, Статьи затрат, Номенклатурные группы, Пользователи и т.д.)

    — Потом с контролем ссылочной целостности программно удалял все, что помечено на удаление

    — Те элементы справочников, которые остались после удаления, снимаем после всего с них, пометку на удаление.

    — Готово

    Эта схема позволяет удалить не только организацию, но и почистить справочники и удалить из них элементы, которые использовались только в конкретной организации, например: в базе БП в которой 5 организаций, только удаляемая организация торговала продукцией «А», логично чтобы после очистки и удаления организации, продукция «А» тоже удалилась, т.к. она больше нигде не использовалась. Поэтому использовал подобные механизм.

    Reply
  17. Deniz200

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

    Reply
  18. Ariko-sv

    Интересно, а будет работать в ЗУПе? Надо попробовать.

    Reply
  19. Ariko-sv

    Нет не работает, кнопка»Очистить» не активна. А хотелось бы чтоб и там работала, это возможно?

    Reply
  20. esoldatov

    Отличная разработка, почему 1с-ки сами не внедрили подобный алгоритм изначально непонятно…

    Reply
  21. StalkerAkella

    спасибо, выручила Ваша обработочка

    Reply
  22. ewqewqewq

    спасибо, выручила Ваша обработочка )))

    Reply
  23. solven

    Версия 1.03 для 8.1 работает с редакцией 1.6 «Версия 1.6.8»?

    Запускаю, появляется ошибка:

    {Форма.Форма(146)}: Ошибка при вызове метода контекста (Выполнить): {(4, 2)}: Таблица не найдена «Справочник.СпособыОтраженияРасходовПоАмортизации»

    <<?>>Справочник.СпособыОтраженияРасходовПоАмортизации КАК СправочникСОрганизацией

    ВыборкаСпр = ЗапросСпр.Выполнить().Выбрать();

    по причине:

    {(4, 2)}: Таблица не найдена «Справочник.СпособыОтраженияРасходовПоАмортизации»

    <<?>>Справочник.СпособыОтраженияРасходовПоАмортизации КАК СправочникСОрганизацией

    Reply
  24. Sharloc

    Версия 1.03 для 8.1 работает с БП не ниже 1.6.25. Добавил уточнение в описание.

    Reply
  25. AzagTot

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

    Рекомендую блок очистки регистров сведений в части, касающейся ресурсов, переделать таким образом:

    //почистим все регистры сведений где есть организация
    ЗаписиКУдалению = Новый Массив;
    Для каждого РегСвМетаданные из Метаданные.РегистрыСведений Цикл
    …
    ЕстьОрганизация = (РегСвМетаданные.Ресурсы.Найти(«Организация») <> Неопределено);
    Если ЕстьОрганизация Тогда
    Состояние(«Очистка регистра сведений: » + РегСвМетаданные.Имя);
    Набор = РегистрыСведений[РегСвМетаданные.Имя].СоздатьНаборЗаписей();
    Набор.Прочитать();
    ЗаписиКУдалению.Очистить();
    Для каждого ЗаписьНабора Из Набор Цикл
    Для каждого УдаляемаяОрг Из масОрг Цикл
    Если ЗаписьНабора.Организация = УдаляемаяОрг Тогда
    ЗаписиКУдалению.Добавить(ЗаписьНабора);
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
    Для каждого ЗаписьНабора Из ЗаписиКУдалению Цикл
    Набор.Удалить(ЗаписьНабора);
    КонецЦикла;
    Набор.Записать(Истина);
    КонецЕсли;
    …

    Показать

    И еще я добавил во всех помечаемых на удаление объектах ОбменДанными.Загрузка = ИСТИНА, т.к. некоторые не записывались (например в договорах 1С-ка ругалась на незаполненные подразделения).

    Reply
  26. yandukov

    для 3.0 есть такая обработка?

    Reply
  27. Sharloc

Leave a Comment

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