Глюк 1С….?




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

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

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

<?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='\

24 Comments

  1. tango

    может в том, что код — строка, длина — 9?

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

    __

    а вообще надо название начать с «8х: знаете ли вы платформу»

    Reply
  2. Шёпот теней

    (1) СПАСИБО tango за сообщение…

    пробовал… доводил текст до 9 символов … результат тот же…

    во-о-оот…

    Reply
  3. coder1cv8

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

    Reply
  4. coder1cv8

    +(3) Пробелы порезались 🙂 я иммел ввиду 22446+4 пробела 🙂

    Reply
  5. Шёпот теней

    (1) может в том, что код — строка, длина — 9?

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

    вопрос: если обозначить код числом, тогда почему не найден, в справочнике.ФизЛица, элемент…? в таком случае…? а только по заданию кода «строкой»…

    воо-о-от…

    Reply
  6. Шёпот теней

    для всех кому интересно:

    пишу:

    //

    // справочник.ДолжностиОрганизаций ТипКод: строка; ОсновноеПредставление: В виде наименования;

    Сообщить(«справочник.ДолжностиОрганизаций»);

    //

    кодПроф = 22446; // число инженер

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«число код «+ссПроф.Код+» «+ссПроф.Наименование);

    // 123456789

    кодПроф = «22446»; //строка инженер

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«строка без код «+ссПроф.Код+» «+ссПроф.Наименование);

    // 123456789

    кодПроф = «22446 «; //строка до 9 символов инженер

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«строка 9 символов код «+ссПроф.Код+» «+ссПроф.Наименование);

    //

    Ответ 1С:

    справочник.ДолжностиОрганизаций

    число код 22 446 ИНЖЕНЕР

    строка без код

    строка 9 символов код

    написал всё дословно….

    воо-оо-оот…

    Reply
  7. Шёпот теней

    кому интересно:

    написал следущий код:

    //

    // справочник.ДолжностиОрганизаций ТипКод: строка; ОсновноеПредставление: В виде наименования;

    Сообщить(«справочник.ДолжностиОрганизаций»);

    // 123456789

    кодПроф = «22 446»; //строка «22_446» инженер

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«строка «»22_446″» 6 символов код «+ссПроф.Код+» «+ссПроф.Наименование);

    // 123456789

    кодПроф = «22 446 «; //строка «22_446___» инженер

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«строка «»22_446____»» 9 символов код «+ссПроф.Код+» «+ссПроф.Наименование);

    получил от 1С:

    //

    справочник.ДолжностиОрганизаций

    строка «22_446» 6 символов код 22 446 ИНЖЕНЕР

    строка «22_446____» 9 символов код 22 446 ИНЖЕНЕР

    воо-о-от такие дела….

    обнаружил… в справочники.ДожностиОрганизации коды указаны с пробелом например: «22_446″…

    Reply
  8. Шёпот теней

    ну, и, уж кому совсем интересно:

    После всех мытарств, выводы:

    Первое:

    Строки:

    //

    кодПроф = «22447»; //строка «22447» 5 символов — «инженер а»

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«строка «»22447″» 5 символов код «+ссПроф.Код+» «+ссПроф.Наименование);

    //

    кодПроф = «22447 «; //строка «22_446___» 9 символов «инженер а»

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«строка «»22447____»» 9 символов код «+ссПроф.Код+» «+ссПроф.Наименование);

    //

    Для 1С — идентичны, будет выдан результат один и тот же: «инженер а»

    Ввёл в справочник.ДолжностиОрганизаций код: 22447 и наименование: «инженер а»

    На строку:

    //

    кодПроф = 22447; //число 22447 5 символов «инженер а»

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«число «»22447″» 5 символов код «+ссПроф.Код+» «+ссПроф.Наименование);

    //

    1с не ответила….

    Второе:

    В справочники.ДолжностиОрганизаций введены коды должностей через пробел, вместо «22446____» ввели «22_446___» вследствии этого стали возможны следующие строки:

    //

    кодПроф = 22446; // число инженер

    ссПроф = справочники.ДолжностиОрганизаций.НайтиПоКоду(кодПроф);

    Сообщить(«число код «+ссПроф.Код+» «+ссПроф.Наименование);

    //

    Где 1С запросто давала ответ, но не давала ответ на строку типа «22446» или «22446____»…

    Воо-о-от и все выводы…. …и такие вооо-о-оот интересные особенности бухгалтерской и программной работы на местах….

    П.С. …кого «достало» может ставить БОЛЬШИЕ минусы…

    Удачи… всем…!

    Reply
  9. Шёпот теней

    ну и совсем уже обнаглев, мне уж это стало интересным, можете сделать смелый творческий эксперемент:

    Можно ввести в любой справочник, в котором код обозначен строкой, и где в программе 1С работает штатно или принудительно группировка чисел: «ЧГ=3,0» новый элемент, например:

    // создать элемент справочника

    Новый_Код = 123123; //(или с форматной строкой новыйКод = формат(123123, «ЧГ=3,0»); )

    новое_Наименование = “здесь был Вася”;

    //

    ….

    // записать(); элемент;

    И задать следующую строку поиска по коду:

    Спр.ИскомыйСправочник.НайтиПоКоду(123123).Наименование; //123123 как «число» и вам ответят: “здесь был Вася”;

    А на поиск «123123» , как строка, ответят молчанием… и на «123_123» тем же и на «123_123__» тем же…. и только на строку где кодом будет:

    спрКод = «3»+Символы.НПП+»331″+Символы.НПП+»111″; вам «Вася» ответит положительно…!

    Только вот проблема: в поиске, в справочнике, по коду, не сможете отыскать нужный вам элемент ни в построчном, ни в общем поиске дальше цифр до первого

    пробела…

    воо-оо-от такие метаморфозы….

    всем удачи…

    Reply
  10. tango

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

    Что считать глюком — не понятно, толи в первом случае (а с какой стати?), толи во втором (опять же — с какой стати?). в любом случае казус проходит по разряду «знаете ли вы платформу» :))

    Reply
  11. tango

    Шепот, замути мульку «поиск неразрыных пробелов в кодах справочников», получишь ++++

    пока — авансом, за мысль 🙂

    Reply
  12. Шёпот теней

    …tango Спасибо за все твои сообщения, пожелания, действия…

    маленькое П.С.: являясь человеком очень неуверенным с т.з. «высказывать своё мнение» и осознавая свой «опыт» постижения 1С в целом и 1С 8.0 в частности, именно поэтому заголовок данной ветки и озвучен как: «гЛЮк 1С….?», именно с вопросительным знаком… «?» — это же «вопросительный» знак….?

    воо-о-оот такой блин сегодня получился почти диалог-с….

    СПАСИБО…. и…. УДАЧИ…

    Reply
  13. tango

    Есть шанс иметь это грабло и в номерах доков. Так что — замути, хуже не будет. Уже.

    пс: будешь в наших краях — дай знать 🙂

    Reply
  14. Шёпот теней

    … и всё можно было бы улыбнуться читая «всё это», но только одно но: наши бухгалтера, например запросто могут организовать в справочниках не только «задва»ения но и «три» и «пять»-двоений, уж как пример, на прошлой моей работе наши бухи умудрились одну и туже улицу «обозвать» 17-ю разными именами… воо-о-оот…

    в данном случае обнаружили, что у нас разные «инженер-технолог»-и их было два, с разными кодами и целых трое «инженеров»… в итоге должность есть, их три и они все разные

    как всегда, бухи а это наши милейшие существа — женщина, кричат (орут), жалуются на 1С, друг – на — друга, и объединившись общим, дружным порывом объявили виноватым наш доблестный отдел АСУ…. ну-ууу и началось….

    такое бывает у всех… и все наверное знают, что бывает….. ну… и я в частности ничего не понимаю, ха…. код такой….. а ничего не работает…. вообщем…

    воо-о-оот такая «грусть» история…

    п.с. спасибо tango…

    удачи!…

    Reply
  15. poppy

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

    Т.е. число 123123 не равно строке «123123», но равно строке «123(пробел)123».

    Соответственно, при выполнении кода Спр.Код = 123123; на самом деле будет выполнено Спр.Код = «123(пробел)123».

    При выпонении НайтиПоКоду(«123123») ничего не найдено, а при НайтиПоКоду(123123) будет найден созданный ранее элемент, также как и пр Спр.НайтиПоКоду(«123(пробел)123»).

    Имхо надо избегать таких значений в качестве кодов элементов, поэтому лучше явно преобразовавать число в строку Спр.Код = Формат(123123, «ЧГ=0»);

    З.Ы. Мне показалось, что неразрывный пробел в коде подменяется обычным.

    Reply
  16. poppy

    (14)

    Как всегда бухши виноваты?

    Зачем было что-то кодить? Ведь можно было воспользоваться обработкой ПоискИЗаменаЗначений.epf с диска ИТС?

    Reply
  17. murat_

    Мне кажется, изначально нужно административно запрещать изменять код пользователям, хоть в доках, хоть в справочниках.

    Reply
  18. Шёпот теней

    (16)

    не-ееее, дорогая poppy!

    бухши как всегда не виноваты….? у них работа такая не быть виноватыми, они же женщины… они, что дуры….

    моё опыт, рисует мне такую картину, повторяющуюся в 80% случаях… крик… гам… в дружных рядах женского гарема под названием «Бухгалтерия» … что-то не «идёт»…. или что «утеряно»…. все бегают ищут, вспоминают… потом дружно обвиняют АСУ…. в итоге… проблема лежала в области «бухгалтерского учёта» а не в программе…. но никогда еще ни одна бухша не извинилась…. и считает это рабочей средой…. гы…. получается, что 80 % всех вопросов от бухш их же собственные, но путём обвинения АСУ они их прекрасно решают не за свой счёт…. за свой дорого и читать надо, или думать…. или «попу» поднять….

    воо-оо-оот такие не веселые мысли о бухш-ах…. но они не виноваты…. «весна» — однако… полететь охота…. или улететь… ветер одним словом — зашелестел…

    П.С. …. а насчёт ИТС… у нас их не выписывют… опять же бухи говорят…. эконмить надо…. а нам, это им значит, это не надо…. они и так всё знают…. видали мы ваши диски, типа, ничего там хорошоге нету… после этого ни о книгах, ни о журналах даже и не заикаемся… ладно хоть интернет не перекрывают… Экономика… блин её с бухшами….

    П.С. если бы знать где, что лежит, или где упадешь…? А, вообще…. очередной поклон… poppy… наверное скоро надо будет… вернее прошу вашу фотография на память… я её поставлю в рамку на рабочее место, как лучшиё образец программо-бухгалтерского ведения учёта…. позвольте попросить… моё е-майл найдёте в профайле… Это я серьёзно, с уважением, и просьбой, и поклоном….

    воо-оо-от …

    Reply
  19. Abadonna

    >… вернее прошу вашу фотография на память

    Губозакаточную машинку подарить? 😉

    Reply
  20. larisab

    <моё опыт, рисует мне такую картину, повторяющуюся в 80% случаях… крик… гам… в дружных рядах женского гарема под названием «Бухгалтерия» … что-то не «идёт»…. >

    е еще знаменитое тошнотворное — «не село»!!!

    Reply
  21. Шёпот теней

    (19) подари abadonna … от тебя с радостью… приму… и память будет на всю жизнь … :-)))

    (20) !!!

    Reply
  22. victuan

    ИМХО: Какой-то у «Шепота теней» тошнотворный стиль изложения материала (прошу прощения за оцену) — еле дочитал ветку до конца!

    Reply
  23. vasilykushnir

    (22) Не стреляйте в пианиста — он играет, как умеет…

    Reply
  24. MagSolD

    Йееех… Всем привет)

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

    Если написать конструкцию:

    Код (тип строка) = НовыйКод (тип число);

    в «нормальных» языках программирования выйдет ошибка компиляции (или чего-нить еще) из-за несовпадения типов. Правильно писать:

    Код (тип строка) = Строка(НовыйКод (тип число));

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

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

    В том же Екселе это неявное преобразование типов иногда жизнь портит, когда номер телефона федеральный предстает в виде Е+8384944 или вроде того.

    Так что это вопрос по сути на знание основ программирования.

    Reply

Leave a Comment

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