Использование методов глобального контекста в системе компоновки данных или недокументированные возможности СКД




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

38 Comments

  1. aka Любитель XML

    Спасибо, хорошая статья

    Reply
  2. tindir

    ага. опять какой-то разраб написать написал, а документацию не догнали. кстати, как там в спавке по поводу ВычислитьВыражение(Выражение, Группировка, ТипРасчета, Начало, Конец, Сортировка, ИерархическаяСортировка, ОбработкаОдинаковыхЗначенийПорядка)? в последнем релизе нет. Мне 1с по качеству и обьемному наполнению справки все чаще начинает напоминать оупень-сорсь, но платный. и если у тебя в node нет мануала к модулю, то всегда можно почитать исходник, а как быть с http в 1с, если тебе нужно что-то сложнее халовордия….

    Reply
  3. Yashazz

    Автор, на каком релизе проверял? Сдаётся мне, это фича из новых, или нестабильно работающих, как всё недокументированное.

    Reply
  4. klinval

    (3) Yashazz,

    Автор, на каком релизе проверял? Сдаётся мне, это фича из новых, или нестабильно работающих, как всё недокументированное.

    В статье специально написал:

    на платформе «8.3.8.1652» в тонком клиенте

    На форуме люди писали, что на 8.3.8.1784 работает. Будет 1С-ка под рукой — опробую ещё на каком-нибудь релизе, статью дополню по результатам. Если уже кто-то уже опробовал: просьба отписываться в комментах!

    Ещё отправил в ТП письмо, они уже переслали разработчикам. Пока ответа нет… Будет ответ — дополню статью, чтобы понимать что это: недоработка документации или функции работающие в тестовом режиме.

    Reply
  5. karpik666

    хм, может конечно я что-то путаю, но данный функционал был доступен всегда, еще по бесплатным курсам Гилева говорилось, что в скд в параметр или вычисляемых полях можно использовать функции 1с, а также функции общих модулей, исполняемых на сервере, однако делать это не рекомендуется так как по сути выполняется код в цикле, и если это будет обращение к базе данных, то это сильно замедляет работу.

    Reply
  6. klinval

    (5) karpik666,

    еще по бесплатным курсам Гилева говорилось, что в скд в параметр или вычисляемых полях можно использовать функции 1с

    Какие именно функции? Какого раздела справки? Я проверял только методы глобального контекста и они работают далеко не все.

    Если эти методы уже давно работали то тогда есть ряд вопросов:

    1. Какого года курсы Гилева, и какая тогда платформа была? Если тогда ещё всё работало, то почему сейчас не работает «СокрЛП»?

    2. Если ещё тогда всё работало, почему в справке ни слова за эти годы не появилось?

    3. Опять таки почему такие ненужные в СКД вещи как ПолучитьИнформациюЭкрановКлиента() работают, а нужные, типа СокрЛП не работают?

    Как по мне больше вероятности что функции заработали в СКД случайно: может некоторые методы «причесали» под какой-нибудь общий формат, благодаря чему они стали доступны сразу в 2 местах: из кода и из СКД. А иначе как объяснить то, что действительно нужные методы не работают, а ненужные работают? Если бы это была системная работа, то логичней сначала заставить работать СокрЛП в СКД.

    Чтобы не гадать подождём что разработчики скажут…

    Reply
  7. klinval

    Проверил на «8.3.7.1845» и «8.3.6.2390» в файловом режиме. Статью обновил.

    Reply
  8. karpik666

    (6) вот про эти курсы говорил http://www.spec8.ru/kurs-po-skd-besplatno

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

    А вот, что нашел про использование функций «ТекущаяДата()» и «значениеЗаполнено()», они вообще доступны с релиза 8.2.14 http://1cskd.ru/2011/07/novye-funkcii-skd-8-2-14/

    Reply
  9. klinval

    (8) karpik666,

    вот про эти курсы говорил http://www.spec8.ru/kurs-po-skd-besplatno

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

    Потом качну/посмотрю. А точно 21 урок? Я вроде по порядку подсчитал: 21 это «Возможности упорядочивания в отчетах». Вы наверное имели ввиду «Вычисляемые поля»?

    А вот, что нашел про использование функций «ТекущаяДата()» и «значениеЗаполнено()», они вообще доступны с релиза 8.2.14 http://1cskd.ru/2011/07/novye-funkcii-skd-8-2-14/

    Про текущую дату уже писал в статье, что про неё есть упоминания в ИТС, но нет в справке. Посмотрел про «ЗначениеЗаполнено» — оказывается есть в справке. Статью поправил, ЗначениеЗаполнено зачеркнул. Так что не удивительно, что они уже давно работают: один я не заметил в справке, другой есть в доках на ИТСе.

    Я не спорю: вполне возможно всё это работает уже давно, просто когда-то кто-то забыл внести это в справку. Т.е. методы уже годами работают, только никто об этом не знает… Может они не внесены в справку, т.к. официально находятся в тестовом режиме. Мы можем только гадать. Будет ответ от ТП — отпишусь.

    Reply
  10. karpik666

    (9) точно 21, но там описывается именно про «Выражение упорядочивания» в параметрах, и как в них использовать общие модули.

    Reply
  11. Synoecium

    Сделал в глобальном модуле такую функцию:

    Функция глВыполнитьПроизвольныйКод(Арг, ТекстКода,Результат=0) Экспорт

    Выполнить(ТекстКода);Возврат Результат;

    КонецФункции

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

    Reply
  12. karpik666

    (11) Synoecium, Например такой?

     Для Каждого лРегистр Из Метаданные.РегистрыНакопления Цикл
    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ Различные
    | Регистр.Регистратор
    |ИЗ
    | РегистрНакопления.» + лРегистр.Имя + » КАК Регистр»;
    лВыборка = Запрос.Выполнить().Выбрать();
    лНаборЗаписей = РегистрыНакопления[лРегистр.Имя].СоздатьНаборЗаписей();
    Пока лВыборка.Следующий() Цикл
    лНаборЗаписей.Отбор.Регистратор.Установить(лВыборка.Регистратор);
    лНаборЗаписей.Записать();
    КонецЦикла;
    КонецЦикла;
    

    Показать

    Reply
  13. klinval

    (10) karpik666, посмотрел 21/22 «Возможности упорядочивания в отчетах» , 20/21 Представление полей компоновки в отчете»и 24/25 «Вычисляемые поля» — там этого нет… Зато есть в 15/16 «Функции выражений компоновки данных» про текущую дату и значение заполнено.

    Но оба этих метода объяснимы: ЗначениеЗаполнено — я не заметил, что оно уже есть в справке, а то что ТекущаяДата() работает на СКД — есть упоминание на ИТСе.

    Попробую проверить на 8.2 что ещё работает. Отпишусь как проверю

    //10.08.16 9:38

    Проверил: естественно не заработали методы которых физически не было в на той платформы типа «СтрНайти» (и даже «найти» не заработало), «ТекущийВариантИнтерфейсаКлиентскогоПриложения» и т.д. А остальные заработали.

    //9:43

    По результатам проверки обновил статью.

    Reply
  14. klinval

    (11) Synoecium, да это понятно. Функции общих модулей уже давно можно было использовать! Вот только что делать если нужно, например «ЧислоПрописью», а база на поддержке? Или пишешь что-нибудь универсальное для публикации на ИС (или для продажи): в инструкции писать, что базу обязательно надо снять с поддержки и внедрить такой-то модуль с таким-то текстом?

    А если база своя то можно где-то обойтись и функциями общих модулей — тут согласен. Правда не всегда это будет оптимально в плане производительности.

    Reply
  15. Synoecium

    (12) karpik666, практически любой, но если получать метаданные и вертеть запросы для каждой записи СКД, то будет очень тормозить (если их много конечно)

    Reply
  16. starik-2005

    Даже экспортные функции и даже на 8.2 работают. Так что не понимаю, в чем новизна статьи.

    Reply
  17. klinval

    (16) starik-2005,

    Даже экспортные функции и даже на 8.2 работают

    Уже который раз пишу: да уже давно работают функции общих модулей. Я это нигде не отрицал и не представлял как своё открытие.

    Так что не понимаю, в чем новизна статьи.

    Покажите мне место в документации или на ИТС, где написано, что, например, ЧислоПрописью работает в СКД? Нигде этого нет, хотя метод работает ещё с 8.2.

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

    Reply
  18. karpik666

    (15) Synoecium, это был сарказм, оставлять метод «ВыполнитьПроизвольныйКод», да и еще и экспортный это огромная уязвимость. такой простенький код как мой может просто уничтожить данные в базе, наверное вишенкой такого метода можно еще выполнять передаваемый код в привилегированном режиме. Если уж хотите выполнять какой-то код из модуля, то лучше передавать наименование метода, и параметры к нему, и обрабатывать его уже в коде. А от вашего способа лучше воздержаться.

    Reply
  19. vec435

    (12) karpik666, а можно передать в эту функцию значение поля конкретной записи как какой-нить параметр?

    Reply
  20. progr-2008

    Интересно как дополнение к курсам.

    Reply
  21. klinval

    (18) karpik666, согласен, что

    «ВыполнитьПроизвольныйКод», да и еще и экспортный это огромная уязвимость

    Единственное, что хотел добавить: СКД на некоторый код пишет ошибку <Установлен безопасный режим. Выполнение операции запрещено> даже если встроить отчет в БД или добавить во внешние обработки с БезопаснымРежимом=Ложь. Соответственно код в привилегированном режиме из СКД работать не будет, т.к. видимо любой код в вычисляемых выражениях принудительно работает в безопасном режиме и это не отменить.

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

    Reply
  22. Synoecium

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

    Reply
  23. Synoecium

    (14) вообще да, согласен. Глобальные методы из коробки — хорошее подспорье для внешних отчетов например. Так что плюс)

    Reply
  24. tiniji

    (2) tindir, Эта информация есть в режиме 1С Предприятие. В конфигураторе такого нет про СКД.

    Reply
  25. klinval

    Пришёл ответ от разработчиков (далее цитирую):

    Ответ от разработчиков:

    В выражениях компоновки данных можно использовать функции общих модулей и функции глобального контекста.
    Reply
  26. herfis
    В выражениях компоновки данных можно использовать функции общих модулей и функции глобального контекста.

    Может, они имеют в виду — при включенном режиме использования функций общих модулей? Потому что иначе это противоречит твоим исследованиям. Глобальный контекст доступен очень ограниченно.

    Результаты сабжевого исследования очень похожи на непреднамеренное «просачивание» контекста в связи с какими-то доработками СКД. Поэтому я почти уверен, что разработчики сами достоверно не знают чего там нового доступно стало в конексте выражений СКД, так как это побочный эффект а не целенаправленный.

    Reply
  27. klinval

    (26) herfis, ну да, тот же СокрЛП не работает, хотя тоже функция глобального контекста. Т.е. их ответ явно не полный.

    Результаты сабжевого исследования очень похожи на непреднамеренное «просачивание» контекста в связи с какими-то доработками СКД. Поэтому я почти уверен, что разработчики сами достоверно не знают чего там нового доступно стало в конексте выражений СКД, так как это побочный эффект а не целенаправленный.

    У меня это тоже основная версия, но никто кроме разработчиков платформы её подтвердить или опровергнуть не может…

    Reply
  28. German_Tagil

    надо запомнить

    Reply
  29. kasper076

    Мин(), Макс() тож не робят.

    Reply
  30. echo77

    (30) Оно и не надо, вместо них есть агрегатные функции Минимум() и Максимум()

    Reply
  31. kasper076

    (28) 1С:Предприятие 8.3 (8.3.10.2466) Синтаксическая ошибка «XMLСтрока». Что я делаю не так?

    Reply
  32. kasper076

    (32) (28) В консоли СКД не работает. А если встроить в базу, то работает. Мож конечно консоль кривая.

    Reply
  33. Aphanas

    (33) У меня здесь работает во внешнем отчете

    https://infostart.ru/public/548198/

    Reply
  34. kasper076
    Reply
  35. Aphanas

    (35) В строке

    «ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровкиОбъект, Ложь);»

    процедуры «Команда1НаСервере», вместо «Ложь» нужно поставить «Истина».

    ПроцессорКомпоновкиДанных (DataCompositionProcessor)

    Инициализировать (Initialize)

    Синтаксис:

    Инициализировать(<Макет>, <ВнешниеНаборыДанных>, <ДанныеРасшифровки>, <ВозможностьИспользованияВнешнихФункций>)

    Параметры:

    <Макет> (обязательный)

    Тип: МакетКомпоновкиДанных.

    Макет, для которого будет выполняться компоновка.

    <ВнешниеНаборыДанных> (необязательный)

    Тип: Структура.

    Ключ структуры соответствует имени внешнего набора данных. Значение структуры — внешнему набору данных.

    <ДанныеРасшифровки> (необязательный)

    Тип: ДанныеРасшифровкиКомпоновкиДанных.

    Объект, в котором нужно заполнить данные расшифровки. Если не указан, то расшифровка заполняться не будет.

    <ВозможностьИспользованияВнешнихФункций> (необязательный)

    Тип: Булево.

    УКАЗЫВАЕТ ВОЗМОЖНОСТЬ ИСПОЛЬЗОВАНИЯ ФУНКЦИИ ОБЩИХ МОДУЛЕЙ КОНФИГУРАЦИИ В ВЫРАЖЕНИЯХ КОМПОНОВКИ ДАННЫХ.

    Значение по умолчанию: Ложь.

    Reply
  36. kasper076

    (36) огромное спасибо. Все оказывается документировано, просто нужно не лениться читать. Еще раз спасибо.

    Reply
  37. Aphanas

    (37) Рад помочь

    Reply
  38. KAV2

    (28)Но только этот способ получения уникального идентификатора не явуляется способом получения в запросе 🙂

    Reply

Leave a Comment

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