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




Принцип обмена данными из 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. Andry.Boris

    Автору +

    Reply
  2. mtv:)

    (0) Спасибо за хорошую идею и за качественное оформление публикации.

    Однозначно плюс.

    Reply
  3. Поручик

    Эээ, извините. А внешнюю обработку ТЧ никак не замутить, а вместо параметра сеанса БуферОбменаТаблицаЗначений приспособить ОбщиеЗначения? Или я чего-то не понял в этой жизни?

    Reply
  4. Sam13

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

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

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

    Reply
  5. mtv:)

    (3) Поручик, если сделать через «Внешнюю обработку заполнения табличных частей», то у документов в закрытом периоде становятся недоступны пункты меню «Заполнить». Правда я сильно не копал в этом направлении, может и можно поправить этот «косяк»/фичу. Если найти, как обойти это, то действительно, через «Внешнюю обработку заполнения табличных частей» будет менее затратно реализовать предложенный функционал. Я уже подумал об этом — надо покопать…

    Reply
  6. MNevgeny

    Молодец автор! Идея очень хорошая. Очень часто возникает необходимость в таком инструменте. Очень многим поможет с экономить массу времени. Однозначно плюсую!

    Reply
  7. Sam13

    В описание добавлено альтернативное решение, использующее только стандартный функционал. В файлы добавлены 2 обработки (одна для Копирования, другая для Вставки), реализующие это решение.

    Reply
  8. mtv:)

    (7) Вопрос: А в альтернативном варианте решен ли вопрос с документами в закрытом периоде? Смотри замечание в (5).

    У меня в документах, которые находятся в закрытом периоде, пункты меню «Копировать» и «Вставить» неактивны, на них невозможно нажать.

    Reply
  9. Sam13

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

    Reply
  10. Ranika

    Автор проделал огромную работу, особенно в написании документации, спасибо!!!

    Reply
  11. worker1c

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

    Reply
  12. mr zafod

    (9) Задача была решена очень-очень давно.

    У меня под рукой очень старая версия УТ, но обратите внимание:

    1. При открытии любой формы только на просмотр блокируются только элементы с установленным свойством ИзменяетДанные

    2. В универсальных механизмах есть такая функция ПолучитьДеревоКнопокЗаполненияТабличныхЧастей и кусок кода заполнения «дерева кнопок»:

    ДобавитьСтрокуВДеревоКнопок(СтрокаПодменю, «ЗаполнениеТЧ»+НомерКнопки, ТипКнопкиКоманднойПанели.Действие, ВыборкаДействий.Наименование, Действие , ВыборкаДействий.Ссылка, , , , , Истина)

    Последний параметр — это свойство ИзменяетДанные будущей кнопки. Нехитрыми манипуляциями решаем задачу.

    В любом случае нужно внести изменения в конфигурацию!!! Но минимальные

    Вот самое простое решение

    ДобавитьСтрокуВДеревоКнопок(СтрокаПодменю, «ЗаполнениеТЧ»+НомерКнопки, ТипКнопкиКоманднойПанели.Действие, ВыборкаДействий.Наименование, Действие , ВыборкаДействий.Ссылка, , , , , (ВыборкаДействий.Ссылка.Комментарий = «НеИзменяетДанные»))

    — Не самый лучший вариант. Для примера. Это позволит просто вписать в комментарий обработки НеИзменяетДанные и кнопка будет доступна 24/7 и при любой погоде.

    Надеюсь комментарий окажется Вам полезным.

    Reply
  13. mr zafod

    (11) По поводу копирования/вставки/сохранения/восстановления.

    Посмотрите немного в сторону — есть же старые добрые «встроенные» возможности:

    СохранитьЗначение и ВосстановитьЗначение которые работают как в текущем сеансе пользователя, так и во всех последующих.

    Reply
  14. rago

    Спасибо автору. Очень пригодилась — как раз искал что-то подобное. Немного доделал — и теперь доволен 🙂

    Reply
  15. apostal86

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

    Reply
  16. itek.09

    оТЛИЧНО ВСЕ РАБОТАЕТ.. большое спасибо автору. очень пригодилась. подошло даже на управление производственным предприятием. и управление торговлей

    Reply
  17. Одинец

    В некоторых случаях (когда пользователь первый раз открывает документ) нажатие на кнопку вызывает:

    {ОбщийМодуль.УниверсальныеМеханизмы.Модуль(342)}: Значение не является значением объектного типа (Расшифровка)

    Расшифровка = СтрокаКнопки.Расшифровка;

    Как поправить?

    Reply
  18. Sam13

    (18) Одинец, Какая конфигурация? Какой документ. Очень любопытно.

    Reply
  19. Sam13

    (16) apostal86, Если разработчик хоть вообще удалит форму и добавить новую — функционал будет работать. Суть методики в том, что форма документа НЕ МОДИФИЦИРУЕТСЯ. Добавление кнопок происходит программно в общих модулях.

    Reply
  20. Sam13

    Готовлю обновление. Количество изменений в конфигурацию сократится до:

    -добавить обработку «БуферОбменаТаблицаЗначений»

    -внести изменения в модуль «УниверсальныеМеханизмы»

    -внести изменения в модуль «МеханизмНумерацииОбъектов»

    -изменить роль «Пользователь» для доступа к обработке

    Расширение функционала:

    -буфер обмена можно сохранить в файл/восстановить из файла

    Оптимизировано:

    -«свои» процедуры перенесены в обработку.

    -картинки кнопок перенесены в обработку

    -используется существующий параметр сеанса «ОбщиеЗначения» — не нужно добавлять новый

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

    Reply
  21. Imm

    Спасибо большое

    Reply
  22. apostal86

    (20) тогда ясно)) плюсик

    Reply
  23. Одинец

    (19) вписал настройку в конфигурацию «Управление торговлей», в документе «Поступление товаров и Услуг», закладка Товары.

    В конфигурации «Бухгалтерия Предприятия» нет процедуры «СформироватьПодменюЗаполненияТЧ» : это функция, поэтому надо изменить поведение «БуферОбмена_ДополнитьПодменюЗаполненияТЧ(ДеревоКнопок,СоответствиеТЧ)»

    а в целом конфертировал Вашу настройку в Бухгалтерию предприятия». Спасибо!

    Reply
  24. zavedeev

    Автор молодец, я думаю программно создавать кнопку в форме объекта делали все только автор пошел дальше. Молодец

    Reply
  25. Sanek_159

    Интересная статья, спасибо. Очень полезно. Будем ждать обновления, для еще меньшего изменения конфигураций =)

    Reply
  26. Поручик

    (21) Лучше создать отдельную роль для доступа к обработке, чтобы не курочить штатную. Я всегда так делаю.

    Reply
  27. Sam13

    (3) Поручик, Вы знаете точно как используют штатные механизмы ПараметрСеанса «ОбщиеЗначения»? Если его использовать не случиться ли так, что система «затрет» наш буфер своим значением. Или наоборот, мы какое-нибудь важное значение «убьем» своим буфером. насколько я понял стандартно система использует ПараметрСеанса «ОбщиеЗначения» для кеширования данных.

    Reply
  28. Sam13

    (27) Поручик, Зачем плодить сущности? Чтобы не было геммороя при обновлении?

    Reply
  29. OleGazz

    спасибо, интересно

    Reply
  30. Nicenick

    Интересная статья, спасибо. Очень полезно. Будем ждать обновления, для еще меньшего изменения конфигураций =)

    Reply
  31. Paul_Nevada

    Спасибо большое за такую разработку!

    Очень нужный функционал, обязан сказать! Вообще, в конфигурациях «Восемь» нет некоторых очень привычных (полезных — самое главное) возможностей, которые имеются в «Семь»… И это — надо править!

    Reply
  32. Paul_Nevada

    *восполнять!

    Reply
  33. tehas99

    интересно, нужно попробывать

    Reply
  34. diarki

    Полезная информация Автору плюс однозначно.

    Reply
  35. Signal

    Такое бы на УТ 11…

    Reply
  36. Shrike

    Спасибо большое! Попробую

    Reply
  37. fixin

    жесть! клевая идея.

    Reply
  38. karakozov

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

    Reply
  39. serpisal

    Отличная идея и её воплащение. Обожаю механизмы, которые не требуют внесения изминений в

    конфигурацию.

    Reply
  40. Brawler

    Недавно скачал альтернативное решение и сразу вылезла ошибка при повторной попытке авторегистрации при нажатии кнопки регистрации. Ошибка наблюдается в обработке «Копирования» и «Вставки».

    Ошибка вылезла в строке

    СпрВнешОбработка.Комментарий = ЭтотОбъект.Метаданные().Имя;

    Исправил ошибку в участке кода

    Было:

     //регистрируем
    Если Выборка.Следующий() Тогда
    СпрВнешОбработка = Выборка.Ссылка;
    

    Стало:

     //регистрируем
    Если Выборка.Следующий() Тогда
    СпрВнешОбработка = Выборка.Ссылка.ПолучитьОбъект();
    
    Reply
  41. Sam13

    Согласен. Есть ошибка. Исправил.

    Reply
  42. Paul_Nevada

    (38) serovmsk, спасибо за информацию-идею! Надо по-скорее проверить в работе.

    Reply
  43. inf0start

    Спасибо за идею! Порадую своих пользователей )

    Reply
  44. heseh

    Респект автору!

    Reply
  45. elena_77

    Авторй плюс. Идея интересная и нужная. Пользователям очень пригодится. Спасибо.

    Reply
  46. inga75

    Интересная идея, Спасибо

    Reply
  47. AAndryA

    Интересная идея и заманчивое описание реализации. Надо внедрить и протестировать в работе. Автору респект и плюс.

    Reply
  48. Filipp_inf

    Очень изящное решение вариант «Альтернативная обработка» для ЗУП,

    т.к ЗУП — та конфигурация, которую никак нельзя снимать с поддержки из-за ПОСТОЯННОГО внесения изменений в законодательство! Большое спасибо!

    И еще как просьба-пожелание:

    — возможность выгрузить буфер в Excel, для правки сумм (или еще каких-нибудь примитивных типов), а потом опять загрузить в буфер для дальнейшей вставки. Вот это был бы класс! Например, постоянно изменяемые оклады или надбавки, которые проще и лучше рассчитать в Excel для ежемесячного документа «Ввод плановых начислений».

    Это точка зрения пользователя-главбуха.

    Reply
  49. ponaroshku

    в упп у меня возникла проблема — документ поступление товаров и услуг, тч товары

    {ОбщийМодуль.УниверсальныеМеханизмы.Модуль(587)}: Значение не является значением объектного типа (Расшифровка)

    Расшифровка = СтрокаКнопки.Расшифровка;

    Хотя все сделала по инструкции и на три раза

    Подскажите, куда копнуть?:(

    Reply
  50. ponaroshku

    (53) разобралась

    незнаю, что это было — запустила в новой чистой конфе, все встало

    Reply
  51. flaks

    Большое спасибо!!! Очень пригодилось.

    Reply
  52. MrFlanker

    Отличная… идея как раз собирался писать нечто похожее в обозримом будущем… хорошо что не придется изобретать велосипед.

    Reply
  53. yura1960

    На БП 8.3 кто нибудь юзал? Выглядит заманчиво. Но не придется ли допиливать? Просто времени разбираться нет, т.к. свою юзаю. Но эта смотрится симпатичнее, хочу её )))

    Reply
  54. Sam13

    На БСП не полетит, конечно же. Там все механизмы переколбашены

    Reply
  55. German_Tagil

    мда я ее переработал под себя

    http://infostart.ru/public/460032/

    сейчас размышляю как дальше ее использовать

    Reply
  56. DEG156

    КнопкаКопировать.Подсказка = «Скопировать таблицу»;

    Reply
  57. axelload

    Автору отдельное спасибо за вот эту обработку ВнешнийОбработчикБуфераОбмена_Вставить.epf

    Reply

Leave a Comment

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