Сохранение настроек колонок, добавленных на форму программно




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

21 Comments

  1. script

    Уже пару раз с такой необходимостью столнулся. Спасибо. Пригодится однозначно.

    Reply
  2. Yashazz

    Делаю такое во всех своих конфах уже очень давно. Действительно, часто бывает нужно.

    Reply
  3. NeronKrasu

    СохранитьЗначение(ИмяНастройки,НастройкиКолонок);

    НастройкиКолонок = ВосстановитьЗначение(ИмяНастройки);

    Это откуда берем?

    Reply
  4. ekaruk

    (3) NeronKrasu,

    Стандартное сохранение средствами платформы.

    Для каждого пользователя сохраняем под уникальным именем настройки конкретной формы.

    СохранитьЗначение (SaveValue)

    Синтаксис:

    СохранитьЗначение(<Имя>, <Значение>)

    Параметры:

    <Имя> (обязательный)

    Тип: Строка.

    Имя, с которым сохраняется значение, используется для идентификации сохраняемых значений.

    <Значение> (обязательный)

    Тип: Произвольный.

    Сохраняемое значение.

    Описание:

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

    ВосстановитьЗначение (RestoreValue)

    Синтаксис:

    ВосстановитьЗначение(<Имя>)

    Параметры:

    <Имя> (обязательный)

    Тип: Строка.

    Имя сохраненного значения.

    Возвращаемое значение:

    Тип: Произвольный.

    Восстановленное значение. Если восстановить не удалось, возвращает Неопределено.

    Описание:

    Получает значение, сохраненное ранее с помощью метода СохранитьЗначение.

    Reply
  5. FractonKireyev

    ЗАЧЁТ!!!

    Идея очень красивая. Спасибо автору. Буду использовать.

    Reply
  6. bayce

    поставил +.

    Интересное решение.

    Reply
  7. Andry.Boris

    Просто и доступно, однозначно +

    Reply
  8. KliMich

    Спасибо! Описано доступно и всерьез!

    Reply
  9. EvgeniuXP

    но для кого-то и облом:

    Доступность:

    Толстый клиент.
    — и этим всё сказано.

    Reply
  10. ekaruk

    (9) EvgeniuXP, не работала с программным добавление реквизитов в списки управляемых форм.

    Возможно, там эта проблема решена на системном уровне.

    Если не решена, то не вижу проблем модифицировать код под синтаксис управляемых форм.

    Reply
  11. unoDosTres

    Спасибо автору за идею, буду пробовать

    Reply
  12. LexSeIch

    Мир этому дому!

    Безусловно полезная заметка. Плюс.

    Reply
  13. unknownN

    Как раз искал для себя подобное решение, спасибо.

    Reply
  14. djserega

    у некоторых колонок ширина «-1» (наверное автоматическая настройка ширины)

    и после того как восстанавливаешь ширину «-1», то она превращается «1» и колонка получается очень узкая

    Reply
  15. ASV085

    Взял на заметку спасибо!

    Reply
  16. Dnki

    Прелестно! Давно задумывался над проблемой, но никак не собрался с мыслями.

    У меня только дополнение к командам Сохранить/Восстановить:

    СохранитьНастройкиКолонок(ЭтаФорма.ЭлементыФормы.Список.Колонки, «УникальноеИмяНастройки»…



    А именно к «УникальноеИмяНастройки». По опыту знаю, фантазия программиста бедновата выдумыванием названий.

    А если вставить так:

    СохранитьНастройкиКолонок(ЭтаФорма.ЭлементыФормы.Список.Колонки, Строка(СправочникСписок)…

    где СправочникСписок — основной реквизит формы

    тогда можно 1) копировать по другим спр-кам 2) четкая гарантия, что сохраняет и восстанавливает под одним именем.

    Reply
  17. nafa

    Все хорошо, но в процедуре восстановления настрек надо добавить проверку наличия колонки:

    Процедура ВосстановитьНастройкиКолонок(КоллекцияКолонок,ИмяНастройки) Экспорт
    
    НастройкиКолонок = ВосстановитьЗначение(ИмяНастройки);
    Если НастройкиКолонок<>Неопределено Тогда
    Для каждого СтрокаНастроек Из НастройкиКолонок Цикл
    ОбрабатываемаяКолонка = КоллекцияКолонок.Найти(СтрокаНастроек.ИмяКолонки);
    Если ОбрабатываемаяКолонка <> Неопределено Тогда
    ТекущаяПозицияКолонки = КоллекцияКолонок.Индекс(ОбрабатываемаяКолонка);
    КоллекцияКолонок.Сдвинуть(ТекущаяПозицияКолонки,СтрокаНастроек.Позиция-ТекущаяПозицияКолонки);
    ОбрабатываемаяКолонка.Видимость = СтрокаНастроек.Видимость;
    ОбрабатываемаяКолонка.Ширина = СтрокаНастроек.Ширина;
    КонецЕсли;
    КонецЦикла;
    КонецЕсли;
    
    КонецПроцедуры
    

    Показать

    А то иначе если колонку удалить (прекратить добавлять) то форма перестаёт открываться и выдает ошибку.

    Reply
  18. morber

    Годная доработка.

    Reply
  19. cdromscsi

    (14) djserega, вот как я решил сию проблему:

    Процедура ВосстановитьНастройкиКолонок(КоллекцияКолонок, ИмяНастройки) Экспорт
    
    НастройкиКолонок = ВосстановитьЗначение(ИмяНастройки);
    
    Если НастройкиКолонок <> Неопределено Тогда
    
    Для каждого СтрокаНастроек Из НастройкиКолонок Цикл
    ОбрабатываемаяКолонка = КоллекцияКолонок[СтрокаНастроек.ИмяКолонки];
    ТекущаяПозицияКолонки = КоллекцияКолонок.Индекс(ОбрабатываемаяКолонка);
    КоллекцияКолонок.Сдвинуть(ТекущаяПозицияКолонки,СтрокаНастроек.Позиция — ТекущаяПозицияКолонки);
    ОбрабатываемаяКолонка.Видимость = СтрокаНастроек.Видимость;
    //на тот случай, когда ширина колонки (-1)
    //т.е. автоматическая ширина
    Если СтрокаНастроек.Ширина < 0 Тогда
    Продолжить
    Иначе
    ОбрабатываемаяКолонка.Ширина = СтрокаНастроек.Ширина;
    КонецЕсли;
    КонецЦикла;
    
    КонецЕсли;
    
    КонецПроцедуры

    Показать

    Reply
  20. Shaldryn

    Хорошая статья, очень помогла!

    А не подскажите, не делали похожий функционал, но только с сохранением высоты табличных полей в обработке. Пример, тот же ПодборНоменклатуры в УТ 10.3, чтобы можно было сохранять высоту остатков товаров и справочника номенклатуры?

    передаю высоту, но он при открытии не восстанавливает высоту. То есть для ЭлементыФормы.СправочникНоменклатуры.Высота присваивается сохраненная, а для ЭлементыФормы.ОстаткиТоваров.Высота остается прежней….Может он не редактируется или же надо еще какой то элемент передавать в настройки?

    Reply
  21. klmsoft

    Если необходимо сохранять настройки всех колонок.

    То заполним строку всеми именами колонок

    Например так

    Для Каждого Колонка Из ЭлементыФормы.Товары.Колонки Цикл
    СписокСохраняемыхКолонок = СписокСохраняемыхКолонок + Колонка.Имя + «,»;
    КонецЦикла;
    СписокСохраняемыхКолонок = Лев(СписокСохраняемыхКолонок,СтрДлина(СписокСохраняемыхКолонок)-1);
    Reply

Leave a Comment

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