УТ 11: Ускоряем форму подбора номенклатуры




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

50 Comments

  1. vandalsvq

    Достаточно давно делал аналогичную работу, заменил типовую форму на свою, повесил на хоткей + немного перебрал некоторые методы и их вызов (Клиент, Сервер и т.д.). Также была изменена методика подбора, и некоторые вещи вроде порядка обхода, пропусков при обходе.

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

    И очень критично было добавить вес, поскольку клиентам было важно чтобы машины по грузоподъемности проходили.

    В общем на самом деле, казалось бы достаточно простая работа, не требует каких-то супер подходов и знаний, просто здравый смысл и секундомер.

    Reply
  2. vandalsvq

    А плюс за то, что заботишься о простых смертных 🙂

    Reply
  3. TSSV

    (2) vandalsvq, спасибо! Да, согласен, ничего особо сложного в этом нет, меня попросили просто подробней рассказать об изменениях в запросе (я как то об этом упомянул в одном своем комментарии), вот и решил — может еще кому нибудь пригодится.

    Reply
  4. Evgen.Ponomarenko

    Автору — респект и уважуха, Статье — плюс, Пользователям — радость, 1С — повод задуматься. Помнится давича кто-то, жаловался, что УТ-11 тормозит в файловой версии при работе в локальной сети в режиме подбора. А ведь просто стоило запустить «Отладка/Замер производительности».

    Reply
  5. rasswet

    спасибо за статью. прочитал с интересом

    Reply
  6. Mortiferus

    Релиз УТ 11.1.2.13 — подбор не работает. При двойном клике на строке с номенклатурой не открывается форма выбора количества и цены. Соответственно в корзину ничего не переносится.

    Reply
  7. sashapere

    + , мне тоже порой кажется, что типовая конфа становится всё дальше и дальше от реальной жизни.

    Reply
  8. sashapere

    + , мне тоже порой кажется, что типовая конфа становится всё дальше и дальше от реальной жизни.

    Reply
  9. BorovikSV

    Этот подбор стыд да позор 1С. Оптимизация запроса,отключение сегментов и прочей лабуды перестает помогать когда появляется много номенклатуры, много складов и много типов цен

    Reply
  10. BorovikSV

    в нашем случае пришлось добавлять отдельный подбор для «оперативных» операций. реализовали несколько кеширующих таблиц (например оперативные показатели на текущий момент — остатки, резерв, транзит). Добавили подписки на события, для обновления этих таблиц.И подстроили запрос под использование этих таблиц.

    В результате запрос стал выполнятся за 50-100 мс, даже на «холодной» базе. Соответственно вопрос с тормозами решился радикально.

    Reply
  11. mbreaker

    Любителям попинать жёлтую тушку компании, обеспечивающей вас работой, напомню: 1С никогда не претендовал на коробочное решение для крупных внедрений. Вариант «из коробки» подходит только для компаний с малым оборотом (речь идёт в первую очередь о системах оперативного учета: УТ, КА, УПП). Немудрено, что «напичканный» функциональностью подбор будет тормозить на больших объемах. Так на то Вы, «скульпторы», и нужны — чтобы отсечь всё лишнее и представить клиенту шедевр. А жаловаться на то, что «из коробки» система плохо работает — оставьте клиентам тех недалёких франчей, которые обещают «золотые горы» сразу лишь бы впарить коробку.

    Reply
  12. Sintson

    Добавлю свои 5 копеек.

    Автор абсолютно прав, запрос списка номенклатуры «не вывозит» тему, когда много складов, номенклатуры, ограничение прав пользователей на уровне РЛС.

    РЛС трогать мне было нельзя, сильно убивать сервис — обработку, как сделал автор, тоже не хотелось.

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

    Кто будет курить УТ дальше, рекомендую в общем модуле подбора номенклатуры, там где устанавливается отбор по иерархии в списке, — лучше устанавливать параметр запроса… короче копать сюда…

    в прикрепленном файле кастрированная мной обработка из УТ 11.1.1.17

    Reply
  13. Sintson

    (10) BorovikSV, Вы не могли бы более подробно рассказать об организации кэширующих таблиц, хотелось бы применить подобный подход.

    Reply
  14. Sasha255n

    Сталкивался с такой же проблемой примерно года 2 назад решением на тот момент так и не нашел. Теперь некторые моменты проясняются автору однозначно плюс и спасибо. Есть чему поучиться и где применнить.

    Reply
  15. Vo-Va

    Тоже столкнулся с этой проблемой. Только у меня запрос еще сложнее, чем типовой поэтому от динамического списка вообще отказался. Использую простую таблицу. Возникали проблемы при ее заполнении, как оказалось передавать результат запроса или саму таблицу с сервера на клиент очень долго. Выполнение запроса 2-3 сек, а переход с сервера на клиент порядка 20 сек. Не знаю с чем это связано, но пока весь код исполняю на клиенте в толстом клиенте управляемого приложения, в таком варианте все летает.

    Reply
  16. TSSV

    (16) Vo-Va,

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

    А сама форма видимо обычная (не управляемая), вставленная через буфер из другой конфигурации с основным режимом запуска «Обычное приложение»?

    Reply
  17. Vo-Va

    (17) нет режим запуска толстый клиент управляемое приложение, форма тоже управляемая. Запрос исполняется &НаКлиенте, чтобы форма проходила синтаксический контроль, это участок кода надо в зять в условие

    #Если ТолстыйКлиентУправляемоеПриложение Тогда
    
    &НаКлиенте
    Процедура ЗаполнитьТаблицу()
    
    ……
    
    КонецПроцедуры
    
    #КонецЕсли
    

    Показать

    Reply
  18. TSSV

    (18) Vo-Va, спасибо, это ценно — не знал.

    Reply
  19. rosinfo1

    А мы после танцев с подборами, сделали проще, ставим 10.3 и не парим мозги не себе не людям… Помимо подборов там еще очень много веселых вещей, одна синхронизация с БП чего стоит.

    Reply
  20. rosinfo1

    Хорошо тем, кто в штате крупной компании, поставил замер производительности и пару дней копания методом тыка в трехэтажном запросе, зарплату то, все равно получит. А меня заказчик не поймет если я ему выставлю счет, за доработку типового решения, которое по логике должно и так работать. Особенно если у заказчика всего два ноутбука в сети. А работать неделями за бесплатно особо не прильщает, коллекционируя письма с зарегистрированными багами от тех поддержки 1С, семья и дети не поймут. К сожалению, я получаю свои деньги только за доработку типового функционала, а не за исправление чужих косяков. Спасибо инфостарту и ребятам коллегам, массу времени экономите :-))

    Reply
  21. SCSI

    Уважаемый Tsaregorodtsev, Ваша форма подбора подключается как внешняя обработка?

    Reply
  22. TSSV

    (22) SCSI, В архиве 2 файла. Первый — отчет о сравнении объектов, в нем изменения, которые нужно внести в общий модуль — там пара строк. Второй — сама обработка, которой нужно заменить типовую через «Заменить на внешнюю обрабтку, отчет». Так же предполагается, что в настройках номенклатуры включен стандратный режим поиска в списках.

    Reply
  23. Klesk666

    а в какую процедуру пихать:

    «·Если Форма.КодФормы = «Обработка_ПодборТоваровВДокументПродажи_Форма» Тогда»

    «··Возврат;»

    «·КонецЕсли;»

    релиз не 11.1.2.10

    Reply
  24. TSSV

    (24) Klesk666,

    Процедура УстановитьТекстыЗапросовСписковФормыПодбора(Форма)

    Если Форма.КодФормы = «Обработка_ПодборТоваровВДокументПродажи_Форма» Тогда

    Возврат;

    КонецЕсли;

    Reply
  25. TSSV

    (24) Klesk666, в общем модуле ПодборТоваровСервер

    Reply
  26. Klesk666

    спасибо, попробую

    Reply
  27. sidka89

    предыстории позавидовал бы сам Толстой, но за идею благодарность

    Reply
  28. нинас

    Спасибо за идею. Попробую ее применить в КА

    Reply
  29. alnovin

    Я в свое время избрал другой путь решения: внедрения обычной формы в УТ 11. решается дополнительная задача с вводом по строке в списке справочника. И не надо про тонкие клиенты и т.д. Сам все знаю )

    А «скорострельность» решили путем введения кэш таблицы.

    http://infostart.ru/public/159749/

    Reply
  30. TSSV

    (30) alnovin, быстрый поиск по первым символам — возможен и в тонком клиенте, вот ссылка на публикацию:http://infostart.ru/public/188259/

    Мы работаем в тонком клиенте. Решение на которое ссылаетеь Вы, рассматривалось и даже приобреталось если не ошибаюь, но нас не устроило.

    И не надо про тонкие клиенты и т.д.

    Что на это ответить?…пожалуй цитатой из одного известного фильма: «Надо, Федя, надо!»

    Reply
  31. glime

    спасибо большое, счас пробовать буду

    Reply
  32. Мать Тереза

    А для УТ 11.0.9.12 будет работать?

    Reply
  33. TSSV

    (33) Мать Тереза, конкретно обработка из вложения — не думаю. Я изначально делал ускорение списка подбора в 11.0. Суть в том, что нужно изменить запрос формы подбора.

    Reply
  34. Mails79

    УТ 11.1 на 8.3 (конфа типовая) Подбор товара в документы закупа вообще не открывается. В отладчике ПриСозданииНаСервере, форма подбора, отрабатывается, но в ПриОткрытии не переходит. Виснет.

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

    Reply
  35. TSSV

    (35) Mails79, Между ПриСозданииНаСервере и ПриОткрытии вызывается ИерархияНоменклатурыПриАктивизацииСтроки

    Reply
  36. bayce

    А как быть с обновлениями конфигурации?

    Reply
  37. TSSV

    (37) bayce, про обновления придется забыть … — это шутка ) Если серьезно, то существуют методики доработки, оптимизированные под удобство обновления. Вот публикация на эту тему: http://infostart.ru/public/170935/

    Reply
  38. alekckuc

    Почему то сравнение выложенного файла с типовым подбором не находит существенных изменений. Может конечно я что то делаю не так подскажите плиз.

    Reply
  39. TSSV

    (39) alekckuc, Самое главное — это изменение текста запроса. Вы можете сравнить запросы, сохранив предварительно их тексты в текстовые файлы и далее сравнить сами файлы. При этом, в типовой конфигурации текст запроса строится динамически и его текст можно получить только в отладчике. После изменения текста запроса и его размещение в качестве источника данных списка, нужно будет отключить динамическое формирование запроса списка в типовой конфигурации, для этого, в процедуре:

    Процедура УстановитьТекстыЗапросовСписковФормыПодбора(Форма)

    в самом начале добавить код:

    Если Форма.КодФормы = «Обработка_ПодборТоваровВДокументПродажи_Форма» Тогда

    Возврат;

    КонецЕсли;

    Так же у меня есть текстовые файлы исходного и измененного запросов для УТ 11.0, могу прислать, пишите свою почту в личку.

    Reply
  40. V_Zhukov

    На 11.0 заработало сходу, только в запросе пришлось убрать строку справочник.свойства, т.к. в нашем релизе этого реквизита в справочнике товаров нет. А так всё норм.

    Reply
  41. OBEH

    Интересно, а для последних версий, например Управление торговлей, редакция 11.1 (11.1.6.20), эта обработка актуальна?

    Reply
  42. 2casp

    (42) OBEH, На 11.1.6.24 не работает

    Из «коробки» выдает ошибку:

    {ОбщийМодуль.ОбщегоНазначенияКлиентСервер.Модуль(1858)}: Ошибка при получении значения атрибута контекста (КомпоновщикНастроек)
    ОтборДинамическогоСписка = ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки.Отбор;
    по причине:
    Ошибка при выполнении запроса. Ошибка при выполнении запроса.
    по причине:
    Ошибка получения информации набора данных
    по причине:
    Ошибка в запросе набора данных
    по причине:
    {(79, 62)}: Поле не найдено «СвободныеОстатки.ВРезервеОстаток»
    СУММА(СвободныеОстатки.ВНаличииОстаток — СвободныеОстатки.<<?>>ВРезервеОстаток) КАК Доступно

    Показать

    Reply
  43. 6y6ka_gop

    Добрый день! Тоже столкнулся с данной проблемой в подборе. прошу подсказки. Вы говорите главное — это изменение текста запроса. Залез в модуль вижу что для обработки формируются три запроса: по списку номенклатуры, по списку характеристики и по списку номенклатуры поставщика. выходит надо изменить все три? также был бы очень признателен если есть возможность прислать тект запроса мне на почту: fenix933@mail.ru

    Reply
  44. SOAD

    Индексы полнотекстового поиска (ППД) эта обработка использует?

    Reply
  45. SOAD

    Статья и проделанная работа исходя из статьи хороша, но вот то — что выложил автор для скачивания, половинчатая если не сказать грубо фигня. Во первых зачем то выложил обработку которая идентична типовой. Во вторых если уж сделал оптимизированный запрос — то и выкладывай его. К сожаление запрос автор не выложил. Зато выложил найденное место, где нужно отключить одну процедуру — ту саму которая подтягивает текст запроса для динамического списка формы подбора.

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

    Reply
  46. Гость

    SOAD,

    В публикации сказано:

    «Во вложении вы найдете измененную обработку подбора и отчет о сравнении объектов. Суть описанных изменений воспроизведена мной специально для данной публикации в релизе УТ 11.1.2.10.»

    Во вложении 2 файла:

    1) Отчет о сравнении конфигураций — очевидно типовой УТ 11.1.2.10 и измененной.

    2) Измененная обработка подбора. Измененный запрос вам следует искать в свойствах динамического списка СписокНоменклатура, это видно из отчета о сравнении.

    Reply
  47. triviumfan

    Актуальна ли ещё этот подбор или типовой уже давно поправили?

    Что-то на 11.3.4.228 притормаживает (9 тыс позиций).

    Открывается 5-10 секунд, при активации группы — 2 секунды, и при прокрутке 2-3 секунды.

    Reply
  48. TSSV

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

    Reply
  49. acanta

    Спасибо за публикацию.

    Вопрос — можно ли в платформе 1с генерировать запрос програмно (с учетом функциональных опций) и назначать его динамическому списку тоже в коде?

    Reply
  50. TSSV

    (50) Спасибо за интерес. Можно. В УТ 11.4 есть такая процедура:

    // Устанавливает значения текстов запросов динамических списков на формах подборов.
    //
    // Параметры:
    // Форма — УправляемаяФорма — форма подбора.
    //
    Процедура УстановитьТекстыЗапросовСписковФормыПодбора(Форма) Экспорт
    
    ЭтоФормаПодбораВДокументыЗакупки = ПодборТоваровКлиентСервер.ЭтоФормаПодбораВДокументыЗакупки(Форма);
    
    Форма.СписокНоменклатура.ТекстЗапроса = ТекстЗапросаСпискаФормыПодбора(Форма, «СписокНоменклатура»);
    
    Если Форма.ИспользоватьХарактеристикиНоменклатуры Тогда
    Форма.СписокХарактеристики.ТекстЗапроса = ТекстЗапросаСпискаФормыПодбора(Форма, «СписокХарактеристики»);
    КонецЕсли;
    
    Если ЭтоФормаПодбораВДокументыЗакупки И Форма.ИспользоватьНоменклатуруПоставщиков Тогда
    Форма.СписокНоменклатураПоставщика.ТекстЗапроса = ТекстЗапросаСпискаФормыПодбора(Форма, «СписокНоменклатураПоставщика»);
    КонецЕсли;
    
    КонецПроцедуры
    

    Показать

    Reply

Leave a Comment

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