<?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='\
По такому принципу работают длительные операции в типовых конфигурациях…
ТаблицаИзВременногоХранилища = ПолучитьИзВременногоХранилища(ЭлементПараметр.АдресТаблицыВоВременномХранилище);
Запрос.УстановитьПараметр(ЭлементПараметр.Имя, ТаблицаИзВременногоХранилища);
Если адресом ошиблись и вернется не таблица?
Используйте инструменты разработчика и отлаживайте свой запрос в предприятии после выполнения команды в табло отладчика:
ВнешниеОбработки.Создать(«%Путь к ИР%ирПортативный.epf», Ложь).Отладить(Запрос)
(2) ИР без встраивания в конфигурацию так может? Адрес таблицы значений можно и не сообщать, а также через табло получить.
(1) Если адресом ошиблись вернется не таблица, а может и не таблица)
Запросник 2.0 умеет делать дамп запроса в файл со всем параметрами, временными таблицами и т. д., и потом восстанавливать запрос из этого дампа в режиме предприятия. Есть на инфостарте.
(3) Конечно, в портативном варианте. При вызове функции все параметры запроса сериализуются и потом доступны для консоли запроса в режиме предприятия. Таблицу значений также можно и через файл передать — это если нужно менять входные данные в консоли например. Более подробно здесьhttps://infostart.ru/public/15126/
Использование ИР — это уже устоявшийся стандарт в разработке на 1С, так что рекомендую к обязательному изучению.
(6) Спасибо! Сделаю очередной подход к ИР, к сожалению предыдущие не удались. А ИР и в управляемом режиме и в такси (асинхронность) работает без встраивания? Помнится, с расширением пытался поработать, но …видимо больше времени нужно уделить, с «наскока» не получается.
(5) Спасибо!
Вот тоже обработка, которая передает все данные запроса из отладчика —https://infostart.ru/public/617990/
если таблица не большая, то можно в отладчике сделать ЗначениеВСтрокуВнутр(ТаблицаЗначений),
а в консоли запросов, поддерживающей вычисление выражений параметров, вставить ЗначениеИзСтрокиВнутр(«Полученное
| в отладчике
| значение»)
А так, да, ИР — бесподобны.
(0) круто конечно. НО!
для каких таких задач это используется? какую задачу вы отлаживаете?
(11) для задач отладки в режиме предприятия запроса дающего не корректный результат, в тех случаях когда источником запроса является таблица значений.
(12) куча консолей с параметром таблица значений. Та же куча показывает результат временных таблиц, да еще и с количеством строк, временем выполнения etc.
Не совсем понял автора, что он пытается решить с помощью отладчика, когда все в консолях отлично отлаживается. Да еще и столько телодвижений лишних. Поправьте, если не прав
(12) задачу из «жизни» напишите пож-та
пока что не услышал для чего отлаживать запрос и передавать ТЗ в качестве источника?
(12) поясню еще раз
я пользуюсь типовой консолью для обычных форм, отлаживаю разные запросы, ни разу не понадобилось передавать ТЗ
типовую консоль на управляемых формах стараюсь не использовать, поскольку неудобно сделали — как будто для галочки сделали
(0) Когда-то писал подобное. Идея та жа — реализация чуть отличаетсяhttps://infostart.ru/public/535520/
(14) Задача из жизни — загрузка данных из внешнего файла ( например csv ) и их дальнейшая обработка ( сопоставление номенклатуры ,контрагентов, документов (если производится повторная загрузка)
(7) Что именно не получается?
(17) попробуйте мою обработку :https://infostart.ru/public/585055/ это доработанная консоль запросов, там сможете прочитать табличный файл и сразу поместить его в запрос. для обработки есть консоль куда впишете произвольный код, которым хотите пройтись по результату. + всё это можно сохранить и использовать повторно. Для описанной в статье задачи тоже подойдет: можно вывести ТЧ в табличный документ и так же его запихнуть в запрос, только там будут строки, а не ссылки, так что надо будет либо по наименованию связать со справочником, либо вывести через «изменить форму» код номенклатуры и связать по этому коду(так надежнее).
(20) Вам весь формат выгрузки прислать ?
Задача загрузить данные из внешнего источника за каждый день выгружаются 6 файлов ( 3 по услугам , 3 по оплатам) данные в них немного отличаются по смыслу но формат единый.
Синхронизация справочников и документов организована с помощью механизма Дополнительные реквизиты и сведения
1) читаются файла за указанный период необходимые данные вносятся в общую таблицу
2) Из этих данных выбираются данные необходимые для поиска и при необходимости создания контрагентов , происходит поиск и создания элементов , результат записывается в отдельную ТЧ , тоже самое происходит и с номенклатурой опять же есть свои тонкости , позиция в файле может быть товаром , а может быть услугой , для определения этого служат необходимо анализировать код номенклатуры в файле и если он один из специальных кодов товаров ( эти коды задаются в обработке) то необходимо брать данные из других колонок файла , опять же готовый результат грузится в ТЧ. Уже в этом пункте надо использовать отладку в режиме предприятия для контроля правильности написания запроса и получения данных
3) из общей таблицы собираются и группируются данные по оказанным услугам и проданным товарам а так же данные по оплатам, формируются специальные поисковый поля для документов (при создании документа это поисковое поле записывается как Доп.сведения для дальнейшего поиска этого документа при повторной загрузке). Результат заносится отдельная ТЧ
4) Итоговый запрос соединяет таблицы услуг, контрагентов, Номенклатуры ( т.е. вместо строковых данных подставляет ссылочные типы) так же производит поиск ранее созданных документом и все это в запросе
И для отладки и контроля я использовал описанный в публикации механизм , так как много тонких моментов которые необходимо было учесть и контролировать правильность полученных данных запросом
(14)
Допустим у вас есть xls файл на 100500 строк с информацией о номенклатуре
И у вас есть справочник Номенклатура, который нужно обновлять из xls файла каждый день, искать номенклатуру нужно, например, по коду
Как будете искать номенклатуру?
Я бы прочитал xls в таблицу значений → указал бы ее как источник таблицы в запросе → соединил бы ее со справочником Номенклатура по коду → Где Номенклатура IsNull — создать новую номенклатуру, иначе — обновить существующую. Ещё кэш новой номенклатуры создал бы предварительно (с типом Соответствие, оно вроде пошустрей аналогов).
Ответил на вопрос?
(16) Не загружается страница, ссылка корректная?
(18) Сейчас уже не помню. Напишу в личку когда попробую и не получится?
(23) я ее неправильно создал , просто скопируй ее и вставь в строку браузера
Или вотправильная
(21) вы описали решение некой задачи — решение возможно не оптимальное. озвучьте пож-та саму задачу.
(22) нет, не ответили
вы описали решение некой задачи
(22)
И у вас есть справочник Номенклатура, который нужно обновлять из xls файла каждый день
напишите в каких задачах такая потребность возникает — тыща строк экселя грузятся в 1с — при чем ежедневно 1с что-то обновляет из эксель…
возможно ваше решение не оптимально
опишите пож-та реальную задачу, я или соглашусь с вашим решением, или предложу свое решение без «ТЗ в запросе»
(27) Напишите как бы вы выполнили поиск номенклатуры по коду или наименованию при загрузке из xls? НайтиПоКоду? НайтиПоНаименованию? И это всё в цикле?
(26) Пишу задачу — загрузка данных из файла — вы пишите — недостаточно , описываю задачу поэтапно — вы опять пишете что это не то ,
Могу сказать общая задача — загрузка данных из системы Fidelio (система управления гостиницами) в бухгалтерскую ПП 1с( Считай как загрузка данных из файлов.)
Еще подробнее — как я писал раньше 6 файлов за 1 день в каждом своя информация (например первые содержит все услуги оказанные всем гостям в этот день, второй содержит только услуги по выехавшим гостям за весь период проживания включая день выезда и т.д. С оплатами тоже самое)
Необходимо все это загрузить в 1с (какие данные грузить — по выехавшим гостям или по всем в расчет не берем). В итоге должны создаться документы реализации , и оплаты (ПКО,РКО, Оплата банковскими картами), возможно повторная загрузка того же периода , поэтому нужна защита от образования дублей справочников и документов.
Еще раз- я не утверждаю, что эту задачу нельзя решить не используя метод из данной публикации или похожий , только отладка в этом случае становится неудобной , например по какой-то причине не загрузился документ или попали некорректные данные, в большинстве случаев ошибка в запросе, и не очень удобно часто перезапускать отладку после изменений
, что бы проверить результат , а так передал нужные таблицы в параметр запроса и в режиме предприятия отлаживаешь и видишь результат.
(29) спасибо за ответ. задачу из жизни вы описали. типовая задача, как и ожидал. 🙂
я решал подобную задачу для сети магазинов Кальцедония и Интимиссими.
в день грузится по 5 магазинам по 2-3 экселевских файла.
В 1С создаются Поступления товаров, Отчет о розничных продажах.
Есть неудобство в отладке процесса чтения и загрузки больших и сложно структурированных файлов эксель.
Но при этом я не использую «ТЗ в запросе» — не услышал от вас — что вы в запросе анализируете?
У меня есть алгоритм обработки эксель-файла — сведения заполняются в ТабличнуюЧасть обработки — далее любые манипуляции происходят поэлементно (построково) — таким образом легко отловить ошибку. Влияние последовательной обработки табличной части на скорость загрузки не критично.
Считаю использование ТЗ в запросе не обязательным.
(28) 1) в цикле
2) товар надо искать по артикулу
этот прием (подход) называется ПоследовательноеЧтение файла
всегда применялось в программировании
(30) так и у меня сначала все данные считываются в ТЧ обработки , только они строкового типа,
Только у меня к Вам вопрос
1) как в этом случае создаётся справочная инфа допустим контрагенты если в файле контрагенты могут повторятся — используете какую-то доп.структуру для хранения ?
2) допустим есть данные для одного документа лежат в разных файлах ( например услуги которые оказываются каждый день , и за каждый день есть файл) и требуется загрузить по данному контрагенту за период в целом. Как вы в этом случае поступаете ?
(31) у меня подобная задача решается не совсем так. Файл csv читается действительно в цикле
Показать
Далее Таблица данных файла используется в запросе как писал автор статьи, а к ней левым соединением тянете номенклатуру или что вам там еще надо(главное не задвоить), таким образом у нас на 100500 строк один запрос. Важно — таблица должна быть типизированной, т.е. надо указывать типы для каждой колонки.
Автору +1
(31) по артикулу? значит НайтиПоРеквизиту в цикле, хм… последовательное чтение — это да, а вот обращение к базе данных в цикле другое, это сколько строк в файле столько же и запросов. Если использовать таблицу значений как источник запроса + кэширование новой номенклатуры, то будет 1 запрос к базе данных. 100500 запросов vs 1 запрос, 100500 запросов vs 1 запрос, 100500 запросов vs 1 запрос…
(32) я не понял пункт 1) и 2) — в чем сложность не понял,
в файле повторяются контрагенты ?
вообще принцип очень простой всех таких загрузок — в обработке создаются столько ТЧ, сколько разных форматов эксель
или на каждый файл эксель — своя обработка с одной ТЧ
ТЧ должна ровно повторить файл эксель — колонка в колонку
ТЧ является промежуточным звеном, чтобы можно было начать работать с данными на языке 1С
Я делаю еще дополнительно так — создаю в ТЧ одну колонку строковую «ИдентификаторКонтрагентаИзФайла» и рядом создаю колонку «КонтрагентВБазе1С».
Визуально отображаю ТЧ на форме — при загрузке вижу — для какого ИДконтрагента нашелся контрагент из базы.
Дальше обрабатываю ТЧ — создаю соответствующий документ и переношу в него сведения.
(35) вы так и не написали — что в запросе надо анализировать? насколько обосновано использовать запрос? что вы в запросе проверяете или соединяете — для чего? какую задачу решаете таким образом? пока не пойму в чем соль использования запроса, не смогу прокомментировать ваше решение.
считаю что для задачи «загрузка из эксель» (из других систем учета через эксель) не нужно использовать «ТЗ в запросе» — поскольку это сильно усложняет отладку и решение, дальнейшее сопровождение обработки.
(32) можно создать две ТЧ — в первой собираются сведения из эксель
во второй дополнительно собираются сведения исходя из всей полученной информации по первой ТЧ — объем оплат за период , собранный из первой ТЧ
в любом случае — работаем с ТЧ, пока запросов здесь не вижу 🙂
(33) я согласен — я тоже использую ТЗ в запросе
но для получения простой информации, которую не приходится отлаживать в консоли.
ТЗ в запросе — частый прием, только я хочу понять для какой такой задачи потребовалось вытащить ТЗ в консоль?
насколько надо было усложнить решение задачи, чтобы прийти к мнению, что теперь надо вытащить ТЗ в консоль, что теперь без этого задачу не решить?
(39) вот Вам пример — я взял одну базу, выгрузил список в эксель, хочу сопоставить с данными в другой базе. запрос в толстом клиенте сразу собираете, смотрите результат, пишете обработчик если надо. И это все не заходя в конфигуратор.
(36) блин , ещё раз , есть n количество файлов , данные файлов читаются в цикле , заносятсятся в ТЧ ( таким образом получается общая ТЧ со всеми данными ) все как у Вас , а вот дальше начинается обработка этой ТЧ
1) для создания контрагентов пишу запрос
Выбрать различные
Поле 1
Поле 2
Поле 3
и
ИЗ &Общей Как общая
Все , в запрос попали все уникальные записи по контрагентам по которым надо найти или создать контрагентов , результат можно поместить во временную таблицу , или опять же в ТЧ обработки для визуального представления ( у меня как раз этот вариант )
Для номенклатуры используется такой же подход
У меня в выгрузке 70 полей , и ещё захламлять таблицу доп.колонками как-то не комильфо
По пункту 2
Как вы собираете данные документов в вашем варианте
Например
Контрагенту оказано 3 услуги
Строка с услугой 1 — 100 строка в файле ,
Строка с услугой 2 -1020 строка с 3 услугой 1500 строка
Без использования запроса к вашей ТЧ
(39) не обязательно решение усложняется , я могу прибегать к данному приему чисто для самоконтроля , что бы удостоверится что я получил нужные данные
Сколько можно из пустого в порожнее.)))
(40) на ходу придумываете? не делали же такого ни разу.
ТЗ как будете собирать в толстом клиенте не заходя в конфигуратор?
(42) хорошо, согласен с вами
только подход к решениям подобных задач у вас прежний — для самоконтроля будете зависеть от собственной настроенной консоли запросов.
я предлагаю использовать типовую консоль и не усложнять решение подобных задач.
«ТЗ в запросе» когда-нибудь пригодится в другой задаче — я уверен.
(43) я не аплодирую, когда вижу отсутствие базовых знаний программирования или придумывания велосипеда там, где ему не место.
уверен, что мои вопросы и комментарии кому-нибудь пригодятся
(44)из табличного файла прочитаю ТЗ. Это я говорю про обработку, которую посоветовал ранее, она это умеет. Задача вполне реальная: есть 2 базы, между ними нетиповой обмен через Вэб сервисы, у меня доступ во вторую базу только на данные, которые идут мне. Мне надо проверить что все корректно перелилось в мою базу. Это уже работает, ничего не выдумываю.
(41) для создания товара или контрагента — не надо использовать несколько полей — поле должно быть одно — некий идентификатор в исходной базе.
возможно, проблема в том, что явного идентификатора нет при выгрузке сведений из исходной базы.
и тогда вам приходится заморачиваться поиском по нескольким полям — что не есть правильно.
я бы сделал так — в артикул номенклатуры записывал такую связку полей = «» + Поле1 + Поле2 + Поле3. Цель — сделать артикул настолько уникальным, чтобы по соот-им полям однозначно определять номенклатуру из 1С.
тоже самое и с контрагентом.
насколько понятно изложил? может ли вам помочь такой способ решать задачу по другому?
(43) согласен, затянули мы с обсуждением 🙂
(48) у меня в запрос передаются данные необходимые для поиска и создания
например
Что в таком подходе не корректного ? файл содержит Юр и физ лица(ТипКонтрагента).
Поиск юр лиц может идти через ИНН , если ИНН не задан то поиск по ИдИзФайла — если и так не нашли то идет создание нового элемента.
(48)
данный подход у меня используется для создания меток для документов
(49) Обрабатывая коллекцию поэлементно, вы многократно дергаете таблицу методами «НайтиПоКоду», «НайтиПоНаименованию» и т. п.
Запросы придумали, чтобы сократить число обращений к БД.
(53) да, я знаю. спасибо за уточнение. 🙂
Автору спасибо, приходится много запросов писать на сравнение всяких данных 1С и Excel файла большого объема.
Доработал свою консоль чтобы файл экселя выгружался во временную таблицу и был источником запроса.