Вариант доработки Бухгалтерии предприятия




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

45 Comments

  1. MRAK

    Опять же, не раскрыта тема внешнего добавления элементов на существующую форму…

    Reply
  2. tsd

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

    Reply
  3. MRAK

    (2) пользователю было бы удобней видеть добавленные элементы в типовой форме

    Reply
  4. …Изменения типовых объектов сведены к изменению 2 процедур общего модуля РаботаСДиалогами, все остальное стоит сбоку и жить никому не мешает :)…

    А разве не нужно в модулях изменяемых документов делать подписку на события: ОбработкаПроведения, ПриЗаписи если мы их будем обрабатывать?

    Reply
  5. MRAK

    (4) при чем здесь модули доков? подписки — это отдельные объекты конфы.

    Reply
  6. tsd

    (4) подписка на событие устанавливается не в модуле объекта. В метаданных есть специальные объекты Общие—>»Подписки на события». В общем модуле Вы пишете свою процедуру, указываете ее как обработчик подписки, выбираете источники действия и указываете событие возникновение которого стартует Вашу процедуру. Процедура будет вызвана в конце события. Небольшим условием является то, что Ваша процедура должна содержать определенные параметры. Первым должен идти Источник действия, далее параметры стандартного обработчика 1С. Кроме того процедура должна быть экспортной.

    Reply
  7. tsd

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

    Reply
  8. coder1cv8

    Очень хорошо!

    Reply
  9. Totoro

    Теперь дошло. А что уникальный идентификатор не стал в пояснении шифровать, так по-моему проще:

    GUID = СсылкаНаОбъект.ПолучитьУникальныйИдентификатор;

    СсылкаНАОбъект = Документы[ВидДокумента].ПолучитьСсылку(GUID);

    Reply
  10. Totoro

    (9)+ перепутал

    GUID = СсылкаНаОбъект.УникальныйИдентификатор()

    Reply
  11. KapasMordorov

    <QUOTE>Изменения типовых объектов сведены к изменению 2 процедур общего модуля РаботаСДиалогами, все остальное стоит сбоку и жить никому не мешает :)</QUOTE>

    В самом начале статьи написано про проведение по дополнительному регистру бухгалтерии.

    Без регистратора может быть только регистр сведений. Т.е. в 67 документах нужно редактировать набор движений.

    Сферический конь в ….?

    Reply
  12. alexk-is

    Предлагаю раскрасить примеры кода

    Reply
  13. tsd

    (10) да я как-то про это вообще не задумывался. Получение ссылки на док труда не вызывает и ладно, кроме того пояснение выводится в строку состояния. Наверное, все же лучше видеть некую внятную подсказку, чем непонятный набор символов 🙂

    (11) да, конечно. В приведенном примере, ессно, добавятся изменения по движениям.

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

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

    В любом случае, это гораздо быстрее чем проверять формы доков 🙂

    Reply
  14. tsd

    (12) не умею 🙁 Подскажи, плиз, куда тыкать нужно.

    Reply
  15. Totoro

    (13) Это я к тому, что дата, как и номер документа являются величинами не постоянными и за время работы в форме могут быть изменены 🙂

    Reply
  16. Totoro

    (11) Ничто не мешает использовать механизм от WiseSnake с учетом приведенного кода … Тогда движения не нужно будет редактировать.

    Reply
  17. alexk-is

    (14) Например, сюда http://www.infostart.ru/projects/4014/

    Reply
  18. KapasMordorov

    (16) Так и получается, что на каждую мелочь нужен механизм.

    И тогда простота обновления отличается от заявленной.

    Reply
  19. Totoro

    (18) Извини, но тут уже готовое решение дано. Хочешь без движений — добавляей свой связанный регистр сведений, а при вызове созданной кнопки будешь открывать форму этого регистра, а не документа по его виду (можно сделать универсальную форму как для свойств) и по ссылке устанавливать подчиненые значения. Тогда изменений действительно минимум — добавить тип обекта в регистр, поведение его форм и прописать создание и выполнение кнопки из советов (можно еще использовать процедурку обновления заголовка формы в БП, что бы проверять запись нового документа и обновления ссылки на кнопке).

    Reply
  20. Каким-нибудь еще механизмом можно отловить событие нажатия созданной кнопки, кроме как через «советы»? Просто советы есть не во всех конфигурациях.

    Reply
  21. tsd

    (17) блин, что-то не ладно с руками в датском королевстве. Оставлю как есть, лучшее враг хорошего 🙂

    Reply
  22. tsd

    (20) по ссылкам можно посмотреть другие способы обработки событий.

    В УТ, например, для установки кнопки можно использовать процедуру УстановитьКнопкуПечати(), а нажатие на кнопку отлавливать через ОбновитьФормуПодбора()

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

    Reply
  23. А возможно отловить событие через свойство Кнопки — «Действие»?

    Пр: Меню.Кнопки.Добавить(, , , Действие).

    В справке написано: «Для обработки события может быть вызвана процедура или функция модуля формы или модуля приложения, имя которой задано в конструкторе.»

    Для того, что б не менять код документа — модуль формы не подходит. А вот в модуле приложения почему-то не запускается процедура 🙁

    Reply
  24. KapasMordorov

    Не буду утверждать, что в каждом документе.

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

    Reply
  25. tsd

    (23) у меня не получилось вызвать процедуру, расположенную не в модуле формы.

    Reply
  26. (24) они не передают в общий модуль имя кнопки, по которой произошло нажатие

    Reply
  27. KapasMordorov

    (25)

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

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

    Reply
  28. inse0f

    (1) а если раскрыта просто никто не хочет ее показывать?))

    Reply
  29. dvv01

    ответ в http://infostart.ru/projects/4332/ — обработка табличных частей — автоматически к нужным документам добавляется меню, таб часть меняется или генерятся новые документы. Конфигурация не меняется (может только права доступа, хотя и это можно проверить в самой обработке). Примеры отобраны из Торговли, но сути не меняет

    Reply
  30. lion11

    Хорошая штука!!!

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

    Reply
  31. tsd

    (30) для чего тебе признак модифицированности?

    Reply
  32. lion11

    (31) Я хочу через таким образом добавленную кнопку вызывать форму дополнительных реквизитов, типа как в http://infostart.ru/projects/4288/ , только через Советы, так меньше изменений в типовой. А если док в основной форме изменен, то в этой форме с доп.реквизитами он уже не запишется. Вот мне надо проверить, были ли изменения в текущей открытой форме дока, и с вопросом записать, а потом редактировать свои реквизиты.

    Reply
  33. tsd

    (32) вечером посмотрю

    Reply
  34. tsd

    (32) у меня проблем никаких не возникло.

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

    Reply
  35. lion11

    (34) Спасибо, посмотрел. Но не увидел вот чего: если я открываю форму документа, что-нибудь на ней меняю, например номер, потом нажимаю кнопку Доп.реквизиты, не идет проверка на модифицированность, только на существование этого документа. В твоем случае — это все-равно, т.к. у тебя доп.реквизиты отдельно от документа, а у меня реквизиты принадлежат этому документу, и если я потом в доп форме жму записать — возникает ошибка. (весь смысл — чтоб типовую форму не менять) Но все равно идею приму на вооружение и буду использовать. Еще раз спасибо.

    Reply
  36. tsd

    (35) я думал ты в процедуру Процедура ОткрытьФормуДопРеквизитов(Кнопка)заглянешь. Там специально вставлено

    ФормаОбъекта = Объект.ПолучитьФорму();

    // Сообщить(«Модифицированность формы: » + ФормаОбъекта.Модифицированность);

    :))

    Reply
  37. lion11

    (36) Вот ведь … :)) Смотрел в эту строчку, но просмотрел. У меня было нечто подобное, но я сначала находил объект, а потом его форму — и не работало, а тут у тебя гораздо проще. Потом почитал хелп ПолучитьФорму() для ссылки — там все написано. А так всё получилось. Огромное спасибо, что наставил на путь истинный 🙂

    Reply
  38. lion11

    Возник вопрос:

    У меня на некоторые документы не ловится список, а именно в строке ИсточникДействия = КоманднаяПанель.ИсточникДействий.ДокументСписок;

    не ловится ДокументСписок. Пробовал на РКО и ав.отчеты. (Бухгалтерия предприятия 1.6.18.2). Хотя ДокументОбъект на эти доки ловится успешно.

    Есть мысли, почему?

    Reply
  39. tsd

    (38) ИсточникДействий должен иметь значение Форма, у формы списка РКО для командной панели ДействияФормы Источник действия установлен ВсеИсточники, поэтому и не ловит

    Reply
  40. lion11

    (39) Понятно, спасибо. Поставил Форму и получилось!

    Интересно, это так задумано или просто недочет разработчиков?

    Reply
  41. tsd

    (40) а кто ж его знает. В типовых это свойство никакой поленой нагрузки не несет, наверное просто не заполнили

    Reply
  42. artbear

    (0) По адресу для скачивания примера лежит файл, который не загружается ни в 8.0, ни в 8.1.14.72

    Какая версия 1С нужна для загрузки примера?

    Reply
  43. tsd

    (42) 8.1. , судя по дате, тогда у меня стоял 12 релиз платформы. Похоже просто файл битый. Посмотрю дома, если пример сохранился, то выложу заново.

    Reply
  44. vladimir_che

    Занимательно. Ваш пост единстенный находится поиском по сайту по слову «писька».

    » .НадписьКартинка «

    Reply
  45. lion11

    Грустное примечание:

    Сделал это все в редакции 1.6, все красиво. Начал переходить на редакцию 2.0 — а там засада: практически нигде нет в процедурах ПередОткрытием Советов 🙁

    Придется сделать через функцию УстановитьДоступностьПоляВводаНомера

    Reply

Leave a Comment

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