Выгрузка в Excel больших отчетов




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

37 Comments

  1. antonrost

    Что-то не скачивается. 🙁

    Хотел сравнить со своим: http://infostart.ru/projects/download.php?id=259&file=270&ref=825

    Reply
  2. vasilykushnir

    А все-таки зыркни на http://infostart.ru/projects/download.php?id=259&file=270&ref=440 — там тоже не хилая скорость и без изворотов с маленькими файлами.

    Reply
  3. CheBurator

    Выкиньте эту бяку и пользуйте нормальный продукт, который позволяет делать тоже самое не заморачиваясь: всего 5 строк кода и все работает как надо и не надо ни о чем беспокоиться, для тех, кто не имеет возможности программировать здесь лежит готовое решение (в нем же даны ссылки на человека, сделавшего возможным такую чудную вещь:

    http://www.infostart.ru/projects/index.php?id=323&ref=174

    И, чтоб не быть голословным: отзыв юзера:

    «Прикраснейшая програ! Прайс который сам создавался 7 минут на 20280 строк выгрузился за 12,7 секунды!!!!! Обалдеть!!! Стандартным способом Сохранить как.. на это уходило часов 10-11!!! Класс! Тест проходил на машине — 2 x Intel Xeon 3,2 Ггц DDR2 4 Гига….

    Разработку victuan имеет смысл юзать там, где политикой запрещено использование ВК.

    Reply
  4. victuan

    Ну что ж. Приятно что есть реакция на мои обработки. Эта обработку я перекинул с 1c.proclub.ru. Сделал я еще до того как была написана упомянутая Che Burashka ВК. В принципе, видимо, моя обработка отыграла уже свою роль, и, если не будет возражений, я ее уберу.

    Reply
  5. CheBurator

    Не надо! Если работает как надо — пусть будет, кому-то подойдет именно эта.

    Reply
  6. victuan

    Не буду!

    Reply
  7. просто все клас. все нормально работает….

    Reply
  8. Господа комментирующие! Просьба «плюсовать» рейтинг! Для меня это будет бОльшая благодарность, чем высказываение типа «просто класс!»

    Reply
  9. JannyFan31

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

    Reply
  10. Gavrish

    А может кто решал похожие задачи:

    — сохранения из 1С в excel в одной ячейке более 256 символов (символы теряются пр сохранении, хотя в самом excel такого ограничения нет), разбивать текст на части не решает вопрос

    — не сохраняется вертикальный текст, хотя в обеих программах возможность вывода такого текста есть.

    Спасибо за информацию

    Reply
  11. Ужас бухгалтера

    (10) Я решал. Здесь: http://yoksel.net.ru/HomePage

    В частности, по 256 символов на ячейку и вертикальный текст здесь: http://yoksel.net.ru/ProblemyStandartnogoMxl2Xls

    Reply
  12. victuan

    Вот хорошее решение описанной задачи без использования ВК: http://1c.proclub.ru/modules/mydownloads/personal.php?cid=5&lid=2188

    Reply
  13. Ужас бухгалтера

    (12) Без ВК, зато с использованием Excel по OLE-automation. И за что боролись?

    Reply
  14. Abadonna

    (13) Целиком и полностью поддерживаю. Чтобы я на терминальный сервер пустил MS Office — да ни в жизнь ;)))

    Reply
  15. Sevko

    У меня куча отчетов со строками под 50 — 60 тыс. Естественно записать все это в Excel — один гемморой (лично я это через 8-ку делаю, благо стоит вместе с 7-кой). Попробовал воспользоваться данной разработкой и сразу же столкнулся с глюком. Отчет в 65000 строк , 14 колонок. Сравнил одну из колонок с оригиналом и выявил 20 различий, в различных строках:

    Получилось Надо

    272630697. 131540.75

    272630697. 131540.75

    272796979. 214681.75

    272682809. 157596.75

    273193696.00 603585.00

    272682776. 157580.25

    272956554.00 326794.50

    272675768. 154076.25

    272748970. 190677.25

    272809415. 220899.75

    13157.24 1315725.00

    13157.24 1315725.00

    273447810.00 1175050.00

    31737.28 3173730.00

    31737.28 3173730.00

    14674.84 1467485.00

    2735151.41 1444375.00

    14674.84 1467485.00

    273340841.00 897875.00

    273723054.00 2454900.00

    Reply
  16. victuan

    1С не всегда правильно сохраняет данные в Эксель.

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

    Также попробуй воспользоваться альтернативными обработками:

    http://infostart.ru/projects/323/

    http://yoksel.net.ru/HomePage

    А вообще, насколько быстро сохраняет твои отчеты моя разработка? Мне просто интересно.

    Reply
  17. Sevko

    После исправлений http://yoksel.net.ru/Hotfixes все нормализовалось.

    Таблицу в 65500 строк и 14 столбцов сохраняет за 32 сек.

    Жаль что нет возможности сохранять более 65536 строк (ограничение Excel) — можно было бы разбивать, скажем, на отдельные листы.

    Reply
  18. Abadonna

    >перенести можно в любой момент и все.

    При одном мААААААААААленьком условии — на компе должен Excel стоять

    Reply
  19. Sevko

    Предлагаю немного дописать код обработки Быстрое сохранение mxl в xls.ert.

    В результате мы получаем название файла из названия отчета. В 99% случаев — срабатывает. Помоему удобно.

    Если ВсеНормально = 1 Тогда

    Сервис = СоздатьОбъект («Сервис»);

    Если Сервис.АктивныйКонтекст (гТаблица) = 0 Тогда

    Сообщить («Нет активного табличного документа»);

    ВсеНормально = 0;

    Иначе

    Если ТипЗначенияСтр (гТаблица) <> «Таблица» Тогда

    Сообщить («Нет активного табличного документа»);

    ВсеНормально = 0;

    Иначе

    //>>> мои строки

    Для НомСтроки=1 По 7 Цикл

    НомКолонки = 1;

    Если ПустаяСтрока(гТаблица.Область(НомСтроки,НомКолонки).Текст)=1 Тогда

    НомКолонки = 2;

    КонецЕсли;

    РазмерШрифта = гТаблица.Область(НомСтроки,НомКолонки).РазмерШрифта();

    Если РазмерШрифта>9 Тогда

    ВыбИмяФайла = ФС.ТекКаталог()+»»+СокрЛП(гТаблица.Область(НомСтроки,НомКолонки).Текст)+».xls»;

    Прервать;

    КонецЕсли;

    КонецЦикла;

    //<<< мои строки

    КонецЕсли;

    КонецЕсли;

    КонецЕсли;

    Reply
  20. victuan

    (19) Моя обработка не должна использовать никаких ВК!

    Reply
  21. PeRom

    17), 18),19),20) Если всё вместе собрать, то получается лучше всего не использовать ничего, кроме чистого 1с — тогда нужно сохранять в виде текста с разделителями……

    Reply
  22. victuan

    (21) Это все дело вкуса. Я не имею ничего против ВК. Просто раз я начал позиционировать свою обработку как «без ВК», то должен быть последовательным.

    Reply
  23. profik777

    после установки этой обработки возникли некоторые проблемы: Если в ячейке более 255 символов — он обрезает ее значение до 255.

    Как можно исправить???

    Reply
  24. victuan

    (23) Обработка тут не причем. Это ограничение, заложенное в платформе.

    Reply
  25. serguson

    Спасибо за обработку !

    Была задачка — выгружать в Excel отчеты размером более 600 000 строк (КУДИР для предпринимателя). После небольшой доработки первоисточника (не более 5 строк) —

    — нам теперь никакие отчеты НЕ СТРАШНЫ !!!

    Reply
  26. assa

    Спасибо.

    Reply
  27. LanaSN

    Спасибо, очень пригодилась обработка, справочник материалов огромный, смотреть по счетам трудно на экране, выгрузить не могли в ексель, теперь все хорошо!

    Reply
  28. serezhka87

    Огромное спасибо автору. Есть один отчёт по задолжности по кварплате идёт на 20 тыщ строк, раньше сохраняли только в ХТМЛ, а теперь как люди может и в Экселе сохранять. =)

    Reply
  29. admitcom

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

    Reply
  30. redeye911

    Спасибо — очень помогло разобраться с механизмом выгрузки.

    Reply
  31. Ice-Stas

    Спасибо

    Reply
  32. Ice-Stas

    Предлагаю немного дописать код обработки Быстрое сохранение mxl в xls.ert.

    В результате мы получаем название файла из названия отчета. В 99% случаев — срабатывает. Помоему удобно.

    Если ВсеНормально = 1 Тогда

    Сервис = СоздатьОбъект («Сервис»);

    Если Сервис.АктивныйКонтекст (гТаблица) = 0 Тогда

    Сообщить («Нет активного табличного документа»);

    ВсеНормально = 0;

    Иначе

    Если ТипЗначенияСтр (гТаблица) <> «Таблица» Тогда

    Сообщить («Нет активного табличного документа»);

    ВсеНормально = 0;

    Иначе

    //>>> мои строки

    Для НомСтроки=1 По 7 Цикл

    НомКолонки = 1;

    Если ПустаяСтрока(гТаблица.Область(НомСтроки,НомКолонки).Текст)=1 Тогда

    НомКолонки = 2;

    КонецЕсли;

    РазмерШрифта = гТаблица.Область(НомСтроки,НомКолонки).РазмерШрифта();

    Если РазмерШрифта>9 Тогда

    ВыбИмяФайла = ФС.ТекКаталог()+»»+СокрЛП(гТаблица.Область(НомСтроки,НомКолонки).Текст)+».xls»;

    Прервать;

    КонецЕсли;

    КонецЦикла;

    //<<< мои строки

    КонецЕсли;

    КонецЕсли;

    КонецЕсли;

    Здорово

    Reply
  33. victuan

    (32)Что за объект Сервис?

    Он нарушает мой девиз: «НЕ использует никаких внешних компонент!!!»?

    Reply
  34. lexa_12184

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

    Reply
  35. Tommy1987

    Да, очень удобно при больших объемах данных. При выгрузках в excel теперь только этот вариант использую.

    Reply
  36. suvorovalena

    А почему просто не сохранить в mxl-формате, а потом пересохранить в xls? в mxl 1c сохраняет мгновенно…

    Reply
  37. victuan

    (37)Пересохранение большого файла mxl в xls происходит долго.

    Reply

Leave a Comment

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