<?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)
А как нужно вызывать Word или Excel на сервере &
(3) НИКАК 0=0. На клиенте.
(4)
Странно.
А вот в SQL Server есть штатные способы взаимодействия. Тот же OPENROWSET/
Да и во «вражеских» ERP штатно работают.
Может проблема не в сервере ?
(5) Проблема в том, что, запуская десктопную программу в контексте сервера, вы разрушаете контекст сервера с вероятностью отнюдь ненулевой (и производитель об этом прямо предупреждаетhttps://support.microsoft.com/ru-ru/help/257757/considerations-for-server-side-automation-of-office) . Нет, можно, конечно пить и из лужи, но вот стоит ли ?
Мой комментарий напрямую не относится к теме, но лучше писать Word.Quit(0).
Например следующий код не закрывает процесс Word:
(7)Пробовал с «0», результат был тот же. Хотя конечно же лучше делать как Вы указали.
(1) Подскажите тогда каким образом получить такой макет на клиенте? макет держать в двоичных данных и передавать через временное хранилище? тогда уходит редактирование шаблона » на лету» через ActiveDocument что в данном решении не подходило.
(3) Сами объекты можно создавать на клиенте предварительно получив на сервере данные для заполнения. Опять же если только это у Вас динамический шаблон без ActiveDocument.
(2) Имеется ввиду вообще без WORD ? или из макета брать данные для заполнения шаблона на клиенте? тогда вопрос как передать макет из обработки с типом ActivDocument на клиент?
(11) Сделать макет с типом Табличный документ. На сервере его заполнить. Дальше у ТД есть метод Записать. Записать можно в файл, а можно сразу в потоквпамяти. Так вот запись в поток и указать тип сохранения. Дальше у потока есть метод ЗакрытьИПолучитьДвоичныеДанные. Дальше ДД в хранилище и адрес этого хранилища передать на клиент. Никакой word не нужен. Единственное что, так это версия платформы 8.3.9+, но так как у Вас ЗУП 3.1, то скорей всего это ограничение не для Вас
(12) )) это здорово конечно, но а как же «Эта форма утверждена и она должна выглядеть именно так вплоть до форматирования» ?
(13) Речь была не про утвержденную форму. Это уже отдельная история. Если сильно захотеть, то можно сделать. В конце концов *docx можно распаковать и через xpath менять что угодно. Опять же, тема отдельного разговора.
(14) согласен с docx, но это совсем другая история )))
(9)https://infostart.ru/public/270277/
;)) всё новое — испохабленное старое
(8) делать лучше так, как чел из 14 года советует ;))
https://infostart.ru/public/270277/
у него там, правда, тоже не без ошибок, но, думаю, разберётесь
(3) Ком не нужен.
1. Переименовываете в .zip
2. Распаковываете во временную папочку обычным архиватором.
3. Заменяете в нужных файликах требуемые параметры.
4. Запаковываете обратно.
5. Переименовываете в .docx
6. Профит.
(17)
здесь разве не нужен доступ к рабочему каталогу клиента из сервера? его может и не быть?
(18) изящно, изначально docx должен быть?
(19)
не разобрались, ага. Понятненько.
Короче, схема такая:
1. Через ВременноеХранилище передаём макет на клиент.
2. На клиенте получаем из ВХ и пишем в файл.
3. Там же, на клиенте, открываем файл как угодно.
Синхрофазотрон ?
(21) это понятно)) изначально макет есть что?
(9) ранее писал:
(22) Да что ж вы к этому несчастному АктивДокументу привязались. Двоичные данные он и пох. Укажете при записи файла расширение ему .дос и будет он вордом открываться как миленький. Есстно нужно правильный док указать — тот же, какой при помещении в макет был.
(23) если на сервере то в данном случае вызовется объект Word 32x что приведет к описанным в топе проблемам) в том вся соль что макет нужен для редактирования «на лету» если бы все было в двоичных данных топика бы здесь не появилось) Макет(AD) в том виде в котором он используется можно записать только на сервере, конечно без zip и тд и тп. Вариантов реализаций данного функционала масса. Но здесь конкретный случай. Переписывать все ПФ на двоичные данные и заполнение на клиенте это уже совсем другой выход.
(24) Вызовется тот, который вы ему скажете. Вы правильно написали всё про 32-64, только на клиенте половины проблем не будет 😉
(25) если двоичные данные .записать(**.doc) как он и был помещен туда на выходе мы получим 32х, про клиент — согласен %)
(26) да что же вы ересь-то такую несусветную пишете 🙂 Файл — он просто вордовский файл, он не бывает 32 или 64 и откроется он тем вордом, который у вас на клиенте стоит.
(27)почему же? я про сервер говорю. ActiveDocument вызывает неявно экземпляр COM (x32) и поэтому все дальнейшие манипуляции нужно делать учитывая это особенность.
(28)
Показать
Какие тут особенности ? ПолучитьСОМОбъект, который есть
?
И, главное, даже если оно рухнет, по неважно даже каким причинам, то сервер не завалится.
(13) Для этого надо использовать LaTeX
Надоели мне постоянные танцы вокруг Офиса, делаю сейчас маленькую подсистемку, собирающую формы сразу в PDF
(29) здесь двоичные данные записанные НА КЛИЕНТЕ в DOCX, капитан. Зачем мне то что я говорил (9) ?
Может сделаете тоже самое только на сервере и с doc?без двоичных данных? в чем холивар ?
(20)
Да, xlsx и docx по сути упакованные xml-ки. А вот doc и xls — нет.
(29) То что данное решение имеет свои плюсы так как выполняется на клиенте это факт. Но я разве ставил под сомнение это?
(31) Здесь ваш АктивДокумент, который есть двоичные данные вордового файла, по-факту. Что же вы никак это не вкурите-то///
АктивДокумент = ДвоичныеДанные(«ИмяФайла.doc»)
(32)ну для этого надо было тогда все шаблоны сохранить из пф потом пересохранить в docx и загрузить обратно в двоичные данные) как новое решение отлично подойдет.
(34) Мне не понятно к чему Вы пишите про двоичные данные и docx если в статье идет про ActiveDocument + &НаСервере ?
(30) Ждем публикацию, интересно будет взглянуть.
(36) пытался объяснить как то же самое сделать на клиенте. сдаюсь. не смог.
(38) я правильно понимаю Вас? Вы рекомендуете все шаблоны переписать на клиент ручками пересохранив Макет в doc потом загрузив обратно в макет двоичные данные далее переписать везде код для работы с клиентом и организовать заполнение на клиенте? и это все из за дерганья com на серевере? риали?
(39) я побоялся это описывать @sergathome . Конечно на клиенте в половины случаев все разное.
(40) исполните вот это и вкурите уже что такое волшебный ваш ActiveDocument
Показать
Насчет рили будете смеяцо когда сервак завалится при паре сотне юзеров в базах ;)) и будет падать каждые полчаса…
(42)
рецепт 18 работает только для docx, на минуточку…
(43)
-Владимир Владимирович, женщина может стать президентом ?
-Нет!
-Почему же?
-Я же не женщина.
можно АД сохранить в файл и передать на клиент без участия COM. Только всю логику в каждой обработке заполнения придется переделать под клиент когда она сделана под СЕРВЕР. из за того что бы не менять пару строчек кода и опять про преимущества клиента почитайте (39).
(44) Опечатка (39)
153 пользователя полет нормальный.
(45) это свежий аргумент. ушёл думать. раньше следующего понедельника не ждите.
(47)будем скучать, возвращайтесь.
(43)
я не смеюсь, серьезно. Просто я не понял : «Переделываем все на клиент !!!!!!» когда проблема решилась и больше не возвращалась.
(39)
А нахрена вообще тогда ставили задачу по формированию документа в ворде? )
Я не говорю, что документы ворда суперские и замечательные. Но если поставили такую задачу — можно решить так. И да — это, конечно же, не универсальное решение.
(50) ))) Ворд жил жив и будет жив) актуш)
(20) А вы не смотрели как это сделано в БСП 3.0.1?
> Существенно ускорено и повышена стабильность формирования печатных форм в формате офисных документов. Команды печати в этом формате теперь доступны во всех видах клиентов в операционных системах семейства Linux, Mac OS, а также в веб-клиенте.
Теперь собственно используется Office Open XML который разбирается и заполняется на сервере как zip архив.
Конечно прикольно когда проблему описанную в моей статье кто-то решает другимспособом , а потом этот другой способ тоже пробуют переделать (плюс параллельно обоснуют и докапываются до причины ошибки)…
Я только одного не понял: а создание папок проблему уже не решает?
C:WindowsSysWOW64configsystemprofileDesktop
C:WindowsSystem32configsystemprofileDesktop
Плюс можно банально отказаться от ActiveDocument и работать с двоичными данными. Пробовали?
См.тут и тут
(54)
1)изначально были в системе до появления «сбоя».
2)Да.
а нельзя ли
вместо
изменить на
тк создание COMОбъект в большом количестве приводит к невозможности его создания
При ПолучитьCOMОбъект такого не происходит, даже когда Новый COMОбъект уже не работает
(56)можно , в коде указанно.
Вроде бы все вопросы задали. Остался главный. А что это за фильм с Траволтой? -:)
(58)криминальное чтиво))
(55) Нашёл свой же комментарий (тут:https://infostart.ru/public/407448/):
Макет.Записать(ПолноеИмяФайла);
Так вот как оказывается можно ещё сохранить! Не заметил, что у ОболочкаActiveDocument есть метод Записать. Обязательно обновите статью, т.к. многие сваливаются на методе SaveAs, а Записать() у ОболочкаActiveDocument фактически является альтернативой
Сама статья тут:https://infostart.ru/public/270277/
Ни у меня ни уCeHbKA эту проблему хоть и касались, но так полно и подробно как у вас и у https://infostart.ru/public/568913/ не разбиралась, поэтому по любому плюс за статью))