Сканирование, хранение и печать сертификатов продукции [Обновлено 17.01.2011]




Принцип обмена данными из 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='\

72 Comments

  1. markers

    Главный плюс, НЕ жадность автора!

    Reply
  2. anig99

    мммм…(1) а чего жадничать-то? вся используемая информация изначально была в свободном доступе…

    Reply
  3. markers

    Ну не знаю почему некоторые жадничают 🙂 За мелкую обработку и проще этой обработку (В плане что мне проще написать) берут денег…

    Спасибо!

    Reply
  4. mirco

    «В Windows 7 соответствующие dll уже входят в комплект» — но работать будет только если для сканера есть драйвера twain совместимые, так ?

    Reply
  5. anig99

    (4) нет. wia и twain — это разные стандарты

    Reply
  6. mirco

    (5) про твайн я образно…

    я имел ввиду что драйвера на сканер должны стоять…

    Reply
  7. anig99

    (6) хотя бы универсальный WIA (в теории, практики такой не было)

    Reply
  8. V_V_V
    Полученное изображение можно повертеть с помощью того же WIA

    А обрезать можно? А сохранить с определенным размером? Очень интересует…

    Reply
  9. anig99

    (8) Можно при сканировании обрезать. А можно через WIA согласно

    http://msdn.microsoft.com/en-us/library/ms630819(VS.85).aspx

    http://www.codeproject.com/KB/shell/resize_image_script_all.aspx

    Дерзайте

    Reply
  10. CheBurator

    паровозом «аналог» для 7.7

    http://infostart.ru/public/15355/

    .

    автору — плюс! порадовал!

    Reply
  11. anig99

    (10) к сожалению scan1c.dll не работает на 8.1 )%

    Reply
  12. lalexrus

    все это хорошо, а если в одном документе продается товар с несколькими сертификатами (например алкоголь, где мб разные даты розлива)?

    Reply
  13. anig99

    (12) для этого существуют Серии, которые данная обработка учитывает. А вот 1с может и не учитывать.

    Программисты 1с то ли схалтурили, то ли специально оставили лазейку:

    Даже если по номенклатуре не ведется учет по сериям, то в документах поступления и реализации для этой номенклатуры можно указывать серии не вызывая форму выбора, а через поле вода введя часть названия. Сами серии тоже можно вводить не через номенклатуру, а через справочник Серии номенклатуры.

    В Вашем случае серии = дата розлива.

    Reply
  14. lalexrus

    (13) собака с датами розлива зарыта в том, что их может быть много для одного товара. Отсюда следует главное неудобство — необходимость в одном документе разбивать одну строку на несколько в соответствии с датами розлива.

    Reply
  15. anig99

    (14) можно копнуть в сторону серийных номеров. В этом случае доработка обработок по сертификации непринципиальна.

    А какие будут Ваши предложения? Ведь проблема дат розлива в алкогольки довольна спецефична и вообще требует отдельных конфигураций.

    Reply
  16. lalexrus

    (15) собственно я покажу вашу обработку сертификатам нашим, что они скажут напишу (включая и мои соображения, практика показала, что я могу думать совсем другое 🙂 )

    Reply
  17. VBWEBMAIL

    anig99! спасибо за обработку.. только не могу разобраться в чем может быть ошибка при выполнении метода Image.SaveFile(ИмяФайла), выдается ошибка Произошла исключительная ситуация (WIA.ImageFile.1): Отказано в доступе… очень странно…

    Спасибо, если поможете!

    Reply
  18. anig99

    (17) windows 7? Если да, то нужно чуть менять обработку — по умолчанию она пишет на диск C:, а доступ на него обычно закрыт. Нужно указать или доступную неадминистратору папку, или использовать функцию 1с по получению имени временного файла.

    Reply
  19. VBWEBMAIL

    🙂 Спасибо! все получилось. с W7 все понятно 🙂 там все автоматом ставится.. а как быть с XP? у Вас был опыт?

    Reply
  20. anig99

    (19) в XP проблем с диском С не возникало

    Reply
  21. VBWEBMAIL

    для XP, как понимаю, нужно скачивать драйвера для WIA 2.0?

    Reply
  22. anig99

    (21) да… но проблем с этим не должно быть. Они лежат в свободном доступе на сайте мелкомягким с инструкцией по регистрации

    Reply
  23. x_mih

    Доработайте пожалуйста чтобы можно было просто указать картинку сертификата. Спасибо.

    Reply
  24. anig99

    (23) доработал

    Reply
  25. CheBurator

    а не думали ли вы о таком «функционале»: есть сканеры с автоподачей — кинул стопку — дивайс их пакетом отсканировал (в папочку).

    Потом берем и на вход «обработки» — подаем отсканированный «пакет» — который обрезаем/выравниваем картинки и привязываем к номенклатуре (источник — любой: документ, группа справочника, список значений, массив, ТЗ…). У мну такая задача в свое время нарисовалась — но я ушел из фирмы…

    Reply
  26. anig99

    (25) нет такой потребности.

    Reply
  27. Sk0rp

    Как туда добавить, что бы окошко настроек сканирования не появлялось, а можно было все программно настроить и сразу начиналось сканирование?

    Reply
  28. anig99

    (27)Посмотрите ShowAcquireImage.

    Точные изменения сейчас не скажу. Нет под времени и сканера под рукой.

    http://msdn.microsoft.com/en-us/library/ms630772(VS.85).aspx — вот справка по данной команде

    Reply
  29. Sk0rp

    (28) О спасибо! Перебирал методы CommonDialog, а в параметры самого ShowAcquireImage заглянуть не додумался.

    Reply
  30. sdvig

    (29) как сделали? пишу: DevManager.ShowAcquireImage(1,4,,,ложь,ложь,); а окно все равно появляется?

    Reply
  31. vdv_4462

    Попробовал обработку. Со сканером все прекрасно (Canoscan Lide 70 с родными драйверами)

    Попробовал также с веб-камерой. И вот тут засада — не появляется никакого окошка для настройки. В результате получаются фото с размером 640*480. А камера может намного больше — и хотелось бы именно этого…

    Подскажите, если не трудно, как можно получить либо окно настройки, либо (еще лучше) фиксированное разрешение, к примеру 1280*1024…

    Reply
  32. anig99

    (31) не пробовал с камерой.

    но где-то здесь

    http://msdn.microsoft.com/en-us/library/ms630492(v=VS.85).aspx — ShowAcquisitionWizard

    Иначе нужно копаться в командах самого устройства.

    Reply
  33. levran

    Одно время работал в торговой компании, активно использующей подобную схему хранения сертификатов. После 1,5 года запуска активной работы, база легла, из-за справочника «Хранилище дополнительной информации». (большой размер базы). Посему обработка сохранения сканов была переписана на внешний каталог. Скорость обработки сканов упала, но не сильно заметно. ИМХО.

    Reply
  34. anig99

    (33) ни того, ни другого в свободном юзабельном виде нигде нет. Никто не запрещает дописать запись и чтение изображений под хранение ссылки на файл во внешнем каталоге.

    Reply
  35. Zen13

    Спасибо! Пригодилась!

    Reply
  36. Nick5k

    Добрый день! Очень нужна Ваша обработка, но нет возможности скачать, если можно вышлите на nick5k@mail.ru.

    Очень надо! А изобретать своё времени нет.

    Reply
  37. RakovskiyK

    уже в который раз автор осчастливливает с нужным продуктом и щедрым подходом!

    Огромное спасибо!

    Reply
  38. CaSH_2004

    А в формат PDF напрямую можно или только перегонкой через виртуальный принтер и аналоги?

    Поискал в нете, нашел намек в документации что можно, но не сказано как

    кстати в тему: http://wiki.kint.ru/index.php/Использование_сканера_(1Cv8)

    и

    как обрабатывать рисунок

    Reply
  39. anig99

    (38) я не искал способа напрямую. не все сканеры поддерживают сканирование сразу в pdf. У меня в более новой версии реализована просто загрузка файлов.

    Reply
  40. dindzilin

    Довольно полезная обработка, раньше использовал внешние компоненты, естественно приходилось регистрировать, копировать… А тут воткнул в конфу и все работает )))

    Reply
  41. RakovskiyK

    поддерживаю (39) на текущий момент не многие организации используют сканирование в PDF, так что обработка более чем актуальна.

    Reply
  42. 404vrn

    Спасибо, очень пригодилась обработочка!

    Reply
  43. raym0n

    Ой, огромное спасибо! Как раз встала задача реорганизации рабочего места сертефикатчиц.

    Будем копать, спасибо!

    Reply
  44. ediks

    Все отлично сканируется в локале и, к сожалению, не работает через Citrix. Хотя с использованием twain документы сканируются и в Citrix. Это не претензия, просто констатация факта :). Возможно, надо добавлять устройство на сервер, а при нашем зоопарке это несколько затруднительно.

    Reply
  45. soba

    По идее тоже самое и под 7-ку можно прикрутить, только обработку переписать ? только вот предпросмотр неясно как организовать. Что-то из внешних компонент надо

    Reply
  46. Ionmuerto

    Возможно ли эту обработку привязать к заявки на расходования БД денежных средств? в качестве изображений выставленные счета на оплату?

    Reply
  47. K_Tanusik

    Спасибо огромное, скачала очень нужная обработка

    Reply
  48. mmk83

    а есть возможность прикрутить сканирование в многостраничный тиф?

    Reply
  49. It-developer

    Респект и уважуха! Спасибо, заюзаю у себя

    Reply
  50. Angeros

    (22) поделитесь ссылкой для xp. я както не могу понять где там искать?! 🙂

    Reply
  51. anig99

    (50) уже убрали. Вот рабочая ссылка

    http://vbnet.mvps.org/files/updates/wiaautsdk.zip

    Reply
  52. val54321

    А есть для 64 битной системы?

    Reply
  53. anig99

    (52) В 7ке и выше WIA стоит по умолчанию. Для более старых систем вроде как нет разницы.

    Reply
  54. val54321

    Я ставлю на сервер, при установке на 32 битный 2003 сервер, все отлично, при установке на тот же 2003 но 64 не взлетает.

    Пробовал взять этут библиотеку из уже установленной вин7 64 битной, не находит процедуру loadlibrary при попытке регистрации.

    Reply
  55. anig99

    (54) http://support.microsoft.com/kb/282747 попробуйте

    Reply
  56. val54321

    Проблема описана в точности как у меня, но так как там описано не взлетает. Точно так же не находит loadlibrary.

    Reply
  57. user_2010

    Как изменить размер картинки при сохранении в базу?

    Какие методы COMОбъект(«WIA.ImageProcess») для этого надо использовать?

    Может быть есть пример кода?

    Reply
  58. anig99
  59. pvlunegov

    anig99

    Я к тебе в гости пожаловал.

    Смотрю ты тут тоже крутые статьи пишешь.

    А помнишь как ты меня лохом обзывал в моей статье, нахер посылал, угрожал, приказывал прекратить печать статей?

    Ну что-ж оценим твои творения!

    Ну что-ж, неплохо для старичка. Потянет на пятерку. Но вот скачивать не буду, хотя вещь хорошая.

    Жалко мне на тебя тратить свои мани.

    Человек ты вроде неплохой, но плохо обзываешься и ведешь себя, я с тобой неиграю!

    Reply
  60. anig99

    (59) pvlunegov, если внимательно и без эмоций прочитаете написанное мною, то личных оскорблений там нет. Есть оценка Вашей работы и моё личное отношение к тем, кто берёт деньги за такое.

    Reply
  61. igorekpanchenko

    Добрый день!

    Подскажите как можно сканированную картинку сразу вывести на экран в форму?

    Reply
  62. igorekpanchenko

    Помогите разобраться где я ошибся. Выскакивает ошибка:

    {Справочник.ХранилищеДопИнформации.Форма.ФормаЭлемента.Форма(92)}: Поле объекта не обнаружено (Картинка)

    Элементы.КартинкаСкан.Картинка = Новый Картинка(ИмяФайла);

    Код:

    &НаКлиенте
    Процедура Сканировать(Команда)
    
    Image = Новый COMОбъект(«WIA.ImageFile»);
    DevManager = Новый COMОбъект(«WIA.CommonDialog»);
    Image = DevManager.ShowAcquireImage();
    IP = Новый COMОбъект(«WIA.ImageProcess»);
    IP.Filters.Add(IP.FilterInfos(«Convert»).FilterID);
    IP1 = IP.Filters(1);
    Для К = 1 По IP1.Properties.Count Цикл
    Если IP1.Properties(К).Name = «FormatID» Тогда
    IP1.Properties(К).Value = «{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}»;
    Прервать;
    КонецЕсли;
    КонецЦикла;
    Image = IP.Apply(Image);
    СохранитьИВывестиИзображение();
    
    КонецПроцедуры
    
    &НаКлиенте
    Процедура СохранитьИВывестиИзображение()
    
    УдалитьФайлы(ИмяФайла);
    Image.SaveFile(ИмяФайла);
    Элементы.КартинкаСкан.Картинка = Новый Картинка(ИмяФайла);
    Элементы.КартинкаСкан.Видимость = Истина;
    
    КонецПроцедуры
    
    ИмяФайла =  «C:CurCertificate.png»;
    Image = Неопределено;

    Показать

    Reply
  63. igorekpanchenko

    Сканирует, потом выводит ошибку.

    Reply
  64. anig99

    (64) igorekpanchenko, а на форме есть элемент типа картинка с именем КартинкаСкан?

    Reply
  65. igorekpanchenko

    (65) Присутствует.

    Вид: поле картинки

    Путь К Данным: АдресКартинки

    Reply
  66. igorekpanchenko

    (65) Кнопка загрузки работает таким способом:

    &НаКлиенте
    Процедура Загрузить(Команда)
    
    файл = «» ;
    ПоместитьФайл(файл,,,Истина,УникальныйИдентификатор);
    Если файл<>»» Тогда
    АдресКартинки = файл;
    КонецЕсли;
    
    КонецПроцедуры

    Показать

    Reply
  67. anig99

    Элементы.КартинкаСкан.АдресКартинки = Файл

    не так должно быть?

    Reply
  68. igorekpanchenko

    Не получается вставить картинку. Выдает ошибку: Поле объекта недоступно для записи (Картинка)

    &НаКлиенте
    Перем Image;
    
    &НаКлиенте
    Перем ЭлементыФормы;
    
    &НаКлиенте
    Перем ИмяФайла;
    
    &НаКлиенте
    Процедура Загрузить(Команда)
    файл = «» ;
    ПоместитьФайл(файл,,,Истина,УникальныйИдентификатор);
    Если файл<>»» Тогда
    АдресКартинки = файл;
    КонецЕсли;
    КонецПроцедуры
    
    &НаСервере
    Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    Если АдресКартинки <> Неопределено Тогда
    Данные = ПолучитьИзВременногоХранилища(АдресКартинки);
    ТекущийОбъект.Файл = Новый ХранилищеЗначения(Данные);
    КонецЕсли;
    КонецПроцедуры
    
    &НаСервере
    Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    ЭтотОбъект = РеквизитФормыВЗначение(«Объект»);
    АдресКартинки = ПоместитьВоВременноеХранилище(ЭтотОбъект.Файл.Получить(), Новый УникальныйИдентификатор);
    КонецПроцедуры
    
    &НаКлиенте
    Процедура Сканировать(Команда)
    
    Image = Новый COMОбъект(«WIA.ImageFile»);
    DevManager = Новый COMОбъект(«WIA.CommonDialog»);
    Image = DevManager.ShowAcquireImage();
    IP = Новый COMОбъект(«WIA.ImageProcess»);
    IP.Filters.Add(IP.FilterInfos(«Convert»).FilterID);
    IP1 = IP.Filters(1);
    Для К = 1 По IP1.Properties.Count Цикл
    Если IP1.Properties(К).Name = «FormatID» Тогда
    IP1.Properties(К).Value = «{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}»;
    Прервать;
    КонецЕсли;
    КонецЦикла;
    Image = IP.Apply(Image);
    СохранитьИВывестиИзображение();
    
    КонецПроцедуры
    
    &НаКлиенте
    Процедура СохранитьИВывестиИзображение()
    УдалитьФайлы(ИмяФайла); //удалим старый файл
    Image.SaveFile(ИмяФайла); //сохраним на жесткий диск объект WIA
    Элементы.Картинка = Новый Картинка(ИмяФайла);
    КонецПроцедуры
    
    ИмяФайла =  «C:CurCertificate.png»;
    Image = Неопределено;
    

    Показать

    Reply
  69. igorekpanchenko

    Заработало, спасибо за помощь.

    &НаКлиенте
    Процедура Сканировать(Команда)
    
    Image = Новый COMОбъект(«WIA.ImageFile»);
    DevManager = Новый COMОбъект(«WIA.CommonDialog»);
    Image = DevManager.ShowAcquireImage();
    IP = Новый COMОбъект(«WIA.ImageProcess»);
    IP.Filters.Add(IP.FilterInfos(«Convert»).FilterID);
    IP1 = IP.Filters(1);
    Для К = 1 По IP1.Properties.Count Цикл
    Если IP1.Properties(К).Name = «FormatID» Тогда
    IP1.Properties(К).Value = «{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}»;
    Прервать;
    КонецЕсли;
    КонецЦикла;
    Image = IP.Apply(Image);
    СохранитьИВывестиИзображение();
    
    КонецПроцедуры
    
    &НаКлиенте
    Процедура СохранитьИВывестиИзображение()
    УдалитьФайлы(ИмяФайла); //удалим старый файл
    Image.SaveFile(ИмяФайла); //сохраним на жесткий диск объект WIA
    АдресВХранилище = «»; //Помещаем картинку в хранилище
    ПоместитьФайл (АдресВХранилище, «C:CurCertificate.png», , Ложь) ; //Помещаем картинку в хранилище
    АдресКартинки = АдресВХранилище; //Вставляем из хранилища
    КонецПроцедуры
    
    
    
    ИмяФайла =  «C:CurCertificate.png»;
    Image = Неопределено;

    Показать

    Reply
  70. al_zzz

    Подскажите пожалуйста, как сделать сканирование с автоподачей в один файл?

    Reply
  71. info1ctart

    Можно ли как-то задать имя сканера, или сделать выбор? А то их несколько, и сканирует не с того.

    Reply

Leave a Comment

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