Хранение настроек внешних отчетов на СКД в 1С




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

60 Comments

  1. Kochevnic

    Спасибо! Опробуем

    Reply
  2. mikl79

    спасибо полезная вещь

    Reply
  3. MYRZILKA123

    надо попробовать…

    Reply
  4. Il

    Спасибо! Работает!

    Reply
  5. netserfer

    Всё гениальное просто, всё сложное не нужно (с)М.Калашников 🙂

    Reply
  6. ligailnet

    Спасибо!

    Reply
  7. Dunga

    Прикольно!!!

    Reply
  8. Dunga

    А как хранить настройки в файле в отчетах не СКД.

    Reply
  9. psamt1k

    Как любит говорить один мой друг: то, что дохтур прописал!

    Спасибо!

    Reply
  10. Istur

    (8) Полностью аналогично. Настойки хранятся в ресурсе «СохраненнаяНастройка» с типом «Хранилище значения». У меня хранится там КомпоновщикНастроек.Настройки, но там может храниться все, что угодно. Структура, ТаблицаЗначения и т.д. По коду мне кажется вполне должно быть понятно, где и что заменять.

    Reply
  11. echo77

    Экспортные процедуры типовых отчетов на СКД:

    СохранитьНастройку()

    ПрименитьНастройку()

    не спасут отца русской демократии?

    Reply
  12. Istur

    (11) Да, можно было бы брать и оттуда, тогда бы сохранение происходило в справочник. Но там не чисто эти 2 процедуры, а из них вызываются еще и другие процедуры. И плюс открытие и закрытие, надо смотреть как там. Реализация через регистр мне показалась проще, чем вычленять код из модуля. В данном модуле все сделано универсально, поэтому брать что-либо достаточно сложно, пришлось бы много удалять.

    Reply
  13. echo77

    (12) я не пойму — вы свою подсистему пишете с нуля? Или же создаете функционал сохранения/загрузки настроек для типовых отчетов?

    Reply
  14. Istur

    (13) второе. Точнее нет, функционал загрузки/сохранения для внешних отчетов, не типовых.

    Reply
  15. echo77

    (14) Судя по скриншотам(панель ваиратов отчета и т.д.) вы делаете это для своих отчетов постронные на базе шаблона типового отчета (Статья ИТС «Разработка отчетов при помощи универсального механизма «Шаблон типового отчета»»)

    Reply
  16. Istur

    (15) нет. панели вариантов там нет. там есть самая обычная командная панель, на которую вынесены кнопки сохранения и восстановления настроек. второе. я не делаю массово это для своих отчетов. один раз на работе нужно было так сделать, на форме должен быть только отбор, поэтому шаблон СКДшный использовать нельзя было. а так у нас на работе есть сделанный на основе типового шаблон отчета, мы используем всегда его. Да и другим рекомендую строить отчеты на шаблоне.. вот не знаю как его назвать. На нем еще отчет построен «План-фактный анализ себестоимости выпуска» в УПП. Поэтому даже не знаю когда придется так делать еще раз. Но думаю рано или поздно придется. На ИТС статью не читал, завтра на работе почитаю. Будет обидно, если там уже все описано.

    Reply
  17. sanjabor

    Если отчет разрабатывается с нуля, можно за основу взять шаблон типового отчета с ИТС. Там в основном нужно только свою СКД и настройки вывода задать.

    ЗЫ Описанные настройки можно применять и к внешним обработкам. Плюсы — те же.

    Reply
  18. Istur

    (17) Я как раз выше распинался что вполне прекрасно знаю о этом отчете. И там же написал, что для решения той конкретной задачи его использование не подходило.

    Reply
  19. angellbroken

    Помоему очень удобная штука)

    Reply
  20. opiumdx

    Спасибо, полезная вещь.

    Reply
  21. Il

    И еще плюсик — можно настройки отчета копировать под конкретного пользователя!

    Reply
  22. dtitov

    Спасибо, очень вовремя.

    Reply
  23. Silvice

    Спасибо, помогло.

    Reply
  24. angler225

    Спасибо, толковая вещь.

    Reply
  25. lsp71

    1. Спасибо за идею и за открытый код.

    2. Интересно, зачем 1С создала 2 разных механизма для одной и той же цели (сохранение/восстановление настроек)?

    Reply
  26. l-Rain

    Спасибо большое! Пригодилось.

    Reply
  27. red80

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

    Reply
  28. Alex141516

    хочу предупредить на всякий случай, а то в инете есть люди которые мучаются вопросом типа почему в запросе есть поле, а в скд оно не выводится (хотя в настройках самого скд оно есть)? в случае если отчет или обработка с использованием скд у вас дорабатывается в процессе, чтобы не попасть в полные непонятки — нужно сбрасывать настройки пользователя после обновления отчета, можно не все, а именно то что касается изменений, я в отчете делаю переменную «версия отчета» и если она у пользователя не совпадает с текущей — сбрасываю настройки пользователя и уведомляю его.

    Reply
  29. unoDosTres

    спасибо за открытый код, весьма эффективное решение

    Reply
  30. ogion

    2 дня искал и вот оно! Спасибо, добрый человек.

    Reply
  31. KlintuhovDE

    Спасибо автору! пригодилось )

    Reply
  32. TeMochkiN

    Замечательное решение, только у меня при закрытии формы автоматически почему-то не сохраняет настройки либо некорректно сохраняется, а при открытии замечательно автоматически восстанавливается настройка, сохраненная вручную

    релиз УПП 1.3.44.1

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

    Reply
  33. TeMochkiN

    Во, добавил одну строчку и заработало:

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

    Показать

    Reply
  34. kernelio

    Спасибо! пригодилось )

    Reply
  35. sternu

    Спасибо огромное, помогло в УПП! А то один пользователь замучил с настройками внешнего отчета, сама не умеет настроить отчет и 1С периодически забывала настройки, а мне не улыбается регулярно по пол-часа по телефону восстанавливать все варианты настроек отчета заново 🙂

    Reply
  36. svilsa

    Спасибо, пригодилось для внешнего отчета, в котором необходимо дать пользователю возможность подсмотреть «Настройки всех пользователей».

    Reply
  37. imozg

    Спасибки!

    Reply
  38. 6630

    Спасибо автору. Работает.

    Reply
  39. Sniper9mm

    Огромное спасибо!!!

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

    Возьму на вооружение. +1

    Reply
  41. Andrekaa

    помогло, спасибо

    еще бы такой же пример для ПостроителяОтчетов

    Reply
  42. PVG_73

    Спасибо, сам начал было сие, но забросил… 🙂

    Reply
  43. a.rezyhin

    Спасибо! Очень нужная статья!

    Reply
  44. buch_n

    Спасибо

    Reply
  45. docerman

    Вот спасибо. Просто спас).

    Reply
  46. Chrizt

    Под управляемые формы в толстом клиенте на 8.2 пришлось немножко переделать, но получилось.

    Спасибо, автор!

    Reply
  47. Lilia

    Спасибо огромное! Мучение с настройками внешних отчетов закончилось!

    Reply
  48. Gary077

    Спасибо! То что нужно!

    Reply
  49. rpgshnik

    Спасибо огромное!

    Reply
  50. AMS_Guskov_VL

    8.3 толстый клиент, не работает. Формы с настройками сохранения и восстановления появляются, список настроек сохраняется. Сами настройки не восстанавливаются. Отличия у меня только рисунки на кнопках сохранения и восстановления, таких рисунков не нашел, переопределить стандартные кнопки тож не сумел. Штука полезная подскажите как пользоваться?

    И в регистре сведений «Сохраненные настройки» сорока появляется.

    Reply
  51. Red_Devil

    Автор ты бы упомянул что в модуле необходимо объявить твою переменную Перем мТекущаяНастройка;

    Reply
  52. Red_Devil

    удалено.

    Reply
  53. user595031_fagosor

    Автору СПАСИБО, пригодилось :)!

    Reply
  54. EvgenS

    Подскажите как можно поместить в настройки табличные части у которые в настройках формы указаны как сохраняемые значения.

    Наверное вместо этой строки

    СохраненнаяНастройка = Новый ХранилищеЗначения(КомпоновщикНастроек.ПолучитьНастройки());

    мне нужно поместить табличные части, подскажите как это сделать?

    Reply
  55. Tapochki-tmn

    При написании обработки обмена добавил форму для установки/сохранения параметров обмена и разместил на форме поля ввода.

    В обработчике «ПриИзменении» этих полей навесил процедуру «ЗначениеНастройкиОбменаПриИзменении»:

    Процедура ЗначениеНастройкиОбменаПриИзменении(Элемент)
    ТиповыеОтчеты.УстановитьПараметр(КомпоновщикНастроек, Элемент.Имя, ЭлементыФормы[Элемент.Имя].Значение);
    КонецПроцедуры

    При закрытии формы, с учетом добавленной строки, как указано выше в 33 комменте…

    мТекущаяНастройка.Вставить(«СохраненнаяНастройка», Новый ХранилищеЗначения(КомпоновщикНастроек.ПолучитьНастройки()));

    …измененные значения параметров сохраняются в регистре и восстанавливаются при открытии формы:

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

    Показать

    Можно использовать типовую функцию:

    ТиповыеОтчеты.ПолучитьПараметр(КомпоновщикНастроекКоллекцияЗначений, ИмяПараметра)
    Reply
  56. Tapochki-tmn

    (50)

    Ты уже наверняка разобрался, но для кого-то может оказаться полезным:

    Кнопки сохранения/восстановления создавал сам на панели, и навесил указанные обработчики.

    После копирования процедур ПриОткрытии() и ПриЗакрытии() не забываем еще раз указать форме, что у нее эти обработчики есть путем выбора этих обработчиков в свойствах формы.

    Для восстановления настроек надо чтобы они сохранились.

    У автора ошибочка в процедуре ПриЗакрытии(), забыл или не посчитал нужным указать строку:

    Если мТекущаяНастройка <> Неопределено И мТекущаяНастройка.НаименованиеНастройки <> Неопределено

    И мТекущаяНастройка.Свойство(«СохранятьАвтоматически») И мТекущаяНастройка.СохранятьАвтоматически Тогда

    мТекущаяНастройка.Вставить(«СохраненнаяНастройка», Новый ХранилищеЗначения(КомпоновщикНастроек.ПолучитьНастройки())); //потому, что значения настроек схемы СКД могли поменяться, а в настройке значения полученные при открытии формы

    Где должна располагаться эта строка уже показали в комменте 33.

    Может это все к твоему случаю и не относилось, но пусть будет тут 😉

    Reply
  57. tinkerbell

    Спасибо, пригодилось!

    Reply
  58. echo77

    Еще вот такая вещь есть: https://infostart.ru/public/623328/

    Reply
  59. UserPro

    Плюсую.

    Reply
  60. amigozzz1@gmail.com

    Идеально. Автор, Спасибо !

    Reply

Leave a Comment

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