Как провести/перепровести другие документы из модуля документа (при проведении)?




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2025-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='\

37 Comments

  1. support

    Во втором документе надо можно форму не открывать, а сразу поставить СтатусВозврата(0)

    Код
    Процедура ПриОткрытии()
    Если Форма.Параметр="ПровестиИЗакрыть" Тогда
    Провести();
    СтатусВозврата(0)
    КонецЕсли;
    КонецПроцедуры
    

    Показать полностью

    Reply
  2. GROOVY

    Подниму рейтинг! Для новичков очень полезно!

    Reply
  3. CheBurator

    Хм…

    а вот из модуля дока 2 не надо док3 провести…?

    где начало того окнца, которым оканчивается начало?

    Reply
  4. Ну не хочет док 2 выполнять команду «Провести();» !?

    Reply
  5. Блокировки видимо — пустое…

    Ну а если второй документ не проведется — тоже сущая безделица…

    Интересно — хоть кто то это применял на живых пользователях?

    Reply
  6. support

    Применял, и достаточно успешно! Проверь и не будет вопросов.

    Reply
  7. mishau

    Столкнулся с такой проблемой:

    Провожу док раньше ТА. Из него проводится другой док, способом описанным в статье. Вылезает окошко «изменить время документа или провести задним числом». Что бы ни нажимал, второй документ не проводится. Процедуру обработка проведения во втором доке даже пустой оставлял. ТО же самое 🙁

    База на SQL. Если форму второго документа не закрывать, а нажать там «провести» вылетает с ошибкой.

    Reply
  8. astonvilla
  9. O-Planet

    ДЯ??? Не знал про ограничение… Блин! Как же у меня в «Кафе-УСН» проводятся сразу ТРИ типовых дока из «Производство»? О_о

    Reply
  10. astonvilla

    Ото ж, решение проблемы существует уже ну оооочень много времени.

    Reply
  11. yuraer

    А как сделать непроведенным?

    Reply
  12. arithmometr

    (11)

    Док.Удалить(0);

    Док.СнятьПометкуУдаления();

    Reply
  13. arithmometr

    Описанный метод успешно использую на практике.

    Это из недокументированных возможностей.

    А вот вопрос к 1С-гуру: на сколько это безопасно для целостности данных.

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

    Reply
  14. artbear

    Способ давно известный и боянистый.

    тонкостей тут много, как уже упомянуто в (6)

    (13) Посмотри ветку http://www.1cpp.ru/forum/YaBB.pl?num=1265375919/11#11

    там как раз глюки с подобным решением обсуждаются.

    Reply
  15. KrakoZyabl

    Искал решение проблемы — эта ветка помогла.. 😉

    Век живи — век учись. Спасибо 🙂

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

    Reply
  16. hello world

    +

    Большое спасибо : )

    Reply
  17. sten_77

    Попробовал этот метод он ставит чёрную галочку, а не красную и при проведении других документов в ручную выдаёт сообщение «Существую более ранние проведенные документы «. Как программно прописать чтобы ставило сразу красную галочку. Заранее спс

    Reply
  18. agressor

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

    Нужно установить ТА на последний документ в полном журнале (контекстное меню).

    Reply
  19. sten_77

    (18) у меня документ2 последний, а предпоследний документ1 он проведен. Если войти документ2 и нажать кнопку провести галочка становится красной, как программно сделать?

    не помогает Провести(3);

    Reply
  20. agressor

    Попробуй установить ТА программно

    УстановитьТАна(НужныйДокумент);

    Reply
  21. gamletspb

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

    Reply
  22. Gkmy

    (21)

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

    Reply
  23. gamletspb

    (22) конфигурация — любая на платформе 7.7

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

    «задача: «в процессе проведения вложенный документ не проводится … нажать кнопочку», — решаема, в большинстве последних конфигураций решена. » — хотелось бы узнать каким образом?

    Reply
  24. Gkmy

    (23)

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

    Reply
  25. Gkmy

    окно «документ не проведен» (23) вам который метод выкидывает?

    — вот за ним и ищите ответ своей задаче «в большинстве последних конфигураций» (21);

    — за вас покуда только алиса и сири ответы ищут.

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

    Reply
  26. gamletspb

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

    СтатусВозврата(0);Возврат;

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

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

    Reply
  27. gamletspb

    (25)

    — за вас покуда только алиса и сири ответы ищут.

    собственно ответов я не ищу, я у себя давно все сделал как мне надо и оно работает, я просто прокомментировал данную методику в том смысле, что у нее есть довольно существенный недостаток

    Reply
  28. Gkmy

    (26) ну и что это за педологическое извращение такое:

    Процедура ОбработкаПроведения()
    СтатусВозврата(0);
    Возврат;
    КонецПроцедуры
    
    Reply
  29. Gkmy

    (27)

    собственно ответов я не ищу, я у себя давно все сделал как мне надо и оно работает

    так и вам о том же:

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

    Reply
  30. gamletspb

    (28) простейшая имитация отмены проведения, что непонятного?

    Reply
  31. Gkmy

    (30)

    простейшая имитация отмены проведения

    «простейшая имитация отмены проведения», — на стадии отладки — согласен

    найдёте подобную конструкцию в релизе

    дам денег… которая сумма вас заинтересует?

    Reply
  32. gamletspb

    (31) Уважаемый, вы читать умеете или вам заняться нечем? Какой нафиг релиз? Я вам просто привел пример как быстро смоделировать ситуацию. Если вам лень три строки кода написать, чтобы самому убедиться, то мне далее данная дискуссия ни о чем не интересна — оставайтесь при своем загадочном мнении

    Reply
  33. Gkmy

    (32)

    релиз

    Рели́з (англ. release [rɪ’liːs]) — освобождение, выпуск: выпуск, демонстрация, публикация, показ — фильма, книги, пластинки, продукта; также сам выпускаемый объект; сообщение для печати; устройство, освобождающее что-либо: в частности…

    Понятие релиз в моем контексте — равнозначно: конфигурации от 1С, официальные,

    выпущенные конечному потребителю.

    Reply
  34. Gkmy

    (32)

    Конструкция опубликованная вами:

    Процедура ОбработкаПроведения()
    СтатусВозврата(0);
    Возврат;
    КонецПроцедуры
    

    — яркий пример педалогического извращения. Конструкция недопустимая в рабочих ИБ. .

    Reply
  35. Gkmy

    (32)

    О том, что такое «педалогическое извращение» — спрашивайте у гугл.

    Reply
  36. CheBurator

    (34) с чего это она недопустимая?

    в типовой ТиС сплошь и рядом при отработке процедур, выполняемых при проведении документа генерится СтатусВозврата(0) (даже внутри вызваемых дочерних процедур)

    Reply
  37. Gkmy

    (37)

    сейчас у меня под рукой только Бух. уч. 636; вам пари или чего?

    Reply

Leave a Comment

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