FAQ или платформа 8 для чайников :)




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

46 Comments

  1. coder1cv8

    P.S. Пока немножко, но работа идет 🙂

    P.P.S. Ну и хотелось бы по мере возможностей не повторять «Простые примеры разработки» 🙂

    Reply
  2. Alex_IT

    Еще часто встречается вопрос (крик): «Невозможно внести изменения в конфигураторе!!!» 🙂

    Reply
  3. CheBurator

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

    Reply
  4. coder1cv8

    (2) Спасибо! Добавлено.

    Как я сам мог забыть о таком актуальном вопросе… ))

    Reply
  5. coder1cv8

    Обновлено.

    Товарищи, активнее поддерживаем блог на плаву. Ставим плюсики! 🙂

    Reply
  6. Maxis

    Если на форму списка документов добавить табличное поле, то как вывести в него содержимое табличной части документа (и, соответственно, менять при переходе по строкам)?

    Reply
  7. coder1cv8

    (6) Посмотри как у меня это реализованно вот здесь: http://infostart.ru/projects/1104/

    Всё достаточно просто…

    Reply
  8. O-Planet

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

    Еще ситуевина, отличающая 8 от 7. Имеется отсортированная по полю таблица или список. Хочу просматривать ее (его) с середины, начиная с некоторого значения…

    Reply
  9. poppy

    (8)

    > Еще ситуевина, отличающая 8 от 7. Имеется отсортированная по

    > полю таблица или список. Хочу просматривать ее (его) с середины,

    >начиная с некоторого значения…

    Что мешает использоват цикл «Для <Имяпеременной> = <Выражение 1> По <Выражение 2> Цикл»?

    Reply
  10. coder1cv8

    (9) Не знаю как в 7.7 (я с ней не сталкивался практически), а в восьмерке я именно так бы и сделал 🙂

    Reply
  11. tango

    В: Как в запросе добавить к полю не строкового типа определенную строку, например ВЫБРАТЬ РеализацияТоваровУслуг.Сумма + » руб.»?

    О: Никак.

    ????? вау?

    Reply
  12. coder1cv8

    (11) Эм… Это недоверие что-ли? 🙂

    Могу удивить вас ещё больше «ВЫБРАТЬ ПРЕДСТАВЛЕНИЕ(Ссылка)+»»какая-то строка»»» тоже нельзя…

    Reply
  13. tango

    Это удивление. Вау — это я так удивляюсь обычно. Вот, например, в понедельник, смотрю — уже начало одиннадцатого (вечера), значит, пора уходить с милонги. Вау!? — говорю. Вау… — говоритона. Это значит: блин, как быстро летит время, пора уходить… Да, пора, — грустно соглашается она.

    Reply
  14. tango

    все 1с Как в 1С в конструкторе запросов сделать составную переменную, включающую символьную строку? ФИОюзера 18.янв Переменная запроса как выражение (сумма) переменных: полей нужных таблиц и и параметра, задается на вкладке справа — параметр равен нужной символьной строке, первый знак перед параметром &.

    Reply
  15. coder1cv8

    (14) чё-то я ничё не понял… )

    Reply
  16. tango

    Милонга — это:

    1) вид аргентинского танго

    2) место, где это танцуют

    3) тусовка там же

    пс: в понедельник милонга в Джигсо, на смоленке (садовое кольцо у ст.арбата)

    Reply
  17. tango

    Или Вы не поняли, что для сабжа надо просто прибавить к полю в селекте параметр, в котором устанавливается строка?

    Но здесь усматривается некая коллизия с Вашим ником.

    Reply
  18. coder1cv8

    (17) И что будет? Это позволит прибавить строку?…

    Reply
  19. coder1cv8

    +(18) А! Я понял! Вы решили, что если конструктор запроса не ругается на неверный параметр, то можно записывать себя в мегаспецы и учить меня жизни… 🙂 Вынужден вас разочаровать, попробуйте выполнить такой запрос…

    Reply
  20. tango

    не попробую.

    18 января это сделал юзер и остался доволен результатом (14 — это фрагмент ексельной таблички заявок 1снику).

    И Бога ради! учить кого бы то ни было чему либо… это очень, очень дорого

    Reply
  21. coder1cv8

    (20) Я не понимаю, мы на разных языках говорим?… Да, в запросе есть конкатенация строк, можно сложить строку «Иванов» и строку «18 янв», к примеру… Я же здесь говорю о том что в запросе нет преобразования типов и поле с типом число (или дата, или ссылка) никогда не соединить со строкой…

    Reply
  22. tango

    ок. спросил юзера, он к строке добавлял строку

    Reply
  23. coder1cv8

    (22) Ну ясен пень! К чему заводить этот спор было?…

    Reply
  24. O-Planet

    coder1cv8 poppy

    Не вьехали вы… В таблице — 3 столбца: товары, характеристики и цены. Отсортировано по товарам. На форме — поле из справочника номенклатуры. По кнопке Сформировать выводим записи по всем характеристикам+ценам одного выбранного товара. Строк в таблице n-сот тысяч…

    На 7.7:

    Код
    НомСтр=0;
    Таб.НайтиЗначение(ВыбТовар,НомСтр,"Номенклатура");
    Пока НомСтр<=Таб.КоличествоСтрок() Цикл
      Таб.ПолучитьСтрокуПоНомеру(НомСтр);
      Если Таб.Номенклатура<>ВыбТовар Тогда
        Прервать;
      КонецЕсли;
      Сообщить( ... );
      НомСтр=НомСтр+1;
    КонецЦикла;
    

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

    Когда с 7.7 перепрыгиваешь на 8.0, то не сразу вьезжаешь, что тут такой алгоритм не сработает: напрямую номер строки по значению поля найти нельзя. Надо сперва искать строку, содержащую это значение, а потом получать ее индекс в таблице.

    Reply
  25. poppy

    (24) O-Planet

    Ты опять привел неудачный пример.

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

    Код
       НомСтр = Таб.Индекс(Таб.Найти(ВыбТовар,"Номенклатура"));
       Пока НомСтр<Таб.Количество() Цикл
          Строка = Таб.Получить(НомСтр);
          Если Строка.Номенклатура<>ВыбТовар Тогда
             Прервать;
          КонецЕсли;
          Сообщить(Строка.Характеристика);
          НомСтр=НомСтр+1;
       КонецЦикла;
    

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

    Можно написать заново:

    Код
       Отбор = Новый Структура("Номенклатура", ВыбТовар);
       МассивСтрок = Таб.НайтиСтроки(Отбор);
       Для ии = 0 По МассивСтрок.Количество()-1 Цикл
          Сообщить(МассивСтрок[ии].Характеристика);
       КонецЦикла;
    

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

    И с номерами строк не нужно заморачиваться, и сортировать по номенклатуре необязательно.

    Reply
  26. coder1cv8

    Добавил пару вопросов. Не совсем уже для «чайников» 🙂 Скорее из того что вызывало затруднения у меня…

    Reply
  27. coder1cv8

    Обновлено. Вверх!

    Reply
  28. delete009

    спасибо мне это пригодилось

    Reply
  29. MariP

    Думаю такой вопрос тоже часто возникает:

    Возможен ли вход без использования паролей?

    По аналогии с 7-кой, когда удаляешь папку юзер и все…

    Reply
  30. coder1cv8

    (29) Возможен ) Но вопросы безопасности не относятся к данной статье. На эту тему есть хоть и старая, но всё ещё актуальная статья вот здесь: http://www.mista.ru/v8/security/

    Reply
  31. NewNick

    Функция ВЗапросеИзЧислаСтроку(ИмяПоля,ДлинаЦел,ДлинаДробь,ЛидирующийСимвол=»»)

    Запрос = Новый Запрос(«ВЫБРАТЬ ВЫРАЗИТЬ(0.5 КАК ЧИСЛО (15,0)) КАК Проверка»);

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

    РЗ.Следующий();

    ЗапросОкругляетПоАрифметическимПравилам = Рз.Проверка = 1;

    Ткст = «ВЫБОР КОГДА «+ИмяПоля+»<0 Тогда «»-«» ИНАЧЕ «»»» КОНЕЦ » + Символы.ПС;

    ИмяПоляАбс = » ВЫБОР КОГДА «+ИмяПоля+»<0 ТОГДА -«+ИмяПоля+» ИНАЧЕ «+ИмяПоля+» КОНЕЦ «;

    Парам = Pow(10,ДлинаЦел-1);

    Для Бегим = 1 По ДлинаЦел+ДлинаДробь цикл

    Ткст = Ткст + ?(Бегим = ДлинаЦел+1,»+»».»»+»,»+»);

    Ткст = Ткст + » ВЫБОР » + Символы.ПС +

    ?(Бегим<ДлинаЦел,» КОГДА » + ИмяПоляАбс + » < » +Формат(Парам,»ЧРД=.; ЧГ=»)+» ТОГДА «»»+ЛидирующийСимвол+»»» » + Символы.ПС,»»);

    Для Цифирка = 0 По 9 Цикл

    Ткст = Ткст + » КОГДА «+ИмяПоляАбс+»-«+Формат(Парам*10,»ЧРД=.; ЧГ=»)+»*ВЫРАЗИТЬ((«+ИмяПоляАбс+?(ЗапросОкругляетПоАрифметическимПравилам,»-«+Формат(Парам*5,»ЧРД=.; ЧГ=»),»»)+»)/»+Формат(Парам*10,»ЧРД=.; ЧГ=»)+» КАК ЧИСЛО(15, 0))»+» >= «+Формат((9-Цифирка)*Парам,»ЧН=0; ЧРД=.; ЧГ=»)+» ТОГДА «»»+Формат(9-Цифирка,»ЧН=0; ЧРД=.; ЧГ=»)+»»» » + Символы.ПС;

    КонецЦикла;

    Ткст = Ткст + » ИНАЧЕ «»0″»»+Символы.ПС+» Конец » + Символы.ПС;

    Парам = Парам/10;

    КонецЦикла;

    Возврат Ткст;

    КонецФункции

    Запрос = Новый Запрос(» ВЫБРАТЬ «»Полученная строка : «»+»+ВЗапросеИзЧислаСтроку(ИмяПоля2,ДлинаЦел2,ДлинаДробь2)+» КАК Стр «);

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

    пока РЗ.Следующий() цикл

    Сообщить(РЗ.СТр);

    конеццикла;

    Reply
  32. NewNick

    Для чайников добавьте плиз — сделать можно все 😉

    Reply
  33. NewNick

    Функция ТекстЗапросаИзСтрокиВЧисло(ИмяПоля, ДлинаСтроки, СимволРазделитель=».»)

    текст = «»;

    текст2 = «»;

    Для позиция = 1 по ДлинаСтроки цикл

    текст = «(«+?(текст=»»,»»,текст+ Символы.ПС + » *ВЫБОР КОГДА ПОДСТРОКА(«+имяПоля+»,»+позиция+»,1)=»»»+СимволРазделитель+»»» ТОГДА 1 ИНАЧЕ 10 КОНЕЦ +»)+Символы.ПС+»ВЫБОР «;

    Для цифирка = 0 по 9 цикл

    текст = текст + Символы.ПС + » КОГДА ПОДСТРОКА(«+имяПоля+»,»+позиция+»,1)=»»»+цифирка+»»» ТОГДА «+цифирка;

    КонецЦикла;

    текст = текст + Символы.ПС + » ИНАЧЕ 0 КОНЕЦ)»;

    текст2 = текст2 + Символы.ПС + » КОГДА ПОДСТРОКА(«+имяПоля+»,»+позиция+»,1)=»»»+СимволРазделитель+»»» ТОГДА «+формат(pow(10,ДлинаСтроки-позиция),»ЧГ=»);

    КонецЦикла;

    возврат текст + Символы.ПС + «/ ВЫБОР » + текст2+Символы.ПС + » ИНАЧЕ 1 КОНЕЦ » + СИмволы.ПС +» * ВЫБОР КОГДА «+ИмяПоля+» ПОДОБНО «»%-%»» ТОГДА -1 ИНАЧЕ 1 КОНЕЦ»;

    КонецФункции

    Reply
  34. NewNick

    Есть два варианта решения проблемы, либо указать для замены вместо пробела Символы.НПП, либо используя функцию Формат().

    СтрЗаменить(ПеременнаяЧисло,Символы.НПП,»»); // 1-й вариант

    Формат(ПеременнаяЧисло,»ЧГ=»); // 2-й вариант

    XmlСтрока однако самый быстрый 😉

    Reply
  35. coder1cv8

    (31,33) Я бы не стал, конечно, столько кода писать вместо одной строки при выводе, но мало ли… Одинэсники разные бывают ) Такой способ имеет место быть, да и обсуждался уже давно на той же мисте…

    (34) Отличный вариант. Приму на заметку.

    Reply
  36. NewNick

    код мой. накидал просто так — ниразу не использовал )) а чем еще заняться когда отдыхаешь от работы за кружечкой водки )). «одна строка при выводе» это отчеты аля 7.7. впрочем для скд этот код уже неактуален, оно и само справляется. просто непонравилась безапеляционность что этого сделать нельзя.

    Reply
  37. Sol

    Must have. Всё известно, но это действительно то, с чем сталкиваешься после семерки. Спрашивают постоянно.

    Осветил наиболее актуальные проблемы, твою статью надо в FAQ — http://v8.1c.ru/predpriyatie/typical_problems_App.htm 😉

    Reply
  38. coder1cv8

    Добавил пару вопросов по временными таблицам.

    Reply
  39. liliabd08

    Огромное спасибо с документом списком!!!

    Reply
  40. anig99

    Неразрывный пробел можно получить зажав alt и набрав 255…

    Reply
  41. rasswet

    спасибо, познавательно!

    Reply
  42. KurchataQ

    Было бы здорово если FAQ написан был бы в файле формата .chm

    Reply
  43. Збянтэжаны Саўка

    Очень хорошо, жаль что так мало!

    Кодер, плиз, не жмись, наскреби еще инфы для новичков, у тебя ведь еще много есть чего нам рассказать…

    ведь у тебя это так хорошо получается!

    Reply
  44. d0dger
    Как из строки с разделителями получить массив

    Вопрос Advanced как наиболее производительно получить из результата запроса строку с разделителями.

    Имеется ввиду результат более 100 000 элементов…

    Reply
  45. dardroze

    Спасибо за FAQ. Почерпнул для себя полезного

    Reply
  46. BalVlad

    Спасибо за FAQ. Хотелось бы узнать, а продолжение — развитие темы не планируется?

    Reply

Leave a Comment

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