Обновление УТ11 с релиза 11.1.2 на 11.1.10 в примерах




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

20 Comments

  1. kwazi

    Умиляет нежелание использовать типовые механизмы интеркампани. Тем более появились они уже давно и хорошо зарекомендовали себя. Бухгалтерия вам бы спасибо сказала.

    Reply
  2. Mortiferus

    (1) kwazi, к сути данной статьи ваш комментарий совершенно не относится, так что попрошу по существу…

    Reply
  3. Ibrogim

    (1) kwazi,

    Умиляет нежелание использовать типовые механизмы интеркампани.

    Умиляет желание мучиться с закрытием месяца по куче организаций, разбираться с косяками в перепродажах между организациями и т.п. Тогда как в предшественнике (УТ10) была возможность учитывать запасы в целом по организации.

    Бухгалтерия вам бы спасибо сказала.

    Более ценно спасибо от собственника. Считаю, что БП на то и отдельная программа, чтобы там спокойно в своём бухгалтерском мире можно было делать любую интеркомпани. Удобство бухгалтерии не должно становиться неудобством основного бизнеса.

    Reply
  4. roofless

    читал по диагонали, работа проделана большая, статья хорошая, вот только актуально ли? не увидел заветного словосочетания «расширение конфигурации» =(

    Reply
  5. FreeArcher

    Даже не знаю, что более затратно подобный механизм, или делать изменение формы через отчет о сравнении объектов.

    Reply
  6. Поручик

    Про незатирание своего кода в переопределяемых модулях не всегда верно. Я довольно часто после обновлений БП 3.0 вставляю свои строки заново. Сейчас вот обновляю УТ 11.1 на УТ 11.2 и тоже пришлось по новой вклеивать код.

    Reply
  7. wolfsoft

    Не к публикации автора, а вообще в целом

    Итак, в релизе 11.1.10 программистами 1С создан механизм, который позволяет нам существенно упростить доработки форм. А именно: во многих модулях форм (а может и во всех — не проверял) в процедурах «ПриСозданииНаСервере», «ПриЧтенииНаСервере», «ПередЗаписьюНаСервере» и т.д. добавлены вызовы общих модулей, ответственных за упрощение доработки конфигурации:

    …это вместо того, чтобы сделать нормальные подписки на события *рукалицо*

    Reply
  8. Поручик

    Не в релизе 11.1.10 появились разные СобытияФорм.ПриСозданииНаСервере() и МодификацияКонфигурацииПереопределяемый, а раньше, ещё в середине или даже в начале 2014 года. Но клиентские обработчики событий для добавленных элементов форм всё равно приходится прописывать в модуле самой формы.

    Reply
  9. Mortiferus

    (7) wolfsoft, полностью согласен…

    Reply
  10. Mortiferus

    (6) Поручик, да, об этом тоже думал, что ежели 1С-ники в этих модулях что-нибудь «допилят», придется руками все переносить, хотя сами они и позиционируют Переопределяемые модули именно для таких целей! Как-то не получается у них написать сразу и навсегда…

    Reply
  11. Mortiferus

    (8) Поручик, согласен, я смотрел уже 10-й релиз, остальные не анализировал. Для меня это был последний на момент экспериментов, так что как-то так… Пардонесс, если кого ввел в заблуждение.

    Reply
  12. Mortiferus

    (4) roofless, внедрять расширение конфигурации пока не собираюсь, поскольку оно еще мало что умеет. Слишком много у нас доработок — расширение с ними не справится однозначно.

    Reply
  13. ivanov660

    Вы не совсем внимательно ознакомились с функционалом механизма работы с событиями форм и механизмов, которые используют разработчики.

    1. Для некоторых случаев п.5, вполне можно не добавлять свои функции в модуль формы, а использовать процедуру «Подключаемый_ВыполнитьПереопределяемуюКоманду». К которой можно привязать ваши процедуры. Подробнее тут: Типовой механизм упрощенного изменения конфигурации в ERP 2.0 и УТ 11

    2. Можно использовать типовую функцию установки подписок: ОбщегоНазначенияУТ.УстановитьПодпискуНаСобытияИзмененияЭлементовФормы

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

    А так надеемся, что в ближайшем будущем в функционале расширений будет серьезный прорыв.

    Reply
  14. Mortiferus

    (13) ivanov660, 1. Это круто! Не знал. Поюзаю эту функцию обязательно.

    Поюзал — и не понял, как она работает. В «Заказе клиента» эта процедура есть, но я в нее не попадаю при изменении реквизитов на форме. Не попадаю ни из тех реквизитов, для которых я переопределил команды, ни из тех, для которых команды не менял. Так что пока эта полезная процедура НЕ работает.

    Reply
  15. ivanov660

    (14) значит используете не правильно, у нас все работает. К стати, с самим заказом клиента не так все просто, как я писал, т.к. разработчики сами переопределяют функции программно. И тут может получится ситуация, что они перетирают Ваше программное переопределение. Попробуйте в качестве примера на другом объекте, к примеру, справочнике контрагент или любом другом.

    Reply
  16. Mortiferus

    (15) ivanov660, может быть и так, но мне-то нужно в этом документе! А в этом документе не работает, так что о чем говорить? Еще раз спасибо за информацию.

    Reply
  17. dklp

    я так до конца и не понял, можно ли в модуле МодификацияКонфигурацииПереопределяемый динамически добавить на стандартную форму новую команду и назначить ей обработчик? работаю с документом РеализацияТоваровУслуг (Конфигурация УТ 11.2):

    // код в модуле МодификацияКонфигурацииПереопределяемый
    Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт
    
    Если Форма.ИмяФормы = «Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента» Тогда
    
    // Добавляю новую команду
    Команда = Форма.Команды.Добавить(«МояКоманда»);
    Команда.Действие = «ПриНажатииМояКоманда»;
    
    НовыйЭлемент = Форма.Элементы.Добавить(«КнопкаМояКоманда», Тип(«КнопкаФормы»));
    НовыйЭлемент.ИмяКоманды = «МояКоманда»;
    НовыйЭлемент.Заголовок = «Выполнить мою команду»;
    
    КонецЕсли;
    
    КонецПроцедуры
    
    // теперь иду в модуль МодификацияКонфигурацииКлиентПереопределяемый
    Процедура ВыполнитьПереопределяемуюКоманду(Форма, Команда, ДополнительныеПараметры) Экспорт
    
    Если Форма.ИмяФормы = «Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента» Тогда
    
    Если Команда.ИмяКоманды = «МояКоманда» Тогда
    Сообщить(«Здесь будет выполняться обработчик команды»);
    КонецЕсли
    
    КонецЕсли
    
    КонецПроцедуры
    

    Показать

    в итоге, кнопка на форму документа добавляется, но при нажатии на неё ничего не происходит. это значит, что всё-таки нужно обязательно обработчик команды в модуле формы прописывать? в чем тогда смысл модуля МодификацияКонфигурацииКлиентПереопределяемый?

    Reply
  18. Mortiferus

    (17) dklp, да, только в модуле формы:

    реализовать новые алгоритмы, к сожалению, мы можем только в самой форме документа

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

    Reply
  19. dklp

    (18) странная какая-то история с этими переопределяемыми модулями и внешними обработками. получается, что в переопределяемом модуле можно динамически создать реквизит для стандартной формы документа (например, как в моем случае — для документа РеализацияТоваровУслуг), но нельзя повесить обработчик на заполнение реквизита по команде, а из внешней обработки наоборот — можно назначить обработчик по команде, но не получится программно создать реквизит на форме владельца. то есть, чтобы добавить, скажем, новую колонку в табличную часть стандартного документа и вывести туда какую-нибудь полезную информацию, нужно объединять два этих подхода. кстати, если использовать механизм заполнения табличной части из внешней обработки, то предварительно каждый раз необходимо записывать документ. это немного раздражает. не знаете, как это обойти?

    Reply
  20. Mortiferus

    (19) dklp,

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

    здесь на форуме куча примеров таких обработок. сам в свое время взял за шаблон одну из них — нет проблем с перезаписью.

    Reply

Leave a Comment

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