<?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='\
Спасибо за плюсы и комментарии! 🙂
В отчете , где присутствуют группировки по строкам и по колонкам , у большинства пользователей вызывает затруднение вопрос :
«Как найти поля всех родителей выбранной ячейки по строкам и по столбцам ?».
Например для того ,чтобы построить отбор для подчиненного отчета.
Было бы полезно , если бы Вы в следующей статье раскрыли бы этот вопрос.
>> 2
Применительно к примеру примерно так
Массив = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьРодителей()
Массив[0] — родитель по горизонтали
Массив[1] — родитель по вертикали
а во как получить настройки СКД при наличии нескольких СКД в отчете (обработке)
СхемаКомпоновкиДанных = ПолучитьМакет(«СтоимостнаяОценкаСклада»);
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
Теперь в настройках только отборы
Группировки подобным образом получить не удалось 🙁
(3) Ну это легко! )
Показать полностью
+(4) Ну что с отображением кода творится?! Хоть тегами не пользуйся! :((
(3) Ответ безусловно верный . Если бы вопрос был о родителях при одноуровневой группировке. Если речь идет ПОЛЯХ ВСЕХ родителей ,то
1.Предполагаются многоуровневые группировки неизвестного уровня.
2.Значения массива , полученного методом НайтиРодителей() могут иметь различные типы и на определенных уровнях могут не иметь полей (неприменим метод ПолучитьПоля()).
Таким образом , предполагается процедура.
Я предположил , что это не частный (узкий) вопрос , и его можно рассмотреть в задаче № 4.
(4)
не так то все и легко 😉
Показать полностью
Отбор загружается, группировок нет.
ФормаНастройки — стандартная форма настройки СКД.
Основная схема компоновки данных отчета не указана. При указании основной СКД отчета группировки остаются от основной СКД, а отбор от загружаемой
(6) Организовать рекурсивную процедуру обхода родителей
(7) «КомпоновщикНастроек» — это расширение формы отчета, не надо так переменную называть! 😉
+(8) В том смысле, что завидите отдельный компоновщик, как у меня в примере и всё будет работать…
С учетом (8)
Выставил макет СКД отчета "СтоимостнаяОценкаСклада"
Показать полностью
В созданном нами компоновщике доступных полей выбора — 0
В в расширении формы отчета доступных полей выбора — 11
Доступные поля выбора не загружаются с настройками??
(10) Хм… Ну вот выдрал пример из своего отчета, где по расшифровке выводятся движения по товару/складу с помощью вложенной схемы:
Процедура ДвиженияПоТовару(Номенклатура,Склад)
ТабДок=Новый ТабличныйДокумент;
СКД_Расшифровка=СхемаКомпоновкиДанных.ВложенныеСхемыКомпоновкиДанных[0].Схема;
КомпоновщикНастроек_Расшифровка=Новый КомпоновщикНастроекКомпоновкиДанных();
КомпоновщикНастроек_Расшифровка.ЗагрузитьНастройки(СКД_Расшифровка.НастройкиПоУмолчанию);
Настройки=КомпоновщикНастроек_Расшифровка.Настройки;
// Установим параметры
Параметры=Настройки.ПараметрыДанных.Элементы;
ПараметрНоменклатура=Параметры.Найти(«Номенклатура»);
ПараметрНоменклатура.Значение=Номенклатура;
ПараметрНоменклатура.Использование=Истина;
ПараметрСклад=Параметры.Найти(«Склад»);
ПараметрСклад.Значение=Склад;
ПараметрСклад.Использование=Истина;
КомпоновщикМакета=Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных=КомпоновщикМакета.Выполнить(СКД_Расшифровка,Настройки);
ПроцессорКомпоновкиДанных=Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);
ПроцессорВывода=Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
ТабДок.ТолькоПросмотр=Истина;
ТабДок.ОтображатьСетку=Ложь;
ТабДок.ОтображатьЗаголовки=Ложь;
ТабДок.ФиксацияСверху=1;
ТабДок.Показать(«Движения по товару <«+Номенклатура+»>»);
КонецПроцедуры
вот так всё работает, 100%
строка кода
СКД_Расшифровка=СхемаКомпоновкиДанных.ВложенныеСхемыКомпоновкиДанных[0].Схема;
предполагает, что у Вас заполнена основная СКД для отчета и Вы используете расширение ОтчетОбъект.СхемаКомпоновкиДанных.
Посмотрите как отработает тот же код если очистить основную СКД отчета и загрузить макет в коде
СхемаКомпоновкиДанных1 = ПолучитьМакет(ИмяВашегоМакетаСКД)
СКД_Расшифровка=СхемаКомпоновкиДанных1.ВложенныеСхемыКомпоновкиДанных[0].Схема;
(12) Насколько я понимаю, между схемой полученной из макета и вложенной схемой, не должно быть принципиальных отличий…
Вообще, есть в СКД некоторые глюки… В частности, заметил, что может «отваливаться» как сама схема, так и форма настроек. В таком случае помогает только пересоздание отчета.
(13) также обратил внимание, что при заполненном свойству основная СКД отчета все работает нормально, а при программной обработке остается только отбор и выбранные поля
Вот где собака порылась!!!
перед загрузкой настроек во вновь созданный КомпоновщикНастроек его надо инициализировать
(16) Запомним!
Как раз появилась задача с изменением стандартной расшифровки СКД 🙂 Только хотел разбираться.
А кто-нибудь смотрел реализацию универсальных отчетов и шаблонов для них на базе СКД в последних версиях БП и ЗУП ?
Сделано очень красиво и удобно для пользователя.
Очень легко портируется в другие конфигурации.
Я где-то минут за 20 перенес универсальный отчет + шаблон + все необходимое в самописную конфу для 8.1
(19) Да, молодцы. Обратил внимание на реализацию формы настроек, штатная — очень уж мудреная для пользователя. Да и запросы в ЗУП, которые были на несколько страниц, на порядок легче читать стало!…
3 пример некорректен. По крайней мере у меня получается : если выбирается действие из произвольного списка, то ОбработкаРасшифровки.Выполнить() возвращает «Непределено»… Т.е. уже не заходит в условие вывода отчета…
(21) В примере, дополнительное действие — это не изменение настроек и (или) вывод отчета, а какое-то другое действие не связанное с выводом, например открытие какой-либо формы, обработки.
Так что всё корректно, опять же в пределах примера )
(22) Точно 🙂 Я чё-то строчку «Иначе» пропустил 🙂
Кто-нибудь знает ответ на еще один подводный или надводный камень в СКД?
http://infostart.ru/forum/forum14/topic9440/messages/
Люди, спасите! Ну никак не могу настроить отбор вложенной схемы, чтобы детализировать общий отчет… У меня процедурка, которая данные для отбора выглядит так:
&НаКлиенте
Функция ПолучитьРекурсивноСтруктуруОтбора(ТекущееПоле, СтруктураОтбора = Неопределено)
Если СтруктураОтбора = Неопределено Тогда
СтруктураОтбора = Новый Структура;
КонецЕсли;
Для каждого ТекЭл Из ТекущееПоле.ПолучитьПоля() Цикл
СтруктураОтбора.Вставить(ТекЭл.Поле, ТекЭл.Значение);
КонецЦикла;
Для каждого ТекЭл Из ТекущееПоле.ПолучитьРодителей() Цикл
Если ТипЗнч(ТекЭл) = Тип(«ЭлементРасшифровкиКомпоновкиДанныхПоля») Тогда
ПолучитьРекурсивноСтруктуруОтбора(ТекЭл, СтруктураОтбора);
ИначеЕсли ТипЗнч(ТекЭл) = Тип(«ЭлементРасшифровкиКомпоновкиДанныхГруппировка») Тогда
Сообщить(«Группировка: » + ТекЭл.Группировка);
Иначе
Сообщить(«Неизвестный элемент: » + ТекЭл);
КонецЕсли;
КонецЦикла;
Возврат СтруктураОтбора;
КонецФункции // ПолучитьРекурсивноСтруктуруОтбора()
Вызывается она так:
ТекущееПоле = ДанныеРасшифровки.Элементы[Расшифровка];
СтруктураОтбора = ПолучитьРекурсивноСтруктуруОтбора(ТекущееПоле);
В итоге значения полей (строк и колонок) получаю спокойно, а из группировок не могу никак вытащить ни название группировки (мне нужно именно получить путь к данным, а не ничего не значащее «ГруппировкаN»), ни значения, которые потом надо установить в отбор во вложенной схеме… Может я что не так делаю? Я только-только начал программить под СКД, 100 грамм не помогли, а тяжелые наркотики я не хочу употреблять, чтобы в этом разобраться:(
Привет! Прикольная функция, тоже думал об этом вопросе, мне кажется так должно работать. Не пробовал на сложных группировках, скажи если проверишь и что не так.
Показать
Правда, тут два раза одни и те же значения добавляются, «Вставить» помогает, но типа не оптимально.
Вопрос автору: есть ли способ получить путь к данным поля, выбранного для расшифровки?
Привет! Подскажите, пожалуйста. Формирую отчет в СКД программно, и расшифровка совсем не работает. То есть привязанная к табличному полю функция на действие «Обработки расшифровки» просто не срабатывает.
Вот так формирую отчет:
ЭлементыФормы.Результат.Очистить();
ИсполняемыеНастройки = КомпоновщикНастроек.Настройки;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИсполняемыеНастройки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ,Расшифровка);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ЭлементыФормы.Результат);
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
Прервать;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
ЭлементыФормы.Результат.ПоказатьУровеньГруппировокСтрок(0);
При инициации процессора компоновки данных можно задать переменную, в которую «будут выводиться результаты компоновки данных» (это по синтакс-помощнику). Я написал — Расшифровка, не работает.
А что там надо написать, какую переменную создать, чтобы расшифровка срабатывала, кто-нибудь знает?
Нашел ответ. Надо было добавить третий параметр ДанныеРасшифровки в КомпоновщикМакета.Выполнить() и в ПроцессорКомпоновкиДанных.Инициализировать(). После этого можно менять расшифровку как угодно.
(28) Не совсем понятен вопрос… По-моему «ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[0].Поле» — это и есть путь к данным, т.е. имя поля в компоновке.
(31) Нет-нет, не имя того поля, ПО которому я щёлкнула, а имя того поля, которое я выбрала для расшифровки текущего!
Т.е. «Расшифровать», и нужно то поле, которое было выбрано в диалоге «Выбор поля»!
32 + Или хотя бы по какому принципу формируется список полей в диалоге «Выбор поля», чтобы это сымитировать…
32+
При повторном щелчке по исходной таблице (после выполнения расшифровки) процедура вылетает на указанной строке с ошибкой:
{Форма.ФормаОтчета(178)}: Значение, соответствующее ключу, не задано
текПоле=ДанныеРасшифровки.Элементы[Расшифровка];
В отладчике значение переменной Расшифровка в обоих случаях одинаково, а вот ДанныеРасшифровки — разные, хотя клик по одному и тому же полю в одной и той же ячейке. Чем бороть?
(34) Сама нашла, у меня ДанныеРасшифровки менялись (неявно) в дальнейшем коде.
Мой код для СКД расшифровка на 8.2. Может сгодиться кому 😀 :
Показать
А у меня следующая ситуация и разобраться в ней пока не получается.
Создаю отчет по результативности звонков. Пример выводимых данных в приклепленном файле.
И мне нужно по нажатию на ячейку с цифрой выводить следующую расшифровку: список событий, по которым был зарегистрирован такой результат. Если пишу
ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьРодителей()[0].ПолучитьПоля().Найти(«Мероприятие»)
то значение мероприятия известно, когда выбранная ячейка находится в строчке «Семинар УТ», если же нажимаю на любую другую ячейку, привязку к данной группировке по семинару не могу найти.
Если кто-нибудь сталкивался с подобной ситуацией, подскажите:)
плюсую, надеюсь будет продожение. Хотел бы посмотреть разных примеров с расшифровкой с помощью вложенных схем
(37) Поддерживаю — как расшифровку распространить на всю строку? Мне надо как то при клике на любое поле в строке получить значение в конкретной ячейке в этой строке.
Это плюс.
(39) GreenFox, задаюсь тем же вопросом.
Отличная статья. Спасибо!
(41) PrinzOfMunchen, уже почти день ковыряюсь над расшифровкой со всей строкой =
Статья — именно то, что нужно. Но вот какая у меня проблема: при сохранении конфигурации системы выдает следующую ошибку:
{Отчет.ОСВ1.Форма.ФормаОтчета.Форма(15,49)}: Слишком много фактических параметров (СкомпоноватьРезультат)
СкомпоноватьРезультат(ЭлементыФормы.Результат,<<?>>ДанныеРасшифровки); // выводим результат (Проверка: Тонкий клиент)
Почему? И что нужно сделать, чтобы все работало?
Всем здравствуйте.
Такой вопрос: настроены две вложенные схемы к основной СКД (схемы идентичные основной, но добавлен параметр для отбора в виртуальной таблице) . Выводятся в отчет последовательно, как 3 отдельных отчета. Так вот как понять к какой СКД относится элемент расшифровки? Т.е., в зависимости от ячейки, расшифровку которой нужно получить, необходимо определить в какой СКД эта ячейка выведена.
На упр формах никак не могу подобраться к ДанныеРасшифровки.
Пытаюсь получить через ПолучитьИзВременногоХранилища(ОтчетДанныеРасшифровки) — пишит «Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа».
На стороне сервера ПолучитьИзВременногоХранилища(ОтчетДанныеРасшифровки) работает, но надо на стороне клиента.
Хелп!
(46) sokir, Надо на стороне сервера вытаскивать все что нужно из данных расшифровки.
Помещать полученные данные скажем в фиксированный массив или в фиксированную структуру,
и возвращать на клиент.
самая первая строка не работает
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(<<?>>СхемаКомпоновкиДанных)); (Проверка: Тонкий клиент)
почему, кто подскажет…
Я «на клиенте.» Но и в примере «на клиенте»!
Для обычных конф. где не подходит расшифровка из «Шаблона 1С» самое простое это:
Показать
(36) Igor2010, привет, подскажи будь добре, у меня пустой результат после расшифровки выходит
http://www.forum.mista.ru/topic.php?id=776248
(11) спасибо за пример. Очень помогло.
(30)
Тоже весь интернет перерыл… везде не полные данные.
СПАСИБО.
А как ограничить вывод (показ) или удалить, на худой конец, некоторые доступные поля, которые есть в диалоге выбора поля при расшифровке ячейки?
Команда «Расшифровать…», вызываемая или двойным кликом по ячейке или через контекстное меню. В открывшейся форме диалога «Выбор поля» необходимо скрыть некоторые поля.
Спасибо
(53) Тоже ищу методы удаления ненужных пунктов контекстного меню.
Двойной клик стандартной обработкой убирается (и настраивается тоже).
А как изменить состав меню, которое вылетает по правой кнопке ?
Кто знает — направьте почитать.
Расшифровка формируется в этом же окне.
Сделал так
Открывается новое окно и в нем расшифрованное вывелось, но сбиваются настройки первой (главной) формы.
Конечно можно через отч = отчеты.ххх.создать, но это может быть и внешняя.
Как правильнее всего отрыть расшифровку в новом окне?
И еще для расшифровки я хочу применить другой вариант (другая структура вывода). Как в этом случае быть?
Добрый день
(57) ОбработкаРасшифровки
СтандартнаяОбработка = Ложь;
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(Отчет));
ОбработкаРасшифровки.Расшифровать(
а тут почитайте что туда передать
Скажите, а при выполнении какого действия «Настройки» будут не равны «Неопределено»??? что-то не совсем пойму, почему-то у меня они всегда равны «Неопределено».