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




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-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 не будет опубликован. Обязательные поля помечены *