Перенос данных о сотрудниках из Зарплаты и Управления Персоналом в Бухгалтерию Предприятия через COM-соединение




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

35 Comments

  1. WiseSnake

    А зачем?

    Reply
  2. jorikfon

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

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

    У нас ведь появится 2 сотрудника с одинаковым наименованием.

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

    Думаю надо добавлять еще и код.

    Reply
  3. fxfan

    (1?2)Эта обработка нужна, если ЗП ведется в ЗУП, а в БП многие сотрудники получают деньги, доверенности, сдают ав.отчеты и там нужны их пасп.данные и должности. В этом случае и повторы не

    страшны. достаточно хотя бы одного элемента справочника в БП.

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

    Reply
  4. Valerich

    «Физические лица сопоставляются по коду справочника» — а вот это ИМХО уже очень плохо. Если есть 2 устоявшиеся базы с большим количеством физ лиц, причем коды разные. У меня синхронизация ЗУП и Бух в плане физ лиц выполняется по номеру ПФР (должен быть у всех). Но если номер все же отсутствует поиск идет по ФИО.

    Reply
  5. fxfan

    (4)Согласен, у меня тоже так было сделано в другой задаче, а здесь ведущая база ЗУП, из нее регулярно ПЕРЕНОСЯТСЯ данные, т.е. первичная синхронизация не требуется, а потом при изменении атрибутов все перенесется правильно.

    Reply
  6. KapasMordorov

    Реквизит «ВидЗанятости» (перечисление) есть в справочниках сотрудниках в обеих конфигурациях. Вполне подойдет для синхронизации совместителей.

    Физлиц лучше конечно по ФИО синхронизировать, не по коду.

    У меня например так: требуются должности и подразделения для указания в печатной форме АО. Зарплата в ЗУП. В БП все сотрудники не нужны. Поэтому в БП создается физлицо без указания прочих реквизитов, потом из ЗУП переносятся кадровые документы по этому физлицу (сотруднику) (синхронизация по полному ФИО). При это в БП в кадровых документах очищаются строки с отсутствующими в БП сотрудниками.

    Синхронизация по ПРФ, например, в этом случае не поможет, т.к. все сотрудники (несколько тысяч) в БП не нужны, подотчетников гораздо меньше.

    Еще так получается потому, что в РКО должность и подразделение не нужны, нужны только в АО, который уже после РКО. Так и получается цепочка: физлицо в БП -> перенос кадровых данных из ЗУП ->печать АО.

    Reply
  7. densss

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

    Reply
  8. vis_tmp

    СПАСИБО!

    Reply
  9. Orland

    Что то не получается к базе ЗУП подключиться

    Reply
  10. fxfan

    Orland! Какие выдаются сообщения при попытке подключения?

    Reply
  11. viplesson

    good

    Reply
  12. andru_dv

    Спасибо!

    Помогло в работе.

    Reply
  13. Я_Лена

    а если база в клиент серверном варианте, подключится?

    Reply
  14. fxfan

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

    Reply
  15. cerg110

    Спасибо. полезный отчет, немного переделать и будет то что надо).

    Reply
  16. Borisych

    глупо синхронизировать физ.лиц по коду — в типовых правилах (например, выгрузка отражения зарплаты в регл. учете, да и в других) синхронизация ф.л. идет по «Наименование + ДатаРождения + ЭтоГруппа»

    Reply
  17. fxfan

    Конечно,Borisych, в общем виде по коду плохо. Здесь это использовано исходя из скорости поиска (для организации Вашего варианта синхронизации потребуется предварительно закачивать весь список физлиц в таблицу значений совместно с Вашим ключом) а также исходя из варианта использования обработки: главная программа-ЗУП, физлицо всегда сначала заносится в ЗУП, а потом переносится в БП, так что коды будут совпадать.

    Reply
  18. Katya.buh

    Здравствуйте, Владимир! А Вы не могли бы скинуть свою обработкумне на эл. почту(S-blueberry@yandex.ru) Ваша обработка очень полезная и нужная

    Reply
  19. novichek_1c

    Не подключается к ЗУП. Выдает сообщение -«Невозможно подключится к ЗУП»?

    БП — 2.0.31, ЗУП — 2.5.43. Поля Дата, путь к базе, пользователь заполнены

    Reply
  20. Katya.buh

    У меня тоже самое «Невозможно подключится к ЗУП»

    Reply
  21. grig_nv

    У меня тоже ошибка открытия базы.

    А просто если внимательно посмотреть синтаксис в помощнике то надо просто еще кавычек добавить. Ну или в форме с кавычками указать.

    Reply
  22. fxfan

    Спасибо, grig_nv!

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

    Еще важно: надо указывать параметры или для клиент-серверного варианта или для файлового (для неиспользуемого варианта параметры должны содержать пустую строку).

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

    Reply
  23. PeaceDOS

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

    Reply
  24. fxfan

    PeaceDOS, спасибо за оценку!

    Уточните, пожалуйста, хронологический порядок- кадровые документы переносятся в БП с теми же датами, что и в ЗУП, т.е хронология за период переноса сохраняется.

    Reply
  25. PeaceDOS

    Скорее всего косяк в моей базе, может тогда подскажете как его решить.

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

    Reply
  26. PeaceDOS

    {Форма.Форма.Форма(1472,9)}: Переменная не определена (ОбщегоНазначения)

    Если <<?>>ОбщегоНазначения.ТолькоЦифрыВСтроке(Регион) Тогда (Проверка: Толстый клиент (обычное приложение))

    {Форма.Форма.Форма(1787,24)}: Переменная не определена (УправлениеКонтактнойИнформацией)

    стрки.Представление=<<?>>УправлениеКонтактнойИнформацией.ПолучитьПредставлениеАдреса(стрки) ; (Проверка: Толстый клиент (обычное приложение))

    {Форма.Форма.Форма(1811,24)}: Переменная не определена (УправлениеКонтактнойИнформацией)

    стрки.Представление=<<?>>УправлениеКонтактнойИнформацией.ПолучитьПредставлениеАдреса(стрки) ; (Проверка: Толстый клиент (обычное приложение))

    Конфигуратор дает такие ошибки. Как блин их исправить?))

    Reply
  27. PeaceDOS

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

    Reply
  28. PeaceDOS

    В общем разобрался со всем. Единственная ошибка обработки которую пришлось исправлять — со внешними/внутренними совместителями.

    Reply
  29. fxfan

    PeaceDOS!Надеюсь, что все в порядке! На всякий случай: обработка просматривает приказы о приеме за заданный период и переносит их, если нет приказа, то не будет записи в регистр Работникиорганизаций и не будет элемента в списке Сотрудники. удя по ошибкам конфигуратора, стоит уточнить релиз конфигурации.

    Reply
  30. PeaceDOS

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

    Reply
  31. fxfan

    30 PeaceDOS! Есть такая проблема.Дело в том, что в приказе о приеме на работу в БП нет даты окончания работы, которая есть в приказе о приеме в ЗУП, т.е. надо генерить приказ об увольнении,которого нет в ЗУП и вряд ли это хорошо. Если человека уволят приказом, то приказ попадет в БП. Если приказа не будет, придется вводить приказ об увольнении руками в БП. Можно, конечно, генерить приказ об увольнении, но надо решить проблему с нумерацией таких приказов.

    Reply
  32. Maranet

    Спасибо, взял за пример

    Reply
  33. muza1969

    Спасибо, помогла в нужный момент.

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

    Reply
  34. Stellarboy

    а мне поможет эта обработка, нужно перенести из зуп в общепит?

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

    скиньте кто-нить на x223322@hotmail.com

    нет к сожалению возможности скачать

    Reply
  35. Meduse

    Здравствуйте, обработка прерывается такой ошибкой:

    {Форма.Форма.Форма(1725)}: Ошибка при вызове метода контекста (получить)

    пасп8=ЗаписьИзНабора8.срезпоследних(ппр.дата,ЗаписьФЛ).получить(0);

    по причине:

    Произошла исключительная ситуация (1C:Enterprise 8.2.17.169): Значение индекса выходит за границы диапазона

    Запущено под Wine Etersoft 1.0 Network. Подскажите как исправить. Очень нужно.

    Reply

Leave a Comment

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