<?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='\
Запомним на будущее.
10#k8SjZc9Dxk8 — это даже больше, чем государственный долг США
люблю математические феньки. практической пользы почти никакой, но — приятно 🙂
Ага. Когда то (в пору динозавров, когда компютеров не было) высчитывал квадратный корень на бумажке. Метод уже не помню, к сожалению (лет 30 назад было)
Молодцы))) Реальных математиков среди программеров ещё поискать)))
(0) А через ряд разложить? )))
Любопытно Но зачем?
(5)
Среди них и реальных программеров ещё поискать)))
Баян, в теме уважаемого ildarovichhttp://infostart.ru/public/90367/?mid=971399 , смотри комментарий 63.
Если есть необходимость вычислить квадратный корень в отчете на СКД, можно использовать вычисляемые поля, вызвав функцию из общего модуля, предварительно описав её там.
(6) Famza,
Через ряд не получается — можно разложить через ряд функцию вида SQRT(1+X), где 0<X<=1. Но как ее применить к данному случаю — непонятно.
(7) Для использования в дальнейших вычислениях. В моем случае задача ставилась так: найти через сигму минимальную вероятную покупку по группам товаров и проанализировать склад на наличие этого количества в течение заданного периода. В вычислении сигмы используется квадратный корень. С ограничениями 1С решение предполагает выполнение запроса, вычисление корня в цикле, выполнение другого запроса. Я попытался вычислить квадратный корень в запросе.
(9) В приведенной Вами ссылке вычисление начального значения SQRT(S) как Значение/2 не выдерживает критики. Как следствие необходимо больше итерационных операций, чтобы увеличить точность вычисления корня. А так да — формула (Xn+S/Xn)/2 — это баян. Она придумана была не нами, а Героном в трактате «Метрика», I век н. э.
(11)
А просто в компоновку запихать и использовать какие хошь функции языка никак? ) Да и в самой компоновке поболе будет возможностей..
(8) Abadonna, и тем не менее, математика научить программировать проще, чем программиста — круто матемачить 🙂
М-да, математика рулит…
В платформе 1С:Предприятие начиная с версии 8.3.1 в языке выражений системы компоновки данных реализована функция Sqrt(). Пользуйтесь на здоровье.
(13) AlX0id,
В данном случае не нужны «какие хошь» функции, нужен квадратный корень средствами языка запросов. Это два принципиально разных подхода: вычисление на уровне СУБД и вычисление на уровне 1С.
(14) Evil Beaver,
Не математик я )))). Все формулы элементарные и подсмотрены в wikipedia, в статье формулы-картинки из нее же. Любой, если задастся целью, может повторить опыт.
(16) nikolal,
Опять одно и тоже. Понятно, что если нам нужно вычислить только сигму и отобразить ее, то можно добавить вычисляемое выражение. А если ее значение должно использоваться в следующем запросе пакета?
Все СУБД: MSSQL, Oracle, Postgree, db/2 содержат SQRT(N)-определение. Почему бы некоторые общие математические функции компании 1С не добавить в язык запросов? Не было бы извращений в виде этой статьи.
Мне кажется, что лучше всего использовать не три итерации, а четыре т.к. именно на этом этапе большинство простых корней приводятся к целому числу 9 к 3 16 к 4 625 к 25 или 5476 к 74.
(18) а я и не говорил, что Вы математик 🙂
(22) ildarovich,
http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
В вашем комментарии есть рациональная составляющая. Запрос выглядит красивее. Но не понятен выбор за основу 2,246827819 и 7,211051877. Если посмотреть расчет грубой оценки в
Основа должна быть выбрана как
Sqrt(Sqrt(10)) = 1.778279410038923
Sqrt(Sqrt(1000)) = 5.623413251903491
Во вложении обработка с оценкой ошибки по 3м способам. Максимальная ошибка получилась при выборе метода из статьи, с уменьшением ошибки идет ваш способ и лучший результат показали основы 1.778279410038923 и 5.623413251903491.
Как только согласуем этот подход, можно будет перейти к п.3 вашего комментария. Думаю, оптимизация будет не лишней. Хотя всю нашу совместную работу перечеркнет добавление функции Sqrt в языке запросов ))). Пункт 2 — на любителя математики, и он может усложнить читаемость.
(22)(23) Я действительно поторопился взять за основу 2,246827819 и 7,211051877 — среднее арифметическое корней 1 и 10 и 11 и 100. Правда оказалась на стороне Википедии (как и следовало ожидать). Я также перепроверил: начальные приближения 1,77827941 и 5,623413252 оказались лучше всего (обработка проверки прилагается). Использование в качестве лучших начальных приближений не среднего арифметического (как я ошибочно думал первоначально), а СРЕДНЕГО ГЕОМЕТРИЧЕСКОГО концов отрезков объясняется тем, что начальное приближение должно быть ближе к истинному не по абсолютному Х-Х’->min, а по относительному значению X/X’->min. То есть среднее как и интервалы аппроксимации выбираются на логарифмической шкале.
Побочным результатом перепроверки является оценка точности метода. Она оказалась очень высокой! На интервале 1 — 100000 максимальная погрешность составила 0,0075844384 (семь с половиной тысячных) процента!
Такая высокая точность делает 2) совершенно ненужным. Тогда единственно, что меня еще беспокоит — это интервал 0-1, то есть отрицательные значения степеней 10. По-хорошему (для минимизации относительной погрешности), там тоже нужно для интервала 0.1-1 брать начальным приближением 0,5623413252, а для 0.01-0.1 брать 0,177827941 и так далее.
(24) ildarovich,
Долго думал про интервал 0-1. Не все так однозначно. Не понятно, почему пристальное внимание уделять именно этому интервалу. Ведь задача может требовать интервала 1-2 или 7-8. Если встанет задача работы с интервалом 0-1, можно будет умножить начальное значение на 10#k8SjZc9Dxk2N, вычислить корень и разделить результат на 10#k8SjZc9DxkN. Как вы думаете?
(25) Мне кажется, что лучше будет полностью воспроизвести метод грубого приближения из Википедии. Там он определен и для отрицательных N. Для нас это означает, что нужно расширить правило на интервалы 1-0.1-0.01-0.001-0.0001-0.00001-… . Иначе ОТНОСИТЕЛЬНАЯ погрешность будет с приближением к 0 бесконтрольно расти. Относительная погрешность — это разница между точным значением корня и посчитанным в запросе, деленная на точное значение (а абсолютная — просто разница).
Иначе правило выбора начального приближения выглядит несимметрично: для степеней больше 8 запрос выдает NULL. Почему? — Видимо, потому, что не обеспечивается достаточная точность. Хотя, взяв в качестве начального значения 6000, запрос достаточно точно определит и корень из 1000 000 000 и корень из 10 000 000 000. Тогда почему для расчета корня из 0.1 и 0.01 мы разрешаем себе пользоваться приближением 2.0? ОТНОСИТЕЛЬНАЯ погрешность вычисления корня из 0.01 при начальном приближении 2.0 будет примерно той же, что и погрешность вычисления корня из 10 000 000 000 при начальном приближении 6000.
Другой вариант — не ограничивать интервал ни сверху, ни снизу, просто указав, что точность вычислений для чисел, больших 10#k8SjZc9Dxk8 и меньших 1 будет уменьшаться при отдалении от этого интервала.
квадратный корень числа = число в степени 0,5
(0) Квадратный корень в запросе — это , конечно, сила..
Сергей , скажи лучше что с «доминиканой» ?
(26) ildarovich,
Добавим в запрос конструкцию для числе меньше 1?
Показать
(27) ex-human,
Очень ценная информация, правда, ума не приложу, как ее использовать.
(29) Можно и так, а еще лучше
Показать
Учитывая то, что шесть знаков после запятой — стандартная точность вычислений в запросах. Ну и отсюда будет понятен принцип, что если «рабочий диапазон» значений аргумента корня другой, то нужно аналогично поменять часть запроса, отвечающую за начальное приближение.
(31) ildarovich,
Возразить ничего не могу против. Изменил запрос в статье согласно вашему коду. Думаю, проблему определения оптимального начального приближения решили.
Давайте поговорим теперь об итерационных шагах. 3х шагов достаточно?
Склеивание итерационных вычислений для 3, 2 и 1 итерации выглядит так:
Показать
(32)(33) Трех итераций хватает. Точность на всем диапазоне от 0.0000001 до 100000000 — семь с половиной тысячных процентов. Для трех итераций после подстановки результатов вложенных запросов в один запрос принимает вид:
Показать
Для сокращения записи первой строчки имя «КвадратныйКорень» заменено на «У». Вложенный запрос при этом понадобился всего один — для выбора начального приближения.
(34) ildarovich,
Проверил запрос — работает нормально. Обновил статью с учетом вашего последнего комментария.
Подскажите как можно сделать такой запрос в динамическом списке?
Динамический список не поддерживает пакетные запросы, никак не могу додуматься.
(36) Alexion,
Не понятно, что конкретно у вас вызывает затруднение. Вложенным запросом целиком в скобках можно заменить временную таблицу.
(17)
Это кто вам сказал такую глупость? Тот, кто показал, как в 1С «круто програмичить»?
Все вычисления в 1С идут через 1С. Через СУБД идет первоначальный
накопление капиталасбор данных.(38) AlexO,
Все вычисления в 1С идут через 1С. Через СУБД идет первоначальный накопление капитала сбор данных.
Ваше утверждение весьма спорное. Не думаю, что элементарные операции плюс, минус, делить вынесены на сторону сервера 1С. Основные конструкции языка запросов 1С соотносятся с конструкциями SQL. Думаю, что они конвертируются в SQL один-в-один. Даже, если в текущем релизе 1С это не так (зная 1С, я допускаю это), то 1С не стоит на месте. И в следующих релизах элементарные операции могут быть вынесены на сервер СУБД. Скорость при этом вырастет, и в 1С-скриптах ничего менять не нужно.
(39) Уважаемый Elisy, прошу оценить мой трудhttp://infostart.ru/public/273699/ по мотивам Вашей разработки.
(40) agrustny,
Спасибо за разработку и ценную ссылку. Добавил вашу разработку в статье. Будет видна после утверждения модератором.
Гы… смешно … и как все это относится к Бухгалтерии и Торговле?.. Такое ощущение что в 1С необходимо расчитывать ядерные реакторы …
(42) Это для конкурсаhttp://forum.infostart.ru/forum1/topic106618/ , чтобы нас
ФФФФсчитали самыми-самыми!(42) Yurcha62,
Когда у вас встанет задача расчетов по модной в определенной среде теории N-сигм, смех, думаю, пропадет )))))))
(43) agrustny,
Спасибо за ссылку — интересный конкурс
(42) Yurcha62, для развоза ИТС даже на инфостарт заходить не надо.
(38) AlexO, а кто вам сказал что это не так? )) Вас кто нибудь учил «круто программить» или вы менеджер или технарь не IT ?
Перехватите на СУБД профайлером оттранслированный в SQL 1сный запрос и посмотрите, что все вычисляется там. Если вы, конечно, понимаете о чем речь и язык SQL вам не чужд.
(47) unsafe, нелепость высказывания AlexO была настолько очевидна, что на нее даже не обратили внимания.
http://forum.infostart.ru/forum24/topic108581/#comm25 (21)
Но!
Насколько быстро «считает» СУБД — вопрос интересный, я его задавал профессору Эльдорадовичу здесь
Вообще рекомендуют арифметику СУБД не использовать.
А Вы что думаете?
(48) agrustny,
Зависит от ситуации, объеме данных. Думаю, процессор не работает особенным медленным образом в режиме СУБД. И почему-то есть уверенность, что MSSQL постарается распараллелить вычислениями своими силами, что даст выигрыш в производительности. Параллельности вычислений от 1С ждать не приходится.
Бывают ситуации, что вынесение арифметики на сторону 1С приводит к нескольким последовательным обращениям к СУБД, задержки от которых буду намного выше, чем потенциальные замедления арифметики СУБД.
Еще некоторое дополнение, не использовать выбор а поместить во временную таблицу и использовать связь. Удобней, и правильней (особенно когда надо извлечь корень из нескольких полей)
Показать
(49) (48), замерил на конкретных данных. ~13500 записей. Увеличение времени выполнения запроса ~300ms
Автору — респектище
(50) блин, пару экранов текста недолистал, сам аналог написал))