Свёртка базы




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

36 Comments

  1. ardn

    Сорри, как убрать минус?

    Reply
  2. indigo_

    (1) Нажмите на красную звездочку внизу публикации

    Reply
  3. frlancer

    Интересная идея. в шапке статьи заявлено что для платформы 1с 8.2. Для 7.7 такой подход не подойдет?

    И второй вопрос, этот метод уже использовался на практике? Можете расписать преимущества перед обычной сверткой?

    Немного не ясно, что дает подмена регистратора? Потом удаляются документы которые делали движения, а «новый документ регистратор» остается? Как тогда будут работать алгоритмы завязанные на регистраторе?

    Reply
  4. insurgut

    Объем данных уменьшится только на количество документов, в регистрах как все было, так и останется (а зачем нам старые обороты, когда важны только итоги на дату свертки?). Половинная свертка получается.

    Reply
  5. Азбука Морзе

    (3) day_light,

    Интересная идея. в шапке статьи заявлено что для платформы 1с 8.2. Для 7.7 такой подход не подойдет?

    Формы обработки и документа управляемая, поэтому только для 8.2(8.3) Для 7.7 есть свои свертки, например http://infostart.ru/public/65228/

    И второй вопрос, этот метод уже использовался на практике? Можете расписать преимущества перед обычной сверткой?

    Эту свертку тестировал на реальной бухгалтерии 2.0 и демо 3.0, ЗУП 2.5. Использую для многократно пиленой УТ 10.2 с кучей доморощенных регистров и документов. Преимущество перед обычной сверткой в случае с УТ 10.2 в том что она работает. Кроме того не нужен монопольный запуск, для каждого вида документа можно установить свой период свертки. Одни документы оставляются за последний год, другие за два, третьи вообще не удаляются.

    Как тогда будут работать алгоритмы завязанные на регистраторе?

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

    (3) insurgut,

    Объем данных уменьшится только на количество документов, в регистрах как все было, так и останется (а зачем нам старые обороты, когда важны только итоги на дату свертки?). Половинная свертка получается.

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

    Reply
  6. iov

    Делал немного иначе

    свертка итогов — ввод начальных остатков. (это монопольно)

    корректировкой записей вводил противоположные записи в нужных регистрах. получалась пара записей с разным значением. в сумме дает 0. (и это монопольно)

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

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

    остальные документы не имеющие записи по регистрам — удалял через стандартную пометку и удаление.

    процедуры не влияют на работу пользователей кроме замедления на больших объемах. Но задержка по времени вам в помощь.

    Если красяво оформить прогресс бары то на недельку (при реально больших объемах) у вас будет что показать руководству и коллегам.

    Не забываем делать бекапы.

    Reply
  7. PYCTAM

    БП 2.0

    Объединяться захотела только под платформой 8.3.

    Думает ооочень долго причем использует только 1 процессор из 8 причем по началу обрабатывает документы быстро а потом по 1 за 2-4 секунды.

    Reply
  8. Азбука Морзе

    (7) PYCTAM, Разве можно ожидать, чтобы скромная обработка управляла загрузкой процессоров. Воспользуйтесь советом Билла Гейтса и обратитесь к системному администратору:)

    Что касается скорости, то да, действительно, поначалу пока набор записей регистратора невелик, работает намного шустрее. Так ведь и алгоритм такой — читается набор записей подчиненный регистратору, добавляются новые записи от очередного документа, по мере возможности свертываются и записываются в базу. Соответственно чем больше становится набор, тем дольше он читается и записывается. Для того чтобы, ограничить его размер воспользуйтесь соответствующей опцией:

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

    Reply
  9. PYCTAM

    (9) Да извиняюсь по поводу процессора это не в тему. А так база свернулась на ура. Спасибо за труды!

    Reply
  10. vsmirnov6

    Идея интересная, хотел протестить, но объеденяется только под 1С 8.3, А есть на 8.2??? Если нет, то измените заголовок!!!

    Reply
  11. Азбука Морзе

    (11) vsmirnov6, одно из свойств конфигурации называется режим совместимости. Чтобы cf-ник для 8.3 превратить в cf-ник для 8.1/8.2 следует изменить режим совместимости (Конфигурация-Свойства-РежимСовместимости-Версия 8.1 или Версия 8.2.13 или …) После этого сохранить конфигурацию в файле _Свертка_82.cf.

    Reply
  12. vsmirnov6

    (12) Спасибо!

    Reply
  13. Twirus

    Отличная обработка. Автору большущее спасибо

    Reply
  14. sergbsv

    Требует 8.3 а заявленна как для 8.2 ;((

    Reply
  15. Азбука Морзе

    (15) sergbsv, прочтите сообщение под номером 12 и ваши слёзы высохнут:)

    Reply
  16. ivanov.dn

    (12) прочитал сообщение под номером 12.Можно подробнее для чайников…Хочу свернуть базу 8.2.18.109.

    Reply
  17. Азбука Морзе

    (17) ivanov.dn, Пожалуйста.

    1.Скачиваем с сайта 1с платформу 8.3 и устанавливаем на свой компьютер.

    2.Создаем пустую базу, в стартере которой указываем: Версия 1С:Предприятия 8.3

    3.В эту базу грузим конфигурацию из файла _Свертка_.cf

    4.Меняем режим совместимости: выделяем наименование конфигурации (например: БухгалтерияПредприятия…) — правая кнопка мыши -Свойства (в самом низу, открывшегося окна) — Режим совместимости — Версия 8.2.16

    5.Сохраняем конфигурацию в файле _Свертка_8216.cf, который можно затем использовать для интеграции с вашей базой на платформе 8.2.18

    Reply
  18. ivanov.dn

    (18) БОЛЬШОЕ спасибо.Буду пробовать!

    Reply
  19. beckss

    Пробовал на ут 10.3.27.2, ошибка при выполнение

    {Обработка._СверткаБазыДанных_.Форма.ФормаУправляемая.Форма(177)}: Ошибка при вызове метода контекста (ПолучитьОбъект)
    МетаданныеДвижения = Обработка.КорректировкаЗаписейСсылка.ПолучитьОбъект().Метаданные().Движения;
    по причине:
    Элемент не выбран!
    
    Reply
  20. Азбука Морзе

    Проверьте заполнен ли у вас реквизит формы «Документ-регистратор». Если заполнен, тогда поможет очистка кэша.

    Reply
  21. KliMich

    Спасибо! Неплохой ликбез по свертке…

    Reply
  22. ilya.n

    Добрый день! У нас база УТ 10.3 на sql, объем около 10 Гб. В базе незначительные доработки.

    Хотим провести свертку базы, типовая с итс «висит» сутки и результатов нет.

    Подойдет ли нам Ваша обработка ?

    Reply
  23. Азбука Морзе

    (23) ilya.n, Подходит для любой конфигурации. Действуйте согласно инструкции и все получится. Свертку можно осуществлять не останавливая работы пользователей, можно свернуть какие-то определенные типы документов, разные периоды для разных документов. Рекомендую на тестовой базе свернуть за 2-3 месяца в режиме «Отладка», чтобы убедится, что в правильности работы.

    Reply
  24. KliMich

    Спасибо!

    Хочу попробовать свернуть БГУ 2.0

    Отнозначно плюс!

    Reply
  25. stas1kbob

    вы сворачиваете 10.2 ут на какой платформе?

    Reply
  26. Азбука Морзе

    (26) stas1kbob, 8.2

    Reply
  27. BigRig

    Добрый день!

    На платформе 8.1.15.14 не получается это выполнить. Пишет «структура конфигурации несовместима с текущей версией платформы». Делал всё по подробной инструкции в 18 сообщении.

    Reply
  28. Гость

    Азбука Морзе, скажите пож-та, у меня есть конфигурация «Зарплата и Управление Персоналом для Казахстана, редакция 2.0, «, сама конфигурация в 8.1, но оболочка в 8.2 подойдет ли ваша обработка?

    Reply
  29. Arbitrium

    Выдает ошибку

    {Обработка._СверткаБазыДанных_.Форма.ФормаУправляемая.Форма(196)}: Ошибка при вызове метода контекста (УстановитьПометкуУдаления)

    ДокументОбъект.УстановитьПометкуУдаления(Истина);

    по причине:

    Ошибка при выполнении обработчика — ‘ПередЗаписью’

    по причине:

    {ОбщийМодуль.НастройкаПравДоступа.Модуль(138)}: Ошибка при получении значения атрибута контекста (ГраницыЗапретаИзмененияДанных)

    СоответствиеГраницЗапрета = ПараметрыСеанса.ГраницыЗапретаИзмененияДанных.Получить();

    по причине:

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

    Reply
  30. tvg258

    Здравствуйте! Интересует применение обработки для ЗУП 8.2. Для каких целей использовалась свертка? Для переноса базы на определенную дату или очистки от «мусора»? Какие были проблемы? Прошу поделиться тех, кто сворачивал на дату.

    Reply
  31. tvg258

    (30)Здравствуйте Виктория! Вы решили проблему с сообщением? У меня таже проблема

    Reply
  32. tvg258

    Здравствуйте! Подскажите пожалуйста по ошибке неинициализированного доступа — у вас такое не встречалось?

    Reply
  33. Arbitrium

    Здравствуйте Татьяна. Проблему решила, но, если честно, уже не помню как именно. Единственное, могу сказать, если это поможет, что ларчик просто открывался и решение было на поверхности. Проблем в процессе свертки возникало много. Поэтому, если есть такая возможность, рекомендую убедить клиентов перейти на 3. И от мусора избавитесь и на нужную дату перенесете.Там все получается красиво и значительно проще.

    Reply
  34. DrBlack

    Переписал две процедуры, дело пошло веселее:

    &НаКлиенте
    Функция ОбработатьДокумент(Документ)
    
    ПолучитьДвиженияПоДокументу(Документ.Значение);
    МаксКолВо = ТаблицаДвижениий.Количество();
    Элементы.Индикатор.МаксимальноеЗначение = МаксКолВо;
    Инд = 0;
    
    МассивСсылок = Новый Массив;
    
    Для Каждого Выборка Из ТаблицаДвижениий Цикл
    
    Инд = Инд + 1;
    МассивСсылок.Добавить(Выборка.Ссылка);
    
    Если МассивСсылок.Количество() < 50 И НЕ Инд = МаксКолВо Тогда
    Продолжить;
    КонецЕсли;
    
    Индикатор = Инд;
    СтрИндиктор = Формат(Инд, «ЧГ=0″) + » / » + Формат(МаксКолВо, «ЧГ=0»);
    СтрокаСсылка = Строка(Выборка.Ссылка);
    Состояние(СтрокаСсылка);
    ПротоколСвёртки.Добавить(СтрокаСсылка);
    
    ДвиженияСохранены = СохранитьДвиженияПоДокументу_Новый(Документ.Значение, МассивСсылок);
    Если НЕ ДвиженияСохранены Тогда
    Возврат Ложь;
    КонецЕсли;
    
    МассивСсылок.Очистить();
    
    ОбработкаПрерыванияПользователя();
    
    КонецЦикла;
    
    Возврат Истина;
    
    КонецФункции

    Показать

    и эту:

    &НаСервере
    Функция СохранитьДвиженияПоДокументу_Новый(ДокументИмя, МассивСсылок)
    
    Обработка = РеквизитФормыВЗначение(«Объект»);
    Документ = Метаданные.Документы.Найти(ДокументИмя);
    
    ДвиженияСохранены = Истина;
    
    Для Каждого Ссылка Из МассивСсылок Цикл
    
    НачатьТранзакцию();
    
    Если Ссылка.Проведен ИЛИ Документ.Проведение = Метаданные.СвойстваОбъектов.Проведение.Запретить Тогда
    ДвиженияСохранены = Обработка.СохранитьДвиженияПоДокументу(Документ, Ссылка);
    КонецЕсли;
    Если ДвиженияСохранены Тогда
    ДокументОбъект = Ссылка.ПолучитьОбъект();
    Если УдалятьДокументы Тогда
    ДокументОбъект.Удалить();
    Иначе
    ДокументОбъект.УстановитьПометкуУдаления(Истина);
    КонецЕсли;
    ЗафиксироватьТранзакцию();
    ИначеЕсли ТранзакцияАктивна() Тогда
    ОтменитьТранзакцию();
    Прервать;
    КонецЕсли;
    
    КонецЦикла;
    
    ЗначениеВРеквизитФормы(Обработка, «Объект»);
    Возврат ДвиженияСохранены;
    
    КонецФункции

    Показать

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

    Reply
  35. Азбука Морзе

    Еще лучше порцию указать в виде параметра на форме. Если 0 — то без индикации и возврата на клиент.

    Reply
  36. DrBlack

    Я надеюсь вы так и сделаете в своей новой версии, т.к. для очень больших баз это критично, а самостоятельно не каждый сможет оптимизировать, а выкладывать свою версию (вашу, но немного мной поправленную) я не имею права. И спасибо за этот инструмент! Отпишусь о результатах «пухлости» до и после )))

    Reply

Leave a Comment

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