<?php // Полная загрузка сервисных книжек, создан 2025-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='\
(0) Все просто — формируем через СКД нужные данные и выгружаем их реквизит формы «табличный документ» Расшифровку передаем через временное хранилище. Если надо предусмотреть параметры колонок или еще что-то делаем это в СКД
(1) seermak,
Это все да, а если Ваша таблица должна получится путем сложных вычислений. Например Запрос — Обработка запроса — Еще Запрос — Обработка запроса, совмещение и расчет данных программно, тогда как?
(2) Вы еще про перебор справочников вспомните) Все Ваши «Запрос — Обработка запроса — Еще Запрос — Обработка запроса» (если Вам нравится туда-сюда)загоняете в таблицу и используете, как внешние данные СКД
(3) seermak, Ну при чем тут перебор справочника. Я так понял, что Вы привыкли получать таблицы значений одним запросом. А я Вам говорю о том, что есть таблицы которые получаются вычислениями вне запросов и при чем тут СКД? И кстати, по поводу перебора справочника, иногда выгоднее сделать перебор, чем делать запрос.
А ещё можно посмотреть, как эта задача давным-давно решена в УТ11 и БП3, и не изобретать велосипед.
Статья неплохая, но опоздала года на полтора.
(5) Yashazz, С таким успехом можно все везде посмотреть. Статья предназначена для тех, кто столкнулся с такой задачей и не хочет где-то искать, а хочет сразу готовое. Каждому свое.
profiprog1c
Спосибо.
Мне очень помогло.
А как Избавится от командного панеля.
Например я хочу импортиромат из .тхт.
В этом случе мне не нужно Командный панел таблицы.
Заране спосибо.
(7) mammadov.zaur.77,
В процедуре СформироватьТаблицуЗначений()
В коде, где создаем объект «ТаблицаПолейВыбора» размещаем строку:
ТаблицаПолейВыбора.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Нет;
Командная панель будет не видна на форме после этого.
У формы стоит АвтоматическоеСохранениеДанныхВНастройках = Истина.
картинку ).
Вопрос: можно ли программно создать реквизит с галочкой «Сохранение»? Не путать со свойством «Сохраняемые данные», Я веду речь о галочке в таблице реквизитов формы в конструкторе (приложил
Просто хочется, чтобы значения программно добавляемых реквизитов сохранялись средствами платформы при закрытии формы (ну, восстанавливать их придется уже самому, это понятно), не хочется писать это самостоятельно. Не нашел такой возможности ни в конструкторе, ни через точку.
+(9) в общем, средствами платформы сохранять значения программно созданных реквизитов нельзя.
Решение следующее: при открытии / перед закрытием / где удобно взводить свойство формы
Автору огромное спасибо!!! Статья пошла в избранное 🙂
Интересная технология. Вот только у меня одна из колонок типа «ЛюбаяСсылка» и не взлетает…((
(13) AndreykO,
В статье я отмечал, что колонка таблицы значений должна иметь явный, конкретный тип, а вот «ЛюбаяСсылка» не является конкретным типом.
Интересная статья, хотелось бы ещё посмотреть создание таблицы с числами, и возможностью последующего вывода итога в подвал.
Пример рабочего кода на тему, на основе примера выше, ТЗ выгружается по результату запроса, Колонки автоматически создаются из колонок ТЗ
Таблица на форме при этом получает колонку с флажком и остальные колонки нормально типизированы
Показать
(16) kitaevay,
Не вводите никого в заблуждение, вы типы присваиваете каждой колонке. И логично, что если вы из запроса грузите данные в ТЗ, то колонки ТЗ будут типизированы, а если они не типизированы вы им пытаетесь присвоить тип. А в моем примере речь шла о колонах в ТЗ, которые создаются руками.
(17) да можно и не типизировать. Вы тут поднагнали пурги, мол, обязательно… Может, в старых релизах и было обязательно, да только всё меняется)
Начиная с 8.3.5, реквизит формы, в т.ч. подреквизит табчасти («колонка реквизита»), неважно, таблица ли значений или дерево, добавлена ли кодом или в конфигураторе — прекрасно может иметь тип «Произвольный». Делается очень просто:
Показать
Именно таким образом можно сделать динамически реквизит, в т.ч. колонку таблицы значений, которая будет вести себя как имеющая «Произвольный» тип. Только что проверено на 8.3.6.2014
Так что не зря я ворчал, публикация не вполне точна в своих утверждениях.
(18) Yashazz,
А где у вас в вашем куске кода Произвольный тип???
От того что вы свою функцию назвали ПолучитьПустоеОписаниеТипов(), она пустой не стала.
В вашем коде я вижу мультитип, число, строка, дата — это да, но пустого в упор не заметил.
(19) Повторяю — именно такое описание типов и даёт эффект работы с реквизитом, как будто он произвольного типа. Собственно, в понятиях 1С именно приведённое мной описание типов и есть произвольный тип. Вы создайте на форме реквизит произвольного типа и посмотрите на него, хоть в отладчике, хоть как. Всё просто.
(20) Yashazz,
Причем тут эффект работы, не играйте словами. Вы колонку тоже задаете как параметр.
В обычном приложении можно создать было колонку:
ТЗ.Колонки.Добавить(«Контрагент») и все — колонка готова.
В вашем примере такое есть? Нету.
И в моем примере идет параметризация и в вашем примере тоже. Только в моем, я задаю конкретный тип, а вы мультитип, все по сути одно и тоже, без разницы.
(21) а, так вы о том, чтобы вообще ничего не писать… Тогда пардон, неверно вас понял. Я всего лишь к тому, что эффект одинаковый — что ничего писать не надо, что мой вариант писать надо — в итоге результат тот же. А мы ведь на результат работаем, верно?
(22) Yashazz,
Результат верен, но неверна терминология.
Я в статье пишу, что в управляемом приложении как в обычном приложении просто задать колонку не получится.
А нужно ее параметризировать, по сути описать. Присвоить колонке пустышку, просто имя, без параметра, как в обычном приложении, нельзя.
Если 8.3.6 есть возможность задать мультипараметр в колонку, да без проблем, но его тоже надо задать, сам он не появляется.
Это все вопросы вкуса программирования конкретного программиста, но пустышку задать нельзя, как это было в обычном.
Все хорошо, но код на 8.3.6.2014 выдает ошибку в строке «НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип(«ПолеФормы»), ТаблицаПолейВыбора);» (а у (16) в строке «НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип(«ПолеФормы»), эТаблица);».
Ошибка одна и та же: Недопустимое значение параметров!
Убил не один час, чтобы понять в каком параметре ошибка. Ответ как всегда прост.
В первом параметре НЕЛЬЗЯ указывать одно и тоже имя с реквизитом. Т.е. вот так если записать «НовыйЭлемент = Элементы.Добавить(ИмяТЗ + Колонка.Имя, Тип(«ПолеФормы»), эТаблица); «, то все Ок.
Удачи. Спасибо за статью.
(24) Novichok777,
Моя обработка, по созданию произвольной таблицы, которую можно скачать, работает и в 8.3.6.2100, проверял.
А вот то, что тут комментаторы пишут и какие-то куски кода лепят в том же (16), я это не тестирую, и оно да, может не работать.
Коллеги,
Требуется создать таблицу значений с неясным количеством колонок. Т.е. делаю запрос, по запросу определяю список покупателей, создаю количество колонок с названием списка покупателей. Посмотрите, что я делаю не так:
Процедура ЗаполнитьКолонки(Элемент)
Запрос = Новый Запрос;
Запрос.Текст = «ВЫБРАТЬ
| ОптовыеЗаказчики.Заказчик,
| ОптовыеЗаказчики.ФормироватьСводныйЗаказ
|ИЗ
| РегистрСведений.ОптовыеЗаказчики КАК ОптовыеЗаказчики
|ГДЕ
| ОптовыеЗаказчики.ФормироватьСводныйЗаказ = ИСТИНА»
;
Результат = Запрос.Выполнить();
Обход = Результат.Выбрать();
Пока Обход.Следующий() Цикл
Таб.Колонки.Добавить(Обход.Заказчик,,Обход.Заказчик,50);
КонецЦикла;
КонецПроцедуры
В результате виртуальная таблица создается, но на форме данные не обновляются. На форме ничего не меняется, колонки не создаются.
(16) kitaevay, ну, мужик! ну благодарю! То, что надо!
Интересно, как сделать, чтобы по клику на заголовке колонки таблица сортировалась по этой колонке.
(24), подтверждаю, имена д.б. уникальными. Имя ТЗ лучше всегда добавлять в данном случае.
(16) Спасибо огромное! Все работает! Платформа 8.3.8.2167
(17) Я не знаю о каком заблуждении идет речь, в моём описание всё по существу, я не обещаю большего, чем есть в предложенном коде. Есть некоторый минимум знаний, который необходим, чтобы воспользоваться моим кодом, который подразумевает, что заблуждения тут маловероятны, а если они вдруг случились, то это поправимо типизацией колонки при добавлении оной вручную 😉
PS я поставил вам лайк, т.к. ваша публикация мне помогла и указал это в своём комментарии, не вижу причин для мелочной ревности. Peace Love Heaviness.
Спасибо! Я в восторге))
Кто-нибудь, напишете как в подвале итоговую сумму вывести, пожалуйста
(33) Ну, если еще не поздно )
Пардон,только учусь у меня при написании кода ,выходит ошибка {ВнешняяОбработка.ВыгрузкаПрайсаXML.Форма.Форма.Форма(195)}: Ошибка при вызове метода контекста (ИзменитьРеквизиты)
ИзменитьРеквизиты(МассивРеквизитов);
по причине:
Неуникальное имя реквизита. Имя: «ТаблицаРеквизитов»
Что делаю не так?
(35) По всей видимость у вас на форме уже есть реквизит с таким наименованием.
Либо вы пытаетесь повторно выполнить команду вывода таблицы значений на форму, предварительно не удалив уже существующую, которую создали после первого вызова вывода таблицы.