Работа с предопределенными элементами в 8.3




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

29 Comments

  1. bulpi

    Вопрос разработчикам : ну и на хрена все это было делать ?

    Reply
  2. Патриот

    (1) bulpi, они заботятся, чтобы у рядовых программеров было больше работы и мы не вымерли с голоду =)

    Reply
  3. alex_4x

    И зачем 1С все эти заморочки придумала с предопределенными элементами? Я считаю что это вообще ненужный механизм. Также как и константы. А за статью большое спасибо!

    Reply
  4. nSpirit2

    (4) Идеология платформы в наконец то двигается в правильном направление. У 1с нет опыта разработки сложных конфигураций? о_0 По моему изменения вполне логичны.

    Reply
  5. alex_4x

    (8) nSpirit2,

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

    Метод «табличная часть», регистр сведений, регистр накопления — оправданы.

    а создание специальных методов для каждого чиха только плодит глюки и нестыковки.

    что такое предопределенные значения — это значения коллекции, которые на момент разработки, закладываются в решение, как присутствующие. Что мешает хранить такие значения в регистре сведений, как связь константы и элемента справочника? Это было бы проще, понятней и предсказуемей. Обработка незаполненных значений и вопросы репликации — решались бы в рамках общей парадигмы.

    Reply
  6. nSpirit2

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

    Не правильно вы к этому относитесь как внедренец собственно. Предопределенный элемент это именованная ссылка. Это необходимо для тех кто сам пишет конфигурации потому что наверняка вам не приходилось добавлять предопределенные элементы в типовые справочники. Если честно то сам считаю механизм предопределенных очень глупым и стараюсь не использовать его в коде. Но 1С вполне логично дает возможность изменения всего из режима предприятия для для еще более гибкой настройки.

    Reply
  7. alex_4x

    «Для еще более гибкой настройки» это выливается в косяки ради не пойми какой выгоды.

    Если решение настраиваемо в рамках рантайма — никто не мешает сделать форму для заполнения того же самого регистра сведений, причем там можно запрограммировать нужные проверки и всё что душе угодно. То есть на качество возможностей кастомизации применение «предопределенных значений» положительно не влияет. А вот «видимость возможности настройки с кучей подводных камней, делающей эту возможность глючной и геморройной» — да, появляется. Фактически разработанный механизм — искусственный источник проблем и ошибок, которых можно было бы избежать, просто правильно применяя универсальные механизмы, уже заложенные в платформу.

    Reply
  8. nSpirit2

    (13) alex_4x, Сам механизм именования ссылок конечно кажется выраженным на первый взгляд но полезность его весьма интересна. Представим обстрактную ситуацию у вас есть Предопределенный элемент который используеться в движениях. Настал момент и вам нужно вместо него использовать другой и что делать лезть в конфигуратор и там менять код? А если механизм из типовой конфигурации вон в зарплате таких хватает что с поддержки снимать из за этого? Собственно замена в предприятии одного элемента на другой и решит проблему.

    Ваша идея с регистром очень хороша но идея предопределенного в том что ссылка точно есть. А вот в регистре записи может и не оказаться.

    Reply
  9. alex_4x

    (14) nSpirit2,

    О том и спор, что кажется, будто бы «предопределенное значение» снимает ответственность с программиста на этапе разработки решения проверки корректности заполнения этого значения. В Вашем случае, во время проведения проверки на правильность и наличие «предопределенного значения» делать вроде как и не надо. Это уже потенциальный источник проблемы. Если это предопределенное значение берется допустим из процедуры глобального модуля СслылкаСправочникаВидыНалоговНДС18 = глПолучитьПредопределенноеЗначение(«НДС18»,СсылкаДляКого,ТекущаяДата()); то потом в модуле проведения (на этапе проектирования) должно быть предусмотрено, что возможно такое значение и не заполнено. Что уж там дальше делать — опять же должно быть на этапе проектирования предусмотрено. В результате получим, что в режиме использования можно производить Предусмотренные настройки, а при не правильной настройке система будет на это адекватно реагировать. Минусов в таком решении не вижу, только одни плюсы.

    А если при не заполненном значении нельзя продолжать работать вообще — замечательно — проводи проверки всех критичных значений при запуске приложения и если что-то не заполнено, оповещай пользователя и не давай работать, пока не будет что надо заполнено. Опять же — всё решается на уровне проектирования системы и лежит не в плоскости «система сама за нас всё сделает, а правильно или нет — мы не ведаем», а определяется разработчиком прикладного решения.

    Reply
  10. nSpirit2

    (15) alex_4x, Вы не подумайте я с вами согласен. Я про само развитие так сказать. Использование предопределенных сродни найти по коду. Ну собственно вот и идею и довели до полного соответствие теперь вроде как возвращается то что выберет пользователь.

    А теперь представите что в вашем регистре храниться что-то важное для проведения что нужно всем документам. Вот и узкое место в вашей системе при большой нагрузке все проводимые документы будут читать одну и туже таблицу. В «теории» предопределенные значения должны работать быстрей. Ну и главная проблема а как обеспечит целостность таких настроек как быть если пока документ проводился настройку удалили? Блокировать их? Предопределнные хороши тем что всегда дадут вам ссылку пусть даже на не существующие данные это потом проще исправить чем перепроводить документы с потерявшейся настройкой.

    Reply
  11. Aleksey.Bochkov

    Сделал простую обработку, которая поможет сгенерировать код для принудительного обновления предопределенных в узлах РИБ, когда объекты не входят в РИБ. Может кому будет полезно.

    У меня получилось 197 (!!) таких случаев.

    Reply
  12. Aleksey.Bochkov

    (1), (2) — ИМХО, идеологи платформы сильно оторваны от реальности. У них нет практического опыта разработки, внедрения и эксплуатации более менее серьезных конфигураций. А выстраивать диалог с теми, у кого этот опыт есть, категорически не хотят, хотя и декларируют постоянно обратное. В итоге и получаются решения, которые в теории хорошие, а на практике сплошное разочарование.

    Reply
  13. Aleksey.Bochkov

    (6) nSpirit2,

    Идеология платформы в наконец то двигается в правильном направление.

    Я не утверждал, что направление неправильное. Речь про ряд неудачных решений в последних релизах 8.3.

    У 1с нет опыта разработки сложных конфигураций?

    Повторюсь — у идеологов платформы нет собственного практического опыта разработки, внедрения и администрирования решения.

    У идеологов и разработчиков прикладных решений Фирмы 1С есть огромный опыт разработки (скорее, хорошая теоретическая база), и не такой существенный по внедрению и администрированию.

    Это разные люди и отделы. Как мне кажется, нормальных коммуникаций там нет.

    По моему изменения вполне логичны.

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

    Reply
  14. Aleksey.Bochkov

    (8) nSpirit2,

    Ваше утверждение не соответствует действительности. Ознакомьтесь с позицией Сергея Нуралиева на партнерском форуме.

    Как раз-таки разработчики платформы ставят перед собой цель создать максимально готовый инструмент для написания бизнес-приложений, а не предоставлять низкоуровневые механизмы для кастомизации решения. Проводить параллель между C++ и 1С ошибочно.

    Думайте у Страуструпа был большой опыт написания и внедрения сложных приложений на С++.

    Это конечно, порадовало :). Нет, блин, он его в пьяном бреду придумал.

    Reply
  15. A_Max

    А потом ещё вернут галочку у реквизитов «переодический»…

    Reply
  16. Evil Beaver

    (10)

    Нет, блин, он его в пьяном бреду придумал.

    Иногда мне кажется, что это, все-таки, правда)

    Reply
  17. svetanik

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

    Reply
  18. Aleksey.Bochkov

    UPD — оказывается, ошибка с падением платформы в 8.3.5 не исправлена.

    У нас проявляется если отвязать периферийный узел от РИБ и зайти под полными правами.

    Reply
  19. hakerxp

    (20) такая же беда. Ждемссс обновления.

    Reply
  20. wolfsoft

    (1) bulpi, на хрена, на хрена… когда коту нечего делать… ну, вы знаете.

    Reply
  21. ekaruk

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

    http://infostart.ru/public/305892/

    Даже у себя нашла дубли.

    А вообще по-моему все-таки правильное решение дать пользователям возможность самостоятельно устанавливать предопределенные элементы.

    Не нужно изобретать лишние сущности.

    Reply
  22. fixin

    познавательно, спасибо

    Reply
  23. rozer

    было полезно — отличная статья

    Reply
  24. Shaldryn

    Я так и не понял что то, добавил в УНФ предопределенные элементы в справочник, в предприятии их не вижу, и чтобы я не делал(Реструктуризация, запуск с параметром обновления), никак не отображаются(в запросе они есть), что я упустил?

    Reply
  25. SkrAn

    посоветуйте как быть:

    Есть РИБ УТ 10.3 — нужен новый узел.

    Проблема в том что при запуске в конфе идет обращение к предопределенным элементам.

    То есть если я залью конфу, и запущусь с ключом : /SetPredefinedDataUpdate -DoNotUpdateAutomatically, то не смогу зайти в режим предприятия из за обращения к предопределенным которых еще нет.

    Если я закомментирую обращения к предопределенным (а там довольно много) — то после возврата ключа авто не смогу принять обмен (отличия в конфигурациях риб)

    Reply
  26. SkrAn

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

    Reply
  27. SkrAn

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

    Reply
  28. METAL

    Вопрос: можно ли (если да — то как?) программно получить список всех предопределённых элементов конфигурации, независимо от того, что с данными в режиме Предприятия?

    Reply
  29. acanta

    Очень интересно и статья и комментарии. Добавить нечего.*Мектуб*

    Reply

Leave a Comment

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