Всякие полезности




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

57 Comments

  1. NoMax

    (0) уважаемый а можно сжать в файл? а то у меня походу не все выводит.

    На «Как отобразить на географической схеме выбранный город?» обрезает и дальше «молоко».

    Reply
  2. begemot

    Так это же «А.П. Габец, Д.И. Гончаров

    1С:Предприятие 8.0 Простые примеры разработки»

    http://ifolder.ru/7909799

    Reply
  3. Minotavrik

    там многое из др. источников.

    Reply
  4. oleg974

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

    Reply
  5. alyona.iva@gmail.com

    Да, да — я тоже за файл. Мелкий текст получатся — глазки начинают болеть быстро(((

    Reply
  6. sytkosa

    Автору надо все это «добро» сложить в откомпилированный chm или html и тогда будет однозначно большой ПЛЮС

    Reply
  7. kosb_64

    Согласен с предыдущими комментариями!

    Reply
  8. dobrynin.i.s

    тут http://infostart.ru/public/60366/ этот хелп в формате файла шаблонов.

    Reply
  9. pavel_pss

    Спасибо, на всякий случай полезно

    Reply
  10. Dillan

    Спасибо, пригодится

    Reply
  11. xxx6662000

    Посмотрел листинг и мне показался смутно знакомым, и нашел аналогичное 1:1 в книге «Ганчаров Грабеч. 1С Предприятие 8.1 Простые примеры разработки». Такого явного плагиата я не встречал очень давно.

    Reply
  12. vip

    (11) см. (2) и (3)

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

    (11) из 8.1 ничего не нашел, спецом искал темы про временные таблицы — глухо, по ходу это из 8.0.

    (12) других источников что-то тоже увы в упор не вижу в этой огромной свалке от Габеца для 8.0.

    Reply
  14. KukA.5

    (11) согласен это ПОЛЕЗНЫЙ МАТЕРИАЛ, но …из хорошей книги.

    Плюс ставлю — рекомендую всем этот объективно полезный материал.

    Автору рекомендую в самом начале написать благодарности Габцу и Гончарову.

    Reply
  15. powar

    Название скромное больно. Это скорее «Пособие юного програмиста».

    Reply
  16. the1

    Спасибо! Буду осваивать)

    Reply
  17. Serg_KSV

    Как создать новый документ?

    НовыйДокумент = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();

    НовыйДокумент.Дата = ТекущаяДата();

    ФормаНовогоПКО = Документы.ПриходныйКассовыйОрдер.ПолучитьФормуНовогоДокумента();

    ФормаНовогоПКО.Открыть();

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

    СоздатьДокумент() создает документ, в который записывается НовыйДокумент.Дата = ТекущаяДата();

    ПолучитьФормуНовогоДокумента() тоже создает документ, очень неудачно подобран пример с датой, дата нового документа всегда ТекущаяДата().

    Если будет заполнение другого реквизита, например,

    НовыйДокумент.СтатьДвижения = Командировочные;

    То в открываемом документе ФормаНовогоПКО.Открыть(); СтатьДвижения заполнена не будет.

    Правильно делать так:

    НовыйДокумент = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();

    НовыйДокумент.Дата = ТекущаяДата();

    ФормаНовогоПКО = НовыйДокумент.ПолучитьФорму();

    ФормаНовогоПКО.Открыть();

    И если это плагиат, то качество источника оставляет желать лучшего.

    Reply
  18. makeya

    Очень полезные «полезности»! хоть и столь знакомые по книжке.

    Reply
  19. Igortid

    хорошая подборка, спасибо

    Reply
  20. mtv:)

    (5) Смотри версию для печати — там всё хорошо читается.

    Reply
  21. voyger_men

    Спасибо большое, уже полгода не могу нормально с 1с разобраться, то времени нет то меня… теперь немного проще с этим!!!

    Reply
  22. hohmankia

    Отличная подборка, спасибо большое!

    Reply
  23. Lizi60

    Материал, несомненно, очень полезный.

    Reply
  24. zverek2

    Спасибо, материал полезный, иногда приходится пользоваться подобными разработками, только пока приходилось их самому придумывать и воплощать, а теперь можно уже разработанное взять и не терять время на реализацию своего. Автору огромное спасибо!

    Reply
  25. KresteG

    Спасибо, плюс

    Reply
  26. bolush

    Классно, очень хорошо помогает для начинающих программистов, программирую уже 7 мес, все это время только сюда заходил:))

    Reply
  27. yartkin

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

    Reply
  28. u_n_k_n_o_w_n

    Плагиат!!!

    Автору «-«, но не могу пока к сожалению.

    Reply
  29. KillHunter

    прикольная штукенция, спасибо 🙂

    Reply
  30. DitriX

    (0)Как привести строку типа «20.10.2012 12:03:40» к дате 1С

    Судя из справки — надо вычленить отдельный составляющие и получить строку типа:

    «20121020120940» и потом сделать Дата(«20121020120940»).

    но можно и просто Дата(«20.10.2012 12:03:40»).

    Я так понимаю тут зависит от региональных настроек и т.д. Но главное — что оно работает (на 8.2.16)

    Я не знал, может кому поможет.

    Reply
  31. Bukaska

    (29) u_n_k_n_o_w_n,

    В коей степени с вами согласна, но…Но не у всех есть возможность заказать большую книгу почти за 3000 по розничной цене))))

    Reply
  32. u_n_k_n_o_w_n

    (32) Bukaska, давайте уточним цену: 350 руб.

    Плю ко всему Вы получаете диск с данными где все это есть в электронном виде.

    Reply
  33. Bukaska

    (33) u_n_k_n_o_w_n,

    http://v8.1c.ru/metod/books/book.jsp?id=401

    Я про эту книгу поняла из темы)))

    Reply
  34. u_n_k_n_o_w_n

    Это уже набор «всю включено». Обязательно приобрету.

    Reply
  35. s_a_r_u_m_a_n

    (0), (35) народ, «всё включено» на сайте help1c.com, а это плагиат какой-то.. минус не ставлю только потому, что автор потратил своё время на копи паст.. даже не позаботясь об оформлении статьи..

    все, кто хочет изучить 1С — найдите книжки «Профессиональная разработка в 1С:Предприятии» первой и второй редакции и по ним учитесь.

    Reply
  36. Gulak

    Спасибо!

    Reply
  37. KillHunter

    неплохая статья, правда их уже немеренно на сайте однотипных!

    Reply
  38. Alekta

    Спасибо. В данной теме нашла то, что искала.

    Reply
  39. Рамзес

    В функции проверки массивов на идентичность:

    Если НаибольшийИндекс > ВторойМассив.ВГраница () Тогда
    Возврат Ложь;
    КонецЕсли; 

    Мне думается, что правильнее

    Если НаибольшийИндекс <> ВторойМассив.ВГраница () Тогда
    Возврат Ложь;
    КонецЕсли; 
    Reply
  40. mie24

    В вашей статье нашла ответ на свой вопрос. Спасибо.

    Reply
  41. serg1974

    нехватает очень следующего (авторство не мое)

    Можно ли в запросе , в качестве источника данных, использовать таблицу значений ?

    Да. Это можно сделать с помощью временных таблиц:

    // Сначала помещаем ТЗ во временную таблицу

    Запрос = Новый Запрос ;

    Запрос .МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

    Запрос .Текст = «ВЫБРАТЬ * ПОМЕСТИТЬ ТЗ ИЗ &ТЗ КАК ТЗ»;

    Запрос .УстановитьПараметр(«ТЗ», ТЗ);

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



    // Теперь ТЗ можно использовать в запросе :


    Запрос .Текст = »

    |ВЫБРАТЬ

    | ТЗ.Номенклатура,

    | Остатки.КоличествоОстаток

    |ИЗ

    | ТЗ

    | ЛЕВОЕ СОЕДИНЕНИЕ

    | РегистрНакопления.ТоварыНаСкладах.Остатки() КАК Остатки

    | ПО

    | ТЗ.Номенклатура=Остатки.Номенклатура»;

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

    —————————-еще момент !!!!—————————————

    Если ошибка: «Тип не может быть выбран в запросе» в 1С 8

    При использовании в запросе таблицы значений, возникает ошибка: «Тип не может быть выбран в запросе». Почему?

    Дело в том, что колонки таблицы значений, передаваемой в запрос в качестве источника данных, должны быть явно ТИПИЗИРОВАНЫ. Т.е. если мы используем таблицу значений, так же в свою очередь выгруженную из результата запроса или из табличной части документа например — то такой проблемы не возникает, т.к. в таком случае колонки будут типизированными. А если мы сами создаем таблицу значений, то нужно явно указать тип для каждой колонки:

    ТЗ = Новый ТаблицаЗначений;

    ТЗ.Колонки.Добавить(«Номенклатура», Новый ОписаниеТипов(«СправочникСсылка.Номенклатура»));

    Reply
  42. serg1974

    Пользуюсь темой — как справочником — но еще одной полезной конструкции тут нет:

    «Как открыть форму ссылки под курсором в форме списка» (регистр значений например)

    Форма = этаформа.ТекущийЭлемент.ТекущиеДанные[этаформа.ТекущийЭлемент.ТекущаяКолонка.Имя].ПолучитьФорму();

    Форма.Открыть();

    Добавьте пожалуйста!

    PS сегодня 1,5 часа искал — как это сделать 🙂

    Reply
  43. pavelyar

    Спасибо помогло !

    Reply
  44. grand.pers

    искал преобразование даты в строку — так и не нашел 🙁

    Reply
  45. ildarovich

    (45) grand.pers, вот по этой ссылке http://www.forum.mista.ru/topic.php?id=388253 в комментарии 23 есть решение

    Reply
  46. mukilka

    Спасибо, есть много полезных вещей

    Reply
  47. CratosX

    В связи с отказом от модальности, функция Предупреждение нежелательна

    Reply
  48. chmv

    48 А ЧТО надо использовать?

    Reply
  49. Джон Смит

    Полезная информация!

    Reply
  50. MPV

    Как таблицу значений «ТаблицаПолучатель» заполнить данными таблицы значений «ИсходнаяТаблица»?

    Этот код не совсем верный

    ТаблицаПолучатель = ТаблицаИсходная.Скопировать();

    Для Каждого СтрокаИсходнойТаблицы Из ИсходнаяТаблица Цикл НоваяСтрока = ТаблицаПолучатель.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсходнойТаблицы); КонецЦикла;

    Здесь нужно использовать просто

    ТаблицаИсходная.Скопировать();

    ИЛИ метод СкопироватьКолонки();

    ТаблицаПолучатель = ТаблицаИсходная.СкопироватьКолонки();

    Для Каждого СтрокаИсходнойТаблицы Из ИсходнаяТаблица Цикл НоваяСтрока = ТаблицаПолучатель.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсходнойТаблицы); КонецЦикла;

    Reply
  51. NazarovV

    в функции СформироватьЗапроспоТабличнойЧасти — ошибка :

    так у вас: (ЗначениеНеЗаполнено(Реквизит.Ключ)

    правильно:(Не ЗначениеЗаполнено(Реквизит.Ключ)…

    p.s. спасибо за статью.

    Reply
  52. chmv

    Красиво

    Reply
  53. ak0710

    (52), Вадим в старой версии платформы была функция ЗначениеНеЗаполнено, наверное вы не сталкивались

    Reply
  54. Altair777

    (0)

    ДАТАВРЕМЯ(2005, 01, 01)

    ???

    Вообще-то это Системные перечисления/Разные/ЧастиДаты/ДатаВремя

    Reply
  55. Altair777

    (0)

    Товар = Справочники.Номенклатура.ПустаяСсылка();

    а почему не?

    Товар = Неопределено;

    Особенно, для полей составного типа

    Reply
  56. Altair777

    (0)

    СледующийДень = ТекущаяДата() + 60 * 60 * 24;

    А тяжело посчитать на калькуляторе и просто написать 86400 ?

    Кстати, а если 2 ння?

    Функция ДобавитьДни(Дата, КоличествоДней) Экспорт
    //Назначение: Добавляет к дате определенное количество дней
    //Описание
    // Возможны отрицательные значение — тогда не добавление, а вычитание
    Возврат Дата + КоличествоДней * 86400; //60*60*24
    КонецФункции
    
    Reply
  57. zodus

    я себе давно делал тоже обработку с примерными модулями )

    Reply

Leave a Comment

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