Получение списка родительских и подчиненных документов из структуры подчиненности




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

23 Comments

  1. AJlEKCA

    не во всех конфигурациях есть модуль «ПолныеПрава»

    Reply
  2. Bezeus

    Кстати, верное замечание. Или перетащи функцию ПолучитьВыборкуПоКритериюОтбор() к себе, или сам напиши.

    Reply
  3. bursanb

    Самое оно! В Комплексной модуль «ПолныеПрава» есть, т.ч. мне подходит.

    Reply
  4. LexBG

    В БП 3.0 модуля ПолныеПрава нет, а жаль очень полезная функция была бы

    Reply
  5. heavymetal
    Reply
  6. sahn

    В БП 3.0 модуля ПолныеПрава нет, а жаль очень полезная функция была бы. Нет модуля. Используй УстановитьПривилегированныйРежим(Истина)

    Reply
  7. heavymetal

    (6) sahn, кстати да. В управляемом приложение необходимо использовать данную функцию «УстановитьПривилегированныйРежим(Истина)». В обычном же приложение положить эти функции в общий модуль с привилегированным режимом выполнения на сервере.

    Reply
  8. 1CSoft

    Использовал функции без доработок в обработке групповой печати документов реализации для получения связанных с документами «Реализация товаров и услуг» счетов, заказов и налоговых накладных.

    Все работало без замечаний благодарность автору!

    Reply
  9. v777k

    Спасибо за статью, очень выручила!

    Reply
  10. zmaxp

    Очень полезная статья. Большое спасибо

    Reply
  11. vgstepanov

    Функции для получения списка подчиненных документов можно реализовать так:

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

    Показать

    Reply
  12. vesta60

    Спасибо большое, Сэкономила кучу времени. Пришлось в акт инвентаризации добавлять суммы из документа списание.

    Reply
  13. smellofsky

    Большое спасибо за подаренное время! Автору респект 🙂

    Reply
  14. alexisalserv

    Большое спасибо

    Reply
  15. Светлый ум

    Пример теста функции на внешней обработке — упр. формы (заменяйте СсылкаНаОбъект на свои документы)

    Reply
  16. echo77

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

    https://yadi.sk/i/e9IAtTyEy9Xng

    Reply
  17. morgershtern

    Спасибо! очень полезно. Использовал при групповом создании документов наряда на основании заказов.

    Reply
  18. Just

    (15) А где ?

    МойМодуль2.ПолучитьРодительскиеДокументы(Объект.СсылкаНаОбъект, Неопределено, Неопределено);

    Reply
  19. avz_1C

    Спасибо, дорогой товарищ.

    Поставил «плюсик».

    Reply
  20. Batman

    Спасибо

    Reply
  21. SurmachAU

    Спасибо огромное. Встретила Ваши функции на новой работе. Программист не поленился и написал ссылку на Вашу статью. Очень хорошая тема для развития.

    Reply
  22. kaps22

    Спасибо добрый человек!!! ВСЕ РАБОТАЕТ!!!

    Reply
  23. shulya83

    если кому интересно разобраться с этой темой то в каждой конфигурации есть общая форма «Структура подчиненности» в ней есть все актуальные процедуры и функции по этой задаче.

    Reply

Leave a Comment

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