<?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='\
спасибо большое за изложенный материал, почерпнул для себя новое
Честно говоря для подобных моментов использую добавленный справочник «Настройки» с предопределенными элементами. Таким образом получение элементов осуществляется
Т.к. правка стандартных справочников (создание предопределенных элементов) чриевата при обновлении, а планы видов характеристик, как-то уж слишком заморочены (судя по коду).
Есть еще один довольно простой способ. Получаем GUID элемента, и ищем по нему.
(2) davdykin, вполне согласен. Но тут есть два момента.
Первый — у плана видов характеристик есть встроенное в платформу свойство Тип характеристик. А на справочнике придётся добавлять многотипный реквизит.
Второй — есть ещё одно преимущество на регистре сведения, о котором забыл упомянуть — иногда бывает нужно, чтобы в разные моменты времени значения переменных были разными. Тут и спасает периодичность регистра сведений.
Но в целом да, можно и справочником обойтись. Честно говоря, статьёй хотелось не столько показать способы, сколько привлечь внимание к проблеме, о которой многие ни сном, ни духом.
(3) WizaXxX, получаем каким образом? Если честно, не совсем понял приведённый код. Для работы с ГУИДом нам ведь его нужно вначале где-то взять, так же как и код или наименование, и с этим-то и проблема в работе с непредопределёнными элементами.
(5)
Открываем табло, и там пришем
А потом ворочаем как хотим в коде, будучи застрахованными от переименования и смены кода.
(5) проблема с непредопределенными элементами в том, что любой реквизит в нем по сути можно изменить, кроме, как раз, уникального идентификатора. Он для существующего в базе объекта не поменяется никогда ни при каких обстоятельствах.
Плюс (3) — нет необходимости создавать какие бы то ни было объекты. Минус (3) — сам код конечно будет удручать своей непонятностью и непрозрачностью.
(6) Gureev, нет, как получить уид я знаю, спасибо, я имел в виду саму методологию такого способа. Но тут, по сути, получается тот же самый хардкодинг — вместо наименования зашиваем в код УИД, а потом идущие за нами будут с интересом разглядывать эти иероглифы и слать нам в след проклятья 🙂
(3) WizaXxX, надёжно, но неудобно/непонятно/нечитабельно. Это называется «магические строки».
(0)
С какого релиза? Это раз. И в каком режиме совместимости? Это два.
Сам подскажу: видимо только с версии 8.3.3.641 (может быть раньше? поправьте меня, если не так), и, соответственно, в режиме совместимости 8.3.2 — не работает. То есть просто нет такого свойства как ИмяПредопределенныхДанных.
И еще: на мой взгляд важно отметить, что просто назначить элемент предопределенным — нельзя. Можно только переназначить предопределенному элементу ссылку.
А вообще — кратко, интересно, полезно. Ставлю плюс.
(8)
В комментарии к коду пишем что значат иероглифы. Считаю метод с заранее полученным и известным уид самым простым и менее затратным.
(10) quebracho, хардкод всегда был и будет одним из подвидов Г-кода. Конкретно в данном случае — способ с уидом не подойдёт для распространения релизов. Т.е. в новой базе будет новый элемент с новым уидом.
Вообще в среде 1С, видимо из-за того, что здесь все самоучки, совершенно не распространено стремление к хорошо написанному и легко читаемому коду. А вот, скажем, в том же Эклипсе при написании кода на джаве у вас даже программка не сохранится, если вы переменную назовёте с большой буквы, хотя сам язык не ставит ограничений на регистр имени переменных (можно тот же код написать в блокноте и скомпилировать) — просто там есть хороший тон в написании кода, там даже среда разработки заботится о чистоте и красоте кода. А в 1С этого самого хорошего стиля нет и, наверное, ещё долго не будет. Нет понимания, что твой код, помимо того, что ты его написал, ещё должен работать максимально быстро, быть читаемым и понятным, быть простым и лаконичным, быть универсальным и работать не только в одном сегодняшнем дне. Поэтому запросто можно встретить в коде обращение к реквизиту через пять точек, копирование одного и того же кода в сто разных мест, миллион строк кода без единого пробела и комментария и прочую «красоту и оптимальность».
Возвращаясь к уиду, расскажу, как было в одном из моих случаев. Был большой заказчик, была ооочень сильно переписанная типовая конфигурация, было наследство из тон Г-кода с тысячами НайтиПо…(«»). Был прикручен механизм из моего второго способа, удалены из кода все НайтиПо…(«»). Со временем заказчик понимает, что у него так много уникальных доработок, что их можно продавать, ставит цель — новое отраслевое решение. Переписывать всё под предопределённые элементы уже слишком затратно, а вот механизм с ПВХ и РС отлично подойдёт и для вновь разворачиваемых баз. А вот если бы там НайтиПо…(«») было бы заменено на УИДы, пришлось бы переписать всё ещё раз.
Всегда нужно помнить, что ГУИД — это только здесь и сейчас, что это заплатка на конкретный случай, что это просто проще написать и отдать заказчику.
(11)
Конкретно в другом случае — способ с уидом подойдет, т.к. заведомо не планируется распространение релизов.
Не переводится как «самое правильное решение на все случаи жизни».
Палка о двух концах «зачем городить кучу новых объектов, и переписывать код под них, когда решение конечное и проще привязаться к УИДу» и «зачем привязываться к УИДу, когда конфигурация — будет распространяемой, ссылки на объекты будут различными».
1С сама решает просто 🙂 Либо предопределенные элементы справочников, либо при старте чистой конфигурации создаются новые элементы справочников, и ссылки на них заталкиваются в константы.
Уникальный идентификатор — такая же не универсальная вещь как и использование методов НайтиПо.
С целью исключения дальнейших трудностей с обновлением после доработок, можно создать, например, отдельный справочник «Служебные значения». И в нем создавать предопределенные элементы.
Значение будет иметь составной тип.
В модуле менеджера справочника прописать функции получения элементов справочника для гарантии корректности «вытаскивания» данных.
Но логичней/правильней всего, считаю, было бы использование регистра сведений и плана видов характеристик.
НайтиПо… — дурной тон программирования.
(12) insurgut, возможные способы заполнения я описал в статье, так же и те, что вы упомянули — из типовых, при разворачивании. Константы на дают расширяемости, т.е. если я захочу ещё одну переменную, нужно создавать ещё одну константу.
Да, статья действительно об уже работающих конфигурациях, но, как я уже говорил, уже работающие могут превратиться в релиз. Да и к тому же, как мне кажется, любая заплатка должна всё равно иметь «человеческое лицо» 🙂 Т.е. если можно поставить заплатку на сегодня или же попытаться поставить заплатку на всегда (или на обозримое будущее) то лично я выберу второй способ, пусть даже он будет более затратным (в разумных пределах, конечно).
(15) ProX, нет
дурной тон программирования — это:
Если вдруг не понятно, то НайтиПо… это не дурной тон, дурной тон — не уметь его правильно использовать.
(17) Gureev,
использование чрезмерно сложных механизмов для простейших задач,
непонимание/неумение правильно использовать предлагаемые платформой механизмы в нужном месте в нужное время.
Если вдруг не понятно, то НайтиПо… это не дурной тон, дурной тон — не уметь его правильно использовать.
полностью согласен с каждым словом. К этому от себя могу только добавить, что ещё дурным тоном является зашивание в код значений (хардкодинг).
Баянчик, за исключением не совсем точно сформулированной фичи 8.3, а так — крик души из серии «наболело».
Напомню, что хардкодинг — он не только в упоминании конкретных экземпляров данных на уровне метаданных, а в стиле программирования, в подходе. Ничто не спасёт от сотни переменных в модуле с именами навроде «Случай№20», поди пойми, что за оно. От 5-7 почти одинаковых процедур в одном модуле, отличающихся парой строк. От реквизитов справочника, например, «ЦенаДляИванИваныча».
А огульно наезжать на хорошие методы языка — лишнее, имхо.
(19) Yashazz, всему своё место и время. Для НайтиПо() тоже своё место и время должно быть. Поэтому про огульно — это вы загнули, я как раз и описал тот случай, когда для этих методов совершенно не место.
А хардкодинг — это именно указание значений в коде, ничего больше. То, что вы описали, «стиль программирования, подход» — это уже более общее понятие — Г-код.
(20) если уж на то пошло, это даже не Г-код, а Г-проектирование и архитектура. Как-то так))
(21) Yashazz, согласен — как говорится, разруха — она в головах. Зачастую руководство не только не препятствует генерации Г-кода, а наоборот, поддерживает и всячески препятствует его искоренению. Работал я в такой организации — ессно, уволился из-за конфликта с начальством.
(22) for_sale, у меня примерно схожая ситуация… В довесок к основной деятельности наблюдаю за сайтом своей организации на Битриксе, с которым настроил синхронизацию с номенклатурой. Вроде интернет-магазина. Нашли хороший типовой шаблон. Связал его, настроил, чтобы все работало. Нашли маркетолога, который пытается этот шаблон видоизменить, и мягко говоря не в лучшую сторону (вставка неуместных блоков, не имеющих отношение к интернет-магазину, размещение элементов в совсем иной цветовой гамме, в результате чего они начнут выбиваться из дизайна). Пока сопротивляюсь. Но это совсем другая история. 🙂
Вовремя статья написана. Как раз столкнулся с этой проблемой. Сначала установил предопределенные в справочнике и обработкой заменил все значения. Управился за 3 часа (база больше 300 гигов).
Есть еще несколько таких же справочников, но теперь ссылок гораздо больше. Попробую вашу идею. Спасибо!
ну потом еще поиском и заменой ссылки заменять,а смысл,может просто закрывать права всем на изменение этого элемента не?
есть еще один способ, на мой взгляд от куда более предподчительный….
создаем новый общий модуль повторного использования (в сеансе) «ПИ» в нем пишем все наши
Показать
я специально здесь взял пример с хардкодинком для примера.
плюсы
1. даже если есть хардкодинг он весь в одном месте и его легко изменить в будующем, то есть относительно легко готовить «временные решения» а уже потом их цементировать… Временные решения нужны например когда до конца нет полной картины развития системы (когда планируется что то глобальное переделывать в ближайшем будущем)
2. получаем очень хорошую скорость
3. в коде запись проще и понятнее, есть контекстная подсказка. Сравните:
Первый способ — отлично работает на практике, создаётся предопределённый элемент с таким же кодом, а потом заменой ссылок объединяется со старым элементом и лишний удаляется.
Второй способ — какие-то константы на курьих ножках. Не вижу практически никаких преимуществ перед рекомендованным типовым механизмом.
Также в (26) хороший метод, сокрытие деталей реализации получения нужного значения. Если в функцию добавить аргумент дата можно и периодическое значение получать (неважно из регистра или в самой функции зашито), аналогично можно вводить аргументы-«измерения». Главное если есть функция получать значения только с помощью функции (к сожалению в 1С нельзя так гибко программную видимость настраивать как в ООП, где к закрытому полю физически не обратиться вне класса). В типовых обычно получение константы обёртывают в подобную функцию.
(10) quebracho, ага, а если базы две одинаковых по CF, но разные по данным, то ваш код будет редкой жутью. Считаю данный приём достойным ещё одного персонального котла в аду.
Статья ни о чем. Создание механизма для подстановки значений в параметры ? Да там с десяток таких механизмов написать можно разной степени извращенности. Суть в другом ты хоть стопитцот раз создавай свои планы характеристик но суть останется одной и той же — нет у тебя заполненного значения и идёшь ты лесом со своим алгоритмом. Плохой тон программирования заключается не в использовании функции найтипокоду найтипонаименованию а в дебильной уверенности что она тебе обязательно что то найдёт. Есть такое правило программирования — «обнуляй переменные» и пусть на заметку другие возьмут ещё одно правило «проверять заполненность переменных» при их использовании.
Давно для таких целей использую специальный справочник с предопределенными элементами. В этих элемента храню значения, которые и нужно жестко получать.
Вот подробнее:Предопределенные элементы. Добавление в типовую конфигурацию.
Мне почему-то кажется, что самый красивый вариант отказаться от использования НайтиПо… это получить строку ссылки через ЗначениеВСтрокуВнутр() и использовать эту строку в коде через ЗначениеИзСтрокиВнутр().
Конечно есть и минусы такого подхода — работает сей код только в одной ИБ, поэтому сделать внешнюю обработку для разных ИБ не получится.
Кстати к подходу, описанном в данной статье этот минус тоже относится.
Поэтому вывод: Если мы пишем для разных ИБ — однозначно используем НайтиПо…, а если для одной ИБ — каждый по своему извращается. Лично я выбираю ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр()
(31) YPermitin, да, как я уже выше писал, такое решение аналогично тому, что я в статье привёл. Только у вас огромный минус — нужно строкой передавать имя предопределённого. Намного проще использовать типовую ОбщегоНазначения.ЗначениеРеквизита(ПредопределенноеЗначение(Справочники.Предопр.Товар), «Значение»).
Ну или аналогичную функцию написать, Чтобы обрабатывать пустые значения и возврат значения по умолчанию.
(27) FullMoon, не понял, как переход на константы избавляет от необходимости менять Г-код? Тут либо вы оставляете всё как есть и все НайтиПо() или же переходите на какой-то механизм (пусть на константы) и тогда идёте в код и везде всё заменяете.
Но у констант перед справочником или ПВХ есть огромный минус — они висят в одном общем котле. Т.е. ваша «ПредопределённыйТоварБулочкаСМаком» будет висеть в одном ряду с ВалютаРегламентированногоУчета и прочими типовыми и будет совершенно непонятно, зачем она нужна и что она делает. У меня количество предопределённых элементов в ПВХ доходило до полутора сотен — представьте, что вы в УПП добавили ещё полторы сотни констант, потом с выходом новых релизов УПП, с работой ещё каких-нибудь разработчиков, с обновлениями криворуких ИТС-ников, туда добавится ещё несколько десятков констант и перемешается порядок — что там можно будет найти?
И ещё один огромный минус — не забывайте, вам надо будет каждую из ваших констант вывести в какую-то форму, чтобы задать её (если вы хотите задавать их через пользовательский режим). С программной задачей значений этот минус нивелируется, но тогда вы не можете одним движением руки посмотреть, правильно ли у вас задано значение конкретной константы или вы в обработке заполнения одной буквой ошиблись и у вас константа пустая. Вообще вглухую задавать значения даже служебных переменных без возможности посмотреть их через форму — это ещё один пример «заботы» о прозрачности механизма.
Нет, про константы не согласен. Согласен, что можно вместо ПВХ и регистра использовать справочник, но константы из-за описанных выше минусов явно проигрывают.
(32) opx, не понял, как должен работать такой механизм? приведите пример кода, пожалуйста. Не понял, потому что чтобы закинуть ссылку в строку, её нужно вначале где-то взять.
Данное решение довольно спорно. Во-первых, если Вы добавляете свои объекты, значит в конфигурации включены возможность изменений. Тогда возникает вопрос, почему бы не сделать уже по человечески через предопределенный элемент? Если Вы пишете свою конфигурацию, то тут вообще без комментариев. А методы Найти по наименованию или по коду приходится использовать когда конфигурация стоит полностью на поддержке без возможности изменений. Вот тут для обработок приходится извращаться через наименования или коды, так как указанный метод явно не подходит.
(36) help1Ckr, по человечески не получится, потому что база уже работает, нельзя создать предопределённый элемент и ходить заменять ссылки во всех существующих объектах, об этом в статье написано.
(33) for_sale, не вижу огромного минуса, ибо делалось эти с тем умыслом, чтобы потом сделать получение значений этих предопределенных элементов через кэширование повторно используемых значений. Да и изменения в функцию получения значения внести легче, если нужно глобально поменять поведение функции получения значений из предопределенных.
Вообщем, спор бессмыслен) Прочитал комментарии Выше и понял, что каждый при своем мнении)))
(37) for_sale, в чем проблема замены ссылок?
(38) YPermitin, функция ПРедопределенноеЗначение() и так кэширует значение до следующего изменения конфигурации, вне зависимости от того, где вы её вызываете, так что не вижу, в чём преимущество передавать имя переменной вместо ссылки на неё.
А минус в том, что, если она у вас называется как-нибудь «ПредопределённыйЭлементБулочкаСМакомКраснаяСвежаяВкусная», то ошибиться можно очень легко в какой-нибудь букве, а так ктрл+пробел сделает всю работу за вас. Можно, конечно, писать полную форму, а потом стирать — но зачем лишние действия, если плюсов в этой форме записи никаких?
При своём остаётся тот, кто боится признаваться в своих ошибках. Я, например, не боюсь, поэтому и признаю, что способ со справочником, который я не упомянул, не хуже моего способа с ПВХ и РС.
(39) help1Ckr, всего лишь в том, что нужно заменить стотыщмильйонов ссылок в круглосуточно работающей базе с сотней пользователей. Но в небольшой базе это проблема номер два, а проблема номер один — механизм замены нужно ещё написать. Не забыв абсолютно все места, где используются ваши ссылки. И зачем? Из-за боязни добавить лишний ПВХ и РС или справочник?
(35)Пишите внешнюю обработку, вставляете реквизит «Реквизит1» с типом «Справочник.Ссылка», «Документ.Ссылка», ну и т.д.
На кнопку вешаете код:
Сообщить(ЗначениеВСтрокуВнутр(Реквизит1));
Выбираете значение в реквизит1, жмете кнопку — вуаля.
Затем в коде пишите:
НужноеНамЗначение = ЗначениеИзСтрокиВнутр(«{«»#»»,a60de1b9-e80b-4519-947b-e45c0562461a,238:9ca4001635aff8e111e29d0602fcbd78}»);
Где («{«»#»»,a60de1b9-e80b-4519-947b-e45c0562461a,238:9ca4001635aff8e111e29d0602fcbd78}») — это то, что нам выдало сообщение.
И пофиг все. Другой номер, наименование или еще что-то: ссылка не меняется.
(41) for_sale, вопрос не в боязни. Вопрос в бессмысленности. Во первых, его должен кто то заполнять и следить за ним. Во вторых, усложняется написание запросов и в самом коде нужно проводить проверку на заполненность данного значения. А замена ссылок — чем типовая то не устраивает с ИТС? (сам не пробовал еще но планирую потестить) )
(42) opx, так это же тот же самый способ с УИДом, который выше в комментариях описывался, только в профиль.
Но это тот же хардкодинг.
(43) help1Ckr, типовой я пользовался очень давно, но, если мне память не изменяет, там есть какие-то ограничения. Плюс в большой-прибольшой базе цена ошибки тоже очень велика. Если где-то какую-то ссылку заменить не получится, то всё пойдёт на смарку. В общем, я бы не стал так просто играться с пользовательскими данными, особенно в большой базе — пусть уж лучше НайтиПо() остаётся, работает — и ладно.
(34) for_sale, отпадает необходимость менять код при смене значения.
Пусть висят в одном общем котле. Как я уже писал, пишется внешняя обработка, где все константы можно посмотреть и поменять. Форма этой обработки может быть любая, константы можно разбить по группам, разукрасить и т.п. Что касается их положения в конфигураторе, просто добавляются префиксы к их именам, пишутся комментарии.
Всё гениальное просто, если знать как это правильно применять, а если не знать, можно до бесконечности изобретать велосипеды.
Горячее обсуждение, обжечься можно, тоже буду думать.
Было бы здорово так:
…заходит враг, и электрический кулак ему по роже!в-общем, чтоб ручками на основе типовой чего-то наворотил, 1С куда-нибудь себе это записала, а потом если что — можно и редактировать только изменения в текстовом редакторе: как макросы в Excel записываешь в интерактивном режиме, а оно выдает Visual Basic. Наверное, плохо формулирую, но идея понятна?
Уважаемый! Будьте по-проще! Высокомерием и шибкоумием аж за версту несет! Да, использование данных конструкций не камильфо, но и без них подчас не обойтись, а уж в толстом клиенте приходится закрывать глаза. 🙁
(46) FullMoon, а потом приходит следующий программист и чешет репу — что это за сотня констант? Обработка внешняя для просмотра, ессно, затерялась, поэтому писать нужно ещё одну. На написание обработки тоже надо время, потому что там есть «праведные» и «неправедные» константы, зачем нам в этой обработке показывать ВалютуРеглУчёта?
И самое главное — для чего создавать всю эту неразбериху? Опять из-за боязни добавить лишний ПВХ, РС или справочник? Чем ваш велосипед лучше моего? Он быстрее собирается? Нет. Он удобнее в использовании? Ни в коем случае. Он лучше справляется с задачей? Ни разу. Он производительнее? Опять нет.
Какой код и зачем менять при смене значения?
У меня в коде есть переменная ПВХ.СлужебныеПеременные.РозничнаяЦена, которую я в пользовательском режиме задал как элемент справочника ТипыЦен «Розничная СПБ». Если я потом захочу установить в эту переменную «Розничная Москва», то я иду в регистр и задаю это значение — и всё. Что мне в коде нужно менять? Цель этой статьи и была — показать, как можно обойтись без смены кода при смене значений.
Если уж критикуете велосипед, то предложите хотя бы хороший велосипед взамен, а не коленную поделку. Если выбирать велосипед из ПВХ и из констант, то я уж лучше сделают ПВХ, где у меня в одном месте будут все мои потребности и который я, если вдруг нужно будет, одним движением руки грохну и забуду, чем буду генерировать тонны мусора, намертво сцепленного с жизненно важнными механизмами типовых.
(48) DoctorRoza, уважаемый, уточняйте, к кому вы обращаетесь, тут все уважаемые.
(48) Мне кажется, столько пару не столько от «констант», сколько от обновления «модифицированных«
я использую регистр сведений — в нем храниться только одна запись, в ресурсах по имени храниться значение, так же в ресурсах может быть хранилище значений для таблицы значений.
P.S. недавно при обновлении УПП с 1.3.44 на 1.3.51 случайно узнали что длина кода «Классификатора единиц измерения» увеличилась с 3 до 4, и поэтому код «=» перестал работать (такого кода осталось мало, но у нас он еще кое где встречается потому что очень большие наработки)
(49) for_sale, все описанные вами проблемы решаются добавлением внешней обработки в дополнительные обработки (я не представляю как её оттуда можно потерять) и написанием инструкций для следующего программиста. Вместо того чтобы спрашивать чем мой велосипед лучше, обоснуйте чем он хуже.
(53) FullMoon, чем ваш велосипед хуже я уже описал два раза в комментариях выше. А «написать инструкцию следующему, прибить гвоздями обработку, чтобы не потерялась» и прочие образцы народного рукоделия — это больше смахивает на блок в голове — «решить задачу любыми средствами, только бы не через ПВХ и РС». Плановидохарактеристикофобия какая-то.
И мне ещё говорят, что у меня слишком сложный механизм 🙂 Создай ПВХ и РС, заполни и используй в коде — вот как сложно! Чтобы не идти таким сложным путём, лучше просто загадить константы, написать обработку, которая будет показывать константы (только нужные) и сохранять их значения, написать инструкцию по использованию всего этого хозяйства, положить её куда-то, чтобы она не потерялась (как это бывает всегда), и не забыть носить оберег от сглаза, чтобы проклятия программистов, открывших ветку «Константы», не сбылись. При этом всё равно снимать конфигурацию с замка, всё равно через конфигуратор добавлять новые элементы, всё равно переписывать код под этот «механизм». В чём плюс — не понятно, зато мы избежали использования ПВХ и регистра сведений — Родина нас не забудет.
(54) ПВХ — это какая-то фигня, являющаяся, по сути дела, генератором типа. Наверное, ее загаживать лучше, хотя при бесчисленном количестве объектов в конфигурации это все равно, лишь бы «префиксы» были. На самом деле написать код в 100-1000 строчек куда проще, чем в таком же объеме разбираться, как бы хорошо он не был написан, и какими бы прекрасными комментариями не был снабжен. Все это часть системного кризиса…
Как говорится, не ссорьтесь, девочки, все равно это лишь разные виды заплаток, хорошо работать может только компилируемое. Тут уместна была бы цитата из Толстого.
У меня создалось впечатление, что автор ни разу не пользовался старой доброй обработкой «Поиск и замена значений»…
(56) dsv_nsk, впечатление почти верное — автор пользовался ею два раза года четыре назад. Надеюсь, за это сейчас не расстреливают?
Почему-то автор не упомянул, что при обновлении созданные «на местах» предопределенные элементы становятся непредопределенными.
Кроме того, у меня есть некоторый стаж работы программистом 1С и ни разу описанных траблов с конструкциями НайтиПо… у меня в практике не было — даже с 7.7, где эти поля не защищены от прямого редактирования, про 8.х я уже и не говорю.
Предлагаемый автором способ с ПВХ — уныл и непроизводителен, при поддержке чужого кода проще и быстрее понять конструкцию с «НайтиПо..» нежели предложенные изощрения.
лучше справочника настройки ничего не придумана зачем городить с характеристиками не понятно
что в том что в этом случае снимать с поддержки
(58) Lancelot-2M, какие предопределённые становятся непредопределёнными при обновлении?
Про производительность, пожалуйста, примеры и замеры какие-то, а то как на лавочке во дворе.
Про то, что НайтиПо() проще — полностью согласен. Но проще — это только один из параметров хорошего кода.
Вот текст простой обработки:
Показать
Замер производительности данного кода на картинке.
В справочнике Контрагенты 7300 групп и элементов, а в регистре сведений нДопРеквизитыКонтрагентовМакет 54 записи
(58) Lancelot-2M,
Да, понять
конечно же проще, чем
(62) for_sale,
Во-первых, вы выбираете кучу полей, когда вам нужно только одно, Контрагент. Вы думаете, что это не влияет на скорость?
— это реально необходимая выборка из регистра с настройками печатных форм, этот регистр заменил собою ряд конструкций «НайтиПо» и «Если СокрЛП(Контрагент.Код) = …» при переходе с ПУБ на УПП. Как человек ныне поддерживающий наши многострадальные печатные формы, могу со всей ответственностью заявить, что регистр настроек оказался очень неудобен при доработке печатных форм под новые требования контрагентов. При написании кода содержимое регистра неочевидно и это просто неудобно все время смотреть то в регистр то в код. Я уже не говорю, что при таком подходе добавление новых настроек требует обновления, а не только редактирования обработки внешней печатной формы.
— я ж для примера, не цепляйтесь к таким мелочам)
Сделал выборку одного поля из регистра — данные те же:
Возможно в вашем случае, на управляемых формах в тонком клиенте, результат иной…
(63) for_sale,
Да, понять
Справочники.КакойНибудьСправочник.НайтиПоКоду(«23400023423»);
конечно же проще, чем
ПолучитьЗначениеПредопределённого(ПланыВидовХарактеристик.Предопределённые.РозничнаяЦена);
а понять
думаю еще проще — и никакой документации для последователей — все в коде и очевидно.
(64) Lancelot-2M, да понятно, что код у вас вырван из контекста и в своём месте он вполне логичен и работоспособен, только в данном случае он никак не может быть примером. А тонкий или толстый клиент — в данном случае не имеет значения, потому что и первый, и второй способ выполняются на сервере.
(66) for_sale, тем не менее смотрите мои замеры в посте 62
(65) Lancelot-2M, да, конечно, если бы в коде было много комментариев, да ещё и по делу, да ещё и понятных — доработка была бы намного проще. Только почему-то в реальной жизни всё немного сложнее.
Другой пример — казалось бы, кому понадобится изменять код в элементе справочника? Никаких логических причин, вроде бы как, не должно быть, тем не менее сплошь и рядом!
В общем, я свою позицию высказал — хардкод был и останется вариантом Г-кода (это, кстати, не только моя позиция, во всех языках программирования, имеющих бОльшую историю, чем 1с, всякие книжки по оптимальному коду и т.п. эта позиция чётко прослеживается). С его помощью можно на ходу какую-то заплатку слепить, с которой последователи будут только мучаться, но не сделать нормальное решение.
(68) for_sale, лично мой опыт говорит об обратном — часто погоня за мнимым универсализмом и «оптимальным» решением лишь затрудняют развитие и поддержку прикладных решений — такова специфика нашей сферы, мы не статичные программульки с парой функций пишем — конфигурации развиваются и меняются всё время и адаптируются именно к частным случаям конкретных организаций
(70) EvilDoc, РС ЗначенияСвойствОбъектов не решает проблему — просто искать по коду/наименованию придется не в справочнике, а в ПВХ СвойстваОбъектов.
(69) Lancelot-2M,
с этим тоже согласен, но не считаю, что это тот случай. Говорил уже об этом в комментариях неоднократно, с примерами — несколько несложных действий помогут избежать кучи проблем. Да, потратить нужно будет на 10-15-20 минут больше, чем с НайтиПо, но время, затраченное на оптимизацию я не считаю потерянным в пустую.
(30) sanek_gk, полностью согласен, если уж и используется найти по коду или наименованию то всегда нужно быть готовым что то что мы ищем не найдется и соответственно обрабатывать данный вариант
(79) Хорошо, т.е. в 100500 местах программы, где было написано
нужно написать
(3) WizaXxX,
Потом требуется развернуть новую БД с данной конфигурацией, берем cf, разворачиваем… и наслаждаемся массовым падением всех этих конструкций.
(83) GreyJoJo, тут, пожалуй, любой способ, кроме предопределенных элементов, приведет к «осыпанию» подобных конструкций.
Можно, конечно, при запуске (или еще когда?) проверять наличие подходящих элементов, и создавать их принудительно. У самого возникла завязка на конкретный элемент справочника (сам справочник небольшой, но ссылок на него о-о-о-очень много). Извращался так: найти по наименованию, если пустая ссылка — создать с таким наименованием. Бинго! Ждем переименования элемента.
После прочтения статьи создал предопределенный элемент, переназначил его существующему, и радуюсь тому, насколько можно упростить код, сделать его аккуратнее и красивее.
Кстати: что-то не помню в этом обсуждении еще одного немаловажного камня в огород метода НайтиПоНаименованию и ему подобных: при существовании нескольких подходящих метод возвращает ссылку только на один «первый». Если с кодом еще можно бороться (проверять уникальность и запретить неуникальность), то запретить неуникальность наименований — практически нереально (можно, но в здравом уме этого делать не станешь).
(0), есть предложение дополнить приведенную процедуру одной строкой, сделать так:
Показать
+ (2) тоже используем справочник, только название другое)
Помимо описанного в статье в этом же справочнике хранятся различные настройки изменяющие поведение программы (например — «Распределять налог по обособленным подразделениям» или «Использова
(80) agrustny, а почему ты решил что данные привязанные к коду или наименованию справочника по прежнему актуальны после изменения кода или наименования ? Обычно когда адекватный человек пишет такой код он рассчитывает на то что эти данные также постоянны как константы и любое изменение этих данных сродни сбросу настроек. Единственное что нужно предусмотреть это тот самый сброс. Если я ищу в базе организацию по ИНН или наименованию то не вижу ни одной объективной необходимости создавать адский механизм усложнения и без того не всегда прозрачных расчетов(сомневаюсь что найдется много баз где заведено более 10-15 организаций). Многие владельцы фирм временно делают какие то изменения в своих базах потому что, кто то «так придумал:подсмотрел у кого то: или ему подсказали» (нужное подчеркнуть), через время забывая а нахрена они это делали и чем руководствовались. и по мне такие случаи так и нужно отрабатывать чтобы не возникало ложной уверенности что всё работает как «раньше» и расчеты корректны. Поменяли «постоянный элемент» — получи сообщение об этом и расчеты не могут быть продолжены. Это условные конструкции языка, которые очень нужны в «неустоявшихся неуниверсальных схемах» и вряд ли должны быть в обоснованных универсальных механизмах.
Другое дело когда их лепят везде где нужно и где не нужно.
А если у тебя написано что то «одно и тоже» в 100500 местах значит есть проблемы со структурированием кода и пора пересмотреть свой подход к программированию (аля глобальные модули). Конечно это не относится к индусскому коду)))) где платят за количество символов…..
(17) Gureev, поддерживаю. В некоторых случаях использование методов НайтиПоКоду(), НайтиПоНаименованию() вполне оправдано. И в типовых конфах довольно часто используется… Вообще не люблю категорических утверждений.
(105) DAnry, а разве кто-то говорит, что эти методы вообще нельзя использовать? Речь идёт о конкретных случаях использования их не по назначению.
(106) Вы в своей статье об этом и говорите, более того во вступлении вы практически прямо указываете, что те кто используют НайтиПо… неудачники у которых нет друзей и с которыми ниодин программист не будет общаться.
Спешу вас разочаровать, что фирма 1С в своих типовых очень активно использует и НайтиПоКоду (например Валюта, Банк, Планы обменов) и найтиПоНаименованию (страны мира, пользователи, варианты отчета и даже ЕИ)
А самое ужасное, для некоторых, что она использует … ПЕРЕЙТИ в своих типовых
Т.е. я искренен не понимаю почему часть программистов так рьяно пытается искоренить в своих программах некоторые возможности языка и пытается городить огород в виде отдельных справочников/регистров. И вместо того чтобы написать одну строчку НайтиПо готовы писать процедуры на 3 страницы
(107) Aleksey_3, вполне возможно, что я как-то выразился не так, что меня можно понять неправильно, но эта статья направлена не против методов НайтиПо, а против хардкодинга. Хардкодинг — это зашивание в код каких-то значений вместо использования переменных.
Объясняю по-простому:
НайтиПоНаименованию(ДанныеИзСтрокиПоиска) — это хорошо (хотя можно и лучше).
НайтиПоНаименованию(«Пирожок с капустой и грибами») — это плохо.
А про равнение на типовые — даже не говорите об этом, типовые тоже пишут живые люди, а не боги, так что там тоже куча всякого мусора. А ещё там куча всякого мусора, который кочует из версии в версию с самой 8.0, когда и язык был скуднее, и знаний-опыта у программистов было меньше. Например, в типовых везде ещё с версии 8.0 идёт обращение к предопределённым элементам просто как Справочник.Номенклатура.Пирожок, хотя уже есть функция ПредопределённоеЗначение(), которая кэширует полученное значение.
А ещё в комплексной (да и, по-моему, в остальных типовых тоже) меня просто убил типовой механизм напоминалки в заказе покупателю. Там просто в реквизиты добавлен реквизит ДатаНапоминания и всё! Если я хочу отложить напоминалку, я должен перезаписать документ, если у меня, например, закрыт период на дату документа, То напоминалка будет меня мучать до конца моих дней. Никаких возможностей назначения пользователей, никаких возможностей управления напоминанием, никакой возможности задавать какой-то текст напоминанию, каждая операция с напоминалкой дёргает документ. Вот вам типовой механизм! Так что равняться на типовые можно, но не всегда и с умом, а не просто — а вот в типовой так делают, значит и я так буду делать.
(107) Aleksey_3, Представляю, как сразу обвалятся ВСЕ стандартные конфигурации, если изменятся коды валюты или единиц измерения!!!
Везде должен быть разумный подход и планирование. Фирма 1С конечно же влет выпустит обновления. А вот что будет с самописными объектами. Целые системы могут полететь при таком подходе. Согласна, фирмам-франчайзи частенько очень удобно привязывать клиента неоправданно сломанными конфигурациями и конструкциями типа НайтиПо, и много еще чего…. Другое дело, если тебе ЭТО обслуживать. Очень хочется, чтобы система стабильно работала, невзирая на шаловливые ручки пользователей.
(109) Т.е. в нашу таблицу соответствие эти самые шаловливые руки не могут влезть???
По крайне мере НайтиПоКоду избавляет нас от двух проблем
А. Кто то не заполнил наш новомодный регистр
Б. Кто-то изменил значение в нашем регистры
(110) Aleksey_3, Ну и какая от этого беда случилась? А вот если код изменили и нет копии со старым кодом, фиг потом узнаешь, что там было. Если изменили значение в регистре, значит, у пользователя был к нему доступ. И следовательно, человек знал, что и зачем делал. Незаполнение регистра обычно исправить намного проще, чем отыскать следы измененного кода или наименования…Это я сужу сугубо по собственному опыту.
(107) Aleksey_3, а что? Лучше в 100500 местах по всей конфигурации искать один и тот же элемент по наименованию/коду? (досталась мне одна такая конфа, в которой один элемент искали реально раз 20+, и в каждом месте еще проверяли и создавали если его не было. хорошо, что он ни разу не переименовался =D ) Тогда уж лучше вынести такие конструкции в отдельный модуль, как это предлагалось выше. Из двух зол нужно выбирать меньшее.
(109) for-elenak, подобную байку слышал про деноминацию 1998 года, когда в программе резко потребовалось убрать по три нуля. Причем только из вновь вводимых документов…
А про типовые — можно до бесконечности обсуждать. НЕ ЭТАЛОН! Но иногда очень полезно заглянуть, подсмотреть что-нибудь заковыристое.
В какой-то типовой мне попадался даже такой коктейль:
ЕдиницаШтука = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию(«шт»);
…
ЕдиницаШтука = Справочники.ЕдиницыИзмерения.НайтиПоКоду(«123»); //важен не код, а подход к отысканию одного и того же элемента.
Причем это не было контрольным поиском. Просто с разницей в полстраницы кода Штуку искали сначала по наименованию, потом по коду.
(110) Aleksey_3, ну как дети, честное слово! Ставите права на чтение у пользователя и на изменение у администратора и никакой пользователь больше не влияет на вашу таблицу соответствий. А регистр заполняется при первом запуске.
Почитайте комментарии, там уже сто раз говорилось о плюсах и минусах НайтиПо и предложенного механизма.
(111) Аналогично можно рассуждать и по коду. Если кто то поменял, значит … и далее по вашему тексту
(112) ну у меня есть такой код в обработке обмена между 7-кой и 8-кой. Т.е. пытаюсь найти ЕИ по наименованию которая в источнике, если не нашли, то ищу шт, не пустые же оставлять.
(114) Я согласен с плюсами и минусами обоих подходов, и в работе использую и тот и тот подход. Я против посыла с которого начал автор
Т.е. когда какая нибудь конструкция языка объявляется вне закона и начинается охота на ведьм. Яркий пример использование «Перейти»
(117) Aleksey_3, про посыл — не нужно цепляться к наименованию статьи — туда, к сожалению или к счастью, не влазит весь текст статьи, так что я там не стал расписывать, что конкретно имеется в виду. Название должно зацепить и сподвигнуть на чтение, если вы прочитали только название и стали делать выводы — то могу только посочувствовать.
По поводу Перейти — не поверите, но это действительно тоже плохая конструкция. Причём, в отличие от НайтиПо(), она всегда плохая, если вы не смогли придумать ничего лучше перейти, то, наверное, нужно ещё что-то почитать, посмотреть, в общем, повысить уровень. За всю свою карьеру программиста я ни разу не использовал эту конструкцию, а значит можно обойтись и без неё. Плоха она тем, что создаёт путаницу в коде. И, кстати, в языке ActionScript 3 (который во флеше используется) тоже есть конструкция GoTo и там во всех курсах объясняется, что это — атавизм из второй версии и что не нужно его использовать.
Если вы не согласны, то приведите, пожалуйста, пример, где применение Перейти уместно и является самым оптимальным выходом. А заодно буду благодарен за пример использования Перейти в типовых — сам я ни разу её там не видел.
(118) За свою жизнь мне ниразу не понадобился грузовой автомобиль. Отсюда вывод требую запрет эксплуатации грузовых машин, потому что мой опыт показывает что можно обойтись без них
(123) Aleksey_3, разве кто-то требует запрета конструкции Перейти? Я вас просто попросил привести адекватный пример этой самой Перейти, где без неё не обойтись. Если у вас есть, то покажите, если нет, тогда понятно.
(124) Любую конструкцию можно объявить вне законна и найти способы не использовать эту конструкцию. Яркий пример модальность, с которым сейчас борется 1С с помощью простыни кода
Разумное использование перехода ничем не вредит ни коду, ни программисту. Программисту и коду вредят бездумное следование хрен знает чему…
amounts of indentation. That’s _especially_ true if the code flow isn’t
actually naturally indented (in this case it is, so I don’t think using
goto is in any way _clearer_ than not, but in general goto’s can be quite
good for readability).
Of course, in stupid languages like Pascal, where labels cannot be
descriptive, goto’s can be bad. But that’s not the fault of the goto,
that’s the braindamage of the language designer.
(с) Linus Torvaldshttps://lkml.org/lkml/2003/1/12/128
(125) Aleksey_3, про модальность, по-моему, всё доступно уже было объяснено — в браузерах работает криво и с пинка, если не пользуетесь браузером, то пользуйтесь модальностью, никто ж вам не запрещает.
Про Перейти — в третий раз прошу какие-нибудь примеры. Я не заявляю, что это плохая конструкция, просто у меня в жизни не было никаких посылов ею пользоваться, но я с радостью учусь всему новому, если увижу какой-то пример, где она к месту — обязательно возьму на вооружение. Но вы так и не соизволили привести никаких примеров, одна вода и сердечная боль за ущемление прав на равноправие конструкций кода.
(115) Aleksey_3, изменение кодов и наименований справочников доступно почти ВСЕМ пользователям. Почувствуйте разницу.
(126) for_sale, примеры Перейти в типовых конфигурациях 1С в студию:
— ЗУП 2.5.80.1 Регламентированный отчет Авансы по ЕСН
— ЗУП 2.5.80.1 Регламентированный отчет Авансы ПФР
— ЗУП 2.5.80.1 Регламентированный отчет ЕСН
— ЗУП 2.5.80.1 Регламентированный отчет ПФР
(правда там все использования в формах отчетов за 2004-2007 годы)
— БП 3.0.33.19 Регламентированный отчет Прибыль иностранной организации, формы за 2007 и 2014 годы
— БП 3.0.33.19 Регламентированный отчет Статистика прочие формы
— БП 3.0.33.19 Обработка Обработчики выгрузки в Управление Торговлей 10.3
Хотя представить было трудновато. Когда увидел — конечно согласился с их использованием: прерывание родительского цикла из вложенного.
При том, что регламентированные отчеты — не самая быстрая вещь, использование конструкции Перейти вполне может дать реальное ускорение, нежели использование 100500 проверок типа «Если ПораПрерватьЦикл Тогда». (честно — не замерял).
Пример не из 1С: недавно пришлось кое-что автоматизировать с помощью BAT-файлов. Вот там не нашел ничего лучше, чем GOTO. Нужно было организовать множественное ветвление. Контраргумент: язык командных файлов тоже можно назвать stupid language…
(26) vde69,
Заголовок статьи надо поправить типа: Как отказаться от использования НайтиПоНаименованию(«…»)
ИМХО это лучший способ:
1.Ускоряется время ответа.
2.Вся помойка в одном месте.