<?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='\
а для 77 есть что-то похожее??
(1) по уму д.б. настраиваемя обработка для удаления из любых строковых реквизитов определенного настраиваемого набора «символов», как-то : табцляции, переводов строк и прочего — что напрочь ломает выгрузку/загрузку в XML и прчие неприятности делает…
Есть претензии к реализации 🙁
1. Нафига нужна переменная Отказ?
представь, что у тебя глюк/отказ на первом же элементе?
у тебя в транзакции сначала обработаются все элементы, а потом все равно будет отмена этой транзакции.
После Отказ = Истина сделай Прервать
2. не видно, по какой причине элемент может быть не записан, т.е. по какой причине выдано исключение 🙁
3. у тебя будут обрабатываться/изменяться все элементы, независимо от наличия у них нужного сочетания пробелов.
Совсем не гуд.
Ведь в запросе можно сразу выбрать только те элементы, у которых в выбранном поле есть более 2-х пробелов.
В общем, до исправления вышеперечисленного минусую.
(1) Для 77 реализовать такой алгоритм не получится, т.к. в ней нет оператора Выполнить()
(2) Если осуществлялся переход с другой системы учета, которая уже не используется, то обмен не нужен. При распределенной базе данных, поменяв данные на главном узле, изменения расползутся по всем базам.
(3+) 4. Нафига нужен код
Ссылка = Справочники[Справочник].НайтиПоКоду(1);
он все равно подходит не для всех справочников 🙁
юзай
Ссылка = Справочники[Справочник].ПустаяСсылка();
(4) «Для 77 реализовать такой алгоритм не получится, т.к. в ней нет оператора Выполнить()»
вот с чего ты это взял? там есть штатный метод Шаблон, + в ВК 1С++ есть мощнейшний объект ВыполняемыйМодуль.
(3+) 5. Также я посоветовал бы код
исправить на следующий
Т.к. в некоторых конфигурациях синоним не всегда «совпадает» с именем, и это далеко не редкость 🙁
Будет чуть удобнее 🙂
(3) (5) (7) Спасибо большое! все поправил 🙂
(6) я имел ввиду именно такой алгоритм. А вообще, я всех тонкостей 77 не знаю, т.к. 1С начинал изучать сразу с 8.1
(8) зря ты исправил порядок замены пробелов.
Раньше, когда сначала 3 пробела менялись на один, а потом 2, было правильно.
А сейчас наоборот и это неверно.
Например, стоит 3 пробела, у тебя сначала заменятся 2 пробела, и останется также 2 пробела, которые уже не будут заменены 🙁
(8) 1. Я бы код
заменил бы на немного другой, без обращения к реквизиту через объект, а через спец.переменную значениеРеквизита, которая заполняется из Выборка.Реквизит, а перед записью
Объект.[Реквизит] = значениеРеквизита;
2. сообщение о замене совсем не актуально и наверняка не очень нужно.
ИМХО удобнее просто вывести количество заменяемых элементов 🙂
В (9) был неправ 🙂
забыл, что ты исправляешь пробелы от 2 до 4 включительно, большее количество пробелов не будет исправлено, хотя такое их количество большая редкость, конечно.
наверное, это также не гуд 🙂
На ИТС есть Универсальный поиск и обработка объектов. в ней в режиме 1С-Предприятие прикручиваешь свой код, который пишется за 5 минут (СтрЗаменить) — и вуаля!!!
Щасте!!!!
(12) Да, все правильно. Только не все могут написать код. И на портале не только программисты…
(0) Ты по (10) исправил?
(14) Да, все исправил.
Минус убрал.
Таб=СоздатьОбъект(«ТаблицаЗначений»);
Таб.НоваяКолонка(«Номенклатура»,»Справочник.Номенклатура»);
Таб.НоваяКолонка(«НовоеНазвание»,2,200);
Тов=СоздатьОбъект(«Справочник.Номенклатура»);
Тов.ВыбратьЭлементы();
Пока Тов.ПолучитьЭлемент()=1 Цикл
Нашли=0;
Название=Тов.Наименование;
Пока Найти(Название,» «)>0 Цикл
Нашли=1;
Название=СтрЗаменить(Название,» «,» «);
КонецЦикла;
Если Нашли=1 Тогда
Таб.НоваяСтрока();
Таб.Номенклатура=Тов.ТекущийЭлемент();
Таб.НовоеНазвание=Название;
КонецЕсли;
КонецЦикла;
Таб.ВыбратьСтроки();
Пока Таб.ПолучитьСтроку()=1 Цикл
Тов.НайтиЭлемент(Таб.Номенклатура);
Тов.Наименование=Таб.НовоеНазвание;
Тов.Записать();
КонецЦикла;
(17) Да, ты прав, так все будет работать. А вот как сделать, если мы не знаем ни названия справочника, ни названия реквизита на этапе кодинга?
Скачал… работает, но не совсем корректно… пробовал для справочника Номенклатура… во-первых, может обрабатывать только Полное наименование, а Наименование почему-то нет… во-вторых, как я понял, убирать заданное количество пробелов, т.е. если есть 5 пробелов, то за один прогон обработка уберет 2 или 3 пробела, следовательно, обработку надо запускать несколько раз…
(0) Предлагаю дополнить функционал — убивать лидирующие пробелы.
(18) В смысле — как в 77 по символьному имени обращаться?
Спр=СоздатьОбъект(«Справочник.» + имяСправочника);
ЗНРекв=Спр.ПолучитьАтрибут(имяРеквизита);
Спр.УстановитьАтрибут(имяРеквизита,ЗНРекв);
Для ТЗ — ПолучитьЗначение/УстановитьЗначение. Подробнее см. синтакс-помошник.
(2) (19) (20) Реализовал все (или почти все) ваши предложения. Спасибо.
(22) Ну, если все так, то обрати еще внимание на оформление. Где картинка для анонса? Проверь, обработка точно будет под 8.0 и 8.2. Как это заявлено?
Вот примеры публикаций с неплохим оформлением
http://infostart.ru/public/62722/
http://infostart.ru/public/16630/
(18) в 8-ке не знаю, а 7.7 методами рвстроенного языка можно получать перечень всех справочников, документов, их реквизитов, типов и длин реквизитов и т.д.
Метаданные.Справчочник(счетчик1).Реквизит(счетчик2).Тип или .Длина
(24) В 8-ке почти так же…
(23) Да какраз после н.г. оформить хотел… на 8.0 работает, 8.2 дистрибутива пока нет, но должна работать. Насколько я понял в 1С работа с метаданными со времен 7.7 почти не изменилась.
(26) Да, «почти»… 🙂
(4) «Для 77 реализовать такой алгоритм не получится, т.к. в ней нет оператора Выполнить()»
А зачем через Выполнить()?
Можно выбросить присвоение ТекстКода и писать сразу код.
И еще надо проверять на модифицированность объекта чтобы не делать лишних телодвижений:
СтароеЗначениеРеквизита = Выборка[Реквизит]; //+
ЗначениеРеквизита = Выборка[Реквизит];
…
Объект[Реквизит] = ЗначениеРеквизита;
Если Объект.Модифицированность() Тогда //+
Счетчик = Счетчик + 1;
Попытка
Объект.Записать();
// Показать что именно изменили
Сообщить(Объект.Код + «: Изменен реквизит » + Реквизит + » с <» + СтароеЗначениеРеквизита + «> на <» + ЗначениеРеквизита + «>»);
Исключение
Сообщить(«Не могу записать элемент » + Объект.Код + » по причине: » + ОписаниеОшибки());
Счетчик = Счетчик — 1;
КонецПопытки;
КонецЕсли;
И еще в процедуре СправочникПриИзменении
маленькое удобство добавить, сразу же и присвоить первый элемент реквизиту, на одно движение меньше:
…
ЭлементыФормы.Реквизит.СписокВыбора = СписокВыбора;
ЭлементыФормы.Реквизит.Значение = СписокВыбора[0]; //+
(4) у 7.7 нет Выполнить(), но есть Шаблон() 🙂
(28) Спасибо, добавил.
Не обрабатывает двойные кавычки, например 3,5″ поменять на 3.5″.
Доработал:
в функции Выборка, где встречается СтрокаСимволов.Символ
СтрокаПоиска = СТрЗаменить(СтрокаСимволов.Символ,»»»»,»»»»»»);
крутая вещь !!! респект
Спасибо за обработку, тема актуальна…
Действительно стоящая обработка — любят у нас придумывать новую номенклатуру особенно через пробелы. Все исправляется и меняется
Обработка полезна, но пока скачать и посмотреть не могу. Чем она отличается от поиска и замены значений?
(35) Отличается тем, что ей может пользоваться простой пользователь, не программист, для конкретной задачи. Дописывать ничего не придется.
прочитал по диагонали отзывы, бросилась в глаза дискуссия по убиранию пробелов, двойных, тройных и т.п..
я не знаю, как в 1с, возможно ли, но я такой алгоритм писал на SQL. все делается за один цикл. убирается/меняется двойной пробел » » на одинарный » » в цикле, пока находится двойной пробел. что то типа такого:
WHILE POS (str, » «) > 0 BEGIN
REPLACE(str, » «, » «)
END
при таком алгоритме гарантированно все лишние пробелы убираются и сокращаются до разрешенного одного. пробелы в начале и конце строки обрабатываются обрезанием (если нужно)
(37) Да, алгоритм тут до боли простой. Но эта разработка была моим дебютом на Инфостарте))
Обработка действительно полезная!Пожалуйста, рассмотрите возможность фильтрации (отбора) внутри справочника. т.е. изменить какое-либо значение в справочнике при отборе по конкретному: коментарию, НДС, другим полям как номенклатурной катрочки, так и других справочников. Надеюсь идею смог донести!
(39) Да, идею донести смогли, но пока времени нет заниматься этим, если будет свободное время — сделаю. Или можете сами (если есть желание) доработать / выложить со ссылкой на исходник.
Желание есть, но знаний не хватает! Буду смиренно ждать вашего релиза, в любом случае спасибо за оперативный ответ и обработку!
Добрый вечер.
Не найдется ли файл RENUMBER.ERT для 7
Благодарю.