<?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='\
Если метаданные не изменились (почти не изменились) то, возможно, удобнее воспользоваться стандартной обработкой ВыгрузкаЗагрузкаДанныхXML.
Выгружаем объекты в XML.
Загружаем измененную конфигурацию с потерей информации из объекта МД (или реквизита) с изменившимся идентификаторам.
При необходимости модифицируем файл метаданных, добавляя недостающие реквизиты. Сделать это относительно не сложно, выгружаем образец XML из свежей конфигурации, смотрим глазами и через групповую замену текста приводим структуру XML файла к новой.
Загружаем XML.
//
Вариант 2. Переименовать объект МД (или реквизит) в *_OLD, обновить конфигурацию через сравнение, перебросить значение объекта МД (или реквизита), загрузить измененную конфигурацию.
(1) NikNik, навскидку
1. ВыгрузкаЗагрузкаДанныхXML — сопоставляет объекты метаданных и объекты ИБ по внутреннему идентификатору. Соответственно, если при загрузке не будет найден объект метаданных со «старым» идентификатором — выдаст ошибку. Модифицировать XML файл — теоретически возможно, но надо учесть, что надо знать старый и новый GUID справочника, а также старые и новые GUID элементов этого справочника
2. как вы предлагаете перебросить значения объекта МД (или реквизита) ?
(0)
1. При сравнении/ объединении конфигураций, можно объекты сопоставлять.
2. Если требуется конвертация реквизита, то делается это обработку.
(2) vdscom,
1. Обработка сопоставляет метаданные по имени, а ссылки на элементы конечно по идентификаторам.
<V8Exch:Data>
<CatalogObject.Контрагенты>
<Ref>0ccd343a-7ee1-11dd-7284-00119526ff1f</Ref>
2. Написать обработку или воспользоваться УниверсальныеПодборИОбработкаОбъектов.epf
(2) vdscom,
1. Обработка сопоставляет метаданные по имени, а ссылки по идентификаторам.
<V8Exch:Data>
<CatalogObject.Контрагенты>
<Ref>0ccd343a-7ee1-11dd-7284-00119526ff1f</Ref>
2. Написать обработку или воспользоваться УниверсальныеПодборИОбработкаОбъектов.epf
(3) awk,
1. при сравнении, объединении — сопоставление объектов происходит по имени объекта метаданных. при этом сопоставление можно задать вручную.
при создании файла поставки и затем обновлении конфигурации, находящейся на поддержке — сопоставление происходит только по внутреннему идентификатору. при этом при обновлении конфигурации файлом поставки (не через сравнение, объединение) — справочник «Номенклатура», например, со старым GUID будет удален, и вместо него будет добавлен такой же справочник «Номенклатура», но уже с новым GUID. Все данные в базе, связанные с этим справочником, конечно же, пропадут.
2. насчет конвертации реквизита — не совсем понял вашу мысль
(6) vdscom,
Да проще все делается.
1. Переименовывается объект основной конфигурации, Номенклатура -> УдалитьНоменклатура.
2. Обновляется до конфигурации поставщика.
3. Делается обработка:
Пока Выборка.Следующий() Цикл
ОбъектЗаполнения = НайтиИлиСоздать(Выборка);
ЗаполнитьЗначенияСвойств(ОбъектЗаполнения, Выборка);
КонецЦикла;
(7) awk,
я наверное туплю, поясните, что вы делаете этой обработкой ?
что я смог понять:
1. старый справочник переименовываем, обновляем конфигурацию файлом поставки, получаем в конфигурации 2 справочника — старый и новый
2. пишем обработку, которая копирует элементы справочника из старого в новый
вопросы:
1. как вы обработкой измените типы значения реквизитов других объектов ИБ, в которых есть ссылки на элементы старого справочника, а главное, как вы выполните во всех этих реквизитах замену ссылок на элементы старого справочника на ссылки на элементы нового справочника ?..
(8) vdscom,
1. Есть такой метод НайтиСсылки.
2. Я, скорее всего, вообще не совсем понимаю модель обновления.
Вариант 1 (девелоп):
Есть три конфигурации. Вы их сливаете в одну и поставляете потребителю.
Тогда проблема старых гуидов — это надуманная проблема. Так как возникнуть она может только если клиент модифицировал конфигурацию сам. А то что он сам наделал — это уже его головная боль или ваши дополнительные деньги (какие тут три поставки?).
Вариант 2 (продакшан):
У вас есть база и вы хотите ее слить с двумя и более. Тогда зачем использовать механизм поставки? Тут скорее применение инструмента не по назначению (топором дрова рубят, а не бреются, хотя это не запрещено, но вряд ли целесообразно). В данном случае больше подойдет хранилище конфигурации, а не механизм поставки.
Вариант 3 (обновление):
Вы переходите от старой версии к новой. Тогда одно из двух либо у вас совместимые базы (бух 2.0 -> бух 3.0, вариант 3.а) либо не совместимые (бух. 1.6 -> 2.0, вариант 3.б).
Если совместимые и обновление будет проходить без конвертации, то делается как я описал с переименованием объектов и реквизитов, перебросом их на новые и последующем их удалении при очередном обновлении.
Если у вас несовместимые конфигурации, то очевидно что будет выгрузка/конвертация/загрузка всей базы.
Так что способ в вашей статье я могу отнести только к 3.а или к 3.б, поскольку считаю вас квалифицированным специалистом, который не будет бриться топором (вариант 2) или не соблюдать правила при доработке типовых конфигураций у клиента (вариант 1). А так же знает, что конфигурация 1 + конфигурация 2 = конфигурация 3, но не как ни конфигурация 12 или конфигурация 21.
В принципе статью нужно было бы начинать с объяснения того, как можно объединить продукты, что в результате получится, как при этом перенести/сохранить данные. Было бы очень познавательно, особенно для новичков.
(9) awk,
ок, поясню немного ту ситуацию, с которой столкнулся я и для которой было выработано данное решение.
в организации было порядка 8 вариантов конфигураций бухгалтерских баз, основанных на одной конфигурации «Бухгалтерия для Украины». все эти конфигурации обновлялись и дорабатывались независимо, пока мне это не надоело и я не объединил их конфигурации в одну.
эта объединенная конфигурация подключена к хранилищу, и для обновления всех 8-и баз формируется файл поставки.
по факту оказалось, что один справочник, одинаковый по сути для всех баз, в 3-х из 8-и исходных конфигураций имеет GUID, отличающийся от GUID этого справочника 5-и других конфигураций. этот справочник во всех базах активно использовался, поэтому просто удалить его и создать новый не представлялось возможным.
собственно, так и было выработано решение — выгрузить/загрузить данные через КД. иных вариантов я до сих пор не вижу. кстати, как мне мог бы помочь метод НайтиСсылки ? он может изменить тип значения реквизита объекта ?
по вашей классификации, можно считать, что у меня были 2 несовместимые конфигурации
(10) vdscom,
1. А зачем файл поставки? Если можно просто подключать и обновлять напрямую с хранилища?
2.
Есть Конфигурация 1 (КФ 1) и Конфигурация 2 (КФ 2)
КФ 1:
Допустим Контрагенты КФ1 <> Контрагенты КФ2.
Берем КФ1 преименовываем справочник Контрагенты в кф1Контрагенты
Преименовываем рекфизиты с типом Контрагенты в кф1Контрагент, кф1Грузополучатель и т.д.
Обновляем
В итоге:
Показать
Показать
После обработки объекты кф1 можно удалять.
(11) awk,
1. одна тестовая конфигурация (в которой выполняю и тестирую доработки) подключена к хранилищу, в ней создаю файл поставки, им обновляю 8 рабочих баз. если есть способ делать это быстрее, просветите меня
2. возможно, ваш метод и работоспособен, надо проверять. а нужно ли ? будет ли он проще, чем мой метод ?
на самом деле, создать правила обмена в случае когда конфигурация источник = конфигурация приемник и фактически надо настроить ПКО только для искомого справочника, а для всех других объектов — только поля поиска и сам реквизит, содержащий ссылку на этот справочник — занимает до получаса. и это вместе с самой процедурой выгрузки/загрузки и обновление конфигурации.
и не надо несколько раз модифицировать конфигурацию (переименовать справочник, добавить новый, удалить старый).
(12) vdscom,
1. Да, напрямую обновится из хранилища.
2. Теперь представь, что конфигурация которую ты ставишь на такую поддержку (через выгрузку/загрузку) обменивается с другими базами по ИД. Сколько дублей у тебя появится? Сколько правил обмена надо переписать? Что произойдет если изменить поиск по уникальному идентификатору, на поиск по коду, а пользователь изменит код?
3. Код не рабочий. Я его в браузере писал.
(13) awk,
1. согласен, будет немного быстрее. но не всегда это применимо (для удаленных баз, например)
2. не спорю, в такой ситуации изменение УИД недопустимо. но это был не мой случай.
3. я имел ввиду не работоспособность конкретного кода, а работоспособность предложенного метода. а в этом у меня есть некоторые сомнения. УИД конкретного элемента справочника таким способом вы сохраните, а УИД самого справочника как объекта метаданных ?
(14) vdscom,
А тебе он зачем? Как его получить? Где и зачем его надо использовать?
(15) awk,
пока он мне не нужен. понадобится ли завтра — не знаю, не берусь загадывать.
кстати, обновление конфигурации из хранилища мне не понравилось — для конфигурации включается возможность редактирования, что для рабочих баз совсем не нужно. и по времени выигрыша я не заметил, разве что меньше мышкой клацать нужно.
(16) vdscom, А ты клевый.
1. Хранилище можно через http подключить.
2. Для обновления и кликать не нужно — скрипт в задании сам все сделает (без разницы поставка или хранилище у тебя).
3. Если модифицирование конфигурации не нужно в продакшене, зачем в конфигуратор пускать кого-то с такими правами, кроме себя любимого?
(13)awk,
есть у меня подозрение, что при изменении GUID справочника с помощью КД GUID его элементов сохранятся. скорее всего для этого в настройках ПКО справочника надо поставить галочку «Поиск по внутреннему идентификатору».
будет время — проверю.
(18) vdscom, Ты с 8.2 давно работаешь? У меня чувство, что ты недавно пересел с 7.7.
(19) awk, в моем последнем посте было что то не так ?..
(20) vdscom, Не в последнем. Во всех.
А если брать последний комментарий, то можешь не проверять. ГУИД при переносе с опцией ПКО так же переносится. Если ты имел ввиду:
(21) awk, вы уж извините, если я оказался недостаточно профессиональным в ваших глазах. поверьте, я на этом ресурсе не для того, чтобы произвести на вас впечатление.
ну, а если брать во внимание ВАШ последний комментарий, тогда непонятно, чем вас мой метод изменения GUIDa не устраивает, и за что вы мне поставили минус. пал единственный аргумент в пользу вашего метода.
да, я именно процитированный вами текст и имел ввиду
(22) vdscom, По порядку:
1. Я не оценивал профессионализм, я высказал сложившееся у меня впечатление.
2. За что минус:
2.1 Заголовок статьи не соответствует ее содержанию
Заголовок: изменение GUID объекта метаданных
По факту: Частичная конвертация информационной базы.
2.2 Непоследовательность статьи и содержания комментария.
В статье:
В комментариях:
2.3 Куча побочных эффектов метода.
2.4 Алгоритм «мертвый» для баз больших размеров.
(23) awk,
частично согласен только с п. 2.2. поскольку на момент а) проработки метода и б) написания статьи — меня сохранение GUID элементов не беспокоило.
хотя странно, если в процессе обсуждения статьи мое мнение изменилось — это называется «непоследовательностью» ? для чего тогда придумано обсуждение ?
2.1. очень даже соответствует. тем более что в аннотации написано: «Методика изменения внутреннего идентификатора объекта метаданных с помощью конфигурации «Конвертация данных»».
впрочем, переубеждать не буду
2.3. каких ?..
2.4. приходилось переносить через КД порядка 1ГБ данных (размер XML файла).
(24) vdscom,
1. Поменялось мнение, поменяй содержание статьи. Для этого и придуманы комментарии к статье :)))
2. Ты ничего не изменяешь. Ты удаляешь старый объект и создаешь новый. Это принципиально разные понятия для объектных данных.
3. Зависит от правил поиска.
4. 18 000 объектов обмен порядка 2-4 часов (средний справочник номенклатура у продавцов автозапчастей без аналогов).
(25) awk,
1. статью отредактировал
2. а чем еще отличается один объект метаданных ИБ от другого ?.. только GUID-ом. то есть любая смена GUID объекта (в том числе и прямыми заменами в таблицах БД средствами SQL), с точки зрения платформы, является удалением старого объекта и созданием нового.
но с точки зрения прикладного решения, процесс замещения одного объекта метаданных другим, при котором не происходит потери или изменения данных ИБ, является именно изменением GUID.
чтобы подчеркнуть этот «дуализм» в определениях, я взял в заголовке статьи слово «изменение» в кавычки
3. Правила поиска простые — по внутреннему идентификатору. если объект не найден, включается поиск по стандартным полям поиска — «Код», «ЭтоГруппа», «Владелец», «Дата», «Номер». впрочем, учитывая что данные будут выгружаться и загружаться обратно в одну и ту же базу, не думаю, что объект может быть не найден по внутреннему идентификатору
4. а) если (по вашему мнению) метод неприменим для больших баз, это не значит, что он неприменим для малых или средних баз. б) учитывая, что необходимость в «изменении» GUID возникает довольно редко — даже 2-4 часа на выгрузку/загрузку данных это не так и много
(26) vdscom,
Шаг 0. Создаем копию базы и обновляем. Это делает ненужным бэкап.
Не любую, а конфигурацию приемник. После объединения объекта метаданных реквизитов может быть больше чем в источнике, а некоторые из них мы захотим установить в значения по умолчанию. А может быть и меньше, тогда загрузка может выдать ошибки.
Нет смысла использовать поиск по полям, базы одинаковые ищем по УИ.
1. Нам нужен:
Для объектов:
* Реквизит ссылающийся на справочник
Для регистров:
* Все поля. Т.к. при чтении файла обмена наборы читаться не будут, а будут заполняться целиком.
Для регистров бухгалтерии:
* Все поля. Т.к. при чтении файла обмена наборы читаться не будут, а будут заполняться целиком.
* Режим Загрузка=Ложь; иначе на скульных базах рискуем получить дубль уникального индекса в итоговых таблицах
2. В документах установить режим не проводить.
1. Если хотим перенести не все данные. Если хотим перенести все, то делаем ПВД и для справочника.
2. Для ускорения переноса отказываемся от стандартной выгрузки и фильтруем на не пустое значение нашего реквизита.
Излишне при пункте 0.
Излишне при пункте 0.
(27) awk, спасибо за уточнения.
совершенно упустил из виду регистры…