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




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

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 не будет опубликован. Обязательные поля помечены *