Импорт файлов типов XLS, DBF, и TXT в табличное поле (Простой читальщик xls файлов)




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

35 Comments

  1. vasilykushnir

    C почином, Санек. Поддержим коллегу!

    Reply
  2. Abadonna

    Кушнир-то фиг проверил, нет у него восьмерки, а я проверил 😉

    Рабочая, как новичку- плюс

    Reply
  3. vasilykushnir

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

    Reply
  4. imsoftware

    Просто и понятно. +1

    Reply
  5. Abadonna

    Предусмотри и еще один режим на тот случай, если первая строчка ёкселя содержит заголовки колонок, в это случае создавать колонки не Колонка1…КолонкаX, например, Наименование-Количество-Цена. Будет юзабельнее

    Reply
  6. Шёпот теней

    (5) Спасибо, Abadonna!

    У меня так и работает. Да! Если это ещё кому то нужно, обязательно вставлю… Просто хотелось максимальной простоты, понятности и универсальности… Особенно для новичков… Когда месяц назад стал изучать 8-ку был в ужасе… теперь ничего…

    Спасибо, ещё раз… Удачи!

    Reply
  7. Шёпот теней

    (5) По совету «Abadonna» дополнил отчёт перенаименованием колонок табличного поля по выбранной строке или по выбранной ячейки см. файл и описание к файлу «ЧтениеЭкселя_01»

    Спасибо всем кто выразил своё мнение в комментариях и/или скачиваниях данного отчёта.

    Всем удачи и успехов!

    Reply
  8. serg1c

    Ну вообще-то обработкой текстовый файл можно назвать только с натяжкой!

    А файлы .efd вообще как обработка не котируются.

    Я не понял. Или убрали с сайта .ert или так и было?

    Reply
  9. serg1c

    Я видать не понял.

    Это для 8-ки что-ли?

    Reply
  10. Шёпот теней

    Спасибо магнтогорцам за советы и общение…

    Всем удачи!

    Reply
  11. Abadonna

    (8,9) А фигли понимать?

    Вверху четко написано, хоть и мелкими буквами: «Внешняя компонента для 1С: Предприятие 8.0»

    Правда она не внешняя, но для 8.0 — точно 😉

    Reply
  12. PeRom

    >открытие и чтение файла с количеством 5…10 000 строк происходит за 1…5 секунд

    Как этого добился? Что используешь?

    Последнюю обработку скачать не могу, а в текстовых тот-же принцип, что и у меня:

    Код
    Файл = Новый COMОбъект("Excel.Application");
    Файл.DisplayAlerts = 0;                   //не задавать вопросы
    Файл.Application.AutomationSecurity = 3;  //уровень безопасности
    Книга = Файл.Workbooks.Open(ФайлХЛ);//строка выполняется 5-6 минут, какая альтернатива?
    Лист = Книга.Worksheets(2);
    Пока (НЕ ПустаяСтрока(Строка(Лист.Cells(строкаXL,1).Value))) или
       (НЕ ПустаяСтрока(Строка(Лист.Cells(строкаXL,2).Value))) Цикл
       строкаXL = строкаXL+1;
    КонецЦикла;                                      
    COMSafeArrayМассив = Лист.range(Лист.Cells(1,1),Лист.Cells(строкаXL,249)).Value;
    Книга.Close();
    

    Показать полностью

    открываю файл с несколькими листами, макросами и паролем. Как ещё можно считать из него инфу и желательно без ВК?

    Reply
  13. Dirk Diggler

    Отличная обработка. Пару идей выскажу. Лично мне не хватает:

    • возможности редактировать содержимое таблицы
    • загрузки нескольких листов по выбору
    • Удаления столбцов и строк
    • переноса в выбранную табличную часть
    Reply
  14. uri1978

    Спасибо. Буду использовать как пример для написания своей обработки.

    То что нужно!

    😉

    Reply
  15. Шёпот теней

    (13) загрузка из листов реализовано здесь: http://infostart.ru/public/22279/ … думаю что реализовать загрузку из нескольких листов в одну ТЗ труда не составит …

    Reply
  16. Шёпот теней

    (14) … и вам спасибо …

    по поводу любой работы с XLS все ноги растут так или иначе от господина Душелова … и эта разработка была написана на основе чтения его обработок … и пользуясь случаем хочется выразить ему багодарность …

    быстрота чтения из Ексель достигается чтением листа не по ячейкам, хотя и это иногда нужно, а сразу весь лист оператором UsedRange.Value … а при записи использовать в ексель файл использовать запись всей ТЗ используя МассивКОМ = Новый COMSafeArray(«VT_VARIANT», ВсегоКолонок, ВсегоСтрок);

    всё это есть в обработке: http://infostart.ru/public/22279/

    … вот …

    Reply
  17. Шёпот теней

    для uri1978 … и кому интересно … есть интересный сайт http://www.citforum.ru/programming/windows/ … тут можно найти некоторые ответы …

    на вопрос:как при использовании UsedRange.Value избежать автоматического перевода текста «0100100» в число (100100) прямого ответа у меня нет …

    КТО знает подскажите … ?

    я делаю так … в ексель при помощи функции «СЦЕПИТЬ» добавляю к явному текстовому полю знак апострофа … а потом его удаляю …

    п.с. видимо надо копировать надо не UsedRange.Value а другим оператором копирования колонок с заданным форматом …

    дополнительные операторы можно посмотреть тут : http://msdn.microsoft.com/en-us/library/aa215923(office.11).aspx

    … вот …

    Reply
  18. gaglo

    (17) Заинтересовался… ибо вопрос сформулирован несколько расплывчато. Что есть «явное текстовое поле«? Ячейкам в Экселе задан формат «текстовый»? Последующее упоминание апострофов наводит на мысль, что формат всё-таки «общий», и тогда поле «явно текстовое» только для человеков.

    По результатам моих экспериментов для чтения через Value выводы таковы:

    — если ячейке Экселя явно задан формат «текстовый», то в 1С попадает значение как строка;

    — если задан формат «числовой», то в 1С попадет число;

    — если формат ячеек (по умолчанию) «общий», то по дороге неизбежно происходит то самое автоматическое преобразование: значения становятся числами, если только их возможно полностью преобразовать в число, иначе становятся строками (.10 будет числом, .10.24 — станет строкой);

    — формат ячеек Экселя должен быть установлен до ввода значений в них!! иначе придется «обновить» значения в ячейках с измененным форматом, хотя бы банальным F2-Enter, чем я иногда и занимаюсь (с помощью кнопки и макроса).

    Насчет другого оператора копирования колонок сильно сомневаюсь; можно попробовать забирать UsedRange.Text, тогда все ячейки превратятся в строки; поможет ли это в деле последующего разбора? Пока непонятно…

    PS Тут же и попробовал — UsedRange.Text как массив не берется (не то что Value), а по одной ячейке неинтересно ;-[

    Reply
  19. Шёпот теней

    (18) … нууу… просто СПАСИБО … и не ПРОСТО то же… ВОТ …

    хм… проблема в том, что если в Екселе стоит формат.общий и там стоит «001» то если колонку с данной ячейкой сделат формат.текстовое то ексель делает «001» как (1) … приходится копировать колонку и вставлять её как текст что не всегда получится … ))) … поэтому делаю как в (17) …

    полностью согласен поячеечное чтение не «фонтан»…

    мне больше нравится сохранять данные из 1С в 1С через mxl или ЗначениеВФайл/ЗначениеИзФайла …

    … вот …

    Reply
  20. Шёпот теней

    (22) … всё стало понятно … оказывается то была реклама…)))

    сначало чем не устраивает поячеечное чтение обработки с диска ИТС … а потом купите у меня … моя лучше… ))))

    … вотоднаковот …

    п.с. Eugeneer — не перебАрщивай с манией …

    Reply
  21. Шёпот теней

    (26) … вместо цыц … взял бы и научил бы нас как в 1С … «в 1с …вся экселевская таблица…..полностью загружается в таблицу значений 1С……ОДНИМ методом….. » …

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

    … вОт …

    п.с. по поводу 2010 года… это была моя самая первая обработка написаннная в 2007 году на 1С 8.0 … и прекрасно помню как с БОЛЬШИМ интересом читал подобные обработки …

    Reply
  22. Шёпот теней

    жаль… жаль… что Eugeneer так и не научил нас : … «в 1с …вся экселевская таблица…..полностью загружается в таблицу значений 1С……ОДНИМ методом….. » …

    видимо умность и жадность рядом ходят …. хм… или на одной шеи сидят …

    … ВОТведьВОТ …

    Reply
  23. Шёпот теней

    (30) … Eugeneer ! … у вас ко мне мания …

    … данная обработка и txt — загружает, и dbf — грузит (хотя и dbf лучше открывать как xls — меньше проблем с кодовыми страницами) …

    … воообщем НЕпонятно чтоТО или чтоТО не о ТОМ …

    … вотВобщемТАКвот …

    Reply
  24. larisab

    (24) И это при том что сабж 2008 года 😮

    Reply
  25. gaglo

    (19) Мы вдвоем взаимно согласны друг с другом!

    Но теперь мне непонятно: как можно сделать в Экселе формат общий и значение 001? Руками не получается, даже если я набираю клавишами 001; стоит нажать Enter, и в ячейке остается и значение 1, и видимое представление «1», но без всяких нулей. Речь идет, что ли, о табличке -продукте быстрой выгрузки из 1С?

    Reply
  26. Шёпот теней

    (33) … правила — ОБЩИЕ … применение — «ЧАСТНОЕ» …

    форматОбщий не даст сделать «001» … либо текствоый либо какой-нибудь придумать форматСпециальный …

    … наверное …

    если сохранять методами 1С «вывести» и «сохранить копию» там то же будет куча вопросов … т.к. формат подберЁтся весьма странный … вОООбщем теория всегда Общая а практика всегда — Частная …

    … ВОТ …

    Reply
  27. Ish_2

    Шепот , ты не поверишь !

    Искать , заморачиваться было некогда .Нужно было быстро,»с ходу» загрузить некий xls именно в ТЗ как самый удобный формат для дальнейшей обработки.

    Воспользовался.

    Reply
  28. aleks_pro

    Выдает ошибочку. Будем смотреть

    Reply
  29. Stepan_1c

    Спасибо за работу=)

    Reply
  30. lushka

    Спасибо, очень выручили 🙂

    Reply
  31. Boudybuilder

    Спасибо за работу. Будем смотреть что за зверь такой.

    Ато я тут парюсь со своей разработкой.

    Хотелось чтоб скачивать значения из прайса можно было в регистр НоменклатураКонтрагентов , а потом уже загружать из разных фирм прасов цены , вот так чтоб каждый день свеженькую информацию иметь .

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

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

    Reply
  32. Boudybuilder

    (Спасибо за работу. Будем смотреть что за зверь такой.

    Ато я тут парюсь со своей разработкой.

    Хотелось чтоб скачивать значения из прайса можно было в регистр НоменклатураКонтрагентов , а потом уже загружать из разных фирм прасов цены , вот так чтоб каждый день свеженькую информацию иметь .

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

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

    Reply
  33. Шёпот теней

    (40) … УДАЧИ … вот …

    Reply
  34. 7OH

    А не подскажете пример, такой же, но с возможностью редактировать загруженное.

    Загрузить на чтение у меня и так получилось.

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

    Reply
  35. Шёпот теней

    (42) для возможности непосредственного редактирования надо указать ТИП колонок таблицы … вот …

    Reply

Leave a Comment

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