Почему все рекомендуют добавлять префиксы слева от идентификатора. Вот в первых типовых решениях на 1С Предприятие 8, и их расширениях (тогда это ещё не было видом конфигурации ибо платформа была 8.0) были префиксы перед идентификаторами – было ужасно неудобно (особенно при поиске по первым буквам – строки фильтра в дереве метаданных ещё не было, и в быстрой подсказке); и от этого отказались. Теперь опять советуют префиксы слева от идентификатора. Жесть. Не…. ну я понимаю, что платформа тут очень ущербна и что-бы не нарваться на дубли имён при очередном апдейте (в т.ч. с расширениями) и для повышения понимания того «кем добавлен» и к чему относится тот или иной идентификатор нужно как-то разграничивать пространства имён идентификаторов (за неимением в платформе более продвинутых механизмов) – но почему тогда не ставить эти присловутые префиксы как суффиксы (окончания) СПРАВА от идентификатора «МойРеквизит_МойПрефикс» - так они не будут никому мешать, названия реквизитов будут лаконичны, легко набираемы, легко читаемы (особенно когда идентификатор длинный, а префикс «ещё длиннее»).
Я, вот, ставлю, префиксы справа – и очень доволен (насколько можно быть тут довольным в ущербной платформе 1С Предприятие 8)! Но да - «1С Совместимо» такая конфигурация вряд ли пройдёт (хот я считаю «1С Совместимо» весьма корявым стандартом, но он хоть какой-то стандарт, в 1С среде стандартов мало…. Хе… кто бы жаловался на то что стандартов мало, а не наоборот – слишком много).
Кстати, говоря, если присмотреться, то типовые конфигурации от 1С используют префиксы-суфиксы и именно СПРАВА:
Примеры префиксов: |
---|
ОбщегоНазначенияБП
ОбщегоНазначенияБЗК
ОбщегоНазначенияБРО
ОбщегоНазначенияБТС
ОбщегоНазначенияУТ
ОбщегоНазначенияСлужебныйКлиентСервер
ОбщегоНазначенияЛокализация
ОбщегоНазначенияЗУП
ОбщегоНазначенияУХ
ОбщегоНазначенияЭДКО
ОбщегоНазначенияЭД
ОбщегоНазначенияMicrosoftExcelКлиентСерверУХ
ОбщегоНазначения_ОДП //Это уже мой модуль
ПроверкаИПодборПродукцииЕГАИС
ПроверкаИПодборПродукцииЕГАИСУТ
ПроверкаИПодборПродукцииИС
ПроверкаИПодборПродукцииИСМП
ПроверкаИПодборПродукцииИСМПУТ
ПроверкаИПодборПродукцииМОТП
Неужели так было бы лучше (но именно так, в общем-то, предлагает данная рекомендация):
БП_ОбщегоНазначения
БЗК_ОбщегоНазначения
БРО_ОбщегоНазначения
БТС_ОбщегоНазначения
УТ_ОбщегоНазначения
Служебный_ОбщегоНазначенияКлиентСервер
Локализация_ОбщегоНазначения
ЗУП_ОбщегоНазначения
УХОбщегоНазначения
ЭДКООбщегоНазначения
ЭДОбщегоНазначения
УХ_MicrosoftExcel_ОбщегоНазначенияКлиентСервер
ОДП_ОбщегоНазначения
ЕГАИС_ПроверкаИПодборПродукции
ЕГАИСУТ_ПроверкаИПодборПродукции
ИС_ПроверкаИПодборПродукции
ИСМП_ПроверкаИПодборПродукции
ИСМПУТ_ПроверкаИПодборПродукции
МОТП_ПроверкаИПодборПродукции |
«Дублирование кода (ООП): Общие процедуры и функции нужно выносить в общие модули» - рекомендация отчасти противоречит заголовку. Ущербная платформа 1С Предприятие 8 – не совсем ООП – вернее почти совсем не ООП для тех, кто в ней парограммирует. Но – этот ООП отчасти можно эмулировать – как раз используя обработки – как псевдо-объекты. Тогда – как раз можно было собирать общие алгоритмы в таких обхектах-обработках создавать их, передавать их и вызхывать их методы – простите – функции и процедуры. Но… модуль объектов как и модуль менеджера не доступен на клиенте (ущербная платформа), хотя для клиента можно использовать форм(у)ы обработки. И это, относительно удобно – хотя мало разработок этим пользуется (хотя, вот, есть Инструменты разработчика от Tormozit). Место ООП такие объекты можно воспринимать как библиотеки. Хотя, т.к. нельзя эффективно управлять директивами препроцессора – то это решение имеет много минусов, по сравнению с общими модулями, хотя у кого их больше – это ещё вопрос – в неуправляемом приложении уж точно.
А размещение алгоритмах в обработках позволяет легко создавать локальный контекст «библиотеку» - называем обработки длинными уникальными именами (чтобы во всех конфигурациях и расширениях они не пересекались) и пишем специальную функцию – которая по имени контекста будет создавать и наполнять структуру объектами таких обработок с унифицированными именами (если в составе общей конфигурации есть повторяющиеся унифицированные имена обработок – то просто выбираем одну из них (по старшинству версии; стратегия MIXIN тут не получится – хотя при должной сноровки и её можно было бы эмулировать) – далее либо используем экземпляр такой структуры локально – либо присваиваем глобальной переменной (увы – только в клиентском контексте (для упр. приложения нужно создавть экземпляры форм); на сервере можно было бы запихнуть в параметры сеанса – если было бы можно – хотя можно во временное хранилище – но лучше просто обойтись функцией в модуле повторного использования – а там уже задейстовать и параметры сеанса и временное хранилище). Таким макаром можно и более-менее полноценную иерархию пространств имён получить (с вложенными модулями). Справедливости ради, замечу, что эта стратегия работает и с общими модулями – но ими управлять куда менее удобно и менее универсально! А орбработки бывают ещё и внешними – что открывает коллосальные возможности к динамическому программированию.
Не «1С Совместимо»!
Говоря о функции «ЗначенияРеквизитаОбъекта» стоило бы упомянуть и функцию «ЗначенияРеквизитовОбъекта» - потому что редко, когда нужно взять только один реквизит. А заодно и другие функции получения значений реквизитов объектов.
Использовать «Выразить» для реквизитов составного типа в запросах – это палка о двух концах. С одной стороны – да нужно стараться использоваться (особенно при работе с субконто и характеристиками). А, вот, приведённый пример «ВЫРАЗИТЬ(УчетНоменклатуры.Регистратор КАК Документ.РасходнаяНакладна).Номер» очень спорный – т.к. в данном случае как раз обычно нужны номера любых документов, зарегистрировавших запись. И что делать – если (а так обычно и бывает) нужно более 1-го вида регистратора регистратор? Но бывают, конечно исключения – и вот... программисту лень городить сложные конструкции с оператором «ВЫБРАТЬ КОГДА ТОГДА» и «ВЫРАЗИТЬ», тяня туда десятки видов документов. А если нагородит – то потом появляется новый вид документа (например, подключится расширение) и…. БАА!.. запрос уже не работает корректно (работает без ошибок, но некорректные результаты выдаёт)! Пойди найди все такие запросы, чтобы внести в них правки! Налицо очередная ущербность платформы и неудачная рекомендация!
Не говоря уже о том, что одно лишь «ВЫРАЗИТЬ» без фильтра «ГДЕ ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор Ссылка Документ.ПоступлениеТоваровУслуг)» никакого особого выигрыша в производительности (и уж тем более в корректности результата) не даёт (но защищает от переполнения числа таблиц в итоговом запросе – что может быть чревато для некоторых старых СУБД). А если написать указанный фильтр – то «ВЫРАЗИТЬ» уже можно не писать (если этого не требует логика) – выигрыша в производительности почти не будет (хотя это может только MS SQL умеет так условия проталкивать) – почти все соединения будут пустыми.
Хотя это очередной раз говорит об ущербности платформы – ведь можно было бы не делать соединения с таблицами, если их нет в условии с оператором «Ссылка» (когда его можно однозначно определить). Не говоря уже о том, что все эти фильтры и выражения типа нужно декларировать вне запроса (в дереве метаданных) и лишь применять в запросах – чтобы не выискивать их потом. Сделать это можно было бы вообще круто – введя интерфейсы – и используя их как как типы, да хоть в том же операторе «ВЫРАЗИТЬ» но уже одном – а на выходе будет NULL если интерфейс не поддерживается; или все доступные поля интерфейса (да ещё и, возможно, по-разному реализованные (да хоть имеющие разные имена идентификаторов) в разных источниках, но сведённые к единой мнемонике использования в запросе; а настраивалось бы всё декларативно в конфигурации).
«Использование условий в секции ГДЕ вместо параметров виртуальных таблиц» – это справедливо только для регистров накопления и иже с ними. Применение в регистрах сведений должно быть с осторожностью – т.к. это может повлиять на логику выборки среза.
А чем не угодил метод «Сообщить»? Он вроде бы внутри реализует логику объекта «СообщениеПользователю» (пусть и в урезанном виде).
«Не использовать проверку на тип «булево», через ИСТИНА или ЛОЖЬ» - вот это рекомендация просто убила! Что – и тут 1С Предприятие 8 имеет проблемы? А в друг в переменной будет значение «неопределено» или «null» (это могут быть как легитимные значения, так и не очень – ведь 1С Предприятие 8 – это система с полностью динамической типизацией). Скажите – уж лучше в этом случае ошибку получить? Когда-то да – лучше – но чаще – просто можно считать условие не выполнившимся! Хотя, вот числовые значения 1С приводит неявно к булевым – и ничего – никто не умер (я надеюсь)!
Примера с транзакциями очень неудачные – скорее всего научат как раз плохому коду!
« Правильное решение - это использовать регистр сведений в котором будет четыре измерения: “Аналитика” (составной тип)» - Вот это можно пояснить. Зачем тут 4 измерения аналитики, да ещё и составного типа?
Я использую регистр сведений: |
---|
Измерения:
Идентификатор
ДатаНачала
ДатаОкончания
Организация
База (для идентификации ИБ, в т.ч. узла при применении распределения настроек из единого центра)
Пользователь (для персонализации по пользователю)
Метаданные (для привязки к конкретному метаданными – для удобства интерактивной настройки)
- все, кроме идентификатора, не обязательны к заполнению
Реквизиты:
ДатаИзменения
АвторИзмиенения
Ответственный (Владелец параметра)
Описание (параметра)
Комментарий (к текущему значению
И ресурс «Значение» - строковый неограниченной длинны – хранит серилизованное значение (т.е. так можно хранить куда больше вариантов типов данных, в т.ч. списки и даже деревья значений). И нет проблем с неэффективным хранением значений разных примитивных типов, и можно хранить неограниченные строки.
Идентификатор – может быть ссылкой на отдельный справочник/ПВХ с предопределёнными значениями (для удобства), но может быть и просто строкой (ограниченной длинны).
Доступ к регистру через функцию модуля повторного использования – так что обращения кэшируются.
По-моему, почти идеально! |
Вот про контроль изменения значений в модулях повторного использования можно подробнее. Ранее уже пробовал городить огород на эту тему – но пока плюнул на это дело – не сталкивался на пактике с большими проблемами с отсудившем такого контроля. Хотя можно завести отдельну константу – дата сброса кеша (и параметре сеанса – с текущей датой сброса кеша) – периодически проверять в каждом сеансе, и если дата в константе станет моложе даты в параметре сеанса – то вызвать функцию «ОбновитьПовторноИспользуемыеЗначения()» (очень неудачное имя идентификатора) – сбросив вообще весь кеш (и обновит параметр сеанса) – соответственно пользоваться этим только при очень большой необходимости.
«Для отладки сложных запросов используйте дамп запроса.» Что это такое?
Странно, что нет ни слова про применение окончаний а-ля "Клиент" "КлиентСервер", "ПовтИсп", "ПолныеПрава", "ВызовСервера".., и суффиксов а-ля "Переопределяемый", "Служебный", "События"...
Хотя, лично я, против такой практики - из-за неё в ERP2 больше сотни общих модулей, и очень сложно разобраться к какому же модулю нужно обращаться. Я перешёл к практике 2-3 префиксов на модуль:
В первом располагается вся логика
Во-втором осуществляется переход на сервер из функции первого модуля (если того требует контекст) и обратный возврат вызова в первый модуль (здесь нет никакой логики - только смена контекста)
В-третьем - кеширование - когда нужно - и вызов опять первого модуля
Всё разделение на контексты доступности реализую директивами препроцессора уже внутри первого общего модуля.
Это очень удобно.
Вообще можно было бы обойтись одним первым общим модулем (особенно если бы платофрма 1С Предприятие не была такой ущербной и позволила бы применять аннотации контекста (как в управляемых формах) внутри общих модулей (в т.ч. для смены контекста вызова). Или можно просто сделать два ЕДИНЫХ общих модуля для смены контекста и производить его смену через функцию "вычислить" (все вызываемые методы должны быть функциями - впрочем я всегда так стараюсь делать) - увы - не будет работать на iOS - а ссылок на функции в 1С Предприятие 8 не завезли (и это в процедурном то языке программирования). Хотя можно частично выкрутиться через "ОписаниеОповещения" (увы - только на клиенте - хотя нужно это только для iOS).
Тогда смену контекста можно производить через общие прокси функции, вызывающие нужные функции по строковому пути - на производительности это не сильно сказывается