СКД-отборы списков на обычных и управляемых формах




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

28 Comments

  1. fomix

    Описания явно не хватает! Рассчитано на подготовленного пользователя, уже умеющего работать с управляемыми формами.

    Только сегодня на сайте » » вышли видеоуроки по применению СКД для реализация универсальных отборов . Привожу ссылку на страницу http:// /news/2016-04-28-skd-free-video/. Привожу здесь не в качестве рекламы, а для изучения…

    Reply
  2. fixin

    (1) ну батенька это мастер-класс, для тех, кто уже знает СКД и хочет на ее основе крутить фортеля. Не для новисов, да.

    Выстрадано на своей шкуре. В свое время делал на обычных формах, на СКД пришлось повозиться.

    Reply
  3. fomix

    (2) Аналогично, дружище!

    Reply
  4. Трактор

    Ничего исправлять ненадо. Кратко, только суть. Видео, которое тут рекламируют занимает гораздо больше времени на просмотр, чем чтение этой статьи и обрывается на самом интересном месте.

    fixin, если придут тебя бить — зови, помогу 🙂 Тебе помогу, не им.

    Reply
  5. Prometeus2011

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

    ОтборСтрок = <ТабличнаяЧастьИсточник.ОтборСтрок>;
    ПостроительЗапроса = Новый ПостроительЗапроса;
    ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличнаяЧастьИсточник);
    // Добавляются необходимые отборы, такие же как в отборы в табличной части.
    Для Каждого ЭлементОтбора Из ОтборСтрок Цикл
    Если ЭлементОтбора.Использование Тогда
    НовыйОтбор = ПостроительЗапроса.Отбор.Добавить(ЭлементОтбора.Имя);
    НовыйОтбор.Использование = Истина;
    НовыйОтбор.ВидСравнения = ЭлементОтбора.ВидСравнения; // нужный вид сравнения
    НовыйОтбор.ЗначениеС = ЭлементОтбора.ЗначениеС;
    НовыйОтбор.ЗначениеПо = ЭлементОтбора.ЗначениеПо;
    НовыйОтбор.Значение = ЭлементОтбора.Значение;
    КонецЕсли;
    КонецЦикла;
    
    ПостроительЗапроса.Выполнить ();
    
    Результат = ПостроительЗапроса.Результат; // отобранные строки типа РезультатЗапроса

    Показать

    Источник — не помню.

    Reply
  6. Prometeus2011

    Да, вот то-же самое с построителем отчета.

    1. Добавляем на форму реквизит с типом «ПостроительОтчета» и назовем его так-же «ПостроительОтчета».

    2. На форму кладем ЭУ типа «Табличное поле», звать — как хотите. Источником данных у элемента управления назначаем наш реквизит формы «ПостроительОтчета».

    В модуль формы:

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

    Показать

    Такое кунг-фу в групповой обработке на обычных формах юзалось эффективно достаточно.

    Понятно, что работать будет только на обычном приложении.

    p.s. Процедурку УстановитьСтруктуруНастроекДляВыводаВТаблицуСКолонкойСсылка(Настройки) можно не вызывать, а структуру вывода в ТЗ запаять прямо в схему макета СКД (это я про вариант автора).

    Reply
  7. rozer

    (2) небольшое замечание:

    Судя по описанию «ОтборКонтрагентов» это «реквизит формы»


    В форму добавляем реквизит «ОтборКонтрагентов» типа «КомпоновщикНастроекКомпоновкиДанных».

    А не объекта. И тогда так не сработает …


    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    ….

    ОО.ОтборКонтрагентов.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(URLСКД));

    НастройкиПоУмолчанию = СКД.НастройкиПоУмолчанию;

    ОО.ОтборКонтрагентов.ЗагрузитьНастройки(НастройкиПоУмолчанию);



    КонецПроцедуры

    Но так будет работать…

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

    Показать

    Reply
  8. dusha0020

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

    Reply
  9. fixin

    (9) я недавно делал клиенту задачку с отбором по сотрудникам, сам нашел в интернете эту свою статью и заюзал. крутой отбор получился, а то бы пришлось делать убожество со списком сотрудников, например.

    Reply
  10. catlina

    Подскажите, а если в отборе должно быть два справочника по контрагентам и статьям затрат. Есть ли пример, когда в запросе не один справочник, а несколько?

    Reply
  11. fixin

    (11) два отбора на форму можно. Или один отбор с несколькими полями. Тоже вариант.

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

    Показать

    не работает

    {ВнешняяОбработка.РаботаСДеревом82_1.Форма.Форма.Форма(87,5)}: Переменная не определена (ЭтотОбъект)

    <<?>>ЭтотОбъект.ОтбиратьПроекту.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(URLСКД)); (Проверка: Толстый клиент (обычное приложение))

    Reply
  13. German_Tagil

    разобрался

    Reply
  14. _Enot_

    (10)подскажи как выгрузить теперь значения из отбора на форму (УП)?

    Reply
  15. _Enot_

    подскажите как выгрузить теперь значения из отбора на форму (УП)?

    Reply
  16. koln

    В своей статье Вы пишите: «Размещаем созданный реквизит на форме перетаскиванием поля «КомпоновщикНастроекКомпоновкиДанных.Отбор» на форму». Объясните, пожалуйста, какое именно поле на скрине нужно перенести на форму?

    Reply
  17. _baa_

    (17)

    Отбор из ветки «Настройки»

    Reply
  18. koln

    (18) При добавлении данного поля на форму в виде таблицы и проведения корректировок, как указано в статье (заголовок и т.п.) получается форма следующего вида (в конфигураторе и пользовательском режиме, как показано на скринах). После добавления кода получения настроек из макета СКД ничего не меняется. В чем может быть проблема?

    Reply
  19. fixin

    А получается по нажатиб insert добавить новый отбор в режиме 1с:предприятия?

    Надеюсь, вы для добавленного отбора прописали скд, как в примере?

    Reply
  20. koln

    (20) Макет добавлен, код есть до того момента, чтоб вывести список настроек, как у Вас, но сам список не выводит. По кнопке Insert строку отбора добавляет и значение дает выбирать из справочника «Контрагенты».

    Reply
  21. fixin

    (21) оформите в виде внешней обработки и прикрепите здесь, я посмотрю.

    Reply
  22. koln

    (22) Высылаю обработку

    Reply
  23. fixin

    (23) Вот, поправил.

    В СКД_Контрагенты зайдите на закладку Настройки, затем Отбор и добавьте те условия, которые хотите видеть.

    Reply
  24. koln

    (24) Да, так получилось. Просто в статье не сказано, что предварительно нужно в макете отборы настроить. Спасибо!

    Reply
  25. fixin

    (25) да, этот момент упущен в статье.

    Reply
  26. acanta

    Спасибо большое. А в тонком или веб клиенте работает?

    Reply
  27. fixin

    (27) разумеется работает, механизмы то штатные.

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

Leave a Comment

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