Бухгалтерия / Говнокод #13113 Ссылка на оригинал

0

  1. 1
Если Найти(Строка(ТипЗнч(Ссылка)),"Документ") Тогда

Проверка, является ли переданная ссылка документом. Сегодня без авторства.

Запостил: ilya2184 ilya2184, (Updated )

Комментарии (40) RSS

  • Должно быть
    Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка)) Тогда

    если кто не понял
    Ответить
    • Метаданные. Документы.Содержит(Ссылка.Метаданные())
      Почему этот метод лучше: встречал затыки с вашим способом, по-моему возвращалась Истина, если передать Неопределено. Некая логика есть, ведь "многотипные" реквизиты могут принимать значение Неопределено.

      А насчет первоначального говнокода, я встречал винды, где конфигуратор по умолчанию считает родным английский. Да, 1С берет локализацию из винды, если она явно не указана.
      Строка(ТипЗнч(Ссылка)) вернет что-нибудь типа "DocumentReference.Blablabla".
      Тыкну пальцем: такое встречал в конфигурации "ИТРП: Процессное производство". Написал авторам. Исправили. Но не везде. Типа, "Рефакторинг? Не, не слышал". Ну хотя бы поиск по всей конфигурации могли бы сделать.
      И кстати, исправили на ваш же вариант 🙂 После чего я им снова тыкнул на косяк с Неопределено 🙂
      Ответить
    • Ну, моя метода только ссылку от объекта не отличит, но это лечится проверкой ТипЗнч(Ссылка) = ТипЗнч(Ссылка.Ссылка). А еще проще, Ссылка = Ссылка.Ссылка. Впрочем, вы там замеры делали... Коль не лень - сделайте замеры по методу метаданных 🙂
      Ответить
  • > ТипВсеСсылки()
    А почему у документа может быть несколько типов?
    Ответить
    • "Документы" - класс без экземпляров его подклассы например "документы.счетфактуравыданный".
      Ответить
        • что конкретно интересует? =)
          в случае счета фактуры он обычно называется СчетФактураВыданный. Без нижних подчеркиваний.
          Ответить
        • Есть Соглашение при написании кода\Оформление модулей\Имена процедур и функций
          Есть Соглашение при написании кода\Оформление модулей\Правила образования имен переменных
          Говнокодеров развелось хоть пруд пруди, и про документ "Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8 " знает очень небольшой процент.
          Ответить
          • > Система стандартов и методик разработки конфигураций
            В десяти томах?
            Ответить
            • А хрен его знает: документ электронный, по разделам. Там не мало, но *по большей части* полезно.
              Есть на дисках ИТС, для действующих подписчиков можно на сайте ознакомится http://its.1c.ru/db/v8std
              Ответить
  • отработает, кстати, быстрее, чем указанный выше вариант через СодержитТип().
    С точки зрения человека, который не пишет на 1с - лютое говно.
    С точки зрения человека, который знает баги 1с и места тормозов в 1с - вполне рабочий костыль, который можно применять. Костыль, который работает быстрее методов, предоставляемых платформой и рекомендуемых к использованию 1с.
    Ответить
    • В российской локали - может быть и быстрее, в остальных будет ой.
      Ответить
    • Специалист по костылям, и крупный сециалист по багам в 1С?
      Я проверил
      10M раз Строка() и ТипВсеСсылки()
      затратили на Строка(): 108 сек
      затратили на ТипВсеСсылки(): 95 сек

      платформа 8.2.18.61
      по замеру производительности в режиме отладки 50K раз
      Если Найти(Строка(ТипЗнч(Ссылка)),"Документ") Тогда КонецЕсли	 0,394504 сек
      Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка)) Тогда КонецЕсли	 0,307880 сек


      Так что не Найти() не быстрее, и работает не всегда
      Жаль что специалистов таких как ты, я вижу, уже двое...
      Ответить
      • Это вопрос кэша.
        на единичном запуске вариант со строкой отрабатывает быстрее (так же на 8.2.16.61). Циферки с замера привести или на слово поверите?
        А вот на личности переходить не стоит.
        Ответить
        • Код и цифры замера в студию, у меня при единичном запуске:
          конфа: Бухгалтерия "допиленная"
          Строка() 0,000364
          СодержитТип() 0,000134
          Процедура КнопкаВыполнитьНажатие(Кнопка)
          	Ссылка = Документы.СчетФактураВыданный.ПустаяСсылка();
          	//ПолеВводаСколькоРаз - реквизит формы
          	А = 0;
          	Для К = 1 По ПолеВводаСколькоРаз Цикл
          		Если Найти(Строка(ТипЗнч(Ссылка)),"Документ") Тогда КонецЕсли
          	КонецЦикла;
          	Б = Истина;
          	Для К = 1 По ПолеВводаСколькоРаз Цикл
          		Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка)) Тогда КонецЕсли
          	КонецЦикла;
          КонецПроцедуры
          Ответить
          • 157 типов документов, может что-то упустили? типа преобразование числа в булево.
            Ответить
        • Да и вообще: как может быть быстрее когда ТипВсеСсылки() - уже лежит в памяти (сервера или толстого клиента), предполагаю что в виде коллекции, а тип как мы знаем - число в глубинах платформы. То есть:
          получение типа, вхождение числа в коллекцию чисел
          против
          получение типа, получение имени из коллекции, поиск по подстроке, преобразование числа в булево

          Не верю
          Код в студию
          Ответить
          • Конфигурация - собственный ТОР компании, демо-база, развернутая на ms sql 2008, управляемое приложение.

            Тестировал на этом:
            // Реквизит1 - реквизит на форме, в котором выбирается конкретный документ.
            	
            //Для сч = 0 По 50000 Цикл
            	Если Найти(Строка(ТипЗнч(Реквизит1)),"Документ") = 0 Тогда 
            	КонецЕсли;	 
            	Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Реквизит1)) Тогда 
            	КонецЕсли;	
            		 
            		
            //КонецЦикла;

            Из отличий сразу в глаза бросается то, что я убрал шаг преобразования в булево и порядок вызова функций.
            Замеры:
            СодержитТип() 0,000048
            Строка() 0,00004

            СодержитТип() 0,00006
            Строка() 0,000046

            СодержитТип() 0,000063
            Строка() 0,000051

            После того, как убрал = 0 из условия.
            СодержитТип() 0,000068
            Строка() 0,000055

            СодержитТип() 0,000063
            Строка() 0,00005

            К слову сказать, в обратном порядке вызовов идет обратный порядок в замерах. На мой взгляд, тут идет просадка в скорости при первом вызове ТипЗнч() и помещении этого добра в кэш.
            Ответить
            • ай, код вставил уже с перевернутым порядком. цифры взяты с варианта, когда сначала шел СодержитТип, потом Строка()
              Ответить
              • Знаешь, а я тут на обед ходил и подумал - ведь код-то нерабочий в 8.2 🙂 (не зря я его сразу "отрефакторил" как сконфертил базу)
                Ссылка = Документы.СчетФактураВыданный.ПустаяСсыл ка();
                ТипСсылки = ТипЗнч(Ссылка);
                Сообщить(ТипСсылки);
                вывод:
                Счет-фактура выданный

                :-)))
                Ща я потестю на управляемом приложении (на толстом я так понимаю), но в не думаю что есть разница, между обычным приложением в данном случае, и один замер - не показателен. Определение типа вынесу за циклы.
                Ответить
                • тестировал в тонком. Процедура, естественно, &НаСервере
                  Почему нерабочий? При сообщить() преобразование типов просто проходит. Или я что-то еще не заметил?

                  А я вот никак на обед не могу уйти. =(
                  Ответить
                  • а, все. до меня дошло.
                    Да это прям рекурсивный баг какой-то! 😀 такой спор прервался)
                    Ответить
              • Тонкий клиент сервер в режиме отладки (обработано на сервере): победил ТипВсеСсылки()
                Кстати ЗНАЧИТЕЛЬНО медленнее (50K в одном цикле)
                Найти(Строка(ТипСсылки),"Документ") 1,545385 (против 0,394504 в неуправляемом)
                Документы.ТипВсеСсылки().СодержитТип(Тип Ссылки) 1,441650 (против 0,307880 в неуправляемом)

                ...удивление... а не, не удивление - сервер-то у меня на компьютере в виртуалке 🙂
                в толстом управляемом приложении похожая ситуация.

                Ну да ладно, мне надоело... я считаю что поиск по строке - зло, если переменная типа тип - то работать с ней как с типом, если число - как с числом.
                Ответить
                • Удивительная разница =) не, у меня сервер "живой".

                  Я абсолютно согласен, что поиск по строке - злое зло и делать надо по-нормальному. И благодарю за развенчание моей уверенности в тормознутости работы метода СодержитТип().
                  Надо будет еще перепроверить скорость работы методов вроде Метаданные.Справочники.Найти() и Содержит(), может что в платформе уже успели поправить на этот счет.
                  Ответить
                  • Я думаю это может быть связано с отладкой сервера - у меня "по тихому" развернут сервер приложений с параметром -debug и конфигуратор каждую строку "отлаживает". Это чобы если упадет то только тестовые "стенды" падали.
                    Ответить
                    • мой сервер тоже с дебагом - как бы я на сервере замеры делал =)
                      возможно, что именно виртуалка дает такую разницу.
                      Ответить
      • Если Лев(ТипЗнч(Ссылка), 8)="Документ" Тогда
        1. Документы.ТипВсеСсылки().СодержитТип(нео пределено) вернет Истина
        2. Лев(ТипЗнч(Ссылка), 8)="Документ" вернет истина также в случае, когда переданное значение содержит ДокументОбъект, ДокументМенеджер, ДокументСписок.
        Ответить

Добавить комментарий

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8