Отчет по товарам на складах с Изображениями номенклатуры (пример, как вывести картинку СКД)




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

42 Comments

  1. anton.fly7
  2. fomix

    Большое спасибо за пример отчета. Все получилось! Пример рабочий 100%.

    Reply
  3. lm-alex

    Рад помочь.

    Reply
  4. fomix

    Пытаюсь самостоятельно создать произвольный отчет из справочника Номенклатура (номенклатура+фото). Схема готова, но при создании поля в макете картинка параметра отличается от той, что в вашем отчете. Вместо прочерка стоит «лупа». Все перепробовал не получается! См. приложение.

    При попытке поменять запрос в вашем отчете, запрашивает пароль на модуль. Он почему-то с паролем! А что там может такого быть… не пойму! Спасибо за ответ!

    Reply
  5. lm-alex

    Пароль?! Странно.. вообще там нет в модуле ничего, но пароль и вправду был, снял. могу кинуть на мыло файл…

    На счет этой ошибки я описывал ситуацию…

    Надо сначала сделать вывод ячейки Параметр и Задать имя параметра и параметра расшифровки например «ОсновноеИзображение», в выражении что у вас на картинке указываем Поле от куда будет заполняться параметр..

    тк имена совпадают он будет одной строчкой… потом меняем вывод обратно на текст и получится как у меня… Не понимаю почему так надо делать, возможно какой то глюк платформы.

    Reply
  6. fomix

    Да уж! Шаманство помогло. Смог самостоятельно сделать простой отчет. Еще раз спасибо!

    Reply
  7. lm-alex

    Пожалуйста.

    Не без этого,пришлось голову поломать, а так в принципе все просто.)

    Reply
  8. Nick5k

    Скачать пока рейтинга не хватает, если можно выслать на мейл nick5k@mail.ru

    Reply
  9. sai-2010

    Спасибо автору!

    Отличная обработка!

    Все посто и красиво.

    Спасибо

    Reply
  10. AlexeyK1
    lm-alex пишет:

    На счет этой ошибки я описывал ситуацию…

    Надо сначала сделать вывод ячейки Параметр и Задать имя параметра и параметра расшифровки например «ОсновноеИзображение», в выражении что у вас на картинке указываем Поле от куда будет заполняться параметр..

    тк имена совпадают он будет одной строчкой… потом меняем вывод обратно на текст и получится как у меня… Не понимаю почему так надо делать, возможно какой то глюк платформы.

    понять бы в чем причина такого шаманства потому что на 8.2 так же приходится шаманить

    Reply
  11. lm-alex

    Всегда пожалуйста…

    Reply
  12. Evgeniy

    Думал только мне не повезло с извращенцами, которые хотят продажи видеть с картинками товаров, а нет.

    Таких индивидуумов хватает:)

    Автор спасибо за труд.

    За 10 минут осилил отчет с картинками, на примере твоего шаблона.

    Reply
  13. lm-alex

    за 6 Лет на рынке с франчами и не такое повидаешь…)) Всегда пожалуйста. Пользуйтесь на здоровье.

    Reply
  14. master-adm

    (3) киньте ссылку отчета на мэйл master-adm@mail.ru, пробую ваш сценарий на 1c 8.2, ругани платформы нет, но и не выводит картинку

    Reply
  15. bobaG

    Спасибо за пример, +

    Reply
  16. Tomy82

    lm-alex, ЧЕЛОВЕЧИЩЕ!

    СПАСИБО, ДРУГ, ЗА ЭТОТ КОММЕНТАРИЙ!

    ТЫ ДАЖЕ НЕ ПРЕДСТАВЛЯЕШЬ КАК ТЫ ПОМОГ ЧЕЛОВЕЧЕСТВУ В ЛИЦЕ МЕНЯ! 🙂

    Настроить макет просто: В макетах в СКД выбираем добавить макет поля, выбираем ячейку и добавляем только один параметр в расшифровку как называется у нас поле в запросе с изображением, на картинке видно. (Бывает глючит: тогда делаем поле тип не Текст а параметр и задаем одинаковое имя Параметра и Параметра расшифровки, по умолчанию он напишет : Представление(ИмяПараметра)) стираем Представление и меняем тип поля на Текст и остается только один параметр Расшифровки.

    Я два дня не могу понять почему не получается!

    сначала на своём примере — думал, сам туплю! потом накачал кучу отчётов с выводом картинки — убиваю макеты, сам делаю макет, опять не получается!

    заметил, что иконки разные в «Параметры макета» «Имя параметра» — но не думал, что в них дело!

    Причём один тестовый отчёт как-то получился, но сам дурак — не просёк в чём дело и где копать!

    Спасибо тебе, коллега! удачи и успехов!

    Ваще мега помог!

    не могу сдержать эмоций!

    если кому-то потребуется — у меня глюкнуло на Вин7 Проф, 8.2.15.301, 11.0.7.21, файловый вариант

    сейчас проверил — всё алле зер гут!

    Reply
  17. lm-alex

    Бывает)) 1С Волшебная программа..

    Всегда рад стараться! Спасибо за комментарии)

    Reply
  18. pedroo

    Пожалуйста

    pedroo@yandex.ru

    Reply
  19. pedroo

    Дякую)))

    Reply
  20. kip989

    Спасибо)

    Reply
  21. jarik1409

    Доброго времени суток!У меня такой вопрос: как добавить логотип фирмы в отчет!

    Извините если не по теме!!!!

    Reply
  22. lm-alex

    При выводе уже данных сформированных СКД, ПолеТабличногоДокумента, что на форме, не обязательно должно быть пустым. Ну вот.. Если посмотреть по коду, где выводим отчет, там есть такие строки:

    Результат = ЭлементыФормы.Результат;

    Результат.Очистить();

    Вот после этого можно вставить логотип в Результат.

    Создайте макет, на нем создайте область, туда вставьте рисунок и его выводить в при формировании отчета.

    Как то так:

    Результат.Вывести(ПолучитьМакет(«МакетЛоготип»).ПолучитьОбласть(«ОблЛоготип»));

    Reply
  23. jarik1409

    (24) Спасибо! А увас нету примерчика такого отчета?

    Reply
  24. lm-alex

    Сейчас на этом примере сделаю.

    Reply
  25. jarik1409

    Спс большое!

    Reply
  26. lm-alex

    Кинул в личку.

    Reply
  27. Agnat7

    Доброго времени суток! Скиньте пожалуйста свой пример (Отчет по товарам на складах с Изображениями номенклатуры) в личку.

    Agnat@mail.ru(28)

    Reply
  28. pikos

    Если можно пришлите пожалуйста отчет с выводом картинки номенклатуры на pikos@nm.ru Заранее Вам благодарен!

    Reply
  29. Atom74

    Если можно пришлите пожалуйста отчет с выводом картинки номенклатуры на info@atom74.com Заранее Вам благодарен!

    Reply
  30. Heiton007

    Пришлите пожалуйста отчет с выводом картинки на Goth007@yandex.ru

    Reply
  31. Evgeniy_begin_progger

    Область = ТабДок.ПолучитьОбласть(«R»+Формат(с,»ЧГ=0″)+»C»+Формат(к,»ЧГ=0»));

    ТекОбласть = ТабДок.Область(«R»+Формат(с,»ЧГ=0″)+»C»+Формат(к,»ЧГ=0»));

    Расшифровка = ТекОбласть.Расшифровка;

    Могли бы вы пояснить, откуда параметры области вы брали?

    Reply
  32. Evgeniy_begin_progger

    и еще вопрос: каким образом связывается номенклатура с правильной картинкой?

    Reply
  33. lm-alex

    (33) Evgeniy_progger_1C,

    Reply
  34. lm-alex

    Evgeniy_progger_1C, Картинка хратится в реквизите Основное изображение, тип Хранилище значения. А область, я проверяю все ячейки табличного документа и уже заполяняю изображения. Это конечно не самый удачный метод, но на тот момент в голову ничего больше не пришло.

    Reply
  35. Evgeniy_begin_progger

    А сейчас есть что-нибудь новое?

    Мне нужно в СКД макет добавить ячейку с картинками номенклатуры.

    Так вот у меня вопрос: можно ли реализовать добавление путем изменения только процедуры кнопки сформировать?

    Reply
  36. lm-alex

    (37) Evgeniy_progger_1C, Можно не переписывать процедуру Кнопки сформировать. Все выше сказанное можно заполнять в Предопределенной процедуре ПриКомпоновкеРезультата() в модуле объекта Отчета. через ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент. Я сам не делал, не было необходимости, http://help1c.com/faq/view/1234.html — тут что то похожее, но как то сложновато, ено смысл уловить можно.

    Reply
  37. Evgeniy_begin_progger

    (14) привет! у меня такая проблема:

    ЭлементРезультата = ПроцессорКомпоновки.Следующий();

    Что мы получаем в качестве элемента?

    Это мне важно потому, что мне нужно достать из ХранилищаЗначений картинку, вот мой код:

    СтандартнаяОбработка = Ложь;

    ДокументРезультат.Очистить();

    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

    Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);

    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

    ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);

    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;

    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);

    ПроцессорВывода.НачатьВывод();

    Пока Истина Цикл

    ЭлементРезультата = ПроцессорКомпоновки.Следующий();

    Если ЭлементРезультата = Неопределено Тогда

    Прервать;

    КонецЕсли;

    ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);

    Если ЭлементРезультата.ЗначенияПараметров.Количество() = 0 Тогда

    Продолжить;

    КонецЕсли;

    Для Каждого ЭлементПараметра Из ЭлементРезультата.ЗначенияПараметров Цикл

    Если ТипЗнч(ЭлементПараметра.Значение) = Тип(«ХранилищеЗначения») Тогда

    Изображение = ДокументРезультат.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);

    Изображение.РазмерКартинки = РазмерКартинки.АвтоРазмер;

    Индекс = ДокументРезультат.Рисунки.Индекс(Изображение);

    ДокументРезультат.Рисунки[Индекс].Картинка = Новый Картинка(ЭлементПараметра.Значение.Получить(), Истина);

    ОбластьИзображение = ДокументРезультат.Область(ДокументРезультат.ВысотаТаблицы, 2);

    ОбластьИзображение.АвтоВысотаСтроки = Ложь;

    ДокументРезультат.Рисунки[Индекс].Расположить(ОбластьИзображение);

    ОбластьИзображение.ВысотаСтроки = ОбластьИзображение.Примечание.Высота — ОбластьИзображение.Примечание.Верх;

    КонецЕсли;

    КонецЦикла;

    КонецЦикла;

    ПроцессорВывода.ЗакончитьВывод();

    Но почему то тип значения ХранилищеЗначения он не определяет, и только 3 типа у ЭлементПараметра.Значение: Null, Число и идентификатор расшифровки компоновки значения.

    Изображение — получаю в запросе, Номенклатура.ОсновноеИзображение

    Reply
  38. lm-alex

    (39) Evgeniy_progger_1C, Ну если ты решил идти таким путем, то тебе надо ловить картинтку не через расшифровку, а через параметр, и тип у реквизита СправочникСсылка.ХранилищеДополнительнойИнформации — а там уже хранилище. см вложение.

    Reply
  39. Evgeniy_begin_progger

    (40) выдает ошибку, если твой отчет запускаю:

    Ошибка исполнения отчета

    по причине:

    Ошибка при выполнении обработчика — ‘ПриКомпоновкеРезультата’

    по причине:

    {ВнешнийОтчет.Товары.МодульОбъекта(33)}: Ошибка при установке значения атрибута контекста (Картинка)

    Изображение.Картинка = ИзображениеТовара;

    по причине:

    Несоответствие типов

    И он в строчке

    ИзображениеТовара = ЭлементПараметра.Значение.Хранилище.Получить();

    не получает изображение!

    Reply
  40. lm-alex

    (41) Evgeniy_progger_1C, Пользуйся отладчиком!, смотри какие принимают значения переменные, на какую позицию ругается, если там вообще картинка и тд. У меня все отработало.

    Reply
  41. mudrak

    (41)(41) Evgeniy_progger_1C, это ругается на отсутствующую картинку, надо проверку добавить. Например так, хоть и коряво:

    Если ТипЗнч(ЭлементПараметра.Значение) = Тип(«СправочникСсылка.ХранилищеДополнительнойИнформации») И ЗначениеЗаполнено(ЭлементПараметра.Значение.Хранилище) И ЭлементПараметра.Значение.ИмяФайла <> «» Тогда
    
    Reply
  42. jobkostya1c8

    Одно большое спасибо за мысль

    В запросе всегда выводим поле Основное изображение из Номенклатуры

    сам бы точно я не додумался 🙂

    Reply

Leave a Comment

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