<?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='\
а то это за формат у файлика —
2009.04.08 UdalitjBityeZapisiIzRegistrovSvedenijNakopl?
расширение какое и для какой 1С?
Имя файла обрезалось 55 символами
буду делать короткие имена
Обработка для 8.1, обновил файл
А она применима для РБД, если документ удалился, а движения остались?
Думаю, что да. Модуль под паролем ((
убивает записи где в поле регистратор видишь надпись типа <Объект не найден : и GUID>
сейчас нет примера показать
Пароль для просмотра модуля???))))
а что в этом, простите, сложного? коду ей богу меньше чем на страницу.
сама себе такое писала. Скачала, потому что было интересно посмотреть реализацию. Зачем пароль то?))
{ВнешняяОбработка.УдалитьБитыеЗаписиИзРегистровСведенийНакопления(51)}: Ошибка при вызове метода контекста (Выполнить): {(6, 2)}: Неоднозначное поле «Регистр.Регистратор.Номер»
<<?>>Регистр.Регистратор.Номер ЕСТЬ NULL
по причине:
{(6, 2)}: Неоднозначное поле «Регистр.Регистратор.Номер»
<<?>>Регистр.Регистратор.Номер ЕСТЬ NULL
Процедура УдалитьБитыеСсылки()
Для Каждого Регистр Из Метаданные.РегистрыНакопления Цикл
Состояние(Регистр.Имя);
УдалитьБитыеСсылкиРН(Регистр.Имя);
КонецЦикла;
Для Каждого Регистр Из Метаданные.РегистрыСведений Цикл
Если («» + Регистр.РежимЗаписи) <> «ПодчинениеРегистратору» Тогда
Продолжить;
КонецЕсли;
Состояние(Регистр.Имя);
УдалитьБитыеСсылкиРС(Регистр.Имя);
КонецЦикла;
КонецПроцедуры
Процедура УдалитьБитыеСсылкиРН(ИмяРегистра)
Запрос = Новый Запрос(
«ВЫБРАТЬ
| Регистр.Регистратор
|ИЗ
| РегистрНакопления.» + ИмяРегистра + » КАК Регистр
|ГДЕ
| Регистр.Регистратор.Номер ЕСТЬ NULL
|
|СГРУППИРОВАТЬ ПО
| Регистр.Регистратор»);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НЗ = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Выборка.Регистратор);
НЗ.Записать();
КонецЦикла;
КонецПроцедуры
Процедура УдалитьБитыеСсылкиРС(ИмяРегистра)
Запрос = Новый Запрос(
«ВЫБРАТЬ
| Регистр.Регистратор
|ИЗ
| РегистрСведений.» + ИмяРегистра + » КАК Регистр
|ГДЕ
| Регистр.Регистратор.Номер ЕСТЬ NULL
|
|СГРУППИРОВАТЬ ПО
| Регистр.Регистратор»);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НЗ = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Выборка.Регистратор);
НЗ.Записать();
КонецЦикла;
КонецПроцедуры
(8)
Регистратор в этом случае не документ, обработка корректно отрабатывает битые ссылки для РС, подчиненных регистраторам — документам, а у них номер есть 🙂
Не ребята демократы. С закрытым кодом это все «НАХ». Слишком старшные последствия подобных чисток могут быть.ТОЛЬКО «-«
Добавлена чистка регистров бухгалтерии
А если в поле в поле регистратор нет надпись типа <Объект не найден : и GUID>
— а пусто. Что тогда делать?
Марьяна!
Поподробнее опишите ситуацию, пожалуйста!
Какой регистр, что происходит при попытке открыть регистратор (дабл-клик по полю), скриншот выложите
УТ (1.3.7.9) выдал ошибку:
{Форма.Форма(35)}: Ошибка при вызове метода контекста (Записать): Ошибка записи! Не установлен отбор по регистратору (Регистр накопления: Партии товаров на складах (управленческий учет))
НЗ.Записать();
по причине:
Ошибка записи! Не установлен отбор по регистратору (Регистр накопления: Партии товаров на складах (управленческий учет))
(15) Странно, базы УТ с битыми ссылками у меня нет, но запрос по всем регистраторам очистил регистр без ошибок. Если не разрешите Вашу ситуацию — могу выслать обработку для удаления всей лишней информации, а то что получится после зачистки — присылайте мне для анализа
Регистратор имеет идентификатор равен : 00000000-0000-0000-0000-000000000000
Обробка дает ошибку:
{Форма.Форма(73)}: Ошибка при вызове метода контекста (Записать): Ошибка записи! Не установлен отбор по регистратору (Регистр бухгалтерии: Журнал проводок (налоговый учет))
НЗ.Записать();
по причине:
Ошибка записи! Не установлен отбор по регистратору (Регистр бухгалтерии: Журнал проводок (налоговый учет))
(17) В моей правктике пока такого не встречалось, но предполагаю, что проводилось тестирование и исправление с переключателем «При наличии ссылок на несуществующие объекты» в положении «Очищать ссылки»
Да проводилось проводилось тестирование и исправление, но с переключателем «При наличии ссылок на несуществующие объекты» в положении «Не изменять». Как можно решить єту проблему?
Написать обработку для выявления таких записей и удалить
Если записей не очень много — могу выслать вам универсальную обработку удаления объектов ИБ, дату зададите = дате битой записи регистра
Если много — и все типа 00000000-0000-0000-0000-000000000000 — нужно найти способ выбрать все подобные записи, очистить их, перепровести документы за период появления записей
Обработка сервис – групповое изменение справочников и документов выдает ошибку на этапе — ….ПолучитьОбъект(). Объект не выбран. Если маете другую обработку, которая справляетесь с этим заданием вышлите, пожалуйста!
(21) Адрес
marjanalucik@rambler.ru
По чему модуль под паролем?
При закрытом модуле есть вероятность нахождения вируса в модуле, а значит запускать такую обработку опасно.
А так же считаю не красиво заставлять пользователя голосовать при закрытии.
С удовольствием поставил бы «МИНУС».
Весь код выложен в этих комментах, см. выше
Ничего лишнего в коде нет, гарантирую
Будет время выложу открытую версию
Заодно надо реализовать корректную отработку регистраторов — как документов, так и справочников
Borisych — приношу свои извинения. Про комменты не знал/не понял. Несколько раз качал вашу обработку. Видимо неудачно. «АХРЕНИТЕЛЬНО ВЗЛЕТЕТЬ» -Спасибо за критику, но от своих слов не откажусь под страхом смерти.Преценденты были. Поэтому ко всему с закрытым кодом отношусь только отрицательно.
фигня полная! отбора регистров нет, мусолила базу полчаса потом вывалилась с ошибкой!
(28) При открытии сформируй список регистров — проставь флажки — и используй обработку помеченных
программировать 10 минут
Простая и полезная штука!
Спасибо, реально помогало.
помогает для восстановления обмена, повторная чистка
спасибо, пригодилось для своей разработки
спасибо, пригодилось при повторной настройке обмена данными УТ-БП
Спасибо за обработку, хорошо работает при малых данных, как можно ускорить процесс для больших данных кол-во записей может превышать больше 10 000 записей
Спасибо! Хорошая обработка!
(37) Maks_Payn, пожалуйста 🙂
Спасибо. съэкономил время.
Спасиб! отработала корректно, время заняло немного, всем доволен!
2 (9) Автор, а разве в регистрах сведний с режимом записи не подчиненном регистратору не может быть битых сылок?
В противном случае пишите «Удалиение битых ссылок ТОЛЬКО по регистрам подчиненным регистратору»
Автор, здаестя мне я видел этот код в публикацииhttp://infostart.ru/public/82878/
(43) DenIv,http://infostart.ru/public/19574/ — не кажется, что публикация 19574 была опубликована гораздо раньше чем 82878???
не увидел ответа на вопрос из (42)
(45) DenIv, и не увидишь. в данный момент не интересно заниматься обработкой трехлетней давности
(46) не поверишь — не интересно. посыл был следующий: в описании обработки написать, что удаляет она ссылки ТОЛЬКО по регистрам с режимом записи — подчинен регистратору и не вводить народ в заблуждение и не важно сколько лет поделке.
Спасибо! Пригодилось!
{Форма.Форма(50)}: Ошибка при вызове метода контекста (Выполнить): {(6, 2)}: Неоднозначное поле «Регистр.Регистратор.Номер»
<<?>>Регистр.Регистратор.Номер ЕСТЬ NULL
Выборка = Запрос.Выполнить().Выбрать();
УТ 10.3.7.9
Огромное спасибо!!! Все получилось с первого раза.
Столько времени было потеряно зря.
А, как это лечится?
{Форма.Форма.Форма(50)}: Ошибка при вызове метода контекста (Выполнить)
Выборка = Запрос.Выполнить().Выбрать();
по причине:
{(6, 2)}: Неоднозначное поле «Регистр.Регистратор.Номер»
<<?>>Регистр.Регистратор.Номер ЕСТЬ NULL