<?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='\
Ну ща…!
1.
> Если З.Выполнить(ТЗ)=0 Тогда
{H:\_НАКОПИТЕЛЬОТЧЕТОВ.DIROSTОСТАТКИ ТОВАРОВ ДЛЯ ТОРГОВЛИ.ERT(123)}: Невозможно обращение к итогам после ТА
Какая-то ошибка в запросе!
Типовая ошибка определения конечной даты отчета…
2. В качестве группы дается возможность выбора конкретной позиции = это так задумано…?
3. Выводить в ячейках отчета рассчтываемые значения — это гуд? для целей увеличения скорости формирования? И как это потом скажется на сохранении в эксель.. м.б….?
4. Комментарии отсутствуют как класс
4а. Где множественный фильтр? елы-палы…?!
5. работает быстрее встроенного какого? и насколько? особенно хотелось бы узнать — за счет чего?
6. особенно порадовала конструкция
ТЗ=»//{{ЗАПРОС(Сформировать)
|Период с ДатаДок по ДатаДок;
|Обрабатывать НеПомеченныеНаУдаление;
в применении к регистру
|Склад = Регистр.ОстаткиТМЦ.Склад;
|Фирма = Регистр.ОстаткиТМЦ.Фирма;
|УпрАналитика = Регистр.ОстаткиТМЦ.Фирма.УпрАналитика;
|ЮрЛицо = Регистр.ОстаткиТМЦ.Фирма.ЮрЛицо;
7. опфть же конструкция, которая идет далее:
|Группировка Номенклатура Без Групп;
|Группировка Цена;
|Группировка Вес;
деление по продажным ценам внутри номенклатуры для розничного склада я еще понимаю…, но для оптового? в запросе это никак не фиксируется… зачем гонять «лишнюю» группировку в запросе, если жто не надо?
Чего я не понял — это группировка по весу внутри продажных цен….? хотя, не скинем со счетов, что я просто не догнал..
8. Порадовала конструкция
КК=40;
ККК=0;
Пока Таб.ПолучитьСтроку()=1 Цикл
ККК=ККК+1;
Если ККК>=КК Тогда
Состояние(«ШАГ 1. Обработано «+ККК+» из «+Таб.КоличествоСтрок()+» …»);
КК=КК+40;
КонецЕсли;
..
видимо проги не знают про операцию А%Б
итого вкратце:
— предоставляет расширенные возможности формирования остатков — очень сомнительно
— И вообще, наш отчет работает быстрее встроенного в 1С и является прекрасной иллюстрацией стиля и методов программирования — голословное заявление без должного обоснования — ну, я думаю, в свете озвученного выше — комментировать не будем… каждый выводы сам сделает…
итого: вполне прокатит как учебное пособие для новичков или шаблон для создания своего
Ну не злодей ли, а?
Хоть бы по делу что написал…
1. Про ТА — молчу. Нормальный чел к дате после ТА не обращается.
2. > В качестве группы дается возможность выбора конкретной позиции = это так задумано…?
— ДА
3. > Выводить в ячейках отчета рассчтываемые значения — это гуд?
А ты так смогешь? Ведь работает и быстро однако.
4. > Комментарии отсутствуют как класс
А они кому нужны?
4а. > Где множественный фильтр? елы-палы…?!
Исжил себя, как класс. Ты чо хочешь ентим фильтром фильтровать?
ДЛЯ ОСОБО ОДАРЕННЫХ: Просто щелкни мышью прям в печатной форме по серому заголовку «Код» али «Номенклатура» али «Артикул» . Смотри, что будет. Только сиди, что бы не упасть…
5. > работает быстрее встроенного какого?
Аналогичного по товарам, очевидно. (С твоим любимым множественным фильтром)
> и насколько?
Ну посчетай
> особенно хотелось бы узнать — за счет чего?
А вот и не скажу!
> 6. особенно порадовала конструкция …
Ты верно с базами под SQL не сталкивался, да со справочником товаров в 30000 позиций… Тогда бы понял, почему я к регистру из запроса обращаюсь…
А «Период с ДатаДок по ДатаДок» — это на уровне рефлекса. Учили нас в МГУ перестраховываться, когда программы пишешь.
7. > опфть же конструкция, которая идет далее …
> хотя, не скинем со счетов, что я просто не догнал
Ты действительно, не догнал.
8. … видимо проги не знают про операцию А%Б
ГЫ! Это можно оставить без комментариев, предложив каждому самому решать, какую операцию в цикле предпочтительнее выполнять: сложение или деление. (Кстати, это маленькая подсказка на вопрос 5 за счет чего) Ты так свои мудрые программы пишешь? Втыкаешь куда не поподя разные операторы, которые выглядят кратко, а на деле работают раз в 200 дольше? Да, видимо слова «ассемблер» и «регистр» для некоторых звучит, как «динозавр». А зря! Я чо делаю своей конструкцией? В цикле проверяю в регистре флаг «отрицательно». Это одна операция для процессора, несколько наносекунд. Ты же своим А%В проц грузишь по полной. Впрочем, это секретные технологии, знать которые дано не каждому.
Да, чебурашка. В следующий раз, когда будешь писать коммент на творение программистов, типа меня, употребляй слово «Прог» с большой буквы. Не скучай.
РЕЗЮМЕ. Работает, как и заявлено.
1. Нормальному юзеру, юзающему отчет — нафиг знать дата после ТА или ДО. Итого — ответ не в тему.
2. Согласен.
3. Да не вопрос, работает — и ок.
4. ну, в принципе, для такого шаблона — не нужны.. это точно…
4а. Те же самые свойства товаров… из обсуждения в другом топике 😉
Для особо одаренных: ну и что? это сразу было понятно/видно…
В чем цимус-то? недогоняю… 😉
5. Не будем уточнять за счет чего, ок. Утверждение осталось голословным.
6. Для особо отдаренных: читай описание конструкции «обрабатывать…» и jmkfcnm ее применения, потом — учи программировать других 😉
7. Не вопрос, согласен.. 😉
8. Аргументированное обсуждение будет продолжено позже… 😉
Ну, до Прога ты еще не дорос, это точно.. 😉
То что работает — я и не обсуждал, работает и ок.
Тока это не творение Прога, как это пытаются представить… 😉
В программах на встроееном языке при формировании товарных остатков ловить наносекунды за счет ясности — это ошибочное заблуждение. Смешно даже обсуждать такие навороты с KK = 40. Я полностью разделяю комментарии Che Burashка
Справедливости ради надо сказать, что в варианте О-Планета экономия составляет не наносекунды, а гораздо ощутимие — но заметна она будет на больших объемах данных. Проведем сравнение.
Предварительно, конечно выкинем из цикла такую безумную конструкцию как получение количества строк ТЗ в цикле — наглядная иллюстрация принципа «не надо делать много ошибок в программе — достаточно сделать одну и обращаться к ней в цикле». и проведем сравнение
На цикле из 50 тыс. с шагом в 87 прогоним вариант 1
//*******************************************
Процедура Сформировать1()
КК=Шаг;
ККК=0;
сч = 0;
Время1 = _GetPerformanceCounter();
Для сч=1 По Граница Цикл
ККК=ККК+1;
Если ККК>=КК Тогда
//Состояние(«ШАГ 1. Обработано «+ККК+» из «+Граница+» …»);
КК=КК+Шаг;
КонецЕсли;
КонецЦикла;
Сообщить(«вар.1, «+Граница+» по «+Шаг+» затрачено: «+(_GetPerformanceCounter()-Время1)/1000);
КонецПроцедуры
..
и вариант2
//*******************************************
Процедура Сформировать2()
КК=Шаг;
сч = 0;
Время1 = _GetPerformanceCounter();
Для сч=1 По Граница Цикл
Если сч%КК=0 Тогда
//Если (сч-КК)=0 Тогда
//Состояние(«ШАГ 1. Обработано «+сч+» из «+Граница+» …»);
кк=кк+шаг;
КонецЕсли;
КонецЦикла;
Сообщить(«вар.2, «+Граница+» по «+Шаг+» затрачено: «+(_GetPerformanceCounter()-Время1)/1000);
КонецПроцедуры
…
первый вариант в реднем показывает 0.19 сек, второй — 0.81 сек.
Разница ощутимая? Несомненно! На что влияет такая разница? Да собственно, говоря — ни на что (единственное, позволяет гордиться принадлежностью к клану настоящего Прога — ну, про ТЗ.КоличествоСтрок() в цикле умолчим…) Для юзера — практически незаметно… Хотя если, конечно, цикл увеличить до 1,5 млн — разница уже будет заметна… и 100 юзеров в терминале юзают только такой адгоритм… тады, да, я признаю свое поражение, облажался… 😉
…
Однако первый вариант можно ускорить еще примерно на 10 процентов без особых затрат очень просто: юзать вместо конструкции
Если ККК>=КК Тогда
следующую:
Если (ККК-КК)>=0 Тогда
…
Однако, видимо, настоящие Программисты, до которых я еще не дорос, ассемблер пробежали «по верхам» и разницы не уловили… 😉
ладно, что-то я ваще злобствовать начал 😉
А по поводу высказанного ААА — присоединяюсь.
Сразу видно настоящего рыцаря мыши, умеющего с легким сердцем относиться к поражению. 🙂 Но поражение — действительно, более теоретическое. Мало таких баз данных, где преимущество метода проявится в полной мере. Что делать, учили когда-то, что всегда надо стараться избегать операций * и /. (А было это еще тогда, когда по сравнению с MERA — Masovia считалась супер компьютером, а IBM086 — вообще, компьютером будущего) Кстати, вы на какой компе все это тестили? Чай на пне четвертом? Попробуйте ка все то же самое прогнать на Celeron 733 с оперативкой в 64 мб… (Так что ААА — пролетает)
По поводу ТЗ.КоличествоСтрок() — это от лени, конеечно. Этот отчет прям у клиента писался за два часа, особо вылизывать не приходилось
А ассемблер я действительно, по верхам просматривал, улавливая лишь суть. Он никогда не был моей специализацией. Кстати, я знаю, что хорошие трансляторы, типа Borland, конструкции А0 🙂 Мож, 1С относится к их числу? Хотя… Если кто ради интереса смотрел, как она отрабатывает выражение, типа —
Попытка
Если (12)и(1/0>0) Тогда
Сообщить(«Хороший транслятор!»);
КонецЕсли;
Исключение
Сообщить(«Дура, блин!»);
КонецПопытки;
— то спрашивать об этом не будет…
Сразу видно настоящего рыцаря мыши, умеющего с легким сердцем относиться к поражению. 🙂 Но поражение — действительно, более теоретическое. Мало таких баз данных, где преимущество метода проявится в полной мере. Что делать, учили когда-то, что всегда надо стараться избегать операций * и /. (А было это еще тогда, когда по сравнению с MERA — Masovia считалась супер компьютером, а IBM086 — вообще, компьютером будущего) Кстати, вы на какой компе все это тестили? Чай на пне четвертом? Попробуйте ка все то же самое прогнать на Celeron 733 с оперативкой в 64 мб… (Так что ААА — пролетает)
По поводу ТЗ.КоличествоСтрок() — это от лени, конеечно. Этот отчет прям у клиента писался за два часа, особо вылизывать не приходилось
А ассемблер я действительно, по верхам просматривал, улавливая лишь суть. Он никогда не был моей специализацией. Кстати, я знаю, что хорошие трансляторы, типа Borland, конструкции А больше В сами заменяют на (А-B) больше 0 🙂 Мож, 1С относится к их числу? Хотя… Если кто ради интереса смотрел, как она отрабатывает выражение, типа —
//**************************
Попытка
Если (2>1)и(1/0>0) Тогда
Сообщить(«Хороший транслятор!»);
КонецЕсли;
Исключение
Сообщить(«Дура, блин!»);
КонецПопытки;
//**************************
— то спрашивать об этом не будет…
Это не поражение, это ближе к ничьей… 😉
А ААА прав, как раз читабельность кода на медленных машинах имеет значение… На быстрой — работает — ну и ок, а на медленной — надо смотреть…
Тестил на Атлоне 1800+, 512 Мб
> Тестил на Атлоне 1800+, 512 Мб
А…
> На быстрой — работает — ну и ок, а на медленной — надо смотреть…
Не знаю. На медленной не работать может как раз из-за неоптимальности. Нет, ААА не прав только потому, что назвал безобидный счетчик-ползун в три строки «наворотами». Проблема то в чем? Если прог нормальный, то ему — по барабану, что там будет стоять А%В или А>В — суть -то одна, и она должна быть понятна с первого взгляда. А каких «наворотах» речь-то?
Речь не о наворотах, а о понятности и аккуратности кода.
Не привязываясь к данному КК — согласись, что код обработки далек от читабельности, хотя конечно от бесплатной разработки требовать «красоты» — не все же пишут красиво забесплатно.
Это на первый взгляд так кажется. На самом деле, отчет этот построен строго по определенному методу, позволяющему делать быстрые отчеты с группировками. Похоже, придется как-нибудь статью написать об этом как раз.
Вот такой счетчик будет уже ближе к наворотам 🙂
//******************************************* (в глобальнике)
Процедура Линейка(К,КК,Шаг) Экспорт
Если (К>=КК)и(Шаг>0) Тогда
Зв=КК/Шаг;
Стр1=»##############################»;
Стр2=»~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~»;
Состояние(Лев(Стр1,Зв)+Сред(Стр2,Зв+1));
КК=КК+Шаг
КонецЕсли;
КонецПроцедуры //Линейка
// В какой-нить процедуре …
…
Шаг=Окр(Табл.КоличествоСтрок()/30,0,1);
КК=Шаг;
Для К=1 По Табл.КоличествоСтрок() Цикл
Линейка(К,КК,Шаг);
…
КонецЦикла;
//*******************************************
Вы постоянно сами себе противоречите. То утверждается, что обработка-кладезь программисткой и инженерной мысли, лицо фирмы, в ней заложены ноу-хау (правда невидимые), то, что она написана в качестве невинного упражнения, так чиркнул и все:)
Если уж мне надо быстродействие, я напишу на прямых запросах и ваш % отдыхает. И какая доля % в общем времени отчета?
Может я и неправ, но я предпочитаю ясный и понятный код, чтобы не сидеть через месяц (а не дай бог через года 3, бывало) и не думать, что же я вообще хотел тут сделать
И когда я вижу идентификаторы типа «КК» и конструкции КК=40 (а почему не 43?:)) мне плохо становится, не знаю почему:)) Рефлекс такой
> построен строго по определенному методу, позволяющему делать быстрые отчеты с группировками.
Не вопрос, согласен в ценности МЕТОДА. пусть это будет ++++++++
Но категорически не согласен с оформлением программного кода ———-
Поддерживаю ААА.
> Вы постоянно сами себе противоречите. То утверждается, что обработка-кладезь программисткой и инженерной мысли
Да, лицо фирмы. Потому что она позволяет ПОЛЬЗОВАТЕЛЮ многое из того, что ему не хватало получать ПРОСТО и БЫСТРО. Если кому-то из программистов не нравится стиль (= не хватает ума разобраться), то юзеру то не пофиг ли, что там внутри? По поводу системности — именно так. Писалось два часа по простой и понятной методике составления подобных отчетов. Возможно, конечно, оно кажется угловатым, если с этой методикой не знаком. Но обладая ей, даже новичок сможет быстро своять коммерческую работу.
> И когда я вижу идентификаторы типа «КК» и конструкции КК=40 (а почему не 43?:)) мне плохо становится, не знаю почему:)) Рефлекс такой
Это фобия какая-то? Можно и 43, конечно, это — на любителя.
> Если уж мне надо быстродействие, я напишу на прямых запросах
Попробуйте. Прямые запросы не покатят, потому что там постфункции сортировки реализованы, а это — пересчет всякий раз. Я же от него избавился.
Должно настораживать, что всем вокруг не хватает ума:) это тоже фобия, и покруче нелюбви к КК 🙂
> Но обладая ей, даже новичок сможет быстро своять коммерческую работу.
Читаем статью про «хорошего программиста», вторая стадия «хорошего программиста» — «продвинутый Прог» 😉
Да ну вас, блин! 🙂
Нормальный отчет…
отчет хорош, нет выбора с резервами или без
Выдает ошибку?
КратРубля = глКратностьДляВалюты<<?>>(глРубли,ДатаДок);
{C:DOCUMENTS AND SETTINGSADMINРАБОЧИЙ СТОЛЗАГРУЗКИОСТАТКИ ТОВАРОВ ДЛЯ ТОРГОВЛИ.ERT(130)}: Функция не обнаружена (глКратностьДляВалюты)
Ц=глПересчет(Ц,Вал,ДатаДок,глРубли,КурсРубля,<<?>>Вал.Кратность,КратРубля);
{C:DOCUMENTS AND SETTINGSADMINРАБОЧИЙ СТОЛЗАГРУЗКИОСТАТКИ ТОВАРОВ ДЛЯ ТОРГОВЛИ.ERT(158)}: Слишком много фактических параметров
Сумма=глПересчет(Сумма,Вал,ДатаДок,глРубли,КурсРубля,<<?>>Вал.Кратность,КратРубля);
{C:DOCUMENTS AND SETTINGSADMINРАБОЧИЙ СТОЛЗАГРУЗКИОСТАТКИ ТОВАРОВ ДЛЯ ТОРГОВЛИ.ERT(159)}: Слишком много фактических параметров
(22) Просто у Вас старая конфигурация торговли.
посоветуйте как обновить?до какого релиза?
Считается реально быстро, +