1. 1C / Говнокод #13113

    −80

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

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

    Запостил: ilya2184, 05 Июня 2013

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

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

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

        А насчет первоначального говнокода, я встречал винды, где конфигуратор по умолчанию считает родным английский. Да, 1С берет локализацию из винды, если она явно не указана.
        Строка(ТипЗнч(Ссылка)) вернет что-нибудь типа "DocumentReference.Blablabla".
        Тыкну пальцем: такое встречал в конфигурации "ИТРП: Процессное производство". Написал авторам. Исправили. Но не везде. Типа, "Рефакторинг? Не, не слышал". Ну хотя бы поиск по всей конфигурации могли бы сделать.
        И кстати, исправили на ваш же вариант :) После чего я им снова тыкнул на косяк с Неопределено :)
        Ответить
      • Ну, моя метода только ссылку от объекта не отличит, но это лечится проверкой ТипЗнч(Ссылка) = ТипЗнч(Ссылка.Ссылка). А еще проще, Ссылка = Ссылка.Ссылка. Впрочем, вы там замеры делали... Коль не лень - сделайте замеры по методу метаданных :)
        Ответить
    • Ни того ни другого вообще не должно быть.
      Ответить
      • Вы так к извечному холивару нас приведёте, です。
        Ответить
    • > ТипВсеСсылки()
      А почему у документа может быть несколько типов?
      Ответить
      • "Документы" - класс без экземпляров его подклассы например "документы.счетфактуравыданный".
        Ответить
        • А в1с есть соглашение о наименовании?
          Ответить
          • что конкретно интересует? =)
            в случае счета фактуры он обычно называется СчетФактураВыданный. Без нижних подчеркиваний.
            Ответить
          • Есть Соглашение при написании кода\Оформление модулей\Имена процедур и функций
            Есть Соглашение при написании кода\Оформление модулей\Правила образования имен переменных
            Говнокодеров развелось хоть пруд пруди, и про документ "Система стандартов и методик разработки конфигураций для платформы 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). Циферки с замера привести или на слово поверите?
          А вот на личности переходить не стоит.
          Ответить
          • 8.2.18, пардон.
            Ответить
          • Код и цифры замера в студию, у меня при единичном запуске:
            конфа: Бухгалтерия "допиленная"
            Строка() 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 :-) (не зря я его сразу "отрефакторил" как сконфертил базу)
                  Ссылка = Документы.СчетФактураВыданный.ПустаяСсыл ка();
                  ТипСсылки = ТипЗнч(Ссылка);
                  Сообщить(ТипСсылки);
                  вывод:
                  Счет-фактура выданный

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

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

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

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

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

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