Ошибки в предопределённых элементах




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

32 Comments

  1. monkbest

    Ну собственно тута все есть

    http://prosto1s.ru/index.php/oblako-tegov/6-predopredelennie-elementy-spavochnika

    Reply
  2. buval

    Спасибо за сведения. В РИБ была аналогичная ошибка

    «Справочник.УдалитьСтатусыНалогоплательщиковПоНДФЛ.Резидент. Предопределенный элемент отсутствует в данных»

    Изменил предложенный код и всё получилось

    СсылкаНаОбъект=Справочники.УдалитьСтатусыНалогоплательщиковПоНДФЛ;

    ОбновляемыйОбъект = СсылкаНаОбъект.СоздатьЭлемент();// .ПолучитьОбъект();

    ОбновляемыйОбъект.ИмяПредопределенныхДанных = «Резидент»;

    ОбновляемыйОбъект.Наименование= «Резидент»;

    ОбновляемыйОбъект.ОбменДанными.Загрузка = Истина;

    ОбновляемыйОбъект.Записать();
    Reply
  3. capitan

    Хорошая статья. Помогла.

    А не пробовали разбираться, что меняется в базе, чтобы в периферийном узле предопределенные элементы не обновлялись из конфигуратора ?

    Вариант — отстутствие главного узла не проходит.

    Не пробовал правда саму базу сделать на время главной.

    Reply
  4. ekaruk

    (3) capitan, Зависит от свойства «Обновление предопределеныых данных» конкретного справочника.

    Если «Авто», то в подчиненных базах предопределенные элементы создаваться не будут. Должны прийти с обменом.

    Если «обновлять автоматически», то всегда будут создаваться.

    Reply
  5. capitan

    (4) Не поняли мой вопрос.

    Откуда база узнает ,что она периферийная ?

    Вариант — отстутствие главного узла не проходит.

    Удалял главный узел, все равно предопределенные элементы не создаются.

    Т.е. база еще где то помнит, что она была периферийной.

    Reply
  6. ekaruk

    (5) capitan, Теоретически должны пересоздаться при следующем обновлении конфигурации.

    Т.е. отключить от центрального узла и что-то изменить в конфигурации (банально пробел где-то добавить)

    Либо запустить с ключем /SetPredefinedDataUpdate

    Еще зависит от конфигурации.

    Может быть программно установлен другой режим обновления методом УстановитьОбновлениеПредопределенныхДанных()

    Reply
  7. maikl007

    Спасибо хорошая статейка, и обработка помогла

    Reply
  8. markers

    Полезная статья, спасибо!

    Reply
  9. KliMich

    Очень вовремя, спасибо!

    Обработка как раз кстати…

    Reply
  10. dsp123

    По поводу «самого простого способа №1»

    при переходе с БП на БСО в конфигураторе появились несколько специфических предопределенных «строительных» счетов. в базе данных есть соответствующие им элементы, но связать их никак не получается. При обращении обработками из режима предприятие счета не видны (ни обработкам, ни пользователю). То есть, чтобы связать предопределенные элементы с данными их надо увидеть из пользовательского режима, а для этого они должны быть уже связаны… Как выйти из этого порочного круга?

    Reply
  11. ekaruk

    (10) dsp123, Что имеется в виду под «Не видны»?

    Если они есть в базе, то их просто нужно выбрать.

    Если нету, то создать элементы в базе и привязать.

    Reply
  12. Tolyasik

    Здравствуйте! Ребят подскажите что можно сделать. В плане счетов ЕПСБУ в счете 104.36 появилась галочка «Нет учета по КПС» хотя галочки «Заболансовый» нет, при попытке изменить выдает сообщение что предопределенный элемент не уникален. Я не особый специалист 1С, я только учусь, по этому прошу вашей помощи!

    Reply
  13. ekaruk

    (12) Tolyasik, Как раз об этом второй раздел данной статьи

    2. «Предопределенный элемент не уникален» — задвоенные предопределенные элементы:

    Несколько элементов ИБ привязаны к одному предопределенному в конфигурации.

    Эти проблемы отлично решает обработка

    http://infostart.ru/public/305892/

    Reply
  14. Spacer

    Добрый день!

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

    А почему такая ошибка возникает в запросе, в типовом ЗУП 3.0?

    Я добавил в справочник «ПоказателиРасчетаЗарплаты» новый предопределенный элемент, и теперь выскакивает соответствующая ошибка.

    Общий модуль «СтандартныеПодсистемыПовтИсп», функция «ПредопределенныйЭлемент()», текст запроса:

    ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
    ПОКАЗАТЕЛИРАСЧЕТАЗАРПЛАТЫ.Ссылка КАК Ссылка
    ИЗ
    Справочник.ПоказателиРасчетаЗарплаты КАК ПОКАЗАТЕЛИРАСЧЕТАЗАРПЛАТЫ
    ГДЕ
    ПОКАЗАТЕЛИРАСЧЕТАЗАРПЛАТЫ.ИмяПредопределенныхДанных = &ИмяПредопределенного
    

    ————————————

    Вопрос снят. Протупил. В запрос передавалось неправильное имя предопределенного.

    Reply
  15. mixqn

    (14) Spacer, столкнулся с аналогичной ситуацией. хоть убей не понимаю, почему это должно вызывать ошибку, а не просто пустой результат запроса, как при поиске по любому другому реквизиту строкового типа. бред какой-то…

    Reply
  16. cbu23

    Добрый день! В бух. 3.0 Что то случилось со справочником ВидыКонтактнойИнформации. Когда открываешь справочник, то он пуст. Скачала Вашу обработку, но она видит все предопределенные элементы справочника и ошибок не находит. При этом в любом справочнике, где используется контактная информация ни адрес ни телефон заполнить нет возможности, просто нет гиперссылок. Может вы встречались с такой ситуацией и можете что то посоветовать? Бьюсь уже 2 дня.

    Reply
  17. Den_Zenit

    Спасибо! очень помогло…ошибка возникла в справочнике «Страны Мира»

    Reply
  18. Ioryk

    (2) Спасибо, и у меня получилось, хотя то же пришлось поправить…:

    &НаСервере
    Процедура НС_Установить()
    СсылкаНаОбъект =ОбектПредопределенных;
    ОбновляемыйОбъект = СсылкаНаОбъект.ПолучитьОбъект();
    ОбновляемыйОбъект.ИмяПредопределенныхДанных = «РазрешитьВыборКартыБезEmailПодтверждения»;
    ОбновляемыйОбъект.Наименование= «Разрешить Выбор Карты Без Email Подтверждения»;
    ОбновляемыйОбъект.ОбменДанными.Загрузка = Истина;
    ОбновляемыйОбъект.Записать();
    КонецПроцедуры
    

    Показать

    Reply
  19. Sean1s

    У нас, в ЗУП 2.5, после очередного обновления конфы потребовалось перейти на 8.3. Это было в середине марта. И вот вчера обнаружилось что в документе «Начисление страховых взносов» перестали рассчитываться ФСС НС и ПЗ. Колонка ФСС заполняется, а ФСС НС и ПЗ — нет.

    Два дня искал причину и нашёл — в справочнике ДоходыПоСтраховыхВзносам в предопределенном элементе «ОблагаетсяЦеликом» значение реквизита ВходитВБазуФСС_НС стало Ложь.

    Что характерно у нас несколько баз ЗУП. И в двух из них всё в порядке, а в остальных такое вот.

    Почему? Мне вот не понятно.

    Reply
  20. markovki

    Благодарю автора за статью.

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

    При чем реквизиты создаваемого элемента «оплата от покупателя» ДОЛЖНЫ быть заполнены в точности, как в демо базе, по крайней мере в нашем случае ВидОперации должен был быть правильно заполнен.

    Reply
  21. HamitovaRaisa

    Добрый день) Видимо, я что-то недопонимаю, хотя в 1С работаю уже не 1-й год. Нет у меня в справочнике свойства ИмяПредопределенныхДанных через запрос. Вот код:

    Процедура ()

    Об=Справочники.Автоработы.НайтиПоКоду(«ЦБ000000373»).ПолучитьОбъект();

    Об.ИмяПредопределенныхДанных=»ОсмотрАвтомобиля»;

    Об.Записать();

    КонецПроцедуры

    Ругается:

    Поле объекта не обнаружено (ИмяПредопределенныхДанных)

    Откуда вы видите это свойство в справочнике?

    Reply
  22. spacecraft

    (21)

    Поле объекта не обнаружено (ИмяПредопределенныхДанных)

    Прямо вот точно так ругается? Или может там другая формулировка.

    ИмяПредопределенныхДанных не назначает любому элементу справочника произвольное предопределенное имя.

    Оно назначает уже имеющееся предопределенное имя выбранному элементу справочника, при условии, что этот предопределенный элемент никакому объекту не назначен (как вариант — удален из базы).

    В качестве примера:

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

    Попытка
    ПредопределенныйЭлемент = Справочники.Автоработы.ОсмотрАвтомобиля.ПолучитьОбъект();
    ПредопределенныйЭлемент.ИмяПредопределенныхДанных = Неопределено;
    ПредопределенныйЭлемент.Записать();
    Исключение
    КонецПопытки;
    
    НовыйПредопределенныйЭлемент = Справочники.Автоработы.НайтиПоКоду(«ЦБ000000373»).ПолучитьОбъект();
    НовыйПредопределенныйЭлемент.ИмяПредопределенныхДанных = «ОсмотрАвтомобиля»;
    НовыйПредопределенныйЭлемент.Записать();
    

    Показать

    Reply
  23. HamitovaRaisa

    Полностью Скопировала код. Вот такое сообщение выходит:

    {ВнешнийОтчет.ВнешнийОтчет1.Форма.ФормаОтчета.Форма(3126)}: Поле объекта не обнаружено (ИмяПредопределенныхДанных)

    НовыйПредопределенныйЭлемент.ИмяПредопределенныхДанных = «ОсмотрАвтомобиля»;

    Reply
  24. HamitovaRaisa

    Полностью скопировала код. Вот такое сообщение выходит:

    {ВнешнийОтчет.ВнешнийОтчет1.Форма.ФормаОтчета.Форма(3126)}: Поле объекта не обнаружено (ИмяПредопределенныхДанных)

    НовыйПредопределенныйЭлемент.ИмяПредопределенныхДанных = «ОсмотрАвтомобиля»;

    Reply
  25. HamitovaRaisa

    Полностью скопировала код. Вот такое сообщение выходит:

    {ВнешнийОтчет.ВнешнийОтчет1.Форма.ФормаОтчета.Форма(3126)}: Поле объекта не обнаружено (ИмяПредопределенныхДанных)

    НовыйПредопределенныйЭлемент.ИмяПредопределенныхДанных = «ОсмотрАвтомобиля»;

    (22)

    Reply
  26. spacecraft

    (25) версия платформы и режим совместимости?

    В самой публикации в самом начале указано: «В 8.3.3».

    Reply
  27. HamitovaRaisa

    8.3.10.2580, режим совместимости: 8.2.16

    Reply
  28. spacecraft

    (27)

    режим совместимости: 8.2.16

    Вот и ответ. В 8.2 нет этого функционала.

    Reply
  29. HamitovaRaisa

    (28) Ок, спасибо)))

    Reply
  30. m.pikhota

    Спасибо за статью!

    Добавлю что в типовых ЗУП 3.1 и БУХ 3 есть функция для получения ссылки предопределенного элемента по его полному имени

    Например:

    ОбщегоНазначенияКлиентСервер.ПредопределенныйЭлемент(«Справочник.ВидыИспользованияРабочегоВремени.РаботаВечерниеЧасы»)

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

    // ЛюбаяСсылка — ссылка на предопределенный элемент.

    // Неопределено — если предопределенный есть в метаданных, но не создан в ИБ.

    При ее использовании не будет происходит ошибка «»Предопределенный элемент отсутствует в данных»», как при прямом обращении к предопределенному элементу например «Справочник.ВидыИспользованияРабочегоВремени.РаботаВечерниеЧасы»

    в том случае, например, если в базе не используются «Вечерние часы» и элемент в ИБ не был поэтому целенаправленно создан.

    Reply
  31. shved

    вставлю 5 копеек для плана счетов (ругалось при обновлении на 65ый БП3)

    М = Метаданные.ПланыСчетов.Хозрасчетный.ПолучитьИменаПредопределенных();
    Для каждого Имя Из М Цикл
    
    Попытка
    Ссылка = ПланыСчетов.Хозрасчетный[Имя].Ссылка;
    ОбновляемыйОбъект = Ссылка.ПолучитьОбъект();
    ОбновляемыйОбъект.ИмяПредопределенныхДанных = Имя;
    ОбновляемыйОбъект.ОбменДанными.Загрузка = Истина;
    ОбновляемыйОбъект.Записать();
    
    Исключение
    ОбновляемыйОбъект = ПланыСчетов.Хозрасчетный.СоздатьСчет();
    ОбновляемыйОбъект.ИмяПредопределенныхДанных = Имя;
    ОбновляемыйОбъект.ОбменДанными.Загрузка = Истина;
    ОбновляемыйОбъект.Записать();
    КонецПопытки;
    КонецЦикла;
    

    Показать

    Reply
  32. selez-a

    Спасибо, статья помогла. В БП3 в конфигураторе у справочника СтатьиЗатрат есть предопределенное значение «КомандировочныеРасходы» в режиме 1С Предприятия, такого элемента не было. Пришлось добавлять элемент, используя ваш код.

    Reply

Leave a Comment

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