1С 8.2-8.3. Создать на основании новый документ или открыть существующий.




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2024-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='\

8 Comments

  1. MarSeN

    Для первого опыта пойдет. Но только не для рабочих баз:

    1. У Вас не предусмотрен ввод на основании программным способом. Т.е программно получится ввести дубли. Надо добавить проверку и генерировать исключение (у Вас проверки, скорее всего, нет, раз срабатывает проц. ПриОткрытии)

    2. В Вашем случае ввод на основании все-равно выполняется, но не сохраняется, если есть дубль

    3. ИМХО Так как Вы делаете на УФ, то правильнее выполнить данную задачу, подменив команду ввода на основании. Т.е. Стандартную команду ввода на основании скрываете и создаете свою. В модуле команды на сервере осуществляете поиск, если нет документа — создаете ч.з открытьФорму с параметром Основание, Если есть документ то тоже чз открыть форму с параметром Ключ

    Reply
  2. e401

    (1) MarSeN,

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

    Reply
  3. MarSeN

    (2) e401,

    Если команда ввода на основании создается автоматически, тогда надо в объекте Ввод на основании убрать документ, для которого хотите подменить команду на свою.

    далее добавляете свою команду и реализуете то что писал выше

    Reply
  4. AleksSF

    Если использовать БСП, то можно еще проще.

    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // СтандартныеПодсистемы.ВерсионированиеОбъектов
    ВерсионированиеОбъектов.ПриСозданииНаСервере(ЭтаФорма);
    // Конец СтандартныеПодсистемы.ВерсионированиеОбъектов
    Если Объект.Номер = «» Тогда
    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ
    | СвязанныеДокументы.Ссылка
    |ИЗ
    | КритерийОтбора.СвязанныеДокументы(&ТекущийДокумент) КАК СвязанныеДокументы»;
    
    Запрос.УстановитьПараметр(«ТекущийДокумент», Объект.Основание);
    РезультатЗапроса = Запрос.Выполнить();
    Если Не РезультатЗапроса.Пустой() Тогда
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = «Это выполнение ЗАКРЫТО » + ВыборкаДетальныеЗаписи.Ссылка;
    Сообщение.Поле = «»;
    Сообщение.УстановитьДанные(ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект());
    Сообщение.Сообщить();
    Отказ = Истина;
    КонецЦикла;
    Возврат;
    КонецЕсли;
    Если Объект.Основание.ДатаВыполнения <> ‘00010101’ Тогда
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = «Закрывать можно только выполненную заявку»;
    Сообщение.Сообщить();
    Отказ = Истина;
    Возврат;
    КонецЕсли;
    КонецЕсли;
    // Если документ введен на основании, то запретим редактировать основание
    Если Не Объект.Основание.Пустая() И Объект.Проведен Тогда
    Элементы.Основание.ТолькоПросмотр = Истина;
    Иначе
    Элементы.Основание.ТолькоПросмотр = Ложь;
    КонецЕсли;
    Если Объект.Ответственный = Справочники.Пользователи.ПустаяСсылка() Тогда
    Объект.Ответственный = ПараметрыСеанса.ТекущийПользователь;
    КонецЕсли;
    КонецПроцедуры
    

    Показать

    Reply
  5. artik1994

    зачем все эти заморочки из бочки???

    для нас упростили жизнь и создали конструктор ввода на основании…

    смиритесь и пользуйтесь с удовольствием

    Reply
  6. e401

    (5) artik1994,

    Вы не поняли суть: Используя типовой «Ввод на основании» создать новый документ. Если таковой уже создан, то открыть существующий, а не выводить сообщение о том, что такой документ уже создан.

    Reply
  7. cheiser1982

    Предлагаю по этой теме посмотреть статью: http://infostart.ru/public/636444/

    Для Вашего первого опыта все не плохо, просто некоторых нюансов не предусмотрено…

    Reply
  8. e401

    Спасибо, посмотрю

    Reply

Leave a Comment

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