Сохранить табличный документ по умолчанию в Excel




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

29 Comments

  1. Pari

    Есть штатный метод таблиц Записать(<ИмяФайла>,<ТипФайла>). Возможно есть причины, по которым в данном конкретном случае штатный метод хуже (или вообще не работает), а FormEx соответственно лучше. Но тогда хотелось бы увидеть пояснения на этот счет в описании.

    Reply
  2. CheBurator

    (1) штатный метод Записать() жестоко тупит на больших таблицах — причины этого известны и описаны. Решений всяких море, например, практически аналогичное сабжевому, но с исправлением диких тормозов при сохранении: http://www.infostart.ru/public/14186/

    .

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

    Reply
  3. dagroma

    Задачи оптимизировать сохранение не было. Просто пользователю хотелось меньше нажимать кнопки мыши.

    (1)Я не знаю как можно обратиться к уже открытой таблице штатными методами, поэтому использовал FormEx.

    (2)А Йоксель я гляну.

    Reply
  4. Altair777

    (0) Может, в «Статьи» было бы лучше? Раз обработки все равно нет… 🙂

    Reply
  5. CheBurator

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

    (3) без формекса — только переделкой конфигурации и то без гарантий… 😉

    Reply
  6. Altair777

    (0) Что-то у меня не получается.

    Эта строка просто прелетает как фанерка 🙂

    Если ФС.ВыбратьФайл(1, ИмяФайла, ИмяКаталога, «Сохранить как», «Таблицы Excel (*.xls)|*.xls») = 1 Тогда

    Из отладчика:

    ИмяФайла = «ПЕЧАТЬ: Расходная накладная *»

    ИмяКаталога =

    Reply
  7. Altair777

    Автор, перед строкой из (6) добавьте на всякий случай: 😉

    ИмяФайла=СтрЗаменить(ИмяФайла,» *»,»»);

    ИмяФайла=СтрЗаменить(ИмяФайла,»:»,»-«);

    Reply
  8. Altair777

    +(7)

    А еще лучше так….

    Если Прав(ИмяФайла,2)=» *» Тогда

    ИмяФайла=Лев(ИмяФайла,СтрДлина(ИмяФайла)-2);

    КонецЕсли;

    ИмяФайла=СтрЗаменить(ИмяФайла,»:»,»-«);

    Reply
  9. dagroma

    (7)(8) Изначально у меня было

    ИмяФайла = СокрЛП(СтрЗаменить(ИмяФайла, «*», «»));

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

    Reply
  10. dagroma

    (7) Исправил

    Reply
  11. GSoft
    Reply
  12. Altair777

    (11) Интересно 🙂

    Только вот Пока 1=1 Цикл не нужно.

    Все равно ведь при совпадении имени файла существующие удаляются.

    (9) Очень показательно поведение ФС при запрещенных символах в имени файла.

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

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

    Наверно, при разработке этой подсистемки кодеры 1С что-то откуда-то выдернули как зря и так же как зря и вставили.

    Reply
  13. GSoft

    мне в 11 что нравится — то что перенос идет в цветовой гамме 1С а не экселя, а они как известно не совпадают

    кстати, насчет имен файлов не пробовал — формирую со штатно-крякозябровыми

    Reply
  14. Wicked

    (11) вы не будете против? если я добавлю ваш пример нa help1C.com

    или добавьте сами 🙂

    Reply
  15. foxey
    Добавил в меню «Файл» элемент «Сохранить в Excel»(Объект — Задача, Команда — Задача.Выполнить, Формула — глСохранитьФайлExcel()) — и все, клиент доволен.

    Что-то недопонял… Объект — Задача — это где? Как вставить пункт в меню?

    Reply
  16. GSoft

    (14) я нет, а вот автор не знаю))) в свое время нашел данный код на просторах инета)))

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

    Reply
  17. Altair777

    (15) В редактировании интерфейсов (меню)

    Новая колонка, галочка «Системная», выбрать пункт «Файл»

    Reply
  18. Altair777

    Ой! Чуть не забыл «плюсик» поставить 🙂

    Reply
  19. Wicked

    (16) добавил 😉 http://help1c.com/faq.html

    Reply
  20. GSoft

    (19)

    разделите код семерки и восьмерки — будет более читабельно и удобно

    Reply
  21. MadDAD
    Reply
  22. CheBurator

    ну вы накрутили блин.. давно уже сделано все…

    Reply
  23. melnycky

    Спасибо большое, пригодилось!

    Reply
  24. chmv

    а как проверить табличный документ или нет без dll?

    Reply
  25. chmv

    можно ди тоже самое написать без dll

    Reply
  26. dagroma

    (25)Я такой возможности не нашел.

    Reply
  27. chmv

    ЖАЛЬ. А библеотеку надо регистрировать?

    Reply
  28. dagroma

    Нет, не надо.

    Reply
  29. dimaskl

    Программно сохранить файл Excel в формате 2003 года, надо написать так Книга.SaveAs(ПутьДляЗаписиФайла, -4143);

    Синтаксис команды «SaveAs» во втором параметре разрешает указать формат сохраняемого файла.

    Числовое значение фрмата файла Excel 2003: FileFormatNum = -4143

    Reply

Leave a Comment

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