v8.2 Управляемые формы: Динамические элементы формы и переопределяемые события или как изменить поведение и внешний вид управляемой формы программно без лишних хлопот




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

57 Comments

  1. MarSeN

    Хочу уточнить, то в примере используются переопределение и установка событий &НаКлиенте, но механизм расчитан на все события формы и элементов. т.е. пожно переопределять и устанавливать события как &НаКлиенте так и &НаСервере

    Reply
  2. TitanLuchs

    В реальной жизни уже пробовали тестировать? Как-нибудь отражается на быстродействии, тормозов нет?

    Reply
  3. MarSeN

    (2) Все написанное в обоих статьях с успехом применяется в разрабатываемой и уже внедренной конфигурации УТ11.

    Тормозов нет

    Reply
  4. Evil Beaver

    А в 8.3 обещают подписку на события форм. Тогда даже модуль формы менять не придется.

    Reply
  5. MarSeN

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

    Reply
  6. wunderland

    В стандартных тоже иногда применяется динамическое формирование формы, например в УНФ форма элемента для спр. ФизЛица. Но здесь намного красивее. Мне понравилось, возьму на вооружение…

    Reply
  7. ivs200999

    (4) Обещают? Это было бы прекрасно, если было бы правдой.

    (1) С какой целью создание реквизитов, элементов и назначение обработчиков реализовано тремя вызовами процедур общего модуля? Для наглядности? Не лучше ли сделать один вызов?

    Reply
  8. MarSeN

    (7) для того чтобы не перебирать макет если там нет настроек для этой формы. И конечно так нагляднее.

    Reply
  9. MarSeN

    (9) Эх…

    Цитирую:

    «Данная статья и прикрепленная конфигурация направлена на то чтобы продемострировать возможности возможности платформы 8.2».

    Никто не говорит о том что это ноу-хау. Есть гораздо продуманные системы по «программному добавлению элементов». И подходов множество. Речь совсем не об этом. А о точ то есть такие возможности и, как вариант, этот механизм.

    НО — я еще не встречал механизма который бы давал возможность модифицировать формы (элементы/реквизиты) + их поведение (переопределение событий) в одном флаконе.

    Если бы подобный механизм/функционал был хоть бы в одной конфе — статьи бы тут не было.

    Попробуйте в пару строк распространить механизм документа Установка цен на всю конфу. Для внедрения моего механихма надо перенести 1 общий модуль и одну обработку.

    Reply
  10. MarSeN

    (11) Я только за чтоб в комментах обсуждалось и приводились примеры других реализаций. Но, желательно, не в таком тоне.

    Спасибо за понимание.

    Reply
  11. internetname

    Управляемые формы рулят. Кстати, когда там рабочая версия 8.3 появится?

    Reply
  12. MarSeN

    (13) сам жду с нетерпением )

    Reply
  13. ArtfulCrom

    (13) ) хотел бы я взглянуть в глаза человеку ЗНАЮЩЕМУ ответ на этот вопрос )

    Статья хорошая. Спасибо. Побольше бы таких простых и безхистростных «учебников» для отрастающего поколения

    Reply
  14. marochkin

    Спасибо за метод, давно не видел столь грамотного способа. Сам делал нечто подобное (переопределение действий с сохранением вызова типового) для элементов форм. Чувствуется опыт программирования не только в 1С 😉

    Скорее всего сталкивались со следующим вопросом, очень интересует как решали!?

    БСП входит в состав УТ 11. В своих объектах тоже очень хочется пользоваться плюшками БСП. Самые простые примеры: — структура подчиненности, движения документов, виды объектов доступа и права.

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

    Очень интересен комментарий автора статьи на этот счет!

    Reply
  15. MarSeN

    (16) Спасибо за высокую оценку.

    Я сам пока не заморачивался по «таким» вопросам, так как методику разработал и начал применять относительно недавно. Но на вскидку думаю но структуре подчиненности и движениям документа или другим командам можно просто существующую комманду скопировать в «свою» некую обработку и на нее назначить нужные объекты. при этом больше править ничего не нужно будет. А вот в с составом объектов метаданных, к сожалениию, решений нет. (

    По ролям я делаю на все объекты новые роли. Если нужно убрать на сущ. роли часть прав то копирую нужную — ее правлю и потом в профиле перевыбираю свою вместо преджней.

    Можно устроить мозговой штурм при желании )

    Reply
  16. marochkin

    (17) Да тоже думал над копированием команд, но в некоторых случаях возможно придется копировать объекты целиком, поэтому это пока не сложилось в вариант решения вопроса ))

    Насчет прав я не про роли. А про возможность использовать RLS шаблоны самой БСП. Там нужно в нескольких объектах изменять типы, примеры: ПВХ.Виды объектов доступа, некоторые подписки на события, типы измерений некоторых регистров.

    Reply
  17. MarSeN

    (18) К сожалению приходится нсимать с поддержки и править ручками то что нельзя «отнаследовать». В каждом случае приходится решать проблемку конкретно. Иногда, если есть такая возможность правильнее упростить задачу или решить ее бругим путем. Но 1С в некоторых случаях не оставляет нам другого пути, как решать задачу «В лоб» (

    Reply
  18. ivanov660

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

    Reply
  19. MarSeN

    (20) ivanov660

    Все «динамические» модификации делаются в привелегированном режиме. С правами реквизитов объекта «только на просмотр» все работает корректно. Если отсутствуют права на чтение то будет ошибка. Я делал этот механизм на УТ11 и у в моих задачах не было необходимости запрещать чтение реквизитов.

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

    Reply
  20. Kaval88

    Интересный подход. Хорошо применялась для моих прикладных задач.

    Reply
  21. MarSeN

    (22) Kaval88

    По моему мнению, на данный момент, это наиболее «полный» вариант из имеющихся на инфостарте включающий подписки, элементы формы и реквизиты.

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

    Reply
  22. MarSeN

    (22) я рад, что данная разработка будет применена не только в моих решениях )

    Reply
  23. irishka77

    Спасибо, ко времени.Начала работать с бух3.0.

    Reply
  24. MarSeN

    (25) irishka77,

    всегда пожалуйста )

    Reply
  25. HIgor

    События &НаСервере пробовали переопределять? У меня ошибки посыпались (хотя мог и я недоглядеть что-нибудь, вместо макета справочник дополнительный завел). &НаКлиенте — все отлично переопределяется.

    Reply
  26. MarSeN

    (27) HIgor,

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

    Reply
  27. pbazeliuk

    На версии УТ 11.1.2.8 и выше — не сработает переопределение событий, например в документе реализация товаров услуг.

    Reply
  28. Evgen.Ponomarenko

    Годится, откладываю статью в «закладки»! Вернусь после командировки — разберу по винтикам 🙂

    Reply
  29. MarSeN

    (29) pbazelyuk,

    А на версии ниже работает??

    Думаю, что проблема не в версиях.

    Код в студию )) или в личку.

    Reply
  30. mister_tula

    Интересное решение, но есть большое сомнение в эффективности его применения к изменению типовых конфигураций. Очень большой объем кода приходится вставлять в модули форм, может проще и быстрее вставить «визуальные» элементы и описать на месте все обработчики? Форму-то всё равно придётся скопировать, а потом исправлять! Или Вы меняете существующую форму?

    На первый взгляд вижу только некую «классификацию-напоминалку» внесенных изменений в макете «ДинамическиеЭлементыФорм» и «ДинамическиеРеквизитыФорм»?!! Какое мнение автора? Хотелось бы обсудить!

    Reply
  31. MarSeN

    (32) mister_tula,

    Меняется модуль формы и реквизиты. Вставляются только шаблоны обработчиков и строчка вызова общего модуля.

    Все что в статье описано как пример и работает на демо конфе — в статье отражено ввиде принтскринов. Думаю это не большие изменения.

    или я не понял Вашего вопроса?

    готов обсудить.

    я не совсем понял о чем Вы «Какое мнение автора?»

    Reply
  32. mister_tula

    Возможно Вы меня не совсем поняли. Шаблоны обработчиков необходимо вставлять в форму, сами обработчики в общий модуль. Я пишу о том, что текста то-полно!! Может всё это сразу вставить в форму и будет проще! Зачем такие сложности? Я не вижу достоинств Вашего решения перед более простым. Возможно я ошибаюсь. Я пытаюсь практически применить Ваши решения и пока не заметил преимуществ. Поэтому и хотел с обсудить. Если , конечно, у Вас есть время.

    Reply
  33. MarSeN

    (34) mister_tula,

    Да, давайте обсудим.

    Макеты можно добавлять в конкретные объекты — тогда нудно переписать общий модуль подключений чтоб смотрел модули объектов.

    конечно же все тексты обработчков надо хранить в общих модулях.

    Давайте я помогу разглядеть их — достоинства, но если только Вы их хотите увидеть. В противном случае лучше поступать так:

    Может всё это сразу вставить в форму и будет проще!

    какие у Вас лично проблемы возникают с применением данного метода?

    Reply
  34. mister_tula

    Проблем с «простым» изменением форм — никаких. Я копирую исходную форму, называю её myФормаЭлемента, назначаю основной и вношу все изменения непосредственно в модуль формы.

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

    . В данном случае зачем мне это делать?

    Если я воспользуюсь Вашей методикой:

    шаблоны обработчиков вставляю в мою форму myФормаЭлемента, затем в общем модуле их описываю. Дописываю метод ПриСозданииНаСервере. Если необходимо добавить доп.реквизиты — добавляю в любом случае. Описываю все изменения в шаблоне ДинамическиеЭлементыФорм. Мне кажется манипуляций даже больше. Объективно, в чем преимущества? Пока я вижу только два:

    1) текстовое описание добавляемых реквизитов в шаблоне ДинамическиеЭлементыФорм и ДинамическиеРеквизитыФорм, помогает разобраться в омуте внесенных изменений, СОГЛАСЕН.

    2) если вдруг типовая форма изменилась, мне придется ее скопировать вновь и добавить блок по Вашей методике, по моей методике путь немного длиннее — вставляю реквизиты «руками» и привязываю обработчики событий. Не вижу разницы.

    Возможно несколько примитивно я описал. Но всё-таки есть другие достоинства?

    Reply
  35. mister_tula

    Если не сложно, напишите, как действуете Вы для изменения типовой формы, чтобы потом было легче обновляться. Может я не тем путем хожу (:

    Reply
  36. MarSeN

    (37) mister_tula,

    В статье вроде все подробно описано, ну да ладно

    1. снимаю форму с поддержки

    2. добавляю нужные реквизиты

    3. в макете для элементов прописываю куда и какой реквизит поместить

    4. в при создании на сервере прописываю вызов метода для динамической вставки элементов

    ———————-

    обычные реквизиты без обработчиков готовы.

    если нужны обработчики как на новые так и на существующие элементы.

    1. Прописываю обработчик в макете. если большой текст обработчика — перенаправление в макете в общий модуль

    2. Снимаю, если еще не снята, форму с поддержки

    3. вставляю подключаемые команды (тексты которые я привел с статье и есть в демке) в модуль формы

    4 . подключаю при создании на сервере вызов метода подключения обработчика.

    с реквизитами форм все аналогично

    что это дает?

    При обновлении я вижу что форма поменялась и мне не надо смотреть что там поменялось. Я просто в существующую форму добавляю свои вставки и все. если таковых много — пользуюсь KDiff3

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

    Reply
  37. mister_tula

    СПасибо огромное за разъяснение, я был не прав, использую копирование форм. Ваш метод ГОРАЗДО привлекательнее.

    А KDiff3 по-моему это какая-то прога для сравнения файлов? А что она может интегрироваться как-то с 1С?

    Reply
  38. MarSeN

    (39) mister_tula,

    KDiff3 — программа которая намного удобнее чем то что предлагает нам 1С

    В ней есть возможность сравнивать и объединять до 3-х файлов одновременно. Широко применял для 7.7 в связке с GComp

    Нет. она не интегрирована. Нужно выгрузить модули из 1С ч/з выгрузить модули (есть до версии 8.3) или просто ручками создать 2 текстовых файла старого и нового модуля. Объединить и ручками вернуть обратно.

    если выгружать из 1С то потом загрузить обратно. Все просто.

    Спасибо

    Reply
  39. mister_tula

    Супер, буду пробовать.

    Reply
  40. MarSeN

    (41) mister_tula,

    поделитесь результатами экспериментов )

    Reply
  41. zqzq

    Глянул демо-конфу, достаточно красиво и главное просто реализовано (в отличии от соседней темы где внешние обработки и черт ногу сломит). Единственное, повторяющийся код типа

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

    можно было бы заменить на одну строчку типа

    Выполнить(ДинамическиеЭлементыКлиентСервер.ПолучитьВсеИнструкцииПереопределаемыхОбработчиков(ЭтаФорма, «ПослеЗаписи»)); 
    Reply
  42. MarSeN

    (43) zqzq,

    Спасибо

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

    Reply
  43. zqzq

    (44) ну так загнать массив инструкций в многострочную строку в общем модуле и её уже выполнять на форме.

    Reply
  44. MarSeN

    (45) zqzq,

    ) Согласен, ступил. Спасибо.

    Reply
  45. knasa

    Здравствуйте MarSeN.

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

    Reply
  46. MarSeN

    (47) Да, можно.

    это есть в примере

    Reply
  47. It-developer

    Не знаю, не знаю. Пробовал динамически добавлять элементы, но в обычные формы. Довольно геморройное дело. Слишком много кода.

    Наверно, для каких-то целей такая реализация может подойти. Например, когда у тебя пару сотен узлов, которые ты обновлять не хочешь.

    Но опять же, писать кучу всяких обработчиков в самой форме нужно (не считая события ПриСозданииНаСервере) 🙁

    И потом … в макетах куча описалова по обработчикам, элементам, реквизитам. Приколол макет с реквизитами — куча свойств формы в макете 🙂 — в конце проекта в этом макете будут все свойства реквизитов форм :))

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

    Я поставил плюс, т. к. сама идея мне лично интересна

    Reply
  48. MarSeN

    (49)

    Я объединение делал через KDiff 3 при этом использовал 3 версии текстов (cf) — конфа поставщика, новая версия, и текущая версия.

    при этом кадиф автоматом предлагает, если нет изменений между поставщиком и новой от поставщика, вставить код от текущей версии

    Reply
  49. mikhailv

    (4) Evil Beaver, обещанного 3 года ждут. Исходя из даты сообщения, 01.02.2016 должно случиться чудо:)

    Reply
  50. Cyberhawk

    1. Я правильно понимаю, что переопределить обработчик ПриСозданииНаСервере не получится?

    2. Также желательно описать (и добавить в демо-конфигурацию) переопределение обработчика, получающего на вход больше одного параметра

    Reply
  51. MarSeN

    (52)

    1. Можно переопределить обработчик ПриСозданииНаСервере, но я не заморачивался тогда по причине отсутствия надобности.

    2. Принцип всегда один, но количество параметров зависит от конкретного обработчика. Тут особо описывать нечего. Я всегда брал типовой и на основе него делал переопределеное.

    Reply
  52. check2

    Сергей, просто супер!

    А почему все элементы в один макет? не лучше ли было бы лепить макеты к самому объекту: три макета. Если очень много дорабатываемых объектов, то чуть-чуть выиграем на сканировании табличного документа и… самое главное… я в задании на разработку описываю табличку что во что должно вставиться… Мы просто копируем табличку из задания на разработку и разработчику нужно вставить несколько обработчиков в форму… Щастье… Беру демку, переделаю под себя… Идея просто блестящая.

    Спасибо!

    UPD: Ещё бы и код обработчиков генерился… из обработки… алмаз…

    Reply
  53. check2

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

    Reply
  54. MarSeN

    (54)

    Да, можно было и так сделать, но я ориентировался на минимум изменений в типовых объектах

    Кот обработчиков, если я правильно понял что имеется ввиду, не может быть сгенерирован. Его можно попробовать в обработке разместить, но не весь, только для серверных вызовов. Для клиентских только в общем модуле.

    Прошу прощения если не точно ответил. Писал давно и уже многое не помню

    Reply
  55. MarSeN

    (55)

    Это я не помню. Если такое возможно (платформой и по коду), то я должен был прописать.

    Reply
  56. MarSeN

    Не думал, что данная разработка еще актуальна )

    Reply
  57. check2

    (58) Ещё как актуальна, мы её допилили, добавили работу с существующими элементами — перемещение, скрытие, удаление. Добавили работу с группами, кнопками. Сделали дополнительно обработку — генератор форм. Т.е. в рунтайме правим табличку — получаем форму с новыми вставленными элементами. Очень помогает в процессе написания проектных решений чтобы не просто описывать будущую форму, а заскринить, выделить новые элементы. Затем таблички сохраняем к заданию на разработку.- кодеру достаточно только заменить пути в элементах форм на реквизиты объекта. Как результат — снижение трудоёмкости работ при проектировании.

    Reply

Leave a Comment

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