Transcription
Это слово из трёх букв будоражит умы программистов уже не первый год. Сегодня я расскажу вам свой топ-20 функций БСП библиотеки стандартных подсистем 1С, которые, я считаю, должен знать каждый программист.
[музыка]
Я вас без исключений приветствую. Сегодня я буду исследовать BSP версии 3110 в конфигурации бухгалтерия предприятия. Все материалы из видео вы можете скачать по ссылке в описании. Я подбирал эти функции, исходя из того, что они, во-первых, чаще всего в типовых конфигурациях используются. И, во-вторых, эти функции как раз наиболее часто переписываются разработчиками как велосипеды. То есть они не знают о существовании в этих функциях и часто-часто пишут свой кастомный велосипедный код, который не оптимален, который не протестирован. Поэтому не будьте плохими разработчиками, будьте хорошими разработчиками.
Давайте начнём с полезной функции из библиотеки стандартных подсистем "строка таблиц значений в структуру". Давайте посмотрим основные сценарии её применения. Первый сценарий её использования - это передача таблицы значений или её части с сервера на клиент в виде массива структур, потому что таблица не может быть передана на клиент без преобразования. Она не сериализуется автоматически.
Второй важный случай - это подготовка структуры параметров для вызова стандартных процедур. Например, когда нам нужно создать ключ записи для регистра сведений, процедура потребует именно структуру в качестве параметра. Простая строка таблицы значений здесь не подойдёт. Её нужно сначала преобразовать в структуру. Если мы попытаемся создать ключ записи регистра сведений напрямую из строки таблицы значений во время её обхода, это приведёт к ошибке, которую вы можете увидеть на экране. Поэтому преобразование в структуру в данном случае обязательно. Именно для этого и существует данная функция в библиотеке стандартных подсистем.
Важно также отметить, что структура, полученная из строки таблицы значений, является полностью самостоятельным объектом, и это даёт нам дополнительную гибкость в дальнейшей работе. Мы можем добавлять новые элементы, ключи, удалять существующие элементы, производить любые другие манипуляции со структурой. А со строкой таблицы значений у нас такое не получится. Конечно, мы могли бы создать структуру из строки табличной части вручную, используя объект "новая структура". Но в этом случае нам пришлось бы добавлять каждую колонку отдельной командой. А учитывая, что колонок может быть много, а их названия могут быть непредсказуемыми, неизвестными или изменяться другими разработчиками, значит, использование стандартной функции "строка таблица значений в структуру" является более предпочтительным решением. К тому же эта функция уже протестирована разработчиками платформы, и это гарантирует её надёжность.
Давайте заглянем в исходный код этой функции, написанный разработчиками. Как вы можете видеть на экране, это очень простой и очень компактный код. А именно такой код нам пришлось бы писать каждый раз заново, не будь у нас этой стандартной функции. Согласитесь, гораздо удобнее использовать готовое решение из библиотеки стандартных подсистем. И такое элегантное решение, как на экране, придёт в голову далеко не каждому программисту. Часто начинают писать велосипеды из прямых указаний названий колонок. Старайтесь использовать стандартные процедуры и функции в тех случаях, когда это возможно.
В некоторых случаях, как вот я показал на экране, мы можем захотеть передать несериализуемые данные на клиент. Это у нас не получится. Например, если у нас есть колонка в виде вложенной таблицы значений, то это напрямую не может быть передано на клиент. И если ваша задача передавать данные с сервера на клиент, то нужно будет также рекурсивно создать массив структур. В качестве примера я здесь создаю таблицу значений, добавляю две строки и далее делаю цикл по этой таблице значений и в цикле добавляю в массив структур полученную структуру. Далее я создаю ключ записи для регистра сведений. В этом случае, если у нас есть структура, то всё нормально создаётся. Но если мы попытаемся создать ключ записи из строки таблицы и значений, то у нас ничего не получится. Здесь я также дополняю полученную структуру своими дополнительными данными и вызываю пользовательскую функцию под названием "создать документ". Она у меня просто пустая заглушка. Это в качестве примера. И пытаюсь, соответственно, создать документ. Итак, эмулирую создание документа. То есть вы можете взять строку таблицы значений. Это как пример, для того, чтобы из её данных получать документы в цикле. И вам нужно, например, добавить дату, номер какой-то, идентификатор, которого нет в таблице значений, и далее вы создаёте документ. А если не использовать БСП, то можно собрать данные в структуру с помощью так называемого велосипеда, что я тоже в качестве примера привёл.
Функция номер два называется "только цифры в строке". Эта функция широко используется в типовых конфигурациях, особенно в тех местах, где требуется верификация введённых пользователем данных. Какие основные сценарии применения этой функции могут быть? Например, ввод и проверка ИНН организаций и физических лиц, проверка ОКПО, проверка БИК банков, проверка почтовых индексов, проверка координат, проверка номеров автомобилей, проверка телефонных номеров и так далее. Эта функция помогает нам убедиться, что в введённой пользователем строке содержатся только цифры. Это критически важно для дальнейшей обработки данных, так как это позволяет, во-первых, определить корректность ввода, то, что ввёл пользователь, выбрать нужную ветку алгоритма для обработки данных, то есть в зависимости от того, какой номер был введён или был ли введён он правильно, является ли это строкой или числом, мы, соответственно, идём в соответствующую ветку алгоритма. Вот такой сценарий может быть.
Далее, третий вариант - это своевременно прервать выполнение алгоритма при обнаружении ошибки. То есть, например, у нас эта функция доступна с клиента. Мы должны предварительно верифицировать введённую строку перед тем, как вызвать сервер. Потому что если мы переходим на сервер, то это вызывает дополнительную нагрузку на сервер, чего бы нам очень никогда не хотелось. Поэтому перед тем, как вызывать что-то на сервере с клиента, максимально старайтесь предварительно выполнить все проверки перед тем, как отправить информацию на сервер. Потому что если мы без проверки отправим некорректную строку на сервер, то сервер всё равно не сможет её обработать и вернётся обратно на клиент. То есть будет пустой вызов сервера и лишняя на него нагрузка. Казалось бы, ничего страшного. Ну, отправили мы там какой-то несколько килобайт, несколько, может быть, мегабайт. Ничего страшного, он всё переварит. Но представьте, что если у вас сидит 100-200 пользователей, и они вот постоянно что-то отправляют туда-сюда на сервер и обратно бесполезные данные, соответственно, нам придётся покупать более дорогое железо на сервере, чего бы нам очень не хотелось.
Давайте же заглянем в исходный код этой функции и посмотрим, как она работает. Работает она довольно просто. Код небольшой. Она выполняет проверку входного параметра на тип данных "строка". Функция проверяет, что эта строка идёт дальше. И если параметры не являются строкой, сразу возвращается ложь, так как дальнейшая проверка не имеет смысла. Далее, как работает эта стандартная функция? Она использует элегантное решение на основе стандартной функции "str заменить". И последовательно заменяются все цифры от нуля до девяти на пустую строку. И после этой замены проверяется длина оставшейся строки. Если она больше нуля, значит, в строке были не только цифры, и возвращается ложь. А если длина равна нулю, значит, в строке были только цифры. И возвращается истина. Вот такой простой и эффективный алгоритм позволяет быстро определить, содержатся ли в строке только цифры и в необходимости обработать случаи с пробелами. Это ещё один пример того, как стандартные функции платформы могут быть использованы для создания элегантных решений.
Следующая функция библиотеки стандартных подсистем - это функция "есть реквизит или свойства объекта". Полезна при работе с объектами, в которых структура может быть неизвестна на этапе разработки. Какие основные сценарии для применения? Например, работа с динамическими структурами данных, справочники с изменяемой структурой, которые постоянно изменяются разработчиками, какие-то другие объекты с динамическими наборами свойств, изменение ветки алгоритма в зависимости от наличия реквизита. Например, мы обнаружили реквизит, идём по одной ветке алгоритма. Если этого реквизита в объекте нет, то идём по другой ветке алгоритма. То есть, если в таблице значений нет какой-то колонки, то мы её туда можем добавить. Или если она уже там есть, тогда мы её не добавляем. Также мы можем использовать её при обработке внешних данных, например, при получении данных из веб-сервисов. Или когда мы загружаем Excel-файлы, мы можем проверить полученную структуру.
В чём преимущество стандартной функции? Это, во-первых, безопасность. То есть мы предотвращаем ошибки при обращении к несуществующим свойствам. То есть, если мы обращаемся к какому-то элементу справочника, и мы должны убедиться, что в нём есть этот добавленный реквизит. Ну, к примеру, мы написали обработку для старой версии управления торговлей. Там этого реквизита не было, мы его добавили, а потом мы у другого заказчика или на другой базе данных пытаемся запустить вот обработку. А поскольку этот реквизит там не существует, то обработка будет завершаться с ошибкой. Как вариант безопасности также защищает от сбоев в автоматических процессах. Например, когда у нас идёт автоматическая загрузка прайса в регламентных заданиях или структура прайса изменилась, и тогда регламентное задание может завершаться с ошибкой, и это могут не заметить. Также есть такое понятие, как "graceful degradation", то есть это такой подход к построению систем, при которой система продолжает выполнять свою основную функцию, даже если её отдельные элементы вышли из строя. И здесь мы как раз обеспечиваем такой подход. То есть, если у нас есть такой реквизит, то мы с ним работаем и система полностью, например, какая-то обработка полностью функциональна. А если мы не находим какой-то реквизит, то мы пытаемся работать, например, в его отсутствии.
Также стандартная функция обеспечивает нам высокую производительность, потому что она быстро проверяет наличие реквизита без прямого обращения к данным. То есть нам не нужно делать запрос, чтобы получить все эти данные. Нам не нужно обращаться на сервер. У этой процедуры очень хорошо оптимизированный внутренний алгоритм и эффективно используются ресурсы системы. Ещё важно отметить, вот посмотрите, у меня на экране выведена содержимое этой функции, как она элегантно и просто реализована. И это намного проще и универсальнее, чем традиционные подходы разработчиков, которые часто используют прямые обращения к данным, например, через точку и так далее. А стандартная реализация, как вы видите на экране, обеспечивает очень чистый код и универсальность для любого типа объекта. Здесь не нужно делать какие-то дополнительные проверки. Аа в своей обработке я привёл пример, как пишут код обычно разработчики, если они делают это вручную без использования библиотеки. То есть они обращаются обычно напрямую к метаданным и ищут в реквизитах. Но перед этим, если мы, например, не знаем, какого типа данные, то нам сначала нужно узнать этот тип и так далее. То есть алгоритм становится более витвистым. Кроме того, например, в алгоритме сегодня вам могут передать в качестве проверяемого параметра ссылку на справочник, а завтра там может оказаться структура, и вам это нужно будет учесть в вашем личном алгоритме, в вашем личном велосипеде, который вы напишите. Применяйте стандартную функцию. Она очень хорошо сделана, она очень полезная.
Опять возвращаемся к. Далее идёт функция под названием "свернуть массив". Она пригодится в тех местах, где нужно сгруппировать полученные данные и получить уникальный список, чтобы данные в этом списке не повторялись. Основное назначение функции - это получение уникального списка значений из массива, удаление дублирующихся элементов и оптимизация работы с повторяющимися данными. И если вы будете искать каждый элемент в массиве через стандартные методы поиска, например, "найти", то это занимает много времени. Вы это можете самостоятельно протестировать. Массив не оптимизирован для поиска данных. То есть, если вы будете каждый раз перед добавлением элемента в массив проверять, есть ли там такой элемент уже, то это будет намного дольше, чем добавить все данные подряд, а потом их свернуть по уникальным значениям. И оптимальное решение как раз заключается в этом.
Когда может быть полезна эта функция? Например, при работе с банковскими счетами, когда мы хотим получить список уникальных корреспондентских счетов по всем полученным расчётным счетам. То есть мы собрали все расчётные счета по всем контрагентам и хотим узнать, сколько банков всего у нас там находится. И вот для этого случая можно применить алгоритм, включающий в себя использование "свернуть массив". При формировании запросов к базе данных, когда нужно передать массив ссылок без дублей для того, чтобы избежать излишней нагрузки на сервер. Проблема дублирования в запросах заключается в следующем. Когда мы передаём массив ссылок с дубликатами, СУБД вынуждена обрабатывать одни и те же значения несколько раз, и это создаёт дополнительную нагрузку на сервер. И, соответственно, увеличивается время выполнения запроса и расходуется больше ресурсов и памяти сервера.
Мы также можем сейчас заглянуть под капот, так сказать, этой функции и посмотреть, насколько красиво сделана эта функция в стандартном варианте. Здесь вызывается функция "свернуть массив". И здесь также есть дополнительный вызов "дополнить массив". Давайте посмотрим, что это. Вот буквально 20 строк, которые сворачивают этот массив и оставляют только уникальное значение. Для того, чтобы разработчик написал это самостоятельно, ему придётся долго думать, даже если он опытный разработчик, и в итоге надо будет протестировать. И даже если он потратит на это полчаса, то полчаса - это очень много. Есть готовая функция, которая умеет сворачивать массив и оставлять в нём только уникальное значение.
[музыка]
Следующая функция называется "значение реквизитов объекта". Используется для получения реквизитов с помощью запроса. Это супер удобная вещь, если нужно получить много реквизитов сразу. Также у неё есть разновидность, которая называется "значение реквизита объекта". Если вам нужен один реквизит одного какого-то объекта. В качестве примера я вытаскиваю реквизит "артикул" из базы данных и вид ставки НДС. Если мы будем вызывать через точку, то согласно информации от 1С это приводит к полному чтению всего объекта, то есть в данном случае, например, справочника или документа со всеми табличными частями. А это очень затратная операция для SQL сервера. Возникает логичный вопрос у начинающих программистов. Зачем нужна такая функция? Если мы можем написать, например, запрос или вызвать через точку. А ответ кроется в повседневной практике работы с платформой 1С. И при решении таких задач, как сопровождение типовых конфигураций, разработка отчёта, внесение небольших доработок. И программисты постоянно сталкиваются с необходимостью чтения реквизитов справочников и документов. На практике программисты обычно используют два основных способа получения значений реквизитов. Во-первых, это прямое обращение к реквизиту объекта, например, "номенклатура.артикул". Но по информации от 1С такой подход имеет серьёзный недостаток. Происходит чтение всего объекта номенклатуры по ссылке, всех реквизитов и табличных частей. Если в справочнике много реквизитов, то это создаёт существенную нагрузку на сервер. И такой метод крайне не рекомендуется использовать в реальной разработке.
Далее можно использовать запрос, например, правильный вариант. Вот я вам привёл на экране. Выбираем ссылку с артикулом из справочника номенклатуры. Но у этого способа есть свой недостаток. Код становится громозким и плохо читаемым. Когда модуль обработки наполняется множеством подобных запросов, то это очень усложняет его поддержку и понимание. А неопытные программисты и сталкиваются с необходимостью постоянно писать запросы для извлечения реквизитов. Часто начинают создавать собственные универсальные функции. Это приводит к дополнительным ошибкам и изобретению велосипеда, так как в БСП эта функциональность уже реализована и протестирована годами. Важно отметить, что в БСП также поддерживается мультиязычность. И реквизиты можно называть как на русском, так и на английском языке, если это поддерживается в выбранной конфигурации. И всё это уже учтено в стандартной функции. Запросы формируются оптимальным образом. Единственное ограничение использования этой стандартной функции, оно связано с производительностью при массовом чтении данных. Если требуется извлечь реквизиты для десятков, сотен или тысяч строк, то, конечно, лучше использовать единый ручной запрос вместо вызова этой стандартной функции в цикле.
Пусть иногда и в библиотеке стандартных подсистем есть специальная функция "сообщить пользователю", которая была разработана для удобной связи выводимых сообщений с элементами пользовательского интерфейса. А в стандартном языке 1С, конечно, уже существует два встроенных метода для вызова сообщений. Эта функция "сообщить" - она старая, простая. Она позволяет выводить текст сообщения и устанавливать его статус, но она слишком простая для взаимодействия. И была изобретена функция стандартная языка 1С "сообщение пользователю". Это более сложная функция с множеством параметров. Конечно, у этих стандартных функций есть свои недостатки. Функция "сообщить" слишком простая и не даёт расширенных возможностей. А "сообщение пользователю" слишком громозкое, и её постоянное использование делает код менее читаемым и более загруженным. Это вы можете посмотреть на экране. Здесь очень много параметров, и их неудобно использовать в коде. Код становится слишком грязным. И поэтому в БСП была создана функция "сообщить пользователю", и она предоставляет ряд преимуществ. Во-первых, в одну строку указываются все необходимые параметры для связи с элементами интерфейса, и она даёт возможность настроить открытие определённого элемента по щелчку на сообщение и обеспечивает привязку сообщения к конкретному элементу интерфейса. И, конечно же, делает код более чистым и читаемым. Эта функция, по сути, является удобной надстройкой над стандартными возможностями платформы, и она упрощает работу разработчика и улучшает пользовательский опыт.
Следующая функция называется "установить элемент отбора динамического списка". А часто задача среди программистов 1С - это работа с динамическими списками. Динамический список сейчас применяется практически в каждой конфигурации и чуть ли не на каждой управляемой форме. А в динамических списках всегда возникает задача наложить какой-то отбор. И здесь начинающие программисты начинают изобретать велосипед. Они вбивают в Google, как наложить отбор в динамическом списке, и поисковик выдаёт некий программный код, где вручную создаётся элемент динамического списка и далее настраивается. А на самом деле существует функция библиотеки стандартных подсистем, которая так и называется: "установить элемент отбора динамического списка". На самом деле с динамическим списком не всё так просто, как кажется на первый взгляд, и с его отборами. Во-первых, с помощью функции "установить элемент отбора динамического списка" можно указать в одну строчку кода, где нужно поставить отбор и какую ссылку в качестве отбора. Это гораздо проще того кода, которые пришлось бы описывать вручную. А, во-вторых, помимо компактности кода, есть ещё преимущество в том, что код этой функции уже протестирован многими годами использования. А при работе с отборами в динамических списках существует множество нюансов, которые новичку учесть очень сложно. Динамический список - это достаточно сложный объект, и профессиональное использование библиотечных функций поможет избежать многих ошибок. А одна из подобных проблем, которые будут ждать новичка - это множественная установка одинакового отбора. То есть перед тем, как установить отбор по какому-то полю, нужно сначала проверить, а есть ли он уже или нет, можно ли его использовать, либо его надо удалить. А потому что иначе у нас может получиться пересечение отборов и в итоге возникнет ошибка при наложении этого отбора. А либо отбор становится одновременно по нескольким полям с несколькими значениями. И это может тоже пересечься. А в итоге динамический список получается пустой, и это будет очень неожиданно для начинающего программиста. Поэтому лучше всего использовать функцию из библиотеки. Там все эти проблемы уже решены. И если заглянуть, так сказать, под капот этой функции, как она устроена, вы обнаружите, что там очень много кода. И этот код таков, что новичку это просто не под силу будет написать и учесть все необходимые нюансы.
[музыка]
Следующая функция называется "разложить полное имя файла". Она часто выручает, когда нужно работать с файлами в обработках и в отчётах. Например, делаешь загрузку прайс-листов, пользователь выбирает файл, и тебе надо понять, что это: CSV или XML или что-то ещё, чтобы правильно его обработать. И новички часто думают: "Ну а что тут сложного? Найти последний слэш, взять, что после него, и это и будет именем файла. А что после точки? Это будет расширение". Но тут не всё так просто. А, во-первых, слэши могут быть разные: и обычные, и обратные. Ещё бывают смешанные пути. А, во-вторых, с расширением не всё так очевидно. Файл может называться "отчёт.1924.финальный.xls" и так далее. И где тут понять, где тут настоящее расширение? А если точка будет находиться в имени папки? А если файл вообще без расширения? А самое классное - это то, что в стандартной библиотеке это реализовано просто гениально. Там буквально семь строк кода, которые красиво и грамотно разбирают имя файла на составляющие. Я когда первый раз заглянул в этот код, то был в шоке, насколько всё элегантно написано. И причём эта функция уже миллион раз протестирована и все возможные случаи учтены. А иногда даже самые опытные программисты умудряются писать свои велосипеды, какие-то страшные многострочные функции с кучами условий, а потом мучаются с багами, когда выпадает какой-нибудь нестандартный путь. Так что мой совет: всегда используйте встроенную функцию и не изобретайте велосипед и загляните вот в этот код. Сами увидите, как там всё сделано правильно и просто. А чтобы придумать такое простое и одновременно универсальное решение, надо было всё-таки очень долго думать. А зачем думать, если всё уже придумано за нас?
[музыка]
Следующая функция называется "добавить конечный разделитель пути". Полезная функция. Вы знаете, что как бывает, работаешь с путями, и вдруг оказывается, что в конце пути то ли есть слэш, то ли его нет. А это важно, когда дальше будешь склеивать путь с именем файла. А вот представьте, что у вас есть путь "C:\temp" и имя файла "test.png". И если просто склеить через плюс, то получится имя файла склеенное с именем каталогом, и всё, программа будет сломана. А если функция из БСП будет использоваться, то она как раз проверит, есть в конце пути разделитель или нет. А если его нет, она добавит. А если он есть, тогда она вернёт как всё без изменений. А причём достаточно умно добавляет, что для Windows это будет обратный слэш, а для Linux обычный. Она не добавляет лишнее, если он уже есть. Это, казалось бы, мелочь, но проблем из-за этого может быть достаточно. И в том числе это было на моей практике. Приходит пользователь, говорит, что вот не работает, и выясняется, что программист не учёл склеивание файла и имени каталога. Особенно бывает проблема, когда пишешь кроссплатформенный код для Линукса и Windows одновременно или работаешь с файлами на сетевых дисках. Я видел, как люди делают это вручную, проверяют последний символ, потом добавляют. И бывает, что часто обязательно где-то ошибаются. То ли забудут про разные операционки, то ли добавляют лишние разделители. И у меня тоже такое было. А тут есть одна готовая функция, которая всё сделает правильно. Кстати, если заглянуть в реализацию, там всё тоже очень грамотно сделано, без лишнего кода. Вы можете вот посмотреть на экране. Настоятельно рекомендую для использования.
[музыка]
Следующая функция называется "разложить строку в массив подстрок". Часто используется разработчиками. Её применяют уже много-много лет, и она используется в типовых конфигурациях. Её применяет уже много лет настолько широко, что 1С даже позже в своих более поздних релизах движка выпустила обновление языка, в котором представила встроенную функцию под названием "str разделить". А "str разделить" почти является аналогом старой функции из БСП, за исключением нескольких важных нюансов. Например, один из ключевых нюансов заключается в том, что "strр разделить" стандартное воспринимает переданный разделитель как набор отдельных символов разделителей, а функция из BSP использует многострочный разделитель как единый разделитель. И в этом заключается большая разница их применения. А давайте рассмотрим, для чего можно использовать эту функцию из библиотеки стандартных подсистем. Например, она отлично подходит для разбора различных файлов или составных строк, которые были получены от пользователя или из внешнего сервиса. Также она полезна при обработке данных из файлов Excel. Например, у нас есть некий набор строк или подстрок, например, фамилия, имя, отчество в одной строке. И мы хотим выделить отдельные части этой строки, чтобы потом работать с ними по отдельности. Эта функция идеально подходит для такой задачи. Ещё один распространённый пример использования, когда у нас есть метаданные типа "справочник.номенклатура.реквизиты.артикул". Такую строку удобно разложить с помощью этой функции на составные части, а потом использовать, например, для формирования какого-то универсального запроса по данным или другого алгоритма. И эту функцию тоже постигла участь, что часто разработчики пытаются вручную разбирать строки. Например, фамилия, имя, отчество. Несмотря на то, что функция стандартных подсистем уже существует давно, тем не менее же фамилия, имя, отчество разработчики пытаются разобрать вручную, потом вручную всё это проверять. Можно просто воспользоваться одной строчкой кода. И если вы заглянете в реализацию этой функции в библиотеке, то увидите, что она достаточно сложная. Там учитывается много разных нюансов. И чтобы написать эту функцию самому и к тому же избежать ошибок, это потребует очень много времени. Поэтому пользуйтесь просто одной строкой этой функции уже готовой. Она всё сделает за вас.
[музыка]
Следующая функция называется "текущий пользователь". Эта функция также происходит из библиотеки стандартных подсистем и предназначена для определения, соответственно, текущего пользователя, то есть того, кто вошёл в систему. Основное назначение этой функции - сопоставление пользователя системы с элементом справочника "пользователи". Как это работает? Функция берёт информацию о системном пользователе, того, которого мы видим в списке системных пользователей в конфигураторе, и сопоставляет его со справочником пользователей, который уже существует внутри конфигурации, внутри самой платформы 1С:Предприятие. Эта функция выполняет важное сопоставление между двумя сущностями пользователей и возвращает в качестве результата ссылку на элемент справочника "пользователя". Это позволяет в дальнейшем использовать полученную ссылку для работы с данными конкретного пользователя в различных бизнес-процессах и сценариях.
Давайте рассмотрим, в каких сценариях. Во-первых, можно устанавливать реквизиты документа. Например, "ответственный", вы часто это видели, или "автор", или "кто изменил". То есть сохранение ссылки на текущего пользователя, который выполнил какое-то действие. Далее можно ещё записывать информацию в истории, в плане обмена, в реквизиты документов.
справочников, везде, где необходимо зафиксировать, какой именно пользователь что-то делал или должен сделать. Если мы попытаемся вручную велосипед напишем для сопоставления системного пользователя с элементом справочника пользователей, то столкнёмся с рядом трудностей. Например, если мы реализуем сопоставление по наименованию, то при изменении наименования связь между системным пользователем и справочником сразу потеряется. Поэтому в библиотеке стандартных подсистем используется связь по некому уникальному идентификатору. Кроме того, в реализации библиотеки этот пользователь записывается в параметре сеанса, а функция текущий пользователь уже извлекает его оттуда, и это делает процесс максимально оптимизированным. Также дополнительная польза этой функции в том, что когда мы получили уже текущего пользователя, это является ссылкой на справочник. А в справочнике мы можем получать дополнительные какие-то реквизиты, свойства, права, настройки, то есть получать в зависимости от того, какой текущий пользователь, смотреть, какими свойствами он обладает, для чего он потом использует эти свойства. Например, если у нас есть реквизит типа булева под названием недействителен, то мы можем это использовать потом в алгоритмах и, например, запрещать вход пользователя в систему или сообщать в каких-то алгоритмах, что таким пользователям работать запрещено.
Следующая функция называется роли доступны. Это полезный инструмент, когда нужно проверить, есть ли у пользователя доступ к определённой роли или нескольким ролям. Особенно важно в системах с ограниченным доступом. Проверка роли помогает в сценариях, когда действия пользователя должны строго контролироваться. То есть, прежде чем разрешить выполнение операции, мы проверяем, есть ли у пользователя права на её выполнение. А если прав нет, то система просто заблокирует это действие, не выдавая ошибки. А если мы просто попытаемся сделать это действие, то будет ошибка.
А функция полезна для работы также с интерфейсами. Например, у пользователя есть доступ к чтению данных из справочника физических лиц. Функция позволяет сделать доступными соответствующие элементы интерфейса. То есть, если есть тролль, кнопка появится на экране. Если нет роль, кнопка не появится. Это предотвращает ситуации, когда эти кнопки, флажки становятся доступными всем, а пользователи без нужных прав попытаются ими воспользоваться. То есть, у вас есть кнопка, вы пытаетесь на неё нажать, вызывает системную ошибку, что недостаточно прав. И чтобы такого не было, лучше предварительно проверить, а есть ли вообще роль на выполнение этой операции. И это хорошая практика для интерфейсов: просто сразу блокировать те элементы интерфейса, которым у пользователя нет прав. А так система будет работать стабильнее, и пользователи не сталкиваются с неожиданными ошибками.
В типовых конфигурациях эта функция используется очень часто. Например, когда надо проверить, доступна ли печатная форма для редактирования. И если у пользователя есть соответствующая роль, то он может включить флажок редактирования. А насчёт удобства, то функция из БСП выигрывает по сравнению с стандартной. Роль доступна, которая называется, потому что она позволяет проверять сразу несколько ролей, а стандартная только одну, и это экономит время и ресурсы в разработке. А ещё у этой функции есть интересная особенность, полезная особенность. И если у пользователя есть роль с полными правами или роль администратора, функция всегда возвращает истину. А это значит, что такой пользователь имеет доступ ко всем возможным действиям в системе, и проверка остальных ролей уже, соответственно, не нужна. Это тоже позволяет ускорить обработку и сделает алгоритм более эффективным. [музыка]
Следующая функция называется номер на печать. Удобная штука, если нужно работать с номерами документов или с какими-то строками, которые имеют префикс и лидирующие нули. В типовых конфигурациях 1С часто бывает, что номера документов содержат префиксы, лидирующие нули, когда, например, нужно номер передать во внешнюю систему, например, выгрузить в Excel или удалить лишние символы для какой-то другой цели. А эта функция как раз убирает все эти лишние элементы, и номер остаётся в чистом виде без нулей и префиксов.
А есть особенность, что если номера документов формируются по стандартному шаблону, то есть префиксы сначала, потом лидирующие нули, то функция работает отлично и быстро. Но если номер почему-то сформирован нестандартно, например, содержит нецифровые символы, то функция не отработает, и префиксы и нули останутся на месте, то тогда уже придётся писать свою логику для обработки. И получается, что если номер не соответствует ожиданиям, есть какие-то символы, не тот формат, не та длина префикса, не то количество префиксов и так далее, то функция не сработает.
Также странная особенность у этой функции есть, что она называется номер на печать, но по сути она делает больше, чем просто номер на печать. Она очищает номер от лишних символов и оставляет только какую-то, ну, смысловую часть этого номера. Также, конечно, любой программист может написать такую функцию самостоятельно, но в стандартной библиотеке уже есть готовое решение. А если у тебя стандартная ситуация с номерами, с префиксами и с нулями, то можно лучше сразу использовать эту функцию. Она сэкономит много времени и сил. А если ситуация нестандартная и, ну, и если нужно использовать какое-то большие массивы данных, то тогда, конечно, придётся писать самому функцию обработки. [музыка]
Следующая функция называется скачать файл на сервере. Это полезный инструмент для работы с файлами, которые нужно скачать из интернета. Несмотря на то, что кажется, что можно обойтись и другими методами, например, создать соединение и использовать функцию скопировать файл, например. А на практике это может быть не так просто, особенно когда сервер в интернете имеет ограничения или специфические настройки.
И когда ты пытаешься скачать файл из интернета, то на первый взгляд может показаться, что всё, что нужно, это прямой запрос по ссылке. Ну, в 1С бывают ситуации, когда интернет-сервер может не отдавать файл напрямую, а перенаправляет его на другой адрес. А в этом случае стандартная функция запрос, например, HTTP запрос не справится, потому что она не понимает перенаправлений и будет пытаться скачать файл с того адреса, который указан в исходной ссылке, а не с того, на который фактически был перенаправлен. В случае перенаправлений, когда интернет-сервер перенаправляет запрос, стандартная функция 1С не обрабатывает это перенаправление.
Некоторые сайты могут требовать дополнительные параметры, такие как куки, токены для скачивания файлов. А эти параметры могут быть динамическими, и нужно их отправлять запросом, чтобы получить файл. А стандартные функции скопировать файл в 1С этого не делают, и это очень усложняет нашу задачу. А в некоторых случаях в адресе, по которому нужно скачать файл, не содержится самое файла, а содержится некий параметр. И этот интернет-сервер использует его для определения, какой именно файл нужно отдать. А тут стандартные функции тоже не помогут, потому что они не обрабатывают такие ситуации и не могут автоматически извлечь имя файла.
А вот функция скачать файл на сервере из стандартной библиотеки сделает всё за тебя. Она понимает, как обработать перенаправление, как обработать куки, как работать с параметрами в адресе. И также корректно извлекает имя файла из полученного адреса, если оно не указано напрямую. А вместо того, чтобы всё вручную разбирать, ты можешь просто вызвать эту функцию, и она сама уже заботится о том, чтобы файл был скачан по указанному адресу. Да, можно написать свою логику для скачивания файла, обрабатывать все эти перенаправления, куки, параметры. Но зачем изобретать колесо, если в стандартной библиотеке уже есть готовое решение? И использование этой встроенной функции из библиотеки стандартных подсистем, оно намного упрощает код и снижает вероятность ошибок. Поэтому в типичных ситуациях используй эту готовую функцию. Завтра нас всех уволят мигом.
Следующая функция называется сведения о внешней обработке. Основа для подключения любых внешних отчётов и обработок в типовых конфигурациях. Суть её проста: функция выдаёт нам готовый шаблон со всеми обязательными полями. Это название, версия, точка входа, прочие системные параметры. Особенно полезно для тех, кто работает с типовыми конфигурациями. И если вы первый раз создаёте внешнюю обработку или внешний отчёт, то обязательно используйте эту функцию.
Я привёл её, конечно, в качестве примера. То есть она сама по себе ни для чего не используется, и она применяется только в тех случаях, когда вы пишете внешнюю обработку или внешний отчёт. Ну, я здесь специально на этом акцентировал внимание. Вы будете её часто использовать, потому что все мы пишем внешние отчёты и обработки. И эта функция напомнит вам о том, что в БСП есть специальный механизм для подключения внешних отчётов и обработок. И начинается он как раз с этой функции, которая называется сведения о внешней обработке. [музыка]
Следующая функция называется провести документы. В практике разработки на 1С задача перепроведения документов постоянно возникает. Есть список документов, и нужно провести каждый из них последовательно. Многие программисты просто берут и пишут цикл, вызывают провести для каждого документа. Однако более опытные разработчики добавляют в этот процесс обработку исключений, предварительной проверки, потому что если хотя бы один документ не проведётся, нужно не останавливать весь процесс, а зафиксировать ошибку и просто продолжить работу.
Ключевые моменты, которые нужно учитывать при проведении, их всего три. Первое - это проверка заполнения полей. Если не заполнены обязательные поля, то документ не проведётся. Второе - это определение режима проведения, оперативный или неоперативный. Это зависит от даты документа и относительно текущей даты сеанса. И третье - это фиксация ошибок. Они не должны мешать дальнейшей обработке документов. Именно это и делает функция провести документы из библиотеки. Проверит поля, определит режим проведения и попытается провести документ.
Кажется, что эти 20 строк мы можем написать самостоятельно, но на практике часто забываются важные нюансы: проверка заполнения, правильный режим проведения, сбор и вывод ошибок. И особенно когда это всё нужно уложиться в сжатые сроки, когда у программиста есть какой-то дедлайн. Как правило, подобной задачи, это довольно простая задача, поручают новичкам, которые о всех этих деталях вообще не знают. Они проводят документы прямо в лоб, без проверок, а когда возникают ошибки, они не понимают, в чём причина, и, может, даже не видят эту ошибку. Поэтому, если вы начинающий разработчик, всегда помните: уже есть готовая функция перепроведения.
У этой функции есть особенность. Если документ успешно проведён, она не возвращает никаких сообщений. Информацию можно получить только в случае ошибок. А в моём примере я вызываю перепроведение определённого документа. А если есть ошибки, в цикле вывожу их на экран с помощью сообщить. А вывод: не изобретайте велосипед, используйте стандартную логику, пользуйтесь готовой [музыка] функцией.
Следующая функция называется строка в дату. Суперполезная функция, когда вам нужно из строки преобразовать дату. Проблема часто в том, что у нас есть дата, например, из внешнего сервиса, Excel-файла или из какого-то импортированного документа, но эта дата представлена в виде строки, а нам нужно её превратить в нормальный объект типа дата. Просто так сделать это не всегда выходит, и можно нарваться на ошибку. И тут приходит на помощь функция библиотеки стандартных подсистем строка в дату. Она принимает строку с датой в одном из трёх форматов и делает её типа дата. И всё без заморочек, без лишних попыток и исключений. Просто работает.
Зачем вообще её использовать? Стандартные способы преобразования часто не срабатывают, если формат даты не тот, который ожидает система. Проблемы с годом, с месяцем, днём и всякие разные прочее. А вместо того, чтобы самому писать парсинг строки и вычитывать из неё год, месяц и день, просто вызываем эту функцию и забываем о проблемах. А раз значит нам не надо мучиться с проверками и дополнительными доработками. С функцией строка в дату всё гораздо проще. Она внутри проверяет строку на три стандартных формата даты и дальше уже сама решает, что с этим делать. Выполняет все нужные проверки этой строки. И не надо вытаскивать компоненты из этой строки. И не нужно быть экспертом в парсинге строк. Она всё сделает за тебя.
И да, даже если ты опытный программист, не трать время на создание собственной функции. Эта функция из библиотеки уже давно написана, давно протестирована, работает быстро и без ошибок. Единственное ограничение: она понимает всего три формата даты, но тем не менее обратите внимание, насколько много кода было написано разработчиками, и сможешь ли ты учесть это всё в своей собственной доработке. Это есть большое сомнение. Так что попробуй воспользоваться стандартной функцией. Хотя бы посмотри, как это всё устроено. Если у тебя какой-то уникальный формат даты, в коде ошибки, мы все идиоты.
Следующая функция называется сведения об организации. Часто при написании кода на 1С нам нужно вывести информацию о какой-то организации, чтобы отобразить её на форме или передать во внешний сервис. Например, нам надо собрать основные данные организации, в которой ведётся учёт. Для чего это может понадобиться? Например, название организации, полное наименование, КПП, регистрация в налоговом органе, учётная политика, адрес, контактные телефоны и так далее. Эти данные могут понадобиться для разных целей, например, для формирования печатных форм или для интеграции с другими сервисами.
Часто мы получаем эти данные напрямую через точку, например, для извлечения наименования или ИНН. На первый взгляд это простой способ, но он не очень эффективен. Когда мы обращаемся к этим данным, инициализируется полностью объекты, а это создаёт дополнительную нагрузку на сервер. А если вы несколько раз вызываете через точку, то каждый раз будет вызываться полное чтение объекта. А если нам нужно вывести много информации на форму, то это будет слишком сильно нагружать систему.
Есть также другая проблема. Некоторые данные вообще не хранятся в самом справочнике организации, и их нужно будет вытаскивать из других регистров, а значит, надо будет писать сложные громоздкие запросы. И это вообще не круто. А, конечно, если в будущем изменится структура хранения в типовой конфигурации, например, контактной информации такое уже было. Она сначала хранилась в регистрах, а потом переехала в дополнительные реквизиты, но какая-то новая конфигурация опять может переместить эту контактную информацию в регистр, например, в новых версиях. Никто от этого не застрахован. И если вдруг она начнёт храниться в другом месте, разработчики БСП её это всё перепишут, и нам ничего не придётся переписывать. Наша функция, которую мы используем, функция из библиотеки стандартных подсистем, продолжит работать, как и работала раньше, без ошибок. То есть нам выгоднее использовать функцию из библиотеки вместо того, чтобы писать её самому.
Как дополнение, у вас получается чистый код, вы меньше нагружаете серверы, нет зависимости от структуры и улучшается производительность. При формировании отчётов, печатных форм, например, вам нужно вывести данные об организации. Вы можете собрать все нужные данные одной строкой без лишних строк кода. Интеграция с внешними сервисами. Также иногда нужно передать данные о реквизитах организации во внешний сервис, при выгрузках, при HTTP обменах и каких-то других вариантах обменов. Это всё упрощает процесс. Ищем решение. В отчайни.
Следующая функция называется предопределённый элемент. Эта штука существует уже давно, и многие до сих пор не понимают, зачем она вообще нужна. Кажется, что можно обойтись стандартной функцией предопределённое значение, которое уже есть в языке 1С, и всё будет о'кей. Ну, на самом деле, у функции из библиотеки стандартных подсистем есть свои особенности, которые делают её полезной в определённых ситуациях. Откуда вообще появилась эта, по сути, обёртка к стандартной функции из языка? Давайте разберёмся, что не так с ней.
А, во-первых, кэширование результатов в языке 1С. Стандартная функция языка 1С кэширует свой результат после первого вызова, и этот результат остаётся прежним, пока не изменится конфигурация или версия платформы. Это может быть проблемой, если, например, через инструмент разработчика вы изменяете имя какого-то предопределённого элемента. В этом случае стандартная функция будет возвращать старое значение, даже если вы что-то поменяли. А вот функция из библиотеки всегда работает с актуальными данными, и таких проблем не возникает.
А второй смысл использования - это обработка исключений. Например, когда в базе не созданы нужные предопределённые элементы, стандартная функция языка запроса может выбросить исключение, а в отличие от неё, функция из библиотеки вернёт неопределено и не будет ломать процесс. Это гораздо удобнее.
В-третьих, есть проблема с разными версиями 1С. В некоторых версиях 1С предопределённые элементы могут отсутствовать в информационной базе, даже если они есть в метаданных. А в этом случае нужно вызывать специальную функцию для их создания. И вот для таких случаев ситуации была создана эта обёртка. Она проверяет условия и выкидывает необходимое исключение и правильно работает с именами данных, в отличие от функции языка 1С.
Если вы посмотрите на типовые конфигурации, то заметите, что везде используется не стандартная функция языка 1С, а именно функция из БСП, потому что она гораздо надёжнее и позволяет избежать множества ошибок. И не пытайтесь использовать стандартную функцию языка для работы с предопределёнными элементами. Если вы работаете с типовыми конфигурациями, конечно, если у вас какая-то своя конфигурация со своими особенностями, тут уже вы сами решайте. Ну, в общем случае, лучше всегда обращаться к функции из БСП. Так код ваш будет работать безопаснее. [музыка]
Следующая функция называется описание типа число, описание типа дата и описание типа строка. Я их объединил в один пункт. В 1С есть разные типы данных: строки, даты, числа и прочее. Например, когда добавляем колонку в таблицу значений, важно указать, какого типа будет эта колонка. Если добавляем колонку для сумм, то надо точно указать, что это число, потому что, например, потом захочется посчитать сумму итогов по этой колонке, и это должно быть числового типа. Часто бывает, что нужно прямо указать тип данных, чтобы всё корректно работало. И это важный момент, особенно если речь идёт о более сложных операциях. И вот одна из таких фишек в 1С - это описание типов данных.
Эти функции содержатся в библиотеке стандартных подсистем и позволяют указать тип данных для различных значений. Я рассмотрел три таких функции: для чисел, дат и строк. Эти функции просто возвращают нужный тип данных в зависимости от того, что нам нужно. А разработчики стандартных подсистем в 1Слифункции для удобства, чтобы код был компактным и универсальным. Наверное, также для того, чтобы всё это выглядело как в объектно-ориентированном программировании, где с типами данных можно гибко работать.
Ну, кстати, если будете применять такую штуку, то это покажет вашу дополнительную экспертность, особенно если спросят на собеседовании, потому что вместо этих функций БСП мы можем просто использовать такую довольно простую конструкцию. Но разработчики БСП пошли путём универсализации, путём имитации объектной ориентированности. Ну, значит, будем использовать функции из БСП. Кроме того, это всё действительно показывает вашу экспертность. Вы знаете функции БСП, значит, вы крутой специалист. Пользуйтесь БСП, не стесняйтесь. Это даст вам определённую пользу, это даст вам много пользы, и это покажет вас как эксперта в 1С. А на этом всё. Всем спасибо, кто досмотрел. Пока-пока. До новых встреч.
В офисе тихо, мониторы светят.
Кофе остыл, никто и не ответит.
Клавиатуры стучат, как пулемёты.
В коде ошибки, мы все идиоты.
Стек переполнен, память течёт.
Дибагер плачет. Выхода нет.
Гуглим ошибки, ищем решение.
В отчаянии просим благословение.
Этот код писали малолетние,
но он работает, хоть и криво.
Этот год писали малолетние.
Иначе завтра нас всех уволят. [музыка] Гам.
Компилируем, тестируем.
Снова находим баги, вздыхаем сурово.
Пачим дыры, латаем пробелы.
Лишь бы заказчик был доволен и целым.
Ночь наступает, силы на исходе.
В глазах мелькают стройки в коде.
Мечтаем о сне, о заслуженном отдыхе.
Но завтра опять возвращаемся к подвигу.
Этот код писали малолетние,
но он работает, хоть и криво.
Этот код писали малолетние.
Иначе завтра нас всех уволят мигом. [музыка] Зато мы крутые, мы повели.