gifts2017

Как отказаться от использования НайтиПоНаименованию() и НайтиПоКоду() в уже работающих наполненных базах при дальнейшей разработке.

Опубликовал for_sale for_sale (for_sale) в раздел Программирование - Практика программирования

Как научиться не использовать НайтиПо...() в коде, начать заводить друзей среди программистов и перестать беспокоиться о жизнеспособности своего кода.

Если вы встречали в коде конструкции типа

Справочники.Номенклатура.НайтиПоНаименованию("Большая круглая фиговина 1мм");
Документы.РеализацияТоваровУслуг.НайтиПоКоду("00000000001");

то вы, возможно, вкушали последствия использования таких "образцов идеального кода".

Лично я не один и даже не десять раз наталкивался на последствия хардкодинга в виде использования функций НайтиПоКоду(), НайтиПоНаименованию() и НайтиПоНомеру() с зашитыми в коде значениями. Последствия всегда плачевные, их диапазон весьма широк - недоумение "почему оно не работает" или "почему в документе пустые реквизиты, вчера всё работало", необходимость куда-то лезть и менять прописанные значения, красные глаза от поиска в километрах кода той самой заветной строчки, а иногда и возможность интересно провести ночь за удалением/исправлением неправильно перенесённых/сгенерированных данных.

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

Лучше напишу о том, как избежать использования этих конструкций в коде.

 

Первый способ,

который подсказывает Капитан Очевидность - это использование предопределённых элементов. Если вам в коде нужно сослаться на валюту Рубль и ни на какую другую - создайте предопределённый Рубль в справочнике "Валюты". На этом способе даже не останавливаюсь, потому что он, надеюсь, понятен всем. Минус такого способа в том, что он не применим в базе, которая уже наполнена данными. Т.е. если в базе уже есть непредопределённый Рубль, то вы же не будете добавлять предопределённый и перебивать все ссылки в базе с одного Рубля на другой? Очень надеюсь, что такая мысль не придёт вам в голову.

 

Второй способ.

Для версий ниже 8.3. Долгое время и весьма успешно для искоренения НайтиПо...() из написанного до меня кода я использовал ПланВидовХарактеристик и РегистрСведений.

Допустим, какой-то нехороший человек до вас в коде написал:

 

Документ.Валюта = Справочники.Валюты.НайтиПоНаименованию("Рубль");

 

Тогда вы берёте и, не переставая молиться за спасение души этого человека, создаёте ПланВидовХарактеристик "СлужебныеПеременные" (типы значений выбираете в нашем случае справочник "Валюты") и РегистрСведений "ЗначенияСлужебныхПеременных" (непериодический, неподчинённый) с измерениями "Переменная" (тип ПВХСсылка.СлужебныеПеременные) и "Значение" (тип Характеристика.СлужебныеПеременные). Дальше в ПВХ создаёте предопределённый элемент Валюта_Рубль, а в РС запись - Валюта_Рубль = Рубль (выбираете из справочника "Валюты"). После этого идёте в код и пишете

//Документ.Валюта = Справочники.Валюты.НайтиПоНаименованию("Рубль");
Документ.Валюта = ПолучитьЗначениеСлужебнойПеременной(ПредопределенноеЗначение("ПланВидовХарактеристик.СлужебныеПеременные.Валюта_Рубль"));

// функция по получению значения служебной переменной
Функция ПолучитьЗначениеСлужебнойПеременной(Переменная, ЗначениеПоУмолчанию = Неопределено) Экспорт
	
	// вернём, если ничего не найдём
	прВернуть = ЗначениеПоУмолчанию;
	
// в запросе получаем значение переменной Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | ЗначенияСлужебныхПеременных.Значение |ИЗ | РегистрСведений.ЗначенияСлужебныхПеременных КАК ЗначенияСлужебныхПеременных |ГДЕ | ЗначенияСлужебныхПеременных.Переменная = &Переменная"; Запрос.УстановитьПараметр("Переменная", Переменная); Результат = Запрос.Выполнить().Выбрать();
// если запрос что-то вернул, то это и есть значение переменной Если Результат.Следующий() Тогда прВернуть = Результат.Значение; КонецЕсли; Возврат прВернуть; КонецФункции

Вот и всё. Теперь вы всегда знаете, что ваши механизмы не рассыпятся как карточные домики от изменения пользователем какого-нибудь нолика где-то в дебрях справочников-документов.

Плюс такого подхода - это совершенно отдельно стоящий механизм, который не влияет на типовые механизмы и не затрагивает типовые объекты метаданных.

Минус - да, должен быть заполнен регистр сведений, без него никуда. Здесь можно посоветовать при начале работы системы под админскими правами сверять количество служебных переменных в плане видов характеристик и количество записей в регистре "Значения служебных переменных" и, если какие-то переменные не заполнены - выдавать что-нибудь грозное и устрашающее, пусть заполняют. Ещё можно создать обработку автоматического заполнения регистра. Как заполнять? А с помощью тех самых ненавистных мне НайтиПоКоду("000001") - а что делать, ради такого благого дела можно их и потерпеть ещё разик :) Для особо пугливых можно просто использовать этот механизм как основной, а НайтиПо...() не удалять, а оставить как дублирующий, на всякий случай.

 

Третий способ.

Для версий от 8.3 - неожиданное продолжение первого способа с помощью новых технологий.

В платформе 8.3 появилась интересная возможность переназначать, удалять и всячески извращаться над предопределёнными элементами. Т.е. тот самый Рубль, который непредопределённый, можно просто сделать предопределённым! Не знаю как вы, я вначале не поверил, когда узнал, что так можно. Но оказалось, что да, действительно, докатились, теперь и в мире 1С нет ничего постоянного и надёжного. Но в данном случае это даже хорошо - мы можем, обойдясь подножными средствами, отделаться от НайтиПо...()

Итак, что нужно?

Идём в конфигуратор, открываем нужный объект метаданных (наш справочник "Валюты"), идём в предопределённые, добавляем новый предопределённый Рубль, обязательно задаём ему вручную какой-нибудь незанятый код.

Теперь создаём новую обработку, в ней форму, в форме создаём процедуру ПриСозданииНаСервере(), там пишем

 

&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
	
	// лишаем предопределённый рубль его предопределённости
	Валюта = Справочники.Валюты.НайтиПоКоду([Код_Предопределённого_Рубля]).ПолучитьОбъект();
	Валюта.ИмяПредопределенныхДанных = “”;
	Валюта.Записать();
	
	// освободившуюся предопределённость отдаём старому рублю
	Валюта = Справочники.Валюты.НайтиПоКоду([Код_НЕ_Предопределённого_Рубля]).ПолучитьОбъект();
	Валюта.ИмяПредопределенныхДанных = “Рубль”;
	Валюта.Записать();
	
КонецПроцедуры

 

После этого удаляем тот Рубль, который стал нам не нужен. Всё, теперь на старый, потёртый, использовавшийся в базе Рубль можно ссылаться в коде как на предопределённый элемент. Плюс такого способа - ничего нигде не надо заполнять, включая любые пустые релизы вашей конфигурации, там всё уже будет по умолчанию. Минус - может возникнуть неразбериха при обновлениях, так же, в отличие от предыдущего способа, не может использоваться как отдельно стоящий механизм, который не затрагивает типовые объекты.

 

UPD:

Навеяно комментариями к статье.

В комментариях многие предлагают использовать метод ПолучитьСсылку("уид-того-что-нам-надо") с зашитым в тексте программы УИДом. Но, как и любая разновидность Г-кода, хардкодинг (зашивание значений в код) имеет множество недостатков и кажется мне непримлиемой. Фактически предлагается избавиться от одного хардкодинга другим, мотивируя это тем, что, якобы уид ссылки никогда не меняется. На деле же, как и любой Г-код, это - быстрая и дешёвая заплатка, сделанная на коленке.

Во-первых, УИД может поменяться - не УИД той ссылки, которую мы используем, а сам элемент, который мы используем. Например, раньше нам нужен был УИД элемента справочника Типы цен "Розничная", а теперь нужен "Розничная СПБ". Конечно, нужно лезть в код и менять, а до того система будет работать не так, как нужно.

Во-вторых, можно забыть о тестовых базах - не получится просто взять cf от конфигурации и накатить её на демо-базу и вести разработку там, просто перенося изменения в рабочую. Как раз сейчас работаю на проекте, где изначально было две базы - рабочая и тестовая, создавались они не из одного dt, а независимо друг от друга, соответственно, все УИДы разные. Пытаюсь вести разработку в демо-базе, но каждый раз, когда на тыкаюсь на все эти УИДы, не могу не пожелать долгой и мучительной смерти тому, кто всё это рисовал.

В-третьих, строка

ПолучитьЗначениеПеременной(ПредопределенноеЗначение("ПВХ.Переменные.ТипЦены_Розничная"))

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

Справочники.ТипыЦен.ПолучитьСсылку("с3фацфмыф-ф23аф23аф0-2й3укфафц0-23к2к")

Кто-то писал, что это исправляется добавлением комментария, но всё это из области фантастики - я в своей работе ни разу не встречал комментарий рядом с УИДом.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Александр Лыткин (TrinitronOTV) 25.04.14 05:35
спасибо большое за изложенный материал, почерпнул для себя новое
2. Призрак (davdykin) 25.04.14 06:47
Честно говоря для подобных моментов использую добавленный справочник "Настройки" с предопределенными элементами. Таким образом получение элементов осуществляется
Рубль = Справочники.Настройки.Рубль.Значение;

Т.к. правка стандартных справочников (создание предопределенных элементов) чриевата при обновлении, а планы видов характеристик, как-то уж слишком заморочены (судя по коду).
GATTUSO; klinval; йцукенг; Spacer; m-serg74; the1; Mi4man; bashinsky; zyx2002; awk; baton_pk; YPermitin; DancingShadow; Angry; AnryMc; Lancelot-2M; dsv_nsk; Nefertary; Cvetic; AllexSoft; rasswet; wolfsoft; ZOMI; Rusmus; maxis33; insurgut; Gureev; AlexanderKai; +28 Ответить 2
3. Илья Козырев (WizaXxX) 25.04.14 07:10
Есть еще один довольно простой способ. Получаем GUID элемента, и ищем по нему.
ЭлементСпр = Справочники.Алгоритмы.ПолучитьСсылку(Новый УникальныйИдентификатор("Идентификатор нашего объекта"));//Ищем банан.
teriban; kaufman; Tavalik; biz-intel; awk; ASDF2; baton_pk; Uncore; mtv:); AnryMc; Рамзес; pm74; +12 2 Ответить 3
4. dmb2006vesna (for_sale) 25.04.14 08:48
(2) davdykin, вполне согласен. Но тут есть два момента.
Первый - у плана видов характеристик есть встроенное в платформу свойство Тип характеристик. А на справочнике придётся добавлять многотипный реквизит.
Второй - есть ещё одно преимущество на регистре сведения, о котором забыл упомянуть - иногда бывает нужно, чтобы в разные моменты времени значения переменных были разными. Тут и спасает периодичность регистра сведений.

Но в целом да, можно и справочником обойтись. Честно говоря, статьёй хотелось не столько показать способы, сколько привлечь внимание к проблеме, о которой многие ни сном, ни духом.
5. dmb2006vesna (for_sale) 25.04.14 08:51
(3) WizaXxX, получаем каким образом? Если честно, не совсем понял приведённый код. Для работы с ГУИДом нам ведь его нужно вначале где-то взять, так же как и код или наименование, и с этим-то и проблема в работе с непредопределёнными элементами.
6. Юрий Гуреев (Gureev) 25.04.14 09:14
(5) dmb2006vesna,
Открываем табло, и там пришем

Справочники.Валюты.НайтиПоКоду("840").УникальныйИдентификатор()


А потом ворочаем как хотим в коде, будучи застрахованными от переименования и смены кода.
Дмитрий74Чел; +1 Ответить 1
7. Анянов Михаил (insurgut) 25.04.14 09:45
(5) dmb2006vesna, проблема с непредопределенными элементами в том, что любой реквизит в нем по сути можно изменить, кроме, как раз, уникального идентификатора. Он для существующего в базе объекта не поменяется никогда ни при каких обстоятельствах.

Плюс (3) - нет необходимости создавать какие бы то ни было объекты. Минус (3) - сам код конечно будет удручать своей непонятностью и непрозрачностью.
8. dmb2006vesna (for_sale) 25.04.14 10:10
(6) Gureev, нет, как получить уид я знаю, спасибо, я имел в виду саму методологию такого способа. Но тут, по сути, получается тот же самый хардкодинг - вместо наименования зашиваем в код УИД, а потом идущие за нами будут с интересом разглядывать эти иероглифы и слать нам в след проклятья :)
9. Тимофей Шантин (ShantinTD) 25.04.14 10:36
(3) WizaXxX, надёжно, но неудобно/непонятно/нечитабельно. Это называется "магические строки".

(0)
В платформе 8.3 появилась интересная возможность...

С какого релиза? Это раз. И в каком режиме совместимости? Это два.
Сам подскажу: видимо только с версии 8.3.3.641 (может быть раньше? поправьте меня, если не так), и, соответственно, в режиме совместимости 8.3.2 - не работает. То есть просто нет такого свойства как ИмяПредопределенныхДанных.
И еще: на мой взгляд важно отметить, что просто назначить элемент предопределенным - нельзя. Можно только переназначить предопределенному элементу ссылку.

А вообще - кратко, интересно, полезно. Ставлю плюс.
10. qwe qwerty (quebracho) 25.04.14 10:54
(8) dmb2006vesna,
В комментарии к коду пишем что значат иероглифы. Считаю метод с заранее полученным и известным уид самым простым и менее затратным.
Дмитрий74Чел; Tavalik; mtv:); +3 Ответить 2
11. dmb2006vesna (for_sale) 25.04.14 11:16
(10) quebracho, хардкод всегда был и будет одним из подвидов Г-кода. Конкретно в данном случае - способ с уидом не подойдёт для распространения релизов. Т.е. в новой базе будет новый элемент с новым уидом.

Вообще в среде 1С, видимо из-за того, что здесь все самоучки, совершенно не распространено стремление к хорошо написанному и легко читаемому коду. А вот, скажем, в том же Эклипсе при написании кода на джаве у вас даже программка не сохранится, если вы переменную назовёте с большой буквы, хотя сам язык не ставит ограничений на регистр имени переменных (можно тот же код написать в блокноте и скомпилировать) - просто там есть хороший тон в написании кода, там даже среда разработки заботится о чистоте и красоте кода. А в 1С этого самого хорошего стиля нет и, наверное, ещё долго не будет. Нет понимания, что твой код, помимо того, что ты его написал, ещё должен работать максимально быстро, быть читаемым и понятным, быть простым и лаконичным, быть универсальным и работать не только в одном сегодняшнем дне. Поэтому запросто можно встретить в коде обращение к реквизиту через пять точек, копирование одного и того же кода в сто разных мест, миллион строк кода без единого пробела и комментария и прочую "красоту и оптимальность".

Возвращаясь к уиду, расскажу, как было в одном из моих случаев. Был большой заказчик, была ооочень сильно переписанная типовая конфигурация, было наследство из тон Г-кода с тысячами НайтиПо...(""). Был прикручен механизм из моего второго способа, удалены из кода все НайтиПо...(""). Со временем заказчик понимает, что у него так много уникальных доработок, что их можно продавать, ставит цель - новое отраслевое решение. Переписывать всё под предопределённые элементы уже слишком затратно, а вот механизм с ПВХ и РС отлично подойдёт и для вновь разворачиваемых баз. А вот если бы там НайтиПо...("") было бы заменено на УИДы, пришлось бы переписать всё ещё раз.

Всегда нужно помнить, что ГУИД - это только здесь и сейчас, что это заплатка на конкретный случай, что это просто проще написать и отдать заказчику.
KarpovDeniska; Katren; for-elenak; MarsSt; theshadowco; wolfsoft; +6 Ответить 3
12. Анянов Михаил (insurgut) 25.04.14 11:48
(11) dmb2006vesna,
хардкод всегда был и будет одним из подвидов Г-кода. Конкретно в данном случае - способ с уидом не подойдёт для распространения релизов. Т.е. в новой базе будет новый элемент с новым уидом.

Каких еще релизов? Статья разве не о том, как красиво дорабатывать типовые конфигурации без привязки к элементам справочников по коду или наименованию? Если мы сами разрабатываем свою конфигурацию, само собой тут либо константы, либо предопределенные значения элементов справочников.

ставит цель - новое отраслевое решение. Переписывать всё под предопределённые элементы уже слишком затратно, а вот механизм с ПВХ и РС отлично подойдёт и для вновь разворачиваемых баз.

Как же это он отлично подойдет, кто будет заполнять уйму ваших ссылок?
Дмитрий74Чел; +1 Ответить 1
13. qwe qwerty (quebracho) 25.04.14 11:50
(11)
Конкретно в данном случае - способ с уидом не подойдёт для распространения релизов. Т.е. в новой базе будет новый элемент с новым уидом.

Конкретно в другом случае - способ с уидом подойдет, т.к. заведомо не планируется распространение релизов.
Считаю метод с заранее полученным и известным уид самым простым и менее затратным.

Не переводится как "самое правильное решение на все случаи жизни".
14. Анянов Михаил (insurgut) 25.04.14 11:55
Палка о двух концах "зачем городить кучу новых объектов, и переписывать код под них, когда решение конечное и проще привязаться к УИДу" и "зачем привязываться к УИДу, когда конфигурация - будет распространяемой, ссылки на объекты будут различными".
1С сама решает просто :) Либо предопределенные элементы справочников, либо при старте чистой конфигурации создаются новые элементы справочников, и ссылки на них заталкиваются в константы.
15. Роман Прокопенко (ProX) 25.04.14 12:09
Уникальный идентификатор - такая же не универсальная вещь как и использование методов НайтиПо.

С целью исключения дальнейших трудностей с обновлением после доработок, можно создать, например, отдельный справочник "Служебные значения". И в нем создавать предопределенные элементы.
Значение будет иметь составной тип.

В модуле менеджера справочника прописать функции получения элементов справочника для гарантии корректности "вытаскивания" данных.

Но логичней/правильней всего, считаю, было бы использование регистра сведений и плана видов характеристик.

НайтиПо... - дурной тон программирования.
Светлый ум; wolfsoft; w-divin; for_sale; +4 1 Ответить 1
16. dmb2006vesna (for_sale) 25.04.14 12:20
(12) insurgut, возможные способы заполнения я описал в статье, так же и те, что вы упомянули - из типовых, при разворачивании. Константы на дают расширяемости, т.е. если я захочу ещё одну переменную, нужно создавать ещё одну константу.

Да, статья действительно об уже работающих конфигурациях, но, как я уже говорил, уже работающие могут превратиться в релиз. Да и к тому же, как мне кажется, любая заплатка должна всё равно иметь "человеческое лицо" :) Т.е. если можно поставить заплатку на сегодня или же попытаться поставить заплатку на всегда (или на обозримое будущее) то лично я выберу второй способ, пусть даже он будет более затратным (в разумных пределах, конечно).
17. Юрий Гуреев (Gureev) 25.04.14 17:00
(15) ProX, нет

дурной тон программирования - это:
  • использование чрезмерно сложных механизмов для простейших задач,
  • непонимание/неумение правильно использовать предлагаемые платформой механизмы в нужном месте в нужное время.

Если вдруг не понятно, то НайтиПо... это не дурной тон, дурной тон - не уметь его правильно использовать.
AnddnA; GATTUSO; Xershi; dr.death; FrLenok; Jyseed; anchovy; philya; denisk37; mylogin; DAnry; artem56; danil157; Yury1001; adhocprog; zawal; Mi4man; EmpireSer; lDenisZl; DJDUH; ShantinTD; biz-intel; awk; Alex_IT; xomaq; cegorach; medm; Natalia_1C; Uncore; orefkov; METAL; amon_ra; dsv_nsk; Pavean; nedopro; help1Ckr; Рамзес; AllexSoft; Chif13; AVillain; be-may; sanek_gk; nasonkin; alexkidd; AlexeyFreeLife; ZOMI; VasMart; Yashazz; +48 2 Ответить 2
18. dmb2006vesna (for_sale) 27.04.14 09:08
(17) Gureev,

дурной тон программирования - это:

использование чрезмерно сложных механизмов для простейших задач,
непонимание/неумение правильно использовать предлагаемые платформой механизмы в нужном месте в нужное время.

Если вдруг не понятно, то НайтиПо... это не дурной тон, дурной тон - не уметь его правильно использовать.


полностью согласен с каждым словом. К этому от себя могу только добавить, что ещё дурным тоном является зашивание в код значений (хардкодинг).
19. Яков Коган (Yashazz) 28.04.14 11:31
Баянчик, за исключением не совсем точно сформулированной фичи 8.3, а так - крик души из серии "наболело".
Напомню, что хардкодинг - он не только в упоминании конкретных экземпляров данных на уровне метаданных, а в стиле программирования, в подходе. Ничто не спасёт от сотни переменных в модуле с именами навроде "Случай№20", поди пойми, что за оно. От 5-7 почти одинаковых процедур в одном модуле, отличающихся парой строк. От реквизитов справочника, например, "ЦенаДляИванИваныча".
А огульно наезжать на хорошие методы языка - лишнее, имхо.
20. dmb2006vesna (for_sale) 28.04.14 11:44
(19) Yashazz, всему своё место и время. Для НайтиПо() тоже своё место и время должно быть. Поэтому про огульно - это вы загнули, я как раз и описал тот случай, когда для этих методов совершенно не место.

А хардкодинг - это именно указание значений в коде, ничего больше. То, что вы описали, "стиль программирования, подход" - это уже более общее понятие - Г-код.
21. Яков Коган (Yashazz) 28.04.14 21:43
(20) dmb2006vesna, если уж на то пошло, это даже не Г-код, а Г-проектирование и архитектура. Как-то так))
22. for_sale for_sale (for_sale) 28.04.14 22:07
(21) Yashazz, согласен - как говорится, разруха - она в головах. Зачастую руководство не только не препятствует генерации Г-кода, а наоборот, поддерживает и всячески препятствует его искоренению. Работал я в такой организации - ессно, уволился из-за конфликта с начальством.
23. Анянов Михаил (insurgut) 29.04.14 19:33
(22) for_sale, у меня примерно схожая ситуация... В довесок к основной деятельности наблюдаю за сайтом своей организации на Битриксе, с которым настроил синхронизацию с номенклатурой. Вроде интернет-магазина. Нашли хороший типовой шаблон. Связал его, настроил, чтобы все работало. Нашли маркетолога, который пытается этот шаблон видоизменить, и мягко говоря не в лучшую сторону (вставка неуместных блоков, не имеющих отношение к интернет-магазину, размещение элементов в совсем иной цветовой гамме, в результате чего они начнут выбиваться из дизайна). Пока сопротивляюсь. Но это совсем другая история. :)
24. Михаил Н (Mig_Alm) 30.04.14 07:34
Вовремя статья написана. Как раз столкнулся с этой проблемой. Сначала установил предопределенные в справочнике и обработкой заменил все значения. Управился за 3 часа (база больше 300 гигов).
Есть еще несколько таких же справочников, но теперь ссылок гораздо больше. Попробую вашу идею. Спасибо!
for_sale; +1 Ответить
25. Сергей Толмачев (sss999) 30.04.14 08:14
ну потом еще поиском и заменой ссылки заменять,а смысл,может просто закрывать права всем на изменение этого элемента не?
26. Дмитрий Воробьев (vde69) 30.04.14 08:19
есть еще один способ, на мой взгляд от куда более предподчительный....

создаем новый общий модуль повторного использования (в сеансе) "ПИ" в нем пишем все наши

Функция ВалютаУчета() Экспорт 
	Возврат Константы.ВалютаРегламентированногоУчета.Получить();
КонецФункции

Функция СтатьяПоступлениеОтКлиентов() Экспорт 
	// !!!!!!!!!! временное решение !!!!!!!!!!!!!!!!!!
	Результат = Справочники.СтатьиБюджетов.НайтиПоКоду("000000000065");
	
	Возврат Результат;
КонецФункции

...Показать Скрыть

я специально здесь взял пример с хардкодинком для примера.

плюсы
1. даже если есть хардкодинг он весь в одном месте и его легко изменить в будующем, то есть относительно легко готовить "временные решения" а уже потом их цементировать... Временные решения нужны например когда до конца нет полной картины развития системы (когда планируется что то глобальное переделывать в ближайшем будущем)
2. получаем очень хорошую скорость
3. в коде запись проще и понятнее, есть контекстная подсказка. Сравните:
  Документ.Валюта = ПИ.ВалютаУчета() 
  Документ.Валюта = ПолучитьЗначениеСлужебнойПеременной(ПредопределенноеЗначение("ПланВидовХарактеристик.СлужебныеПеременные.Валюта_Рубль"));
ABudnikov; Ovrfox; pm74; avto1c; Spacer; slavia-tech; cleaner_it; m-serg74; ShantinTD; Дмитрий74Чел; zqzq; ManyakRus; awk; agrustny; +14 1 Ответить 2
27. Юрий Кириллов (FullMoon) 30.04.14 08:20
Не стоит изобретать велосипед. Для таких случаев лучше всего использовать константы и внешнюю обработку для установки их значений. А что касается "расширяемости" и необходимости заводить новые константы, это гораздо меньшее зло, чем менять Г-код во многих местах при каждом изменении значения. Не зря ведь настройки параметров учета - это константы. Можно конечно использовать и справочник с предопределенными элементами, но ИМХО это те же яйца только в профиль, но константы удобнее (не нужно лезть в конфигуратор для замены значения, но в то же время устойчиво к криворуким юзерам).
28. ффф ыыы (zqzq) 30.04.14 08:47
Первый способ - отлично работает на практике, создаётся предопределённый элемент с таким же кодом, а потом заменой ссылок объединяется со старым элементом и лишний удаляется.

Второй способ - какие-то константы на курьих ножках. Не вижу практически никаких преимуществ перед рекомендованным типовым механизмом.

Также в (26) хороший метод, сокрытие деталей реализации получения нужного значения. Если в функцию добавить аргумент дата можно и периодическое значение получать (неважно из регистра или в самой функции зашито), аналогично можно вводить аргументы-"измерения". Главное если есть функция получать значения только с помощью функции (к сожалению в 1С нельзя так гибко программную видимость настраивать как в ООП, где к закрытому полю физически не обратиться вне класса). В типовых обычно получение константы обёртывают в подобную функцию.
agrustny; +1 Ответить
29. Антон Рощин (wolfsoft) 30.04.14 08:53
(10) quebracho, ага, а если базы две одинаковых по CF, но разные по данным, то ваш код будет редкой жутью. Считаю данный приём достойным ещё одного персонального котла в аду.
for_sale; +1 Ответить
30. sanek sanek_gk (sanek_gk) 30.04.14 09:02
Статья ни о чем. Создание механизма для подстановки значений в параметры ? Да там с десяток таких механизмов написать можно разной степени извращенности. Суть в другом ты хоть стопитцот раз создавай свои планы характеристик но суть останется одной и той же - нет у тебя заполненного значения и идёшь ты лесом со своим алгоритмом. Плохой тон программирования заключается не в использовании функции найтипокоду найтипонаименованию а в дебильной уверенности что она тебе обязательно что то найдёт. Есть такое правило программирования - "обнуляй переменные" и пусть на заметку другие возьмут ещё одно правило "проверять заполненность переменных" при их использовании.
SinglCOOLer; agrustny; help1Ckr; +3 Ответить 1
31. Юрий Пермитин (YPermitin) 30.04.14 10:52
Давно для таких целей использую специальный справочник с предопределенными элементами. В этих элемента храню значения, которые и нужно жестко получать.

Вот подробнее: Предопределенные элементы. Добавление в типовую конфигурацию.
32. Павел Опарин (opx) 30.04.14 10:52
Мне почему-то кажется, что самый красивый вариант отказаться от использования НайтиПо... это получить строку ссылки через ЗначениеВСтрокуВнутр() и использовать эту строку в коде через ЗначениеИзСтрокиВнутр().
Конечно есть и минусы такого подхода - работает сей код только в одной ИБ, поэтому сделать внешнюю обработку для разных ИБ не получится.
Кстати к подходу, описанном в данной статье этот минус тоже относится.
Поэтому вывод: Если мы пишем для разных ИБ - однозначно используем НайтиПо..., а если для одной ИБ - каждый по своему извращается. Лично я выбираю ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр()
33. for_sale for_sale (for_sale) 30.04.14 11:07
(31) YPermitin, да, как я уже выше писал, такое решение аналогично тому, что я в статье привёл. Только у вас огромный минус - нужно строкой передавать имя предопределённого. Намного проще использовать типовую ОбщегоНазначения.ЗначениеРеквизита(ПредопределенноеЗначение(Справочники.Предопр.Товар), "Значение").

Ну или аналогичную функцию написать, Чтобы обрабатывать пустые значения и возврат значения по умолчанию.
34. for_sale for_sale (for_sale) 30.04.14 11:19
(27) FullMoon, не понял, как переход на константы избавляет от необходимости менять Г-код? Тут либо вы оставляете всё как есть и все НайтиПо() или же переходите на какой-то механизм (пусть на константы) и тогда идёте в код и везде всё заменяете.

Но у констант перед справочником или ПВХ есть огромный минус - они висят в одном общем котле. Т.е. ваша "ПредопределённыйТоварБулочкаСМаком" будет висеть в одном ряду с ВалютаРегламентированногоУчета и прочими типовыми и будет совершенно непонятно, зачем она нужна и что она делает. У меня количество предопределённых элементов в ПВХ доходило до полутора сотен - представьте, что вы в УПП добавили ещё полторы сотни констант, потом с выходом новых релизов УПП, с работой ещё каких-нибудь разработчиков, с обновлениями криворуких ИТС-ников, туда добавится ещё несколько десятков констант и перемешается порядок - что там можно будет найти?

И ещё один огромный минус - не забывайте, вам надо будет каждую из ваших констант вывести в какую-то форму, чтобы задать её (если вы хотите задавать их через пользовательский режим). С программной задачей значений этот минус нивелируется, но тогда вы не можете одним движением руки посмотреть, правильно ли у вас задано значение конкретной константы или вы в обработке заполнения одной буквой ошиблись и у вас константа пустая. Вообще вглухую задавать значения даже служебных переменных без возможности посмотреть их через форму - это ещё один пример "заботы" о прозрачности механизма.

Нет, про константы не согласен. Согласен, что можно вместо ПВХ и регистра использовать справочник, но константы из-за описанных выше минусов явно проигрывают.
35. for_sale for_sale (for_sale) 30.04.14 11:22
(32) opx, не понял, как должен работать такой механизм? приведите пример кода, пожалуйста. Не понял, потому что чтобы закинуть ссылку в строку, её нужно вначале где-то взять.
36. Саша Безымяный (help1Ckr) 30.04.14 11:34
Данное решение довольно спорно. Во-первых, если Вы добавляете свои объекты, значит в конфигурации включены возможность изменений. Тогда возникает вопрос, почему бы не сделать уже по человечески через предопределенный элемент? Если Вы пишете свою конфигурацию, то тут вообще без комментариев. А методы Найти по наименованию или по коду приходится использовать когда конфигурация стоит полностью на поддержке без возможности изменений. Вот тут для обработок приходится извращаться через наименования или коды, так как указанный метод явно не подходит.
37. for_sale for_sale (for_sale) 30.04.14 11:37
(36) help1Ckr, по человечески не получится, потому что база уже работает, нельзя создать предопределённый элемент и ходить заменять ссылки во всех существующих объектах, об этом в статье написано.
38. Юрий Пермитин (YPermitin) 30.04.14 11:39
(33) for_sale, не вижу огромного минуса, ибо делалось эти с тем умыслом, чтобы потом сделать получение значений этих предопределенных элементов через кэширование повторно используемых значений. Да и изменения в функцию получения значения внести легче, если нужно глобально поменять поведение функции получения значений из предопределенных.

Вообщем, спор бессмыслен) Прочитал комментарии Выше и понял, что каждый при своем мнении)))
39. Саша Безымяный (help1Ckr) 30.04.14 11:44
(37) for_sale, в чем проблема замены ссылок?
40. for_sale for_sale (for_sale) 30.04.14 11:50
(38) YPermitin, функция ПРедопределенноеЗначение() и так кэширует значение до следующего изменения конфигурации, вне зависимости от того, где вы её вызываете, так что не вижу, в чём преимущество передавать имя переменной вместо ссылки на неё.

А минус в том, что, если она у вас называется как-нибудь "ПредопределённыйЭлементБулочкаСМакомКраснаяСвежаяВкусная", то ошибиться можно очень легко в какой-нибудь букве, а так ктрл+пробел сделает всю работу за вас. Можно, конечно, писать полную форму, а потом стирать - но зачем лишние действия, если плюсов в этой форме записи никаких?

При своём остаётся тот, кто боится признаваться в своих ошибках. Я, например, не боюсь, поэтому и признаю, что способ со справочником, который я не упомянул, не хуже моего способа с ПВХ и РС.
41. for_sale for_sale (for_sale) 30.04.14 11:54
(39) help1Ckr, всего лишь в том, что нужно заменить стотыщмильйонов ссылок в круглосуточно работающей базе с сотней пользователей. Но в небольшой базе это проблема номер два, а проблема номер один - механизм замены нужно ещё написать. Не забыв абсолютно все места, где используются ваши ссылки. И зачем? Из-за боязни добавить лишний ПВХ и РС или справочник?
42. Павел Опарин (opx) 30.04.14 12:04
(35)Пишите внешнюю обработку, вставляете реквизит "Реквизит1" с типом "Справочник.Ссылка", "Документ.Ссылка", ну и т.д.
На кнопку вешаете код:

Сообщить(ЗначениеВСтрокуВнутр(Реквизит1));

Выбираете значение в реквизит1, жмете кнопку - вуаля.
Затем в коде пишите:

НужноеНамЗначение = ЗначениеИзСтрокиВнутр("{""#"",a60de1b9-e80b-4519-947b-e45c0562461a,238:9ca4001635aff8e111e29d0602fcbd78}");

Где ("{""#"",a60de1b9-e80b-4519-947b-e45c0562461a,238:9ca4001635aff8e111e29d0602fcbd78}") - это то, что нам выдало сообщение.
И пофиг все. Другой номер, наименование или еще что-то: ссылка не меняется.
43. Саша Безымяный (help1Ckr) 30.04.14 12:09
(41) for_sale, вопрос не в боязни. Вопрос в бессмысленности. Во первых, его должен кто то заполнять и следить за ним. Во вторых, усложняется написание запросов и в самом коде нужно проводить проверку на заполненность данного значения. А замена ссылок - чем типовая то не устраивает с ИТС? (сам не пробовал еще но планирую потестить) )
44. for_sale for_sale (for_sale) 30.04.14 12:14
(42) opx, так это же тот же самый способ с УИДом, который выше в комментариях описывался, только в профиль.
Но это тот же хардкодинг.
45. for_sale for_sale (for_sale) 30.04.14 12:20
(43) help1Ckr, типовой я пользовался очень давно, но, если мне память не изменяет, там есть какие-то ограничения. Плюс в большой-прибольшой базе цена ошибки тоже очень велика. Если где-то какую-то ссылку заменить не получится, то всё пойдёт на смарку. В общем, я бы не стал так просто играться с пользовательскими данными, особенно в большой базе - пусть уж лучше НайтиПо() остаётся, работает - и ладно.
46. Юрий Кириллов (FullMoon) 30.04.14 14:17
(34) for_sale, отпадает необходимость менять код при смене значения.
Пусть висят в одном общем котле. Как я уже писал, пишется внешняя обработка, где все константы можно посмотреть и поменять. Форма этой обработки может быть любая, константы можно разбить по группам, разукрасить и т.п. Что касается их положения в конфигураторе, просто добавляются префиксы к их именам, пишутся комментарии.
Всё гениальное просто, если знать как это правильно применять, а если не знать, можно до бесконечности изобретать велосипеды.
47. анд гру (agrustny) 30.04.14 14:35
Горячее обсуждение, обжечься можно, тоже буду думать.
Было бы здорово так:
...заходит враг, и электрический кулак ему по роже!

в-общем, чтоб ручками на основе типовой чего-то наворотил, 1С куда-нибудь себе это записала, а потом если что - можно и редактировать только изменения в текстовом редакторе: как макросы в Excel записываешь в интерактивном режиме, а оно выдает Visual Basic. Наверное, плохо формулирую, но идея понятна?
48. Алексей Роза (DoctorRoza) 30.04.14 14:37
Уважаемый! Будьте по-проще! Высокомерием и шибкоумием аж за версту несет! Да, использование данных конструкций не камильфо, но и без них подчас не обойтись, а уж в толстом клиенте приходится закрывать глаза. :(
EMelihoff; Дмитрий74Чел; +2 Ответить 2
49. for_sale for_sale (for_sale) 30.04.14 14:41
(46) FullMoon, а потом приходит следующий программист и чешет репу - что это за сотня констант? Обработка внешняя для просмотра, ессно, затерялась, поэтому писать нужно ещё одну. На написание обработки тоже надо время, потому что там есть "праведные" и "неправедные" константы, зачем нам в этой обработке показывать ВалютуРеглУчёта?

И самое главное - для чего создавать всю эту неразбериху? Опять из-за боязни добавить лишний ПВХ, РС или справочник? Чем ваш велосипед лучше моего? Он быстрее собирается? Нет. Он удобнее в использовании? Ни в коем случае. Он лучше справляется с задачей? Ни разу. Он производительнее? Опять нет.

отпадает необходимость менять код при смене значения


Какой код и зачем менять при смене значения?
У меня в коде есть переменная ПВХ.СлужебныеПеременные.РозничнаяЦена, которую я в пользовательском режиме задал как элемент справочника ТипыЦен "Розничная СПБ". Если я потом захочу установить в эту переменную "Розничная Москва", то я иду в регистр и задаю это значение - и всё. Что мне в коде нужно менять? Цель этой статьи и была - показать, как можно обойтись без смены кода при смене значений.

Если уж критикуете велосипед, то предложите хотя бы хороший велосипед взамен, а не коленную поделку. Если выбирать велосипед из ПВХ и из констант, то я уж лучше сделают ПВХ, где у меня в одном месте будут все мои потребности и который я, если вдруг нужно будет, одним движением руки грохну и забуду, чем буду генерировать тонны мусора, намертво сцепленного с жизненно важнными механизмами типовых.
50. for_sale for_sale (for_sale) 30.04.14 14:45
(48) DoctorRoza, уважаемый, уточняйте, к кому вы обращаетесь, тут все уважаемые.
51. анд гру (agrustny) 30.04.14 14:46
(48) Мне кажется, столько пару не столько от "констант", сколько от обновления "модифицированных"
52. Dark.iNiTro Zzz (Dark.iNiTro) 30.04.14 15:34
я использую регистр сведений - в нем храниться только одна запись, в ресурсах по имени храниться значение, так же в ресурсах может быть хранилище значений для таблицы значений.

P.S. недавно при обновлении УПП с 1.3.44 на 1.3.51 случайно узнали что длина кода "Классификатора единиц измерения" увеличилась с 3 до 4, и поэтому код "=" перестал работать (такого кода осталось мало, но у нас он еще кое где встречается потому что очень большие наработки)
53. Юрий Кириллов (FullMoon) 30.04.14 16:01
(49) for_sale, все описанные вами проблемы решаются добавлением внешней обработки в дополнительные обработки (я не представляю как её оттуда можно потерять) и написанием инструкций для следующего программиста. Вместо того чтобы спрашивать чем мой велосипед лучше, обоснуйте чем он хуже.
54. for_sale for_sale (for_sale) 30.04.14 17:33
(53) FullMoon, чем ваш велосипед хуже я уже описал два раза в комментариях выше. А "написать инструкцию следующему, прибить гвоздями обработку, чтобы не потерялась" и прочие образцы народного рукоделия - это больше смахивает на блок в голове - "решить задачу любыми средствами, только бы не через ПВХ и РС". Плановидохарактеристикофобия какая-то.

И мне ещё говорят, что у меня слишком сложный механизм :) Создай ПВХ и РС, заполни и используй в коде - вот как сложно! Чтобы не идти таким сложным путём, лучше просто загадить константы, написать обработку, которая будет показывать константы (только нужные) и сохранять их значения, написать инструкцию по использованию всего этого хозяйства, положить её куда-то, чтобы она не потерялась (как это бывает всегда), и не забыть носить оберег от сглаза, чтобы проклятия программистов, открывших ветку "Константы", не сбылись. При этом всё равно снимать конфигурацию с замка, всё равно через конфигуратор добавлять новые элементы, всё равно переписывать код под этот "механизм". В чём плюс - не понятно, зато мы избежали использования ПВХ и регистра сведений - Родина нас не забудет.
Damian; Bukaska; +2 Ответить 1
55. анд гру (agrustny) 01.05.14 02:50
(54) ПВХ - это какая-то фигня, являющаяся, по сути дела, генератором типа. Наверное, ее загаживать лучше, хотя при бесчисленном количестве объектов в конфигурации это все равно, лишь бы "префиксы" были. На самом деле написать код в 100-1000 строчек куда проще, чем в таком же объеме разбираться, как бы хорошо он не был написан, и какими бы прекрасными комментариями не был снабжен. Все это часть системного кризиса...
Как говорится, не ссорьтесь, девочки, все равно это лишь разные виды заплаток, хорошо работать может только компилируемое. Тут уместна была бы цитата из Толстого.
56. Сергей (dsv_nsk) 01.05.14 10:01
У меня создалось впечатление, что автор ни разу не пользовался старой доброй обработкой "Поиск и замена значений"...
57. for_sale for_sale (for_sale) 01.05.14 12:23
(56) dsv_nsk, впечатление почти верное - автор пользовался ею два раза года четыре назад. Надеюсь, за это сейчас не расстреливают?
58. Rom Shpakoff (Lancelot-2M) 01.05.14 14:48
Почему-то автор не упомянул, что при обновлении созданные "на местах" предопределенные элементы становятся непредопределенными.
Кроме того, у меня есть некоторый стаж работы программистом 1С и ни разу описанных траблов с конструкциями НайтиПо... у меня в практике не было - даже с 7.7, где эти поля не защищены от прямого редактирования, про 8.х я уже и не говорю.

Предлагаемый автором способ с ПВХ - уныл и непроизводителен, при поддержке чужого кода проще и быстрее понять конструкцию с "НайтиПо.." нежели предложенные изощрения.
59. oleg (opus70) 01.05.14 19:49
лучше справочника настройки ничего не придумана зачем городить с характеристиками не понятно
что в том что в этом случае снимать с поддержки
60. for_sale for_sale (for_sale) 01.05.14 21:34
(58) Lancelot-2M, какие предопределённые становятся непредопределёнными при обновлении?

Про производительность, пожалуйста, примеры и замеры какие-то, а то как на лавочке во дворе.

Про то, что НайтиПо() проще - полностью согласен. Но проще - это только один из параметров хорошего кода.
61. Rom Shpakoff (Lancelot-2M) 02.05.14 10:54
Вот текст простой обработки:
Функция ПолучитьКАИзРегистра()
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	нДопРеквизитыКонтрагентовМакет.Период,
		|	нДопРеквизитыКонтрагентовМакет.Контрагент,
		|	нДопРеквизитыКонтрагентовМакет.ПечатнаяФорма,
		|	нДопРеквизитыКонтрагентовМакет.ИмяМакета,
		|	нДопРеквизитыКонтрагентовМакет.ЭтоСеть,
		|	нДопРеквизитыКонтрагентовМакет.НДССверху,
		|	нДопРеквизитыКонтрагентовМакет.ПечататьНомерЗаказаВОсновании,
		|	нДопРеквизитыКонтрагентовМакет.ПечататьНомерЗаказаВДопПараметр2,
		|	нДопРеквизитыКонтрагентовМакет.ГрузополучательБанкРеквизиты,
		|	нДопРеквизитыКонтрагентовМакет.ПлательщикБанкРеквизиты,
		|	нДопРеквизитыКонтрагентовМакет.ГрузоотправительПечататьБанкРеквизитыФактора,
		|	нДопРеквизитыКонтрагентовМакет.ГрузополучательАдресКонтрагента,
		|	нДопРеквизитыКонтрагентовМакет.ПечататьИННГоловнойОрганизации,
		|	нДопРеквизитыКонтрагентовМакет.ПечататьИННГрузополучателя,
		|	нДопРеквизитыКонтрагентовМакет.ПрефиксПередПочтовымАдресом,
		|	нДопРеквизитыКонтрагентовМакет.Комментарий,
		|	нДопРеквизитыКонтрагентовМакет.ПрофильПечати,
		|	нДопРеквизитыКонтрагентовМакет.РезервныйРеквизит1Булево,
		|	нДопРеквизитыКонтрагентовМакет.РезервныйРеквизит1Строка
		|ИЗ
		|	РегистрСведений.нДопРеквизитыКонтрагентовМакет КАК нДопРеквизитыКонтрагентовМакет
		|ГДЕ
		|	нДопРеквизитыКонтрагентовМакет.Контрагент = &Контрагент";

		Запрос.УстановитьПараметр("Контрагент",КА);
	Результат = Запрос.Выполнить();

	ВыборкаДетальныеЗаписи = Результат.Выбрать();

	Если  ВыборкаДетальныеЗаписи.Следующий() Тогда
		Возврат ВыборкаДетальныеЗаписи.Контрагент;
	КонецЕсли;
	
КонецФункции

Функция ПолучитьКАИзСправочника()
	
	Возврат Справочники.Контрагенты.НайтиПоКоду("74070");
	
КонецФункции

Процедура КнопкаВыполнитьНажатие(Кнопка)

  КА1 = ПолучитьКАИзРегистра();
  КА2 = ПолучитьКАИзСправочника();

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

...Показать Скрыть


Замер производительности данного кода на картинке.


В справочнике Контрагенты 7300 групп и элементов, а в регистре сведений нДопРеквизитыКонтрагентовМакет 54 записи
62. for_sale for_sale (for_sale) 02.05.14 12:43
(61) Lancelot-2M, какой интересный у вас код получился :)
С НайтиПо всё понятно, а вот запрос у вас ... в общем, если бы вы не признались, что вы - приверженец хардкода, об этом можно было бы догадаться по запросу.

Во-первых, вы выбираете кучу полей, когда вам нужно только одно, Контрагент. Вы думаете, что это не влияет на скорость?
Во-вторых, вы передаёте в запрос контрагента как параметр, а потом его же и возвращаете в запросе - в одном из месте, где я когда-то работал, такой же код висел в распечатке на стене с кучей весёлых комментариев :)

В общем, я не поленился (в отличие от вас) и сделал более рабочий приближённый к нашим условиям пример. Если мы пользуемся ПВХ или справочником и регистром сведений, то мы должны в запрос передавать не ссылку на самого себя, а ссылку на предопределённый элемент и получать всего-лишь один реквизит - ссылку на непредопределённый элемент.

Вначале я искал элемент по справочнику, в котором чуть больше 6 тысяч элементов (НайтиПоКоду()), а из регистра с почти 90 тысячами записей получал один из реквизитов по переданной ссылке на справочник. В результате время получения из регистра было всего лишь в 8 раз больше, хотя записей в регистре почти в 15 раз больше.



Потом я вспомнил, что у меня есть регистр, точно соответствующий по количеству записей справочнику и попробовал тоже самое на нём. Результат - производительность на запросе почти в четыре раза выше, чем на НайтиПо()



Отчёт по количеству записей



П.С. ах, да, код:

&НаКлиенте
Процедура Сделать(Команда)
	
	Об1 = ЧерезНайтиПоНаСервере();
	Об2 = ЧерезРегистрНаСервере(Об1);
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция ЧерезНайтиПоНаСервере()
	
	Возврат Справочники.Сайт_Объявления.НайтиПоКоду("000000765");
	
КонецФункции

&НаСервереБезКонтекста
Функция ПолучитьЧерезРегистрСервер(Об1)
	
	Возврат ЧерезРегистрНаСервере(Об1);
	
КонецФункции

&НаСервереБезКонтекста
Функция ЧерезРегистрНаСервере(itemid)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Сайт_СвязьОбъявленийИКатегорий.catid
		|ИЗ
		|	РегистрСведений.Сайт_СвязьОбъявленийИКатегорий КАК Сайт_СвязьОбъявленийИКатегорий
		|ГДЕ
		|	Сайт_СвязьОбъявленийИКатегорий.itemid = &itemid";

	Запрос.УстановитьПараметр("itemid", itemid);

	РезультатЗапроса = Запрос.Выполнить().Выбрать();
	Если РезультатЗапроса.Следующий() Тогда
		Возврат РезультатЗапроса.catid;
	КонецЕсли;

КонецФункции
...Показать Скрыть
63. for_sale for_sale (for_sale) 02.05.14 12:50
(58) Lancelot-2M,
при поддержке чужого кода проще и быстрее понять конструкцию с "НайтиПо.." нежели предложенные изощрения


Да, понять

Справочники.КакойНибудьСправочник.НайтиПоКоду("23400023423");


конечно же проще, чем

ПолучитьЗначениеПредопределённого(ПланыВидовХарактеристик.Предопределённые.РозничнаяЦена);
64. Rom Shpakoff (Lancelot-2M) 02.05.14 14:13
(62) for_sale,

С НайтиПо всё понятно, а вот запрос у вас ... в общем, если бы вы не признались, что вы - приверженец хардкода, об этом можно было бы догадаться по запросу.

Во-первых, вы выбираете кучу полей, когда вам нужно только одно, Контрагент. Вы думаете, что это не влияет на скорость?
- это реально необходимая выборка из регистра с настройками печатных форм, этот регистр заменил собою ряд конструкций "НайтиПо" и "Если СокрЛП(Контрагент.Код) = ..." при переходе с ПУБ на УПП. Как человек ныне поддерживающий наши многострадальные печатные формы, могу со всей ответственностью заявить, что регистр настроек оказался очень неудобен при доработке печатных форм под новые требования контрагентов. При написании кода содержимое регистра неочевидно и это просто неудобно все время смотреть то в регистр то в код. Я уже не говорю, что при таком подходе добавление новых настроек требует обновления, а не только редактирования обработки внешней печатной формы.

Во-вторых, вы передаёте в запрос контрагента как параметр, а потом его же и возвращаете в запросе - в одном из месте, где я когда-то работал, такой же код висел в распечатке на стене с кучей весёлых комментариев :)
- я ж для примера, не цепляйтесь к таким мелочам)

Сделал выборку одного поля из регистра - данные те же:


Возможно в вашем случае, на управляемых формах в тонком клиенте, результат иной...
65. Rom Shpakoff (Lancelot-2M) 02.05.14 14:29
(63) for_sale,


Да, понять

Справочники.КакойНибудьСправочник.НайтиПоКоду("23400023423");

конечно же проще, чем

ПолучитьЗначениеПредопределённого(ПланыВидовХарактеристик.Предопределённые.РозничнаяЦена);



а понять
Справочники.КакойНибудьСправочник.НайтиПоКоду("23400023423");//РозничнаяЦена из какого-нибудь справочника

думаю еще проще - и никакой документации для последователей - все в коде и очевидно.
66. for_sale for_sale (for_sale) 02.05.14 18:02
(64) Lancelot-2M, да понятно, что код у вас вырван из контекста и в своём месте он вполне логичен и работоспособен, только в данном случае он никак не может быть примером. А тонкий или толстый клиент - в данном случае не имеет значения, потому что и первый, и второй способ выполняются на сервере.
67. Rom Shpakoff (Lancelot-2M) 02.05.14 18:06
(66) for_sale, тем не менее смотрите мои замеры в посте 62
68. for_sale for_sale (for_sale) 02.05.14 18:12
(65) Lancelot-2M, да, конечно, если бы в коде было много комментариев, да ещё и по делу, да ещё и понятных - доработка была бы намного проще. Только почему-то в реальной жизни всё немного сложнее.

Другой пример - казалось бы, кому понадобится изменять код в элементе справочника? Никаких логических причин, вроде бы как, не должно быть, тем не менее сплошь и рядом!

В общем, я свою позицию высказал - хардкод был и останется вариантом Г-кода (это, кстати, не только моя позиция, во всех языках программирования, имеющих бОльшую историю, чем 1с, всякие книжки по оптимальному коду и т.п. эта позиция чётко прослеживается). С его помощью можно на ходу какую-то заплатку слепить, с которой последователи будут только мучаться, но не сделать нормальное решение.
for-elenak; +1 Ответить 1
69. Rom Shpakoff (Lancelot-2M) 02.05.14 18:45
(68) for_sale, лично мой опыт говорит об обратном - часто погоня за мнимым универсализмом и "оптимальным" решением лишь затрудняют развитие и поддержку прикладных решений - такова специфика нашей сферы, мы не статичные программульки с парой функций пишем - конфигурации развиваются и меняются всё время и адаптируются именно к частным случаям конкретных организаций
portal_orsk; +1 Ответить 1
70. Денис Vvv (EvilDoc) 02.05.14 19:19
говорили уже или нет но для ухода от НайтиПо... можно использовать типовой РС ЗначенияСвойствОбъектов. Ни чего переписывать не надо. Заполнил 1 раз в базе и будет вам счастье
71. т т (MadMix) 02.05.14 21:49
(70) EvilDoc, РС ЗначенияСвойствОбъектов не решает проблему - просто искать по коду/наименованию придется не в справочнике, а в ПВХ СвойстваОбъектов.
72. Денис Vvv (EvilDoc) 02.05.14 22:01
(71) записыми в РС можно заменить свойство "предопределенный" Скажем свойство для справочника валюты "Пердопределенный" в значение истины. Или свойство "Признак" в значение "рубль". На любой базе (с разными уидами) один раз определить свойства и значений и спать спокойно. Получать конкретные элементы справочников по типу и значению.
73. Денис Vvv (EvilDoc) 02.05.14 22:03
(71) хтя да... ты прав. Свойство придется искать(( при чем и в пвх и в справочнике. Тут подумать надо
74. т т (MadMix) 02.05.14 22:40
(73) EvilDoc, все уже придумано до нас и описано в комментариях выше - использовать отдельный механизм ПВХ + РС/справочник. Либо использовать предопределенные элементы. Либо использовать константы.
Можно использовать и связку СвойстваОбъектов/ЗначенияСвойствОбъектов, но создавать предопределенный элемент в ПВХ все равно придется.
75. for_sale for_sale (for_sale) 03.05.14 06:16
(69) Lancelot-2M,
часто погоня за мнимым универсализмом и "оптимальным" решением лишь затрудняют развитие и поддержку прикладных решений

с этим тоже согласен, но не считаю, что это тот случай. Говорил уже об этом в комментариях неоднократно, с примерами - несколько несложных действий помогут избежать кучи проблем. Да, потратить нужно будет на 10-15-20 минут больше, чем с НайтиПо, но время, затраченное на оптимизацию я не считаю потерянным в пустую.
76. Александр Пузаков (puzakov) 03.05.14 09:39
А еще есть вот такие предопределенные функции, позволяющие решить аналогичную задачу:
XMLСтрока(<Значение>) 
XMLЗначение(<Тип>, <СтрокаXML>)
77. Никита Грызлов (nixel) 05.05.14 10:50
(76) puzakov, это тот же вариант с УИДом только в профиль.
78. Олег Мэйер (meier8th) 05.05.14 14:08
79. Иван (SinglCOOLer) 07.05.14 06:53
(30) sanek_gk, полностью согласен, если уж и используется найти по коду или наименованию то всегда нужно быть готовым что то что мы ищем не найдется и соответственно обрабатывать данный вариант
80. анд гру (agrustny) 07.05.14 09:56
(79) Хорошо, т.е. в 100500 местах программы, где было написано
Ыкс=Ыкс+Справка.НайтиПоНаименованию("НебольшойТакойПоросенок",Истина)

нужно написать
Ыгрек=Справка.НайтиПоНаименованию("НебольшойТакойПоросенок",Истина);
Если Ыгрек<>Неопределено Тогда
    Ыкс=Ыкс+Ыгрек;
Иначе
    Сообщить("Здравствуй, Мир!");
КонецЕсли
...Показать Скрыть
81. Елена К (for-elenak) 08.05.14 07:00
Дорогие граждане-товарищи! Пожалуйста, используйте НайтиПоКоду и НайтиПоНаименованию только для ваших коротковременных нужд! Не оставляйте эту лажу кому-то в наследство! Намучилась с этим вволю! Наши пользователи не знают, что какой-то код или наименование элемента справочника вы зашили в код вашей обработки или отчета. И ВСЕГДА найдется изобретатель, который изменит его "под себя". В своей практике использую различные решения. Соответственно задаче. Это и Константы, и предопределенные элементы справочников, и регистры сведений, и даже специальные справочники, в которых храню такие значения...Все зависит от многих факторов. Версия автора имеет право на жизнь. Этот вариант мною тоже уже давно и довольно успешно используется
Bukaska; agrustny; for_sale; +3 Ответить 1
82. анд гру (agrustny) 08.05.14 09:17
(81) for-elenak, Вы умничка=)
Более общё: уважаемые представители ЛГТБ, пишите G-код за пределами РФ, пожалуйста)))
for_sale; for-elenak; +2 Ответить
83. Константин Червяков (GreyJoJo) 16.05.14 20:01
(3) WizaXxX,
Потом требуется развернуть новую БД с данной конфигурацией, берем cf, разворачиваем... и наслаждаемся массовым падением всех этих конструкций.
for-elenak; for_sale; +2 Ответить 1
84. Тимофей Шантин (ShantinTD) 21.05.14 13:43
(83) GreyJoJo, тут, пожалуй, любой способ, кроме предопределенных элементов, приведет к "осыпанию" подобных конструкций.
Можно, конечно, при запуске (или еще когда?) проверять наличие подходящих элементов, и создавать их принудительно. У самого возникла завязка на конкретный элемент справочника (сам справочник небольшой, но ссылок на него о-о-о-очень много). Извращался так: найти по наименованию, если пустая ссылка - создать с таким наименованием. Бинго! Ждем переименования элемента.
После прочтения статьи создал предопределенный элемент, переназначил его существующему, и радуюсь тому, насколько можно упростить код, сделать его аккуратнее и красивее.

Кстати: что-то не помню в этом обсуждении еще одного немаловажного камня в огород метода НайтиПоНаименованию и ему подобных: при существовании нескольких подходящих метод возвращает ссылку только на один "первый". Если с кодом еще можно бороться (проверять уникальность и запретить неуникальность), то запретить неуникальность наименований - практически нереально (можно, но в здравом уме этого делать не станешь).


(0), есть предложение дополнить приведенную процедуру одной строкой, сделать так:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
    
    // лишаем предопределённый рубль его предопределённости
    Валюта = Справочники.Валюты.НайтиПоКоду([Код_Предопределённого_Рубля]).ПолучитьОбъект();
    Валюта.ИмяПредопределенныхДанных = “”;
    Валюта.ПометкаУдаления = Истина;
    Валюта.Записать();
    
    // освободившуюся предопределённость отдаём старому рублю
    Валюта = Справочники.Валюты.НайтиПоКоду([Код_НЕ_Предопределённого_Рубля]).ПолучитьОбъект();
    Валюта.ИмяПредопределенныхДанных = “Рубль”;
    Валюта.Записать();
    
КонецПроцедуры
...Показать Скрыть
for-elenak; for_sale; +2 Ответить
85. for_sale for_sale (for_sale) 21.05.14 14:35
Всем, кто радел за способ ПолучитьСсылку() и рассказывал сказки про комментирование - посвящается!
Щас вот буквально столкнулся с конфигурацией, где повсеместно используется этот способ. Конечно же, нигде ни одного комментария нет, везде в коде

ПланыВидовХарактеристик.ПВХ.ПолучитьСсылку(Новый УникальныйИДентификатор("Хер-его-маму-знает-что-за-элемент")).

Просто офигенный способ - сиди разбирайся с красными глазами, где что, плюс ещё тестировать в отдельно стоящей базе нельзя, нужно всё наживую делать. Отличный способ! В результате за пять минут создал ПВХ и РС и теперь где в коде встречаю эту ахинею - заменяю на предопределённые элементы, а при отладке заполняю в пользовательском режиме. Делов-то на полминуты вместо разборок каждый раз, что за элементы передо мной, да ещё и нервы целы.

Повторяю, Г-код вообще и хардкодинг в частности - это всегда дёшево и сиюминутно.
86. Тимофей Шантин (ShantinTD) 21.05.14 15:23
(85) for_sale, чуть в сторону: про Г-код, а не про предопределенные элементы. История такая: видел конфу на 7.7, разработанную для сети из 10(!) магазинов. В документе были колонки Магазин1, Магазин2,..., Магазин10. А потом количество магазинов поменялось... Продолжать не стану.
87. for_sale for_sale (for_sale) 21.05.14 15:39
(86) ShantinTD, да, это реалии. А потом такой человек сидит на форуме и пишет о том, что нужно грамотно применять НайтиПо() и что если использовать ПолучитьСсылку(), то получится быстрее.
ShantinTD; +1 Ответить
88. анд гру (agrustny) 21.05.14 16:35
89. vicmos victor (vicmos) 30.05.14 11:27
Интересная статейка, но к сожалению ни о чем, откройте регламентированную отчетность и посмотрите, как она формируется, в упр. учете это сплошь и рядом, "здесь играем, а здесь рыбу заворачиваем", а так плюс только за потраченное время
90. for_sale for_sale (for_sale) 30.05.14 11:38
(89) vicmos, откройте любую самописную конфу и посмотрите как там всё написано и давайте теперь тоже так делать. Зачем равняться на то, что написано не самым лучшим способом? А в типовых, особенно в старых, на обычных формах, тысячи мест, где код написан спустя рукава - так что ж теперь, только из-за этого и себе такой же код писать?
91. Елена Пименова (Bukaska) 30.05.14 12:58
92. vicmos victor (vicmos) 30.05.14 16:46
(90) for_sale, Извините, с самописками не работаю, с типовыми хлопот хватает, не считая Хомнет, Инталев и прочими, просто статья ни о чем, разговор идет не о реализации решения задачи, а о предметной области, правила хорошего тона написания кода учат в ВУЗЕ.
93. for_sale for_sale (for_sale) 30.05.14 17:04
(92) vicmos,
разговор идет не о реализации решения задачи

т.е. три варианта решения задачи, описанных в статье, вы не заметили? А ещё говорят, что выделение жирным, капслок, мигающие буквы, крупный шрифт - это плохой тон, а, оказывается, несколько абзацев неподсвеченного текста можно взять и не заметить.
правила хорошего тона написания кода учат в ВУЗЕ

не подскажете, в каком именно ВУЗе учат хорошему тону написания кода на 1С?
ShantinTD; Bukaska; +2 Ответить 2
94. Armando Armando (Armando) 30.05.14 21:56
Комменты не читал - много.
Уже сказали, что Справочник.Валюты.Рубль и Справочник.Валюты.ПолучитьСсылку() на SQL отрабатывают абсолютно одинаково?
Я не призываю использовать ПолучитьСсылку(), просто информирую.
Хотя сам кое где использовал))
95. for_sale for_sale (for_sale) 30.05.14 22:05
(94) Armando, да, но у ПолучитьСсылку есть большие недостатки, которые я даже из комментов в статью вынес.
96. Анатолий К (Radkt) 31.05.14 23:54
Интересная статейка, но по моему выхода из ситуации кроме как создания нового рег сведений нет. Все остальное либо не универсально, либо замедляет работу и опять же требует снимать объект с поддержки(3 способ).
97. Елена Пименова (Bukaska) 02.06.14 10:07
(93) for_sale, ИМХО.. но по 1С Высшей школы нет.. а только опыт, опыт и ещё раз опыт)))
98. for_sale for_sale (for_sale) 02.06.14 10:25
(97) Bukaska, полностью согласен, только не каждому умнику это объяснишь.
Иногда смотришь на комментарии к какой-нибудь статье и представляешь себе большую городскую площадь, куда все выходят не для определённой цели, а просто пройтись, на людей посмотреть и, конечно же, себя показать. :)
99. Елена Пименова (Bukaska) 02.06.14 10:37
(98) for_sale,
и, конечно же, себя показать. :)

Куда ж без этого)))) Это святое)))
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа