Дубли контрагентов. Жесткий запрет на запись дублей [Расширение]




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

55 Comments

  1. Craig

    «+» за оперативное освоение новых технологий (возможность 8.3.6.)

    Reply ↓
  2. insurgut

    Спасибо за пример!

    Reply ↓
  3. logdog

    Для БП 3.0.40.24 ошибка при старте.

    Ошибка подключения расширения: ЖесткийЗапретНаЗаписьДублейКонтрагентов (1.0) — Ошибка свойства РежимСовместимостиИнтерфейса у объекта

    Режим совместимости — Не использовать

    Reply ↓
  4. gorevg

    Интересно, а как расширения сказываются на скорости работы в программе. Ведь, как я понимаю, платформа применяет расширение «на лету». Был у кого-нибудь опыт?

    Reply ↓
  5. mrXoxot

    (3) logdog,

    Да, необходимо снять совместимость с 8.3.5 — это можно сделать в конфигураторе или дождаться когда разработчики БП3 снимут это в типовой конфигурации.

    Reply ↓
  6. logdog

    (5) Я написал, что снято. Прикладываю картинку. http://joxi.ru/zANp9ypS0ZRpm9

    Может есть какое-то отличие в коде для БП КОРП и БП?

    Reply ↓
  7. Поручик

    Ух ты, супер. Расширения — это то, что я так долго ждал.

    Reply ↓
  8. mrXoxot

    (6) logdog,

    Проверил на ПРОФ 3.0.40.24 . Работает, подключается.

    Проверял на платформе 8.3.6.1977. Какая у Вас?

    Reply ↓
  9. logdog

    (8) и на 8.3.6.1977 и на 8.3.6.1999 выдает ошибку =( http://joxi.ru/12M79B7TQ1M8rJ

    Reply ↓
  10. mrXoxot

    Проблема в режиме совместимости интерфейса. Должно стоять — Такси. Разрешить 8.2, как в типовой. У Вас стоит просто Такси.(9) logdog,

    Reply ↓
  11. logdog

    (10) Да, проблема была в этом. Спасибо.

    Reply ↓
  12. planar74

    И как они с РИБ работают? Надо каждому узлу отправлять или достаточно в ЦБ загрузить?

    Reply ↓
  13. qwinter

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

    Reply ↓
  14. planar74

    (13) qwinter,

    «Дополнительных отчетов и обработок» больше не будет?

    Reply ↓
  15. Alex_E

    (14) planar74, Почему? Одно другому никак не мешает. Вот возможность в расширении изменить поведение формы хоть того же документа — это проще в расширении сделать. Можно добавить раздел в командный интерфейс и включить туда какой то свой набор данных (из имеющихся в типовой, если её не менять), плюс отчеты и пр., в общем много чего уже можно, но хотелось бы больше :-).

    Reply ↓
  16. planar74

    (15) Alex_E,

    Раздел в командный интерфейс добавить в конфигурации или расширении? Насколько я понял, в расширение нельзя добавлять новые объекты конфигурации. В ряде случаев, конечно, может помочь, но не сильно. Я крайне редко сталкивался с ситуацией, когда форму или обработку проведения приходилось менять без (например) добавления реквизита в конфигурацию.

    Reply ↓
  17. Alex_E

    (16) planar74, Подсистему в расширение ввести можно, сейчас пишу настройку, добавил — работает… Вообще проверить, что можно что нельзя достаточно просто — в дереве расширения правой кнопкой на то, что хочется добавить, если активно — то можно.

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

    Reply ↓
  18. qwinter

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

    Reply ↓
  19. Alex_E

    (18) qwinter,

    одно другое заменяет. На текущий момент именно так.

    — на текущий момент расширения с типовыми пока ничего не заменяют — чтобы их использовать надо снять конфу с поддержки (совместимости, чтоб их), так что пока типовые с внешими обработками заполнения и пр. остаются актуальными, а жаль — расширения — то чего давно хотелось…

    С другой стороны, что в 8.3.6.* понравилось — это режим объединения, то, что можно текст модулей поменять как захочешь в момент объединения — уже много значит, для настроенных…

    Reply ↓
  20. planar74

    (17) Alex_E,

    И как вы эти дополнительные реквизиты в запросах используете? Через левое соединение с проверкой по коду вида характеристики?

    Reply ↓
  21. Alex_E

    (20) planar74, По разному, в зависимости от ситуации, иногда через http://infostart.ru/public/288722/, иногда в запросе, «по коду» никогда не использую — доп.реквизиты или сведения создаю программно в любом случае. В запросе через левое соединение, нужный доп.реквизит определяется, чаще всего, по заголовку свойства плана видов характеристик, т.е. пользователю «полета для творчества» оставляю минимум. Пока проблем с этим не было …

    Reply ↓
  22. qwinter

    (19) Alex_E, не думаю что типовые будут долго еще на 8.3.5

    Reply ↓
  23. Alex_E

    (22) qwinter, надеюсь 🙂

    Reply ↓
  24. ZOMI

    Дополнительный вопрос это «жесткий запрет» ?

    Reply ↓
  25. Yashazz

    Как показывает опыт, нововведения такого рода энное время лютейшим образом косячат. Я б поостерёгся кидаться ставить это сразу в рабочие механизмы.

    Reply ↓
  26. mrXoxot

    (24) ZOMI,

    Вопрос был в типовом решении.

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

    Но если очень хочется, то можно записать через «Еще»

    Reply ↓
  27. mrXoxot

    (22) qwinter,

    В опубликованных планах сказано, что 3.0.41 будет без режима совместимости с 8.3.5

    То есть, да здравствует 8.3.6.

    Reply ↓
  28. mrXoxot

    (12) planar74,

    Не проверял как работает в РИБ. Но вот, что удалось найти в документации:

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

    Более подробно здесь.

    То есть, кажется, что нужно будет подключать для каждого узла своё расширение.

    Reply ↓
  29. mrXoxot

    (4) gorevg,

    Расширение применяется один раз вначале.

    Подключение расширения к сеансу пользователя выполняется перед вызовом обработчика события УстановкаПараметровСеанса и остается подключенным до завершения сеанса

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

    Reply ↓
  30. 1cmax

    (13) qwinter, абсолютно поддерживаю, это как в мобильной платформе запросов не было сначала, ждемс

    Reply ↓
  31. hobi
    Пока в расширениях нельзя будет добавлять свои справочники, документы, регистры надобности в них нет. Разве что поудобнее будет внешние отчеты цеплять.

    (18) qwinter, мне кажется, самое существенное в расширениях сейчас —

    возможность переопределить типы реквизитов объектов метаданных.

    Можно добавить новый тип в составной в критериях отбора, в определяемых типах, в реквизит «Основание», в план видов характеристик.

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

    Reply ↓
  32. mrXoxot

    (31) hobi,

    Как говорится : «В руках специалиста и табуретка является оружием массового уничтожения».

    Reply ↓
  33. qwinter

    (32) а толку? Не будете же вы добавлять реквизиты отдельно, а форму и типы переделывать в расширении? И как это впоследствии поддерживать?

    Reply ↓
  34. planar74

    (28) по ходу, не только каждому узлу, но и каждому пользователю на узле. Весело, ничего не скажешь.

    Reply ↓
  35. PavelZnaikin

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

    Reply ↓
  36. Alex_E

    (35) PavelZnaikin,

    добавлять будет свои Документы, Справочники.

    — нет

    изменять форму существующих документов и справочников?

    — да

    Reply ↓
  37. Bassgood

    (34) planar74, не каждому пользователю, а для каждого разделителя, если база использует механизм разделения данных, т.е. совсем жестко будет сочетание РИБ + разделение данных.

    Reply ↓
  38. chmv

    ++++++++++ за новое

    Reply ↓
  39. &rew

    Вот тоже осваиваю данный механизм в плане выноса «дописок» для облегчения обновления. Наткнулся на ПВХ. В расширении дает менять составной тип ПВХ, а в режиме предприятия шлет напрочь. Т.е. вопрос — предполагается такая возможность в будущем или просто вследствие сырости не запретили еще менять тип ПВХ в расширении? (вопрос риторический. Время покажет)

    Reply ↓
  40. ekaruk

    (39) &rew, По логике не должно быть такой возможности.

    Изменение типа ПВХ физически это изменение структуры БД (добавление новых физических колонок на SQL сервере)

    А такой возможности у расширений сейчас нет.

    Reply ↓
  41. &rew

    (40) ekaruk, Это все понятно, про таблицы, типы и прочие ограничения, но речь идет о ПВХ. Это некий «хамелеон» от 1С, который как бы сам по себе уникальный вид, но может «притворяться» кем угодно. Понятно что в рамках определенных типов, но всё же. Почему тогда не создать Универсальное ПВХ, и назначить ему в типы все типы (как бы масломаслянно это не звучало), и тащить через все конфы а то и вообще в БСП включить. Это, конечно, я утрирую, но только дабы четче донести свою мыслЮ.

    Reply ↓
  42. shatt

    Доброго дня! Как обстоит дело с отладкой при создании расширений?

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

    Reply ↓
  43. &rew

    (42) shatt, Эээ. Да всё нормально вроде как с отладкой. На 8.3.6.1999 (да и выше пробовал) работает стандартно. Работаю на win 7 и server 2008, 2012.

    Reply ↓
  44. &rew

    (42) shatt, С ИТСа

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

    Reply ↓
  45. AlexeyPapanov

    //правка

    я писал пост ниже, а позже сам разобрался.

    поясните для танкистов. вот скачал расширение, пытаюсь понять как это работает.

    у вас в модуле формы объекта «спр.Контрагенты» две процедуры:

    — Процедура ДублиКонтрагентовПередЗаписью()

    — Процедура ДублиКонтрагентовЗаписатьДубль()

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

    вот допустим стоит задача проверить определенный реквизит и в зависимости от этого разрешить запись элемента или запретить, т.е. поставить Отказ=Истина.

    но процедуры ПередЗаписью или ПриЗаписи находятся же в модуле объекта, а не формы.

    а в расширение попадает только форма.

    поясните, как быть?

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

    вот простой пример

    &НаКлиенте
    Процедура Р_ПередЗаписью(Отказ, ПараметрыЗаписи)
    Если НЕ ЗначениеЗаполнено(Объект.НоменклатурнаяГруппа) И НЕ Объект.ЭтоГруппа Тогда
    Отказ = Истина;
    Сообщить(«Не заполнен реквизит «»НоменклатурнаяГруппа»»!»);
    КонецЕсли;
    КонецПроцедуры
    
    Reply ↓
  46. mrXoxot

    (45) El_Loco,

    Не совсем верно. Сначала выполняется код из расширения, затем код типового обработчика. Но этот порядок можно изменить.

    Reply ↓
  47. SkyHunter

    Господа, а подскажите, чем может быть чревато отключение режима совместимости в Бух 3.0?

    Reply ↓
  48. mrXoxot

    (47) SkyHunter,

    На текущий момент ничего отключать не нужно.

    На актуальном релизе данное расширение работает корректно.

    Совместимость с 8.3.5 была снята в 3.0.41

    Reply ↓
  49. mrXoxot

    Обновил расширения для Бухгалтерия 3.0.44

    Reply ↓
  50. user849791

    А есть такое же, но для документооборота?

    Reply ↓
  51. mrXoxot

    (50) У меня, к сожалению, нет.

    Reply ↓
  52. demaxxx

    В БП 3.0 (3.0.65.72) при подключении расширения

    Ошибки:

    ———————————————————————————

    15.01.2019 12:16:41

    ЖесткийЗапретНаЗаписьДублейКонтрагентов (1.1): Критичная: Не найден объект ФункциональнаяОпция.Новости_РазрешенаРаботаСНовостями

    Reply ↓
  53. mrXoxot

    (52) Можете просто удалить этот реквизит из расширения.

    Обновил расширение в публикации.

    Reply ↓
  54. demaxxx

    (53) Удалить не могу, похоже что возможность редактирования отключена, или я что то не так делаю..

    Reply ↓
  55. demaxxx

    В файловой работает, в SQL при добавлении расширения получаем http://prntscr.com/mbx5wy

    Reply ↓

Leave a Comment

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