Печать универсальная MS Word




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?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='\

30 Comments

  1. Valerich

    плюс пока авансом, позже посмотрю

    Reply
  2. Alex_Sun

    Давайте будем идти в ногу со временем будет ли работать в офис 2007?

    Reply
  3. halushka

    Давайте не будем бежать впереди паровоза 😀

    2007 офис совсем другая бодяга. Там гораздо проще можно. Душелов выкладывал примерчики. При формировании файла даж офис нафиг не нужен. А для 2003-го самое то. 8)

    Reply
  4. I_G_O_R

    паровозы этож прошлый век 😀

    Reply
  5. Zen2004

    Сразу при зпуске 🙁

    {ВнешняяОбработка.ПечатьWord(86,23)}: Переменная не определена (ОбщегоНазначения)

    НазначениеСвойства = <<?>>ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(Объект);

    {ВнешняяОбработка.ПечатьWord(86,23)}: Переменная не определена (ОбщегоНазначения)

    НазначениеСвойства = <<?>>ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(Объект);

    Reply
  6. poppy

    (5) В какой конфигурации?

    Reply
  7. ediks

    аналогичная ошибка — старая конфига УПП конвертированная с 8.0.

    Если обработка претендует на универсальность, то зачем использовать ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке, тем более, что эта же функция уже есть в модуле объекта? Может стоит ее переобозвать типа оПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке и использовать ее?

    Или указать совместимость с типовыми конфигурациями 8.1???

    Reply
  8. Zen2004

    У меня самописка с 0 никаких типовых переменных и процессов нету

    Reply
  9. poppy

    (5),(7) Досадная ошибка. Надо убрать «ОбщегоНазначения.».

    Исправлю, выложу. Спасибо за сообщение.

    Reply
  10. poppy

    Обработка обновлена. Исправлены выявленные ошибки.

    Reply
  11. ediks

    (9) 1) Боюсь, что просто убрать «ОбщегоНазначения.» не получится. Я не зря предлагал переименовать функцию, т.к у меня в общем модуле «Общего назначения» уже есть эта функция (модуль глобальный). В результате имеем:

    {ВнешняяОбработка.ПечатьWord(29,9)}: Процедура или функция с указанным именем уже определена (ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке)

    Функция <<?>>ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(Ссылка) Экспорт

    2) Опять же тяжелое наследие 8.0:

    {Форма.Форма(168)}: Поле объекта не обнаружено (ВидОбработки)

    Форма.ВидОбработки = Перечисления.ВидыДополнительныхВнешнихОбработок.ПечатнаяФорма;

    Форма есть, а вот реквизит отсутствует.

    Reply
  12. poppy

    (11) п.1 так и сделаю. Чуть позже.

    п.2 В «Платежных документах» таже ситуация с реквизитом. Уже исправлено. Скачай, проверь.

    Reply
  13. rasswet

    плюсану, хотя пользоваться не буду. но описано подробно. можно понять зачем и для чего. за это и плюс.

    Reply
  14. alex4x

    на полностью самописной конфе будет работать ?

    Reply
  15. ediks

    (12) Может я чего-то не понимаю, но ситуация совершенно не изменилась. Более того, вернулась к исходному состоянию:

    НазначениеСвойства = ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(Объект);

    {Форма.Форма(138)}: Поле объекта не обнаружено (ВидОбработки)

    Форма.ВидОбработки = Перечисления.ВидыДополнительныхВнешнихОбработок.ПечатнаяФорма;

    (14) Мне кажется, не будет.

    Хранилище = Справочники.ХранилищеДополнительнойИнформации.

    Есть такой справочник?

    Хочу попробовать обработку, но никак не могу 😀

    Reply
  16. ediks

    (14) Извините, погорячился насчет справочника ХранилищеДополнительнойИнформации — его наличие ищется по метаданным и его отсутствие не влияет на работу.

    А вот наличие Справочники.ВнешниеОбработки требуется при начале выбора объекта.

    Reply
  17. poppy

    (15) Да.

    С 14:30 27.10 по 22:00 28.10 на сайте была ранняя версия обработки. Все кто скачал в указанный промежуток времени — скачайте заново.

    (16) В текущей версии наличие справочника «ВнешниеОбработки» проверяется при открытии формы. При его отсутствии, форма не открывается.

    Reply
  18. poppy

    (14) Зависит от конфигурации и полноты использования обработки.

    1. Для использования основного назначения обработки, твоя конфигурация должна уметь работать с ВПФ http://infostart.ru/public/16952/

    2. Если ты хочешь хранить шаблон и (или) алгоритм в файлах, твоя конфигурация должна уметь передавать в ВПФ дополнительные параметры http://infostart.ru/public/17119/

    3. Если ты хочешь хранить шаблон и(или) алгоритм внутри базы, у тебя в добавок к п.2 должен быть справочник «ХранилищеДополнительнойИнформации» с реквизитом Хранилище типа ХранилищеЗначения.

    4. Чтобы в алгоритмах пользоваться функцией ЗначениеСвойства() в конфигурации должны быть соответствующие объекты метаданных http://infostart.ru/public/57375/

    5. Если ты хочешь чтобы обработка сама зарегистрировалась в твоей базе, у тебя ВПФ должны храниться в справочнике «ВнешниеОбработки».

    Reply
  19. malikov_pro

    не заполняет параметры если они расположены в колонтитулах, а хотелось бы 🙂

    Reply
  20. malikov_pro

    алгоритм и шаблон для Трудового договора,

    как заполнить <Период тарифной ставки> не знаю, если кто подскажет — буду благодарен

    для склонений использовал dll из

    http://infostart.ru/public/14656/

    Reply
  21. poligraff

    Либо я что-то не так делаю…

    У меня в Word 2003 не вставляется поле.

    Его предварительно в свойствах документа не надо завести?

    Reply
  22. Ganjubas

    Есть один неприятный момент, когда выгружаешь в Word 2003:

    Если переменная используется в колонтитуле (в моём случае есть только нижний), то она не обновляется автоматически при вызове метода

    Док.Fields.Update();

    т.е. когда документ уже открылся, то нужные значения в колонтитулах не появляются.

    Эту проблему нагуглил в инете и получилось чуть более громоздко, но теперь все переменные заполняются:

    Для каждого oStory Из Док.StoryRanges Цикл

    Для каждого oField Из oStory.Fields Цикл

    oField.Update();

    КонецЦикла;

    КонецЦикла;

    Reply
  23. prog-eg

    Подскажите как обновить переменную в колонтитуле, пробовала как в (22) но все равно не обновляется

    Reply
  24. prog-eg

    Нашла! Это что-то вроде: (Footers — нижний колонтитул; Headers — верхний)

    Замена = Док.Sections(1).Footers(1).Range.Find;

    Замена.Execute(ИмяПеременной, , , , , , , , ,Строка(Значение), 2);

    // обновим поля нижнего колонтитула

    Док.Sections(1).Footers(1).Range.Fields.UpDate();

    Reply
  25. mrsdin

    Скажите пожалуйста, возможно в обработке передать в Word строку неопределенной длины (> 255 знаков) в один шаблон?

    Reply
  26. a_vovan

    Поля типа DocVariable не заполняются в колонтитулах Word-a.

    Есть варианты решения проблемы?

    Reply
  27. tarroman

    Не срабатывает в форме регистрации обработки прикрепление к выбранным объектам (у меня не получилось). Запариваться не стал — зашел в уже подключенной внешней печатной форме в настройки и указал назначение по объектам. Использовал обработку для заполнения шаблоно. От переменных ворда перешел на свойства документа.

    Была еще мысль, что по хорошему нужно знать множество заполняемых свойств файла (один список), а уже его заполнять или же из алгоритмов (когда их заполнение обозначено) или же из свойств некоей унифицированной структуры, заполняемой запросом (в ЗиУП подобные запросы есть). Это я к тому, что всякие там сведения о организациях, физических лицах и т.п. одним шаблоном алгоритма проблематично реализовать…

    Reply
  28. n949eo

    Спасибо) Плюс!

    Reply
  29. taasha25

    (24) prog-eg, Здравствуйте! Хотела воспользоваться Вашим методом. У меня в верхнем колонтитуле НазваниеОрганизации.

    Код:

    // Получим документ из объекта и активируем его

    Документ = ОбъектВорд.Application.Documents(1);

    Документ.Activate();

    //Поиск и замена маркеров в колонтитулах

    Замена1 = Документ.Sections(1).Headers(1).Range.Find;

    Замена1.Execute(«[НазваниеОрганизации]», , , , , , , , ,НазваниеОрганизации, 2);

    // обновим поля верхнего колонтитула

    Документ.Sections(1).Headers(1).Range.Fields.UpDate();

    // Поиск и замена маркеров

    Замена = Документ.Content.Find;

    Замена.Execute(«[НомерПриказа]», , , , , , , , , НомерПриказа, 2);

    Замена.Execute(«[Должность]», , , , , , , , ,Должность, 2);

    Замена.Execute(«[ДатаПриказа]», , , , , , , , ,ДатаПриказа, 2);

    Поля в документе заполняет, а в колонтитуле нет. Что я написала не так?

    Reply
  30. vggrigoryev

    (22) Ganjubas, Хоть совет и старый. Но работает.

    Помогло на отлично.

    Спасибо большое.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *