|
OFF: Может я чего не знаю? Пятничное. 🠗 (Волшебник 26.08.2016 11:22) | ☑ | ||
---|---|---|---|---|
0
Dmitrith
26.08.16
✎
09:58
|
Наткнулся сегодня в конфигурации на одну забавную функцию. Много думал. Может я отстал от жизни и так правильно? Коммент в конце функции мой.
Функция ВернутьШПрофНаст(Номенклатура) ШиринаПрофнастила = 0; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ЕСТЬNULL(Номенклатура.ШиринаПрофнастила, 0) КАК ШиринаПрофнастила |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", Номенклатура); РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); Если Выборка.Следующий()Тогда ШиринаПрофнастила = Выборка.ШиринаПрофнастила; КонецЕсли; Возврат ШиринаПрофнастила; // а почему не просто - Возврат Номенклатура.ШиринаПрофнастила; ????????????????????!!!!!!!!!!!!!! КонецФункции |
|||
1
VladZ
26.08.16
✎
09:59
|
(0) Кому-то платят за количество кода.
|
|||
2
dimaldinho
26.08.16
✎
09:59
|
Через Номенклатура.ШиринаПрофнастила читается в буфер весь элемент Номенклатура, а на него может не быть прав по РЛС
|
|||
3
dmpl
26.08.16
✎
10:00
|
(0) Так быстрее. Когда Номенклатура.ШиринаПрофнастила - то считывается весь объект, если его нет в кеше. Плюс проверка на ЕСТЬNULL намекает на то, что ссылка может быть, а объекта в базе - нет.
|
|||
4
Hitcher
26.08.16
✎
10:01
|
(2) Подтверждаю
|
|||
5
Зая Бусечка
26.08.16
✎
10:01
|
Чтобы не читать весь объект, а только то, что нужно от него
|
|||
6
antgrom
26.08.16
✎
10:01
|
есть такой сайт г0внокод
и там раздел с 1С и самое главное каменты там подобные примеры разбирают и в т.ч. объясняют почему в некоторых случаях запрос правильнее. |
|||
7
Dmitrith
26.08.16
✎
10:03
|
(2) (3) Функция вызывается из модуля формы накладной в нее кладется что-то типа ТекущаяСтрока.Номенклатура. На мой взгляд при вызове функции объект уже в памяти, не?
|
|||
8
Зая Бусечка
26.08.16
✎
10:04
|
(7) Могу одолжить очки, чтобы взгляд был острее
|
|||
9
Пузан
26.08.16
✎
10:05
|
Кто-то видимо слишком буквально воспринял совет получать данные исключительно запросом и довел этот совет до абсурда.
|
|||
10
Зая Бусечка
26.08.16
✎
10:06
|
(9) Он просто знает механизм работы 1с и делает так, как надо.
|
|||
11
dmpl
26.08.16
✎
10:06
|
(7) Автор исходил из того, что функция может использоваться не из одного места. Это правильная практика. Ну и попробуй заменить вызов функции просто на Номенклатура.ШиринаПрофнастила, а потом посмотри на отзывчивость интерфейса в режиме реальной нагрузки.
|
|||
12
hitodom
26.08.16
✎
10:07
|
в типовых есть функции ЗначениеРеквизитаОбъекта
|
|||
13
hitodom
26.08.16
✎
10:07
|
а получение через точку от ссылки - это моветон
|
|||
14
piter3
26.08.16
✎
10:10
|
План запроса обычно показывает истинную картину бытия и сознания
|
|||
15
ice777
26.08.16
✎
10:10
|
код работает- да.
не трогай. |
|||
16
FIXXXL
26.08.16
✎
10:11
|
(13) еще радует подход: "если нельзя запрос в цикле, буду в цикле получать через точку" 100500 раз в коде
а че? это ж не запрос в явном виде :) |
|||
17
ovrfox
26.08.16
✎
10:11
|
(9) Не скажите. Вы видимо не работали в нагруженной системе, когда строк в документе обычно около 200.
Хотя в таком случае, если атрибут требуется для каждой строки, то я обычно выбирал атрибут для всех строк документа сразу, одним запросом. Но даже без этого - данный код в нагруженной системе быстрее просто обращения через точку. |
|||
18
DrZombi
гуру
26.08.16
✎
10:13
|
(0) >>> Возврат Номенклатура.ШиринаПрофнастила
В определенных БД через точку работает медленней, чем через запрос :) |
|||
19
Deon
26.08.16
✎
10:14
|
А мне вот название функции не нравится
|
|||
20
Nuobu
26.08.16
✎
10:15
|
Могу предположить, что раньше вместо ширины проф настила в номенклатуре она бралась из регистра.
|
|||
21
DrZombi
гуру
26.08.16
✎
10:15
|
(19) Мне название не критично. Хоть пусть назовут "Ф00001ZXC022016" :)
|
|||
22
DrZombi
гуру
26.08.16
✎
10:16
|
(20) Ошибочное предположение :)
|
|||
23
Пузан
26.08.16
✎
10:16
|
(17) Таки работал и участвовал в создании таких конфиг с нуля. Тут просто нет контекста. А в не контекста не понятно почему именно так сделал прог. Это может быть как единственным правильным решением ради производительности, так и доведем до абсурда опимизяторством.
|
|||
24
DrZombi
гуру
26.08.16
✎
10:16
|
(0)Единственное, что лишнее, это "ЕстьNull" :)
|
|||
25
ptiz
26.08.16
✎
10:17
|
Акститесь, какой РЛС может быть по отдельным реквизитам номенклатуры!
(7) +1 Вероятно, что объект в памяти и запрос - лишнее дерганье СУБД. Код в (0) - то ли задел на будущее, то ли... не знаю. Надо смотреть откуда идет вызов функции. |
|||
26
ice777
26.08.16
✎
10:20
|
(25) c 8.2 можно
|
|||
27
Dmitrith
26.08.16
✎
10:21
|
(23) на базе Бух 3.0 написано. В контексте особо не лазил, на функцию можно сказать случайно напоролся. Сейчас пока апдейты накачиваю, на дописки потом смотреть буду
|
|||
28
dmpl
26.08.16
✎
10:21
|
(25) А может функция вообще в модуле с повторным использованием расположена ;)
|
|||
29
ice777
26.08.16
✎
10:21
|
(26) * а запросом, можно )
пятница же. |
|||
30
Новиков
26.08.16
✎
10:23
|
(0) ты покажи стек вызова, и те куски кода в нем, что отвечают за получение параметра Номенклатура. А так можно гадать на кофейной гуще долго.
|
|||
31
Dmitrith
26.08.16
✎
10:25
|
(30) Документ-СчетНаОплатуПокупателя-ФормаДокумента
&НаКлиенте Процедура ДеталиДетальПриИзменении(Элемент) ТекущаяСтрока = Элементы.Детали.ТекущиеДанные; ШиринаПрофнастила = ВернутьШПрофНаст(ТекущаяСтрока.Деталь); ТекущаяСтрока.ШиринаД = ШиринаПрофнастила; КонецПроцедуры |
|||
32
4St
26.08.16
✎
10:26
|
(0) Надо смотреть контекст. Если функция вызывается 100 раз подряд для одной и той же ссылки, то получение через точку займет меньше времени, т.к. после первого чтения объект считается в кэш. Хотя это и крайне кривое решение.
Если же функция вызывается 100 раз для 100 разных ссылок, то текущая реализация гораздо лучше, чем получение через точку. Но более правильным будет запрос сразу по всем товарам, для которых надо получить данный реквизит. Кое с чем автор явно переборщил, и поддержу (12): проще было дернуть ЗначениеРеквизитаОбъекта() из БСП |
|||
33
Dmitrith
26.08.16
✎
10:27
|
(32) см. (31)
|
|||
34
Новиков
26.08.16
✎
10:28
|
(31) я правильно понимаю, что ВернутьШПрофНаст описана в этом же модуле?
|
|||
35
Dmitrith
26.08.16
✎
10:29
|
(34) правильно
|
|||
36
4St
26.08.16
✎
10:30
|
(31) Жесть. БСП там явно есть, так что автор явно про нее не знал.
Функция объявлена идет без директив? Если да, то хотя бы &НаСервереБезКонтекста поставь им. |
|||
37
1dvd
26.08.16
✎
10:31
|
допустим, использование запроса целесообразно, однако естьNULL зачем?
|
|||
38
Dmitrith
26.08.16
✎
10:33
|
(36) Функция &НаСервере
|
|||
39
Trance_1C
26.08.16
✎
10:34
|
(37) На тот случай если в параметре Номенклатура вместо объекта идентификатор ссылки на него, а объекта в базе еще нет.
|
|||
40
Trance_1C
26.08.16
✎
10:36
|
Отличный код, отказоустойчивый.
|
|||
41
4St
26.08.16
✎
10:36
|
(38) Получается, каждый раз при изменении номенклатуры на сервер отправляется весь контекст формы размером в несколько десятков Кб ради того, чтоб вернуть одно единственное число ))
|
|||
42
Новиков
26.08.16
✎
10:37
|
(40) Есть табличная часть в документе, в нем - строка, в нем ссылка на номенклатуру, которой еще нет?
|
|||
43
PR
26.08.16
✎
10:38
|
(41) Прикольно, че :))
|
|||
44
dmpl
26.08.16
✎
10:38
|
(32) Перестраховался. Уже сколько раз напарывался с кодом 1С, что перестает работать через некоторое время. А мой код, до которого шаловливые ручки 1С не дотягиваются, работает десятилетиями.
|
|||
45
4St
26.08.16
✎
10:38
|
Тоже поделюсь болью. Досталась на днях нетленка на базе БП 1.5. Платформа 8.1.11. Файловая база на 8 ГБ. Клиенты работают на ней около 10 лет.
Один из перлов: Процедура ЗаполнитьРегионыТариф(НеМенятьСумму = Ложь, НеМенятьПланДоставки = Ложь) ДопСумма = 0; ДопПроцент = 0; Если ДокументОбъект.Доп1 Тогда ДопПроцент = ДопПроцент + 25; КонецЕсли; Если ДокументОбъект.Доп2 Тогда ДопПроцент = ДопПроцент + 30; КонецЕсли; Если ДокументОбъект.Доп3 Тогда ДопСумма = ДопСумма + 250; КонецЕсли; Если ДокументОбъект.Доп4 Тогда ДопСумма = ДопСумма + 500; КонецЕсли; Если ДокументОбъект.Доп5 Тогда ДопСумма = ДопСумма + 500; КонецЕсли; Если ДокументОбъект.Доп6 Тогда ДопСумма = ДопСумма + 150; КонецЕсли; Если ДокументОбъект.Доп7 Тогда ДопСумма = ДопСумма + 150; КонецЕсли; Если ДокументОбъект.Доп8 Тогда ДопСумма = ДопСумма + 50; КонецЕсли; Если ДокументОбъект.Доп9 Тогда ДопСумма = ДопСумма + 50; КонецЕсли; Если ДокументОбъект.Доп10 Тогда ДопСумма = ДопСумма + 250; КонецЕсли; Если ДокументОбъект.Доп11 Тогда ДопСумма = ДопСумма + 250; КонецЕсли; Если ДокументОбъект.Доп12 Тогда ДопСумма = ДопСумма + 300; КонецЕсли; Если ДокументОбъект.Доп13 Тогда ДопСумма = ДопСумма + 500; КонецЕсли; Если ДокументОбъект.Доп14 Тогда ДопПроцент = ДопПроцент + 50; КонецЕсли; Если ДокументОбъект.Доп15 Тогда ДопСумма = ДопСумма + Минута(ВремяОжиданияКурьером)/15*30; КонецЕсли; Если (СхемаОтправки <> Перечисления.СхемаОтправки.Пикап И СхемаОтправки <> Перечисления.СхемаОтправки.ОплатаПолучателем) ИЛИ ВидОперации <> Перечисления.ВидыОперацийНакладная.Обычная Тогда РегионОтправления = ОпределитьРегион(ГородКлиента); ТипТарифнойЗоныОтправителя = ОпределитьТипЗоныГорода(ГородКлиента, Подразделение); РегионПолучения = ОпределитьРегион(ГородСтороны); ТипТарифнойЗоныПолучателя = ОпределитьТипЗоныГорода(ГородСтороны, Подразделение); Иначе РегионОтправления = ОпределитьРегион(ГородСтороны); ТипТарифнойЗоныОтправителя = ОпределитьТипЗоныГорода(ГородСтороны, Подразделение); РегионПолучения = ОпределитьРегион(ГородКлиента); ТипТарифнойЗоныПолучателя = ОпределитьТипЗоныГорода(ГородКлиента, Подразделение); КонецЕсли; // Заполнение расчета тарифа Комментарий = ""; ДнейДост = 0; Комментарий = ""; // Город, регион получателя Если Ссылка.СхемаОтправки = Перечисления.СхемаОтправки.ОплатаПолучателем Тогда РТГород = ГородКлиента; РТРегион = ОпределитьРегион(ГородКлиента); Если Дата <= Дата(2012,02,01) Тогда Если ОпределитьРегион(ГородКлиента) = ОпределитьРегион(ГородСтороны) И ОпределитьРегион(ГородКлиента).Пустая() = Ложь Тогда Если ГородКлиента.ВнутриОбластнойТариф <> 0 Тогда //++АГ //ЭлементыФормы.РасчетыТарифа.ТекущаяСтраница = //ЭлементыФормы.РасчетыТарифа.Страницы.ВнутриОбластной; //АГ++ ЗаполнитьРасчетСумммыВнутриОбластной(); Иначе ДобавитьКомментарий(Комментарий, "Города в пределах одного региона, но не установлен внутриоластной тариф для города """ + ГородСтороны + """"); ЗаполнитьРасчетСуммыОбычный(); КонецЕсли; Иначе ЗаполнитьРасчетСуммыОбычный(); КонецЕсли; Иначе //кмв тут // Заполнение расчета суммы ЭтоГородВСпискеХМАО = НайтиГородВСпискеХМАО(ГородСтороны, ГородКлиента); Если ЭтоГородВСпискеХМАО Тогда //Если (ГородСтороны.Код = 2528 или ГородСтороны.Код = 288 или ГородКлиента.Код = 240 ) Тогда // ЗаполнитьРасчетПоХМАО(ГородСтороны, ГородКлиента); //Иначе ЗаполнитьРасчетПоХМАОКромеСургута(ГородСтороны,ГородКлиента); //КонецЕсли; (дальше не буду, ибо кровавые слезы) |
|||
46
Trance_1C
26.08.16
✎
10:38
|
(42) совершенно верно.
|
|||
47
SimpleOne
26.08.16
✎
10:38
|
(40) Нет. Разрешенные в запросе отсутствует
|
|||
48
Новиков
26.08.16
✎
10:40
|
(46) Например, при организации обмена, в это можно поверить без натяжки. Тут же, получается создается документ, и как так получается, что и номенклатура где-то создается, но еще не записывается? Просто логика не понятно, как такое может быть вообще.
|
|||
49
4St
26.08.16
✎
10:42
|
(39) В этом случае запрос должен выдать 0 строк. А поскольку дефолтный результат функции объявляется в самом начале (ШиринаПрофнастила = 0; ), то 0 и будет возвращено. Так что IsNull ИМХО лишнее.
|
|||
50
ptiz
26.08.16
✎
10:45
|
(36) А что есть в БСП?
Раз зашел такой разговор, вот функция из ЕРП: Модуль менеджера в справочнике Номенклатура: Функция ЗначенияРеквизитовНоменклатуры(Номенклатура) Экспорт Запрос = Новый Запрос(" |ВЫБРАТЬ | Номенклатура.ВестиУчетПоГТД КАК ВестиУчетПоГТД, | Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения, | Номенклатура.СтавкаНДС КАК СтавкаНДС, | Номенклатура.ГруппаФинансовогоУчета КАК ГруппаФинансовогоУчета, | Номенклатура.ПодакцизныйТовар КАК ПодакцизныйТовар, | ВЫБОР КОГДА Номенклатура.ТипНоменклатуры НЕ В | (ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Товар),ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.МногооборотнаяТара)) ТОГДА | Истина | ИНАЧЕ | Ложь | КОНЕЦ КАК ЭтоУслуга |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Ссылка = &Номенклатура |"); Запрос.УстановитьПараметр("Номенклатура", Номенклатура); ... Суть - та же. Так что автор кода в (0) - идет по стопам типовых. Но плохо понимает работу запроов :) ЕСТЬNULL() тут - бессмысленна. |
|||
51
Trance_1C
26.08.16
✎
10:51
|
Возможно автор опасался пустых объектов появившихся в результате обмена, или что внезапно включится РЛС на чтение номенклатуры :)
|
|||
52
Злопчинский
26.08.16
✎
10:55
|
Пожилой программер (ну типа меня) приходит устраиваться на работу.
HR-менеджер: "Вы нам не подходите. Нам нужны молодые, амбициозные, способные творчески расти". Программер: "Запишите мой телефон. Когда выяснится, что у вас все амбициозно растут, а работать некому – позвоните" |
|||
53
piter3
26.08.16
✎
10:56
|
(52) я знаю версию бухгалтера и hr
|
|||
54
GROOVY
26.08.16
✎
10:56
|
ИМХО, не пятничное и совсем не юмор. Пример идеального кода.
|
|||
55
Deon
26.08.16
✎
10:58
|
ШиринаД, ВернутьШПрофНаст()
Сокращун до одной буквы ) |
|||
56
novichok79
26.08.16
✎
11:01
|
(55) это еще не сокращун, я тут разбираюсь с дописками одного программиста, он сокращает все до пары букв, в итоге получается нечитаемый адъ... меня это разочаровывает.
|
|||
57
novichok79
26.08.16
✎
11:05
|
(0) в целом код ахумилителен... правда я бы добавил еще ВЫБРАТЬ РАЗРЕШЕННЫЕ и проверку на тип перед возвратом значения из функции
|
|||
58
Deon
26.08.16
✎
11:06
|
(22) Кстати, почему ошибочное? Это может объяснить наличие ЕстьNULL'а
|
|||
59
Garykom
гуру
26.08.16
✎
11:07
|
(54) Идеально тупого кода.
Чутка подумать вперед и если не нравится ЗначениеРеквизитаОбъекта() то наваять свою с передачей имени реквизита как параметра. А так полный изврат с копи/пасте будет когда другой реквизит номенклатуры получать захочется. Лично сделал бы функцию которая сразу получает "набор реквизитов" и в т.ч. для "списка ссылок". |
|||
60
Deon
26.08.16
✎
11:09
|
(57) тип переменной ШиринаПрофнастила? Зачем?
|
|||
61
novichok79
26.08.16
✎
11:14
|
(60) ну... вдруг (внезапно, suddenly) там будет null... хотя в запросе уже есть null
|
|||
62
Новиков
26.08.16
✎
11:49
|
(50) >>ЕСТЬNULL() тут - бессмысленна.
Если автор добавил этот кусок, то он сделал усилие. Вряд ли б он напрягался, если б не было в этом нужде. Скорее всего, как-то (пока не ясно как), но в этой табличной части действительно может появиться не записанный в базу объект номенклатуры. И автор таким образом подстраховался. Но как такое может быть именно что интерактивно - сложно себе представить. |
|||
63
GROOVY
26.08.16
✎
11:50
|
(59) Кто сказал, что это имеет отношение к БСП?
|
|||
64
ptiz
26.08.16
✎
13:02
|
(62) Если будет несуществующая ссылка, то будет пустой результат запроса. А null - не будет никогда.
|
|||
65
PR
26.08.16
✎
15:01
|
(64) Будет. Если будет битая ссылка.
|
|||
66
del123
26.08.16
✎
17:01
|
Тоже подкину чудокода))
Заполнение строки таблицы определенными элементами массива) Для каждого зн Из масЗначСтр Цикл столбик=столбик+1; ЕСЛИ столбик <5 Тогда Продолжить; ИНАЧЕЕСЛИ столбик =6 ИЛИ столбик =7 ИЛИ столбик =9 Тогда Продолжить; ИНАЧЕЕСЛИ (столбик >10) И (столбик <19) Тогда Продолжить; ИНАЧЕЕСЛИ (столбик >19) И (столбик <24) Тогда Продолжить; ИНАЧЕЕСЛИ (столбик >24) И (столбик <28) Тогда Продолжить; ИНАЧЕЕСЛИ (столбик =29) Тогда Продолжить; ИНАЧЕЕСЛИ (столбик >30) Тогда Продолжить; ИНАЧЕ номЗнач = номЗнач + 1; Если номЗнач>4 Тогда Прервать; Иначе новСтр[номЗнач] = СтрЗаменить(зн,символОграничения,""""); //Запомним сразу дату Если номЗнач=3 Тогда Сдата=зн; КонецЕсли; А=1; КонецЕсли; КОНЕЦЕСЛИ; КонецЦикла; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |