<?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='\
Выполнив следующий запрос:
Показать полностью
можно сразу получить дерево, после чего организовать его рекурсивный вывод. Для определения цвета строки также используем метод
Показать полностью
, ну и не забываем про то что в 8.х есть возможность группировки строк в таблицах. 🙂
З.Ы.: Для того, чтобы понять рекурсию, нужно понять рекурсию 🙂
Нда… Вот поэтому и говорят, что выучить восьмерку проще людям не отягащенным общением с 7.7…
Ну ничего, семерошники бывает ещё и не такое отжигают! )))
>Вот поэтому и говорят, что выучить восьмерку проще людям не отягащенным общением с 7.7…
Выучить восьмерку проще людям не отягащенным общением с 1С ВАЩЕ 😉 А работающим на приличных языках типа Си, Дельфи и даже Basic на худой конец
Эх, блин 😉 Хотел Планет крутизну публикнуть, ан не вышло 🙂
Гы, да еще и мой земляк по носу щелкнул. Жму лапу :)))) Krasnoyasrsk — rules
Ну, вообще-то во всей этой истории к 8.х имеет отношение только фраза о неограниченном количестве уровней иерархии. В 7.7 задачу можно решить аналогичным образом, сформировав прямой запрос, с последующей выгрузкой в индексированную таблицу.
Мне искренне жаль тех людей, которые пишут на чистом 1с 7.7.
(1-6)
Вы вообще, о чем? Жесть! Обсуждают пример. Мне что, надо было приводить супер навороченный запрос, чтобы ни кто не разобрался, что там и к чему? Я взял элементарнейший пример, который будет всем понятен. Для дураков написал приписку «Возможно, задачу можно решить проще, организовав мудрый запрос … » Кто-нить вообще доклады делал когда-нибудь? Обратите внимание, что обычно вся теория комментируется примерами в 2-х, максимум, в 3-х мерных пространствах. Суть статьи — показать, как, имея таблицу данных, получить таблицу иерархии и обойти ее рекурсивно. На практике, не всегда имеется возможность сразу получать таблицу с иерархией. Иногда результирующая таблица собирается из нескольких. Пример, приведенный в (1), убивает часть статьи и лишает ее наглядности.
(6) Тогда уж искренне пожалей тех, кто кодируют на ассемблере. Мне искренне жаль людей, кто начинает изучать программирование с Дельфи и, что хуже, с 1С в любой интерпретации, не почуствовав все нюансы работы с невизуальными средами.
Плюс ко всему, запрос в (1) не рабочий. Дерево-то он формирует, но количество в узлах не считает.
Показать полностью
Результат:
1: Инвентарь:
1.1: Грабли: 40
1.2: Мотоблок: 9
1.3: Лопата: 34
1.4: Метла: 24
1.5: Вилы: 20
2: Тара:
2.1: Ящик (упаковка для вентиляторов): 28
2.2: Ящик — упаковка для телевизора: 2
3: Сборка компьютеров:
3.1: Комплектующие:
3.1.1: Монитор: 55
3.1.2: Системный блок: 55
3.1.3: Мышь: 55
3.1.4: Клавиатура: 35
…
Колдовать с "Итог"?
Если предлагается альтернативный пример, то все-таки, желательно, чтобы он работал…
мдя.. печально… как-то от 8-ки ожидается что-то более интересное, чем тупое повторение того, что на 7-ке сделано давным-давно…
+ стандарт скуля позволяет организовать рекурсию прям в запросе…
Эх, как не хотелось, но все же поставил 8.1 на домашнем ноуте…
(7) О неработоспособности запроса можно говорить только тогда, когда при его выполнении система выдает ошибку, во всех остальных случаях уместнее сказать что запрос работает не так как требовалось.
Если уж говорить о получении данных в требуемом формате полностью из результата запроса, то чуть подкорректируем его:
Показать полностью
Данное обсуждение не состоялось бы, если текст статьи соответствовал заголовку. Заходя по ссылке сюда надеялся встретить какой-нибудь изящный, хитрый рекурентный алгоритм. И что я вижу: бравым тоном разъясняется героическое решение проблем, которые программист может создать сам себе.
З.Ы.: Не считаю запрос навороченным, если в нем нет ни одного соединения. Будь там выборка хоть ста полей.
Молодец! Сперва по носу щелкнул, теперь по лбу 😉
🙂 Если бы это был мой блог, то я бы переместил бы его из раздела «Полезные технологии» не в «Грусть», а в «Юмор».
Для окрыленных рейтингом поясню суть «колдовства» с «Итог»:
1. Считается, что у вас открыт конфигуратор 1с 8.1 и перед Вами запрос из (1);
2. Помещаете каретку возле любого из символов текста запроса (это несложно);
3. Нажимаете кнопку для вызова контекстного меню (находится слева от правой клавиши «Ctrl»);
4. Нажимаете кнопку «Вниз» 11 (одиннадцать) раз до выделения строки меню «Конструктор запроса»;
5. Нажимаее клавишу «Enter». При правильном выполнении первых пунктов, перед Вами должен открыться «Конструктор запроса», если этого не произошло, повторите все сначала;
6. Нажимаем клавишу «Enter» 6 (шесть) раз, для перехода на вкладку «Итоги»;
7. Нажимаем клавишу «Tab» 4 (четыре) раза, для активизации строки «Номенклатура» в дереве «Поля»;
8. Нажимаем клавишу «Вниз» 1 (один) раз, для активизации строки «КоличествоОстаток» в дереве «Поля»;
9. Нажимаем клавишу «Tab» 5 (пять) раз, для активизации кнопки «>», находящейся слева от таблицы итоговых полей;
10. Нажимаем клавишу «Enter» 1 (один) раз, для переноса поля «КоличествоОстаток» в таблицу итоговых полей;
11. Удерживая клавишу «Ctrl», нажимаем клавишу «Enter», для формирования текста запроса.
Если Вы сделали все правильно, то перед Вами появится текст запроса из (10) и «колдовство» можно счиать состоявшимся. Если Вы получили другой результат, то, к сожалению, необходимо повторить все сначала.
(12) Просто мне уже грустно Планету объяснять кое-что… вот я и переместил в «Грусть»
(7) Не знаю, кто о чем… А я о том, что статья это пример того как делать НЕ надо.
И я могу ещё пяток примеров привести решения подобной задачи через ж… Но если ты пишешь статью, то я думаю, нужно стараться показать оптимальное решение. Всё решается очень простым запросом с итогами. Всё! Какие навороты?! Ведь это будут читать люди, которые только начинают изучать восьмерку, а то что написано в статье — методически не грамотно.
Но есть такие люди которые никогда не скажут: «да, ерунду написал», правда?… )
(14) Тут все очень просто. Человек, едва начав изчать 8-ку создал себе идиотскую проблему, кою и решил идиотским способом. Но поскольку, как говорит vip «шпингале… и памфары», срочно захотелось блеснуть мощью интеллекта. Ну ладно бы в 7-ке, где он нормальный девелопер, но тут то куда с голой пяткой против шашки?
(15) Согласен. В общем-то ничего страшного тут нет, как я уже говорил, после клюшек, человек не разобравшись может ещё и не такое написать… )
Примечательно, что Planet никогда не скажет, что ерунду сморозил… )
Кстати, Планет, обрати внимание, какие тут корректные люди собрались!
Мордой в парашу тебя ткнули, но МИНУС никто не поставил 😉
(18) Сергей, ты уж лучше сам напиши блог а «Полезные технологии».
Тут ведь грусть не о коде, а кое о чем другом….
За (18) — плюс однозначно. Я восьмерку действительно, недавно изучаю, с деревьями не работал. Вернее, поработал вчера впервые 😉 Взял на вооружение. Действительно, все очень оптимально выглядит, намного лучше, чем с таблицами. В (12) повеселил. Сделай, друг, милость, распиши также подробно для окрыленных рейтингом, как с помощью конструктора строить вложенные запросы типа:
ВЫБРАТЬ
НЕЧТО.ПОЛЕ1,
…
ИЗ (ВЫБРАТЬ … ) КАК НЕЧТО
честно, не вьеду, леплю вручную 🙂
Собственно, вы все мне тут про запрос толкуете, но я-то более хотел про рекурсию поговорить, точнее, про функцию «ВывестиНоменклатуру», а запрос взял чисто для того, чтобы получить заполненную таблицу. Запрос взял элементарнейший. У меня запрос объединяет данные по нескольким регистрам, поэтому там предложенный алгоритм с иерархией не пройдет: просто иерархия предполагает один справочник, у меня их может быть несколько разных. Правильнее было бы озаглавить именно так: «Итак, если все же к Вам пришла Таблица…»
Абадонна, ты-то что прыгаешь? Я вполне нормально отношусь к критике, если она по существу. Блог удалять не буду, потому что в комментариях есть много полезного. Кстати, если когда-либо встретимся, то могу продемонстрировать наглядно, что можно сделать пяткой против шашки 😉
еще раз: ничего нового про рекурсию рассказано не было.. совершенно аналогичное в типовых ТиСах 7-ки уже сто лет в обед…
..
по пятки и шашки — не надо.. не надо… махатья пятками профессионально против шашек для 1Сника — очень вредно… 😉
(21) вот именно! да и что нового про нее сказать можно 😉
(20)>то могу продемонстрировать наглядно, что можно сделать пяткой против шашки 😉
А заодно попозже написать блог «В отделении нейрохирургии очень хорошие врачи» 🙂
Рыбят! Проще надо быть. Это вы все наровите выложить нечто эпохальное. Обсуждается всего лишь рекурсия в применении к построению отчета. Вам это известно — мАлАдцы! Я лично не так часто встречал рекурсивные функции в 1С. Подумал, что кому-то пригодится, вот и выложил.
Про шашки и пятки — вам сюда:http://russianspetsnaz.com/vidio-clip.php , что бы немного развеялись стереотипы…
(23) Назвал бы блог «Некоторые возможности применения рекурсивных функций в среде 1С», может ни у кого бы вопросов и не возникло….
Да наверное, так и надо было. Писалось с 7 до 8 утра с пятницы на субботу, после 2 л. сбитня и 7 часов игры в Two Worlds… А такой блог точно надо сделать. Сталкивался много раз с тем, что народ не понимает рекурсию и боится ее использовать.
Ысправил…
По просьбе в (20): вот так вот раз доступно объеснишь и тебе уже на шею садятся…
1. Выполняем шаги 3-5 из (12);
2. Нажимаешь клавишу «Tab» 9 раз, для активизации строки в дереве «Таблицы»;
3. Нажимаешь клавишу «ins» 1 раз, для перехода в конструктор вложенного запроса.
Ладно, клавиши, допустим, я нажимать научился. Точнее, там ведь вроде звездочка есть, которая создает вложенный запрос… А вот с чем бы действительно, помог, так это с одной проблемкой… Есть у меня таблица значений, заполненная не важно чем. Хотю ее в запрос включить. Это вообще возможно?
ВЫБРАТЬ
Док.нечто
ИЗ
Документы.Какието как Док
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
<МояТаблица>
ПО
Документы.Какието.Реквизит = <МояТаблица>.Колонка
Можно. Для этого используются внутренние таблицы.
(28) Ну это уж совсем элементарно… )
Показать полностью
Ну и дальше пишешь, собственно, свой запрос так же как выше написал…
ЗЫ: Не забываем, таблица значений должна быть типизированна.
Я опять все проспал, но автор однозначно жжот 🙂
(27)-(31) Забавно!
Из блога «ляля-крутизна» превращаемся в вопрос на форуме «поможите, люди добрые» :)))))
(32) Да ладно, O-Planet в отличии, например, от меня, хотя бы что-то пишет, выкладывает…Пусть не всегда удачно получается 🙂
(30) Мож и элементарно, но ни тут на форуме, ни на мисте не ответили. правда, тогда задача несколько иначе формулировалась…
(32) Крутизна у тебя в голове. Где в этом блоге, скажи, я хоть намек на крутизну давал? Просто секрет тебе маленький открою: люди судят обо всем в меру собственной испорченности 😉 Вообще-то, это совсем не я недавно рубаху рвал на площади, что разные колодезные люки выглядят круче моих суперуникальнонавороченных разработок. Этот блок — рабочая записка. Понравилась мне рекурсия, решил поделиться. Попутно пару вопросов решил, что-то новое узнал. Хороший блог.
(34) Ну, во-первых, я ничего не рвал, а, во-вторых, тебе ж ясно написали, чем и когда я могу гордиться. В моей-то голове точно крутизна, а вот……..
Кстати, нашел тот вопрос:
Есть некоторые документы, имеющие два реквизита типа Дата — период актуальности. Нужно сделать, чтобы один и тот же документ присутствовал N раз в результирующей таблице, в зависимости от своего периода актуальности.
01.01.01 Документ 1 (с 01.01.01 по 05.01.01)
02.01.01 Документ 1 (с 01.01.01 по 05.01.01)
03.01.01 Документ 1 (с 01.01.01 по 05.01.01)
03.01.01 Документ 2 (с 03.01.01 по 05.01.01)
04.01.01 Документ 1 (с 01.01.01 по 05.01.01)
04.01.01 Документ 2 (с 03.01.01 по 05.01.01)
05.01.01 Документ 1 (с 01.01.01 по 05.01.01)
05.01.01 Документ 2 (с 03.01.01 по 05.01.01)
Помогут временные таблицы?
Эх, где же это время, когда мне было интересно читать про 1с))? .NET Framework, вот где можно разгуляться.
(37) дафай, дафай, гомельдрефф… 😉
Угу. А на 36 опять ответов нет. По ходу, такое нельзя сделать…
(39)Сделать то можно, но временные таблицы там непричем.
+(40)Руками придется ТЗ заполнять.
Если кому интересно, предлагаю следующую задачу: имеется дерево, в котором определено два поля, скажем «Ссылка» и «Пометка». Тип поля «Ссылка» — СправочникСсылка, тип поля «Пометка» — Булево. Листья дерева (элементы справочников) могут иметь пометку «Истина» или «Ложь», узлы дерева (группы справочников) пометки не имеют. Задача — получить дерево, содержащее только отмеченные или только неотмеченные листья дерева, в новое дерево лист должен переноситься со всеми родительскими узлами, с сохранением иерархии. Узел не имеющий помеченных (непомеченных) листьев, а также не имющий дочерних узлов с помеченными (непомеченными) листьями не переносится в итоговое дерево.
Хм… Это проверка ума или правда нужно сделать? По ходу, не сложно.
Это проверка. По содержанию статьи я сразу понял, что для тебя это не сложно! Хочется сравнить алгоритмы различных авторов — ведь не исключен и вариант решения через таблицы значений 😉
Я б рекурсией сделал. Собственно, делал такое, но на Builder c…
НайтиСтроки()+ a)Рекурсивно откапываем родителей (универсальное)
б) выполнить запрос к справочнику с итогами по иерархии (в контексте конкретной задачи)
(36) Все даты периода во временную таблицу и соединение к ней по Дата>=Документ.ДатаНачалаПериода И Дата <=Документ.ДатаОкончания. Не оно?
Есть более интересное и простое решение на СКД —http://start1c.blogspot.ru/2017/01/blog-post.html