Возможности перетаскивания, примеры использования, помощь в понимании и отладке механизма работы (8.3, управляемые формы)




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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='\

14 Comments

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

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

    Reply
  2. Yashazz

    Добавка в тему, наблюдал только что на релизе 8.3.6.2390: если в табличном поле нет ни одной строки, перетаскивание не срабатывает, иконка в виде значка запрета, хотя всё включено и в событиях отказов нет. А вот как только появляется хотя бы одна строка, сразу начинает нормально работать.

    Reply
  3. Alias

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

    На примере этой обработки — на первой вкладке иконка для пустой таблицы-приёмника будет разрешающая. На второй вкладке (где как раз дерево) — иконка для пустого дерева будет запрещающая. Почему такое ограничение — не знаю.

    Reply
  4. Yashazz

    (3) именно. Причём получатель-дерево может находиться даже в режиме отображения «список», а всё равно пофигу.

    Reply
  5. Eskimos

    Что за хитрая конструкция?\r

    Выполнение = Ложь;

    Reply
  6. Alias

    (5) Eskimos, Выполнение — это стандартный третий параметр события НачалоПеретаскивания, С-П говорит о нём, что он «управляет выполнением перетаскивания. Если в теле процедуры-обработчика установить данному параметру значение Ложь, перетаскивание не начнется. Значение по умолчанию: Истина.»

    В данном примере Выполнение=Ложь; используется для отмены самой возможности начала перетаскивания в некоторых примерах (вообще нельзя ничего перетащить, можно только нажав Ctrl , можно только правой кнопкой мыши).

    Reply
  7. bestuzhev

    По умолчанию типы считаются совместимыми, если в качестве приёмника выступает ТаблицаФормы или ПолеТабличногоДокумента.

    А можно как-то самому указать какие типы совместимы а какие нет, я например хочу перетащить картинку одну на другую и при этом потом поменять их местами?

    Reply
  8. Alias

    (7) Обычно поведение системы «по умолчанию» можно изменить(отменить), используя СтандартнаяОбработка=Ложь. В данном случае — в событии ПроверкаПеретаскивания у приёмника.

    Однако я приложил обработку — почему-то не смог добиться правильного поведения. Если я использую СтандОбр=Ложь, переопределяя тем самым картинку курсора в приемнике, то сразу перестаёт вызываться событие ОкончаниеПеретаскивания в источнике (возможно, это недоработка платформы?).

    И получается что всё работает, но со старого места картинка не удаляется. Конечно, можно очистить её в событии приёмника, но это будет неправильно — т.к. в нём мы не знаем откуда именно пришло перетаскивание. В случае двух элементов такой вариант будет допустим, но не более.

    Reply
  9. Alias

    (8) описал ошибочное поведение в ветке https://partners.v8.1c.ru/forum/topic/1611250 , ответов не было, видимо тема не очень популярная. Однако судя по тому что в разных версиях (8.2-8.3) платформы обработка выполняется по разному, очень может быть ошибка платформы 8.3.

    Reply
  10. sh18

    (2) Легко решается:

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

    Reply
  11. andy_zhav

    Пытаюсь реализовать перетаскивание между строк одной таблицы формы. В принципе решение нашел, как это сделать, но остается вопрос с формой курсора. Он всегда такой как при отмене. Как можно управлять этим процессом?

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

    Reply
  12. andy_zhav

    (12) Сам нашел свою ошибку. Нужно было написать СтандартнаяОбработка = ложь;

    Reply
  13. user605516

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

    Reply
  14. Alias

    (14) Уточните, пожалуйста: версию платформы, тип форм (обычные/управляемые), тип элемента приёмника, код событий, и что именно не работает.

    Не работать может по многим причинам — например, в проверке перетаскивания не указали СтандартнаяОбработка = Ложь;

    В общем — всё должно работать (за исключением некоторых случаев, например сейчас не работает перетаскивание файлов в ТД из проводника — https://partners.v8.1c.ru/forum/t/1864762/m/1864762).

    P.S. Статья требует правок… Фраза «по умолчанию типы считаются совместимыми, если в качестве приёмника выступает ТаблицаФормы или ПолеТабличногоДокумента» не совсем корректна, там более сложная зависимость.

    Reply

Leave a Comment

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