<?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='\
Со всеми примерами еще подробно не разобрался, но по первому есть вопросы.
Прием с выгрузкой «фальшивого» объекта — крутой и иногда очень сильно спасает, но тут, кажется, можно было сделать проще. Я в похожей ситуации создавал «СписокЗначений», заполнял его значениями с представлениями, имена которых совпадают с именами полей приемника, а потом передавал в ПКО как «ВходящиеДанные». Табличные части передаются как ТаблицыЗначений. При этом получается, что не надо определять в каждом ПКС переменную «Значение», она сама из входящих данных подтянется. ПКО и ПКС выглядят более аккуратно что-ли, ну и по полной используются механизмы, заложенные в КД
Получается что-то вроде такого:
ПВД:
Показать
В ПКО у реквизитов шапки и у ПКГС табличной части ставим флаг «получить из входящих данных». Бонус: в ПКС полей табличной части не надо ничего писать или ставить какие-то галки, все само схватится
Мир этому дому!
Конвертация — как шаманство — есть инструмент и правила, а все остальное свобода творчества. Судя по статье — это результат практического использования. Это всегда плюс.
После того как познакомился с XDTO-серилизацией конфигурацию «Конвертация данных» вспоминаю как страшный сон. Автор молодец. На конкретном примере показал убогость и неестественность правил и приемов КД при обмене данными между разнородными системами. За это и плюсую.
(3) особенно в 7.7 XDTO сериализация рулит 🙂
на практике перенос (планирование — разработка — тестирование — эксплуатация) из конфигурации 77 в 82 с помощью КД выполняется в несколько раз быстрее, чем альтернативные варианты.
(3) xotr, раз такой крутой механизм для тебя, то почему нет ни одной твоей статьи про XDTO-сериализацию?
(5) Istur,
так одно в страшном сне, другое — видимо, в прекрасном сне 🙂
(5) xotr не писатель, xotr читатель:)
п.с. В соседней ветке про XDTO целый цикл статей замутили, желающие могут ознакомится.
Да, это идея, полезная на практике. Ещё в 2008-м пользовался точно таким подходом, разве что между двумя восьмёрочными конфами. Спасибо автору, что подробно всё разжевали и показал, мне в своё время недосуг было.
Автор заслуживает громадное уважение за то, что самостоятельно разобрался с системой КД, т.к описание КД оставляет желать лучшего (мягко говоря). Но сейчас для программистов появился громадный помощник — курсы Гилева. Все подобные задачи на курсах выполняются в качестве домашнего задания, от «шаманства» ничего не остается.
(3) xotr, «На конкретном примере показал убогость и неестественность правил и приемов КД при обмене данными между разнородными системами.»
На самом деле, это вопрос компетенции. Если разобраться с КД — то никакой убогости, вполне достойная и работоспособная система.
спасибо за статью) на пару дней пораньше бы еще лучше было) эээх)
Хорошая статья, очень нужная информация! Плюс однозначно! 🙂
Спасибо! Наглядные и показательные примеры, когда надо «приготовить из ничего…»
Спасибо. Наглядно сделал.
Где вы раньше были? Всех сотрудников с 7-ки руками фигачили 🙁
(3) xotr, Интересно как в XDTO можно решить задачи по конвертации одного объекта в другой, получения из одного объекта двух и более, а также наоборот, настроить поиск и прочие фичи. Сдается мне у вас есть опыт тривиального обмена через XDTO между типовыми конфами в общем виде. Не помню, чтобы при использовании XDTO, можно было бы вмешаться в процесс формирования итогового файла выгрузки.
Отличная статья! Помогла разобраться в некоторых вопросах, где раньше тупил. Спасибо автору!
Спасибо за статью, нормально написано, хоть и не ново.
Видать, стал я матёрым конвертатором, ничего не удивило)
(15)formix
Синтаксис-помощник:
Механизм XDTO позволяет создать модель представления данных (модель типов и значений), которая, с одной стороны, обеспечивает возможность просто и естественно манипулировать данными в среде 1С:Предприятия 8, а с другой стороны, данная модель хорошо приспособлена для прозрачного преобразования данных в другие форматы, главным образом XML.
На практике достаточно:
1.создать модель документа «Ляляля» в базе приемнике
2.создадать и описать файл для записи данных в xlm-формате
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
НоваяЗаписьXML = Новый ЗаписьXML;
ФайлXML = ОсновныеПараметры.ФайлВыгрузки;
НоваяЗаписьXML.ОткрытьФайл(ФайлXML, ПараметрыЗаписиXML);
ЗаписьСообщения.НачатьЗапись(НоваяЗаписьXML, СтрокаТаблицыИнформации.УзелИнформационнойБазы);
// из описания типов фабрики XDTO выберем нужные для создания объектов
Фабрика = ФабрикаXDTO;
документыТип = Фабрика.Тип(«http://www.lalala.ru», «Документы»);
// дальше объектные реквизиты и табличные части
ЛяляляТип = ДокументыТип.Свойства.Получить(«ляляля»).Тип;
ТЧляляТип =ЛяляляТип .Свойства.Получить(«ТЧляля»).Тип;
ЭлементТЧляляТип =ТЧляляТип.Свойства.Получить(«ЭлементТЧляля»).Тип;
3.запросом получить все необходимые данные для заполнения ляляля-объекта
4. обработать выборку:
Документы = Фабрика.Создать(документыТип);
Пока Выборка.Следующий() Цикл
//создадим объект XDTO и заполним его
ЛяляляОбъект = Фабрика.Создать(ЛяляляТип);
ЗаполнитьЗначенияСвойств(ЛяляляОбъект, Выборка)
документыТип.ляляля.Добавить(ЛяляляОбъект);
КонецЦикла;
5. закончить формирование XML-файла
Фабрика.ЗаписатьXML(НоваяЗаписьXML, Документы);
ЗаписьСообщения.ЗакончитьЗапись();
НоваяЗаписьXML.Закрыть();
Курсы — это когда дают знания, которые потом народ не знает, куда применить.
Все это делается более наглядным и быстрым способом — через DBF.
(17) sa1m0nn,
нет, просто тут затронута сугубо узкая специфика.
И все делается кодом — все преимущества КД сведены только к выгрузке в XML.
Из всей неисчерпаемой как атом КД можно зазубрить один приём — в ПВД создается таблица значений по структуре совпадающей с объектом из Приемника и вызывается ПКО — и можно быстро решать массу одноразовых задач. Достаточно посмотреть примеры конвертаций из КД.
(21) Tishu,
«одноразовых» — это только создание в приемнике тех объектов, которых нет с источнике.
(19)
Кому-то каменным топором удобнее, кому-то — станком с ЧПУ… Каждому своё.
Человек, победивший КД, уже достоин уважения 🙂
А еще этот человек не поленился и поделился своими достижениями!
Молодец! Плюс.
XDTO Конечно отличный механизм, и не буду защищать КД, но тем не менее очень часто нужно сделать обмен и очень быстро, правильно описать большие объемы по средствам XDTO это то же серьезная работа, особенно если меняешься между разными структурами метаданных или вообще между 77 -> 8.2 . Или еще усложним, из 8.2 в иные реляционные структуры с извесной нам структурой но не свойственной 1С источнику вообще по структуре МД.Имеет место быть в общмею
(23) saiten,
ну конечно, чем непонятнее и замуторнее — тем лучше: и сам не понимаешь, что там делается, и коллеги ничего не разберут, но зато сколько таинственности и значимости… 🙂
А вот и слушатели под стать:
Эххх мне бы лучше другое
(26) Думаю, эта тема мусолилась уже достаточно, чтобы не поднимать её ещё раз. А непонятность, собственно, — вещь относительная.
Спасибо очент необходимое и интересное ренение
Как алтернатива КД имеет место на существование спасибо
(19) AlexO
Да, Вы правы…
Через DBF все получается гораздо быстрее, прозрачнее и более управляемо.
Можно из одного большого выгруженного файла с кучей информации брать
по необходимости то, что сейчас нужно, а также делать преобразования
объектов «на лету». Причем, для совершенно разных, иногда очень слабо
совместимых конфигураций ( даже и не 1С-овских иногда 🙂 )
Но, все равно, автору большое спасибо за подробное описание процесса !
Очень интересное решение.В практических делах пригодиться,особенно если работаешь с разными структурами метаданных или вообще между 77 -> 8.2 надо делать переброску.
Спасибо за информацию) Оч. сложные приемы конвертации, я бы через OLE, наверное, делала, если бы мне пришлось делать такой перенос)
Нового ничего не узнал, но статья заслуживает уважения. Рекомендую прочитать методичку О. Кузнецовой, все эти моменты там есть.
Недостаток использования переменной ВыборкаДанных с моей точки зрения — слишком много написанного кода, не всегда наглядного. То есть чтобы понять как какой объект или свойство трансформируется нужно читать весь код в обрабочике «передобработкой» ПВД. Кроме того фильтры при выгрузке из 7.7 работать не будут.
В КД есть более эффективные и наглядные механизмы: использование переменных ВходящиеДанные и Исходящиеданные, а также КлючВыгружаемыхДанных, функции ВыгрузитьПоПравилу(). Возможно в этой задаче разница особенно и не заметна, но в основной массе задач, использование указанных мной переменных более оправдано.
Да, статья полезная. Подобный способ сам использовал при переносе из самописной 7.7 в типовую УТ 10.3, кстати методичка Кузнецовой мне помогла.
Вообще КД интересная штука, иногда осознание того, как работает правило приходит только после создания этого правила.
Кстати белый серого сейчас через бедро на иппон бросит.
(0) ИМХО, для каждого ПКС в ПГКС создавать обработчик:
не надо
(34) Franchiser, Здравствуйте. Как раз разбираюсь с этими переменными, есть много вопросов. Так например задача такая — Для простоты будем считать, что конфигурации самописные, и разные по структуре. В источнике есть документ, в приемнике надо из этого документа создать два объекта 1) справочник. 2) РегистрСведенийЗапись. Пытаюсь сделать так. 1) ПКО — Документ ->Справочник,
2) ПКО Источника нет -> РегистрСведенийЗапись, ПКС — В приемнике — структура регистра (3 поля), стоит флаг «Получить из входящих данных». Далее в ПВД Документ. В обработчике «ПослеВыгрузки» запросом получаю таблицу движений документа, для переноса их в регистр сведений в приемнике. Тут же надо вызвать функцию «ВыгрузитьПоПравилу()», но вот сложности. В какие параметры, чего пихать, и как это вообще должно работать. То есть, можно ли в параметр ИсходящиеДанные записать таблицу значений (Выгрузку запроса) или создать выборку, и в цикле формировать структуру, и вызывать выгрузить по правилу. Скажу сразу, в моем случае, ни так ни эдак не работает. Обмен происходит по средствам типовой обработки обмена. Если не сложно расскажите в двух словах, как правильно с этим работать, и использовать.
Добрый день. А есть ли возможность отследить в событии после загрузки, попал ли определенный документ в выгрузку? Мне важно знать есть ли в файле, другой документ по такому же договору как мой, только с другим видом… Не могу нигде найти(
(39) ultrannge89, через [Сообщить()] выводите, в событии [При загрузке].
Здраствуйте! Подскажите, плиз, как перенести справочник Номенклатура по отбору
Показать
Выгрузка проходит успешно.
Но есть проблема: Как правильно задать ПКО и ПКС ?
Спасибушки! безценная консультация!!
Обычно весь выгружаемый объект формируют в ПВД, а не в ПКГС и разных местах.
(43) Да. Можно было бы сформировать в ПВД структуру соответствующую объекту в приемнике и передать нужному ПКО. Это был бы более наглядный вариант.