Вернуть структуру из функции 1с
Войдите как ученик, чтобы получить доступ к материалам школы
Внутренний язык программирования 1С 8.3 для начинающих программистов: функции и процедуры в 1С часть 1
Автор уроков и преподаватель школы: Владимир Милькин
Сегодня мы приступаем к изучению того, без чего не может обойтись ни одна более менее серьезная программа - функций и процедур.
Функции и процедуры в языке 1С 8.3
Давайте я подведу вас к необходимости функций, заодно вы поймёте что это такое и почему они столь полезны для программистов.
Пусть нам требуется написать программу, которая вычисляет произведение суммы и разности двух введенных чисел. Выглядеть она будет так:
В данном случае формула вычисления результата достаточно проста, но она могла бы быть гораздо сложнее. А что если нам нужно вычислять её не один раз, а несколько? Причем в разных местах программы.
Неужели нам снова и снова придётся писать код для её вычисления:
Это никуда не годится. Нам придётся повторять один и тот же код, что приведёт к раздутости программы. И кроме того, переписывая его очередной раз мы можем допустить ошибку по невнимательности.
Вот бы придумать такое имя, которое будет связано с этой формулой и при обращении к нему мы будем обращаться ко всей этой формуле целиком. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Пусть этим именем будет ПроизведениеСуммыИРазности.
Получается теперь мы можем написать:
И всё? Нет, конечно! Ведь непонятно произведение суммы и разности каких именно чисел нужно считать. Гораздо лучше будет передать эти числа нашему имени в качестве параметров, как мы обычно делаем при вызове команды:
Это, так называемый, вызов функции. Он выглядит точно также как и вызов многих других команд компьютера, которые мы уже неоднократно делали. Только это наша собственная команда, работу которой определяем мы, а не компьютер.
Давайте, наконец, определим нашу функцию, чтобы компьютер, встретив её вызов, не растерялся, а выполнил то, что мы хотим:
Что включает в себя определение этой функции?
Прежде всего ключевое слово Функция следом за которым идёт имя, которое мы придумали сами.
Затем следуют имена параметров, заключенные в круглые скобки. Параметры - это данные, которые мы передадим в нашу функцию при её вызове. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Она с ними что-то сделает и возвратит результат. Каждый параметр имеет своё имя, которое мы также придумываем сами. Это имя можно использовать только внутри функции.
Дальше идёт тело. Это команды компьютеру, которые будут выполняться в тот момент, когда мы сделаем вызов нашей функции. Тело заканчивается ключевым словом КонецФункции.
Внутри функции могут выполняться абсолютно любые знакомые нам команды: условные операторы, циклы и прочее. Но хотя бы один раз внутри каждой функции должна присутствовать команда:
Где вместо Результат может быть любое выражение, которое вернётся из функции в качестве её результата.
Мы можем вызывать функцию столько раз в программе сколько нам потребуется.
Процедуры это те же самые функции, но они не возвращают результат и объявляются при помощи других ключевых слов: Процедура и КонецПроцедуры.
Но функции и процедуры не следует писать лишь бы где! Для определения наших функций мы будем использовать новый модуль. Чтобы его добавить следуйте инструкциям ниже.
1. Раскройте список "Общие" в дереве конфигурации.
2. Найдите в нём пункт "Общие модули" и нажмите на нём правой кнопкой мыши. Выберите "Добавить".
3. Добавился модуль. В правой части окна конфигуратора задайте его имя и свойства, как показано ниже.
Внимание! Пожалуйста, ещё раз убедитесь, что вы поставили галки (Клиент, Сервер, Внешнее соединение) также, как на рисунке выше.
4. Перейдите в этот модуль. Всё! Здесь можно писать наши функции и процедуры. Напишите процедуру с именем Привет, без параметров, после вызова которой компьютер просто здоровается с нами.
Обратите внимание на ключевое слово Экспорт, которое идёт следом за круглыми скобками. Его наличие обязательно, так как мы определяем функцию в одном модуле (Уроки), а использовать будем совсем в другом (модуль управляемого приложения).
5. Теперь вернитесь в модуль управляемого приложения.
6. И сделайте вызов нашей процедуры. Так как она находится в другом модуле к её имени добавляется "Уроки.".
Поделитесь, какими способами вы пользуетесь при необходимости возврата функцией нескольких значений. И почему.
Зависит от.
Если надо возвращать корректность работы (что функция отработала корректно), то на мой взгляд удобнее возврат Истина/ложь, а параметры в структуре параметров.
Если корректность не имеет смысла - то можно параметрами, можно структурой.
Опять же вопрос - как потом будут использоваться значения. Может как раз структурой для дальнейшего использования удобнее
(6) а какая разница как будут использоваться значения?
задача - функция должна вернуть больше одного значения, которые будут использоваться
(6) Вообще, считаю, идеологически правильнее не изменять формальные параметры функцией. Функция в математическом смысле однонаправлена. И у неё четко разделены вход и выход.
А если надо менять параметры внутри - надо создавать процедуру.
(8) > Вообще, считаю, идеологически правильнее не изменять формальные параметры функцией. Функция в математическом смысле однонаправлена. И у неё четко разделены вход и выход.
Простой пример: код модуля стал очень сложным, хочется раскидать разные части по отдельным функциям.
Вырезаешь куски в отдельные функции, запускаешь проверку синтаксиса смотришь каких переменных не хваттае и тупо кидаешь их в параметры.
(9) Всё так, но вместо функций тут правильнее юзать процедуры. Идеологическая мешанина процедур и функций - тяжкое наследия языка Си)
(7) Ну вот пример - функция должна вернуть несколько значений, которые потом будут использовать как фильтрующие параметры. Можно вернуть список значений, а можно передать менеджер и сделать временную таблицу
Возврат какого-нибудь списка значений тоже не ахти вариант. Сложней в разборе результата функции. Нет подсказки по возвращаемому значению. Легко перепутать "имена" возвращаемых значений. Было бы понятие типа "структуры" - вопросов бы не возникало.
(19) И что, через полгодика вы вспомните, что функция возвращает в [0]? А тем более, если кто-то другой читать код будет. Варианты типа [0] крайне не рекомендуются во всех приличных местах/языках. Варианты типа ["НомерСтелажа"] тоже, слишком велика вероятность опечатки.
(22) Где написано? В коде вы видите что-то типа:
Ну и как этот код читать? За такое в приличных местах уволить нафиг могут.
(21) Список значений с представлениями позволяет обращаться по имени представления. По сути имитация структуры, которой в семерке нет.
(25) (26) Ага-ага. А когда-нибудь потом, через полгодика, вы узнаете, что в каком-то нечасто выполняющемся куске кода вместо "Количество" вы написали "Клоичество". И хорошо еще если эта ошибка будет быстро замечена, а не приведёт к постоянным косякам за большой период.
По моему, функции, изменяющие свои параметры, это плохо, но возврат списка или структуры - еще хуже.
Если бы в языке был соответствующий тип вроде сишного union - тогда метод возврата структуры был бы хорош.
По частоте использования:
1. Структура, например, если нужно получить что-то связанное с объектом (периодические значения), но получать сам объект не имеет смысла.
2. Функция с параметром, определяющим значение чего будет возвращено.
3. Несколько функций.
(28) Исключение в данном случае благо. Может привести к неверной работе алгоритма, без ошибок времени выплонения.
winapi стаил. Функция возвращает истина/ложь (удачно/не удачно). А в параметры кладем значения возврата. В 1с аналог свойство() для структуры.
(28) Структура плоха тем что:
1. Нельзя использовать автодополнение, выше вероятность опечатки
2. Что бы при чтении кода понять, какие параметры могут возвращаться, приходится переходить к определению функции и читать комментарии к ней. Если они еще есть.
3. На опечатки нельзя проверить формально, надеемся на то, что упомянутое вами исключение выскочит при тестировании у разработчика, а не повалит у пользователей в том куске, который разработчик недостаточно протестировал.
3.1. А бывают еще любители избыточного использование Попытка Исключение. Получается вообще взрывоопасная смесь.
4. При рефакторинге могут возникнуть большие проблемы по переделке кучи мест в коде. Не решаемые полуинтеллектуальным поиском с заменой и прочими подобными инструментами.
. можно еще продолжать про недостатки, но юзверя звонят.
Если нужно вернуть все перестановки какого -либо множества, то лучше сделать так, чтобы следующая перестановка возвращалась на основании предыдущей без изменения каких либо параметров.
Если нужно вернуть линейный размеры объект - тогда лучше структура (а еще лучше - сам объект)
А если нужно вернуть сто случайных значений от 0 до 1, то лучше всего возвращать массив.
Т.е. что лучше зависит от контекста вопроса больше, чем от самого вопроса.
Если функции надо вернуть несколько РАЗНЫХ значений, не объединенных семантически в какое-то целое, значит у тебя косяк в архитектуре и это две функции, а не одна.
А, если эти значения - это атрибуты какого-то одного объекта, то возвращай структуру да и всё.
(38)
> 1. Нельзя использовать автодополнение, выше вероятность опечатки
Автодополнение в 1с много где нет? это вопрос тестирования
> 2. Что бы при чтении кода понять, какие параметры могут возвращаться, приходится переходить к определению функции и читать комментарии к ней. Если они еще есть.
Для этого можно в начале функции инициировать структуру, которая нужно вернуть независимо от успешности функции
> 3. На опечатки нельзя проверить формально, надеемся на то, что упомянутое вами исключение выскочит при тестировании у разработчика, а не повалит у пользователей в том куске, который разработчик недостаточно протестировал.
Это совсем другой вопрос - вопрос тестирования.
> 3.1. А бывают еще любители избыточного использование Попытка Исключение. Получается вообще взрывоопасная смесь.
> 4. При рефакторинге могут возникнуть большие проблемы по переделке кучи мест в коде. Не решаемые полуинтеллектуальным поиском с заменой и прочими подобными инструментами.
Например какие проблемы?
(44) пример такой:
функция возвращает ссылку на объект
если вернуть ссылку не получилось, то также нужно вернуть текст ошибки
(47) При данном примере оптимальнее всего возвращать сылку отдельным параметром, а ошибку - результатом функции. (если ошибка пустая - значит параметр содержит ссылку)
(48) А возвращать в параметрах ещё отстойней.
(52) Кратко пересказать книжки М.Фаулера и Р.Мартина ?
(47) Если функция не нашла значение потому что его нет - возвращается пустое значение, если возникла ошибка из-за неверных параметров, функция должна генерить исключение. Как это исключение будет обрабатывать вызывающая сторона - уже пофиг. Если вызывающая сторона подходит ответственно к параметрам вызова функции, она не должна париться над текстом в принципе.
(54) Там много опирается на то, что функция должна делать что-то одно. А если функция должна делать что-то одно, откуда взяться чему-то второму что можно вернуть?
(58) См(55). Если не убедил - просто посмотри как работает типовая Справочник.XXX.НайтиПоКоду() и аналогичные. Ни одна функция в здравом уме не возвращает текст ошибки и т.п.
(59) а если речь идет о взаимодействии между системами?
1с - драйвер оборудования
1с - 1с по веб-сервсису
и т.п.
Чаще всего использую возврат структуры, но бывает, что в параметрах возвращал значение, а сама функция возвращала статус успешное завершения функции.
В общем случае, возврат нескольких значений - это массив, соответственно, структура, список и т.п. это более упрощённое понимание массива.
Но, реального возврата нескольких значений из функции всё равно нет - вы возвращаете один объект. И, самое главное, что он создаётся, а потом разрушается, что медленнее, чем если передавать эти несколько параметров в функцию или процедуру по ссылке.
Удобство структуры и списка значений в том, что можно указывать имена значений, что не требует следить за их порядком.
Передача же параметров в вызов функции по значению проще для читателя, так как он понимает, что будет возвращено и может не подставлять переменные для тех значений, которые ему не нужны.
(8) Математически операция А = А + 1 недопустима. Так что не стоит математику переносить на программирование.
(10) В Си процедур не бывает. Только функции с возвратом типа void. Так что и мешанины быть просто не может.
(27) Ну создавай структуру с нужными строками в общем модуле отдельной функцией. Тогда очепятка или будет везде, или нигде.
Вставлю своё имхо:
Когда нужно передавать по ссылке и там менять:
1. Когда меняешь движения, дописываешь данные в таблицу, список.
2. Когда у тебя есть большая структура, которая содержит несколько параметров, которые ты будешь использовать и тебе нужно дополнить её.
3. Когда передаёшь "Отказ" и там меняешь его на Ложь.
4. Когда передаёшь форму и добавляешь на неё свои элементы.
5. Когда передаёшь МенеджерВременных таблиц.
Это то, что смог вспомнить.
Во всех остальных случаях нужно возвращать.
(76) из всех примеров возврат значения в параметре только там где "отказ" (отстойная конструкция этот отказ). В остальных случаях это изменение состояния существующего объекта, которое в отсутствие ООП приходится выполнять именно так.
(72) Я знаю. Именно это и создает мешанину в мозгах, когда сишник садится писать на более структурированных языках. У него уже в прошивке отложилось что функция может и должна менять параметры.
(79) В Си как раз все замечательно. Объявил параметр const - значит менять нельзя. Не объявил - значит он может быть изменен. Потому что с учетом требований с скорости работы может потребоваться и результат вернуть, и параметры поменять.
(79) (80) В Си как раз всё просто - если параметр передан по значению (засунут в стек), то в функции будет его копия, а если по указателю, то в функции будет указатель на переменную, которую по указателю можно менять.
А вот в Си++ появились ссылки, когда передаётся как бы значение, но внутри это реализовано как указатель - то есть то, что мы имеем в 1С, если не написали Знач.
И не забываем, что написав Знач, мы получим копию строки - и, если она очень длинная, то можно получить существенное замедление работы.
(81) Суть не в механизме передачи параметров, а именно в том что в Си нет процедур, и для изменения параметров приходится использовать функцию. Именно поэтому пришедшие из Си и создают функции, меняющие параметры. Паскалисты бы так поступать не стали, а написали бы процедуру.
(83) Дык а если надо и параметры изменить, и значение вернуть? Что использовать? А если надо вернуть значение, параметры не менять, но поменять не параметры (например, добавить записи в базу)? Деление на процедуры и функции чисто условное, иначе сам ЯП не давал бы менять параметры в функции.
А лучше бы не давал. С точки зрения парадигмы функционального программирования изменение формальных параметров - жуткая ересь)
(88) А ты с многопоточным программированием и реентрантностью работал? Когда один и тот же код и одни и те же переменные могут использоваться одновременно несколькими потоками? И тогда единственный способ не конфликтовать потокам - это передавать указатель на некую структуру со всем контекстом потока в качестве параметра функции? И, соответственно, параметр там в процессе работы меняется.
(90) В том-то и дело, что как только начинается реальная жизнь - вся академичность летит к чертям. Так зачем все усложнять? В процедуре априори должен выполняться код, который не может сгенерировать ошибку (возврат результата через перереданные параметры - это же неакадемично, для возврата результата предназначена функция). Много такого кода в реальных задачах?
(91) Но, в той же java прекрасно как параметры передаются объекты-контейнеры (BOX) в которых можно менять содержимое, не меняя самого контейнера, то есть так они реализовали указатели.
Что касается передачи параметра в функцию по указателю, то в том же Си всё остаётся на уровне функции - указатель, как бы мы его не меняли, обратно не возвращается, то если является обычным входным параметром, а вот про то, на что он указывает, никто не говорил - его можно менять, получая доступ к ячейке памяти по указателю.
(88) Начнём с того, что во многих языках деление на процедуры и функции чисто условно, так как и те и другие могут иметь как выходные так и выходные параметры.
Просто у функции есть основной параметр, который только выходной.
А если смотреть на низком уровне, то все высокоуровневые процедуры и функции - это вызов кода, возвращающего код ошибки исполнения, а все параметры и результаты хранятся в отдельной области памяти.
(93) Там просто сборка мусора работает тогда, когда памяти стало очень мало - в результате - если память есть, то её будут жрать, пока не надоест. Но, есть ключи запуска, где всё это можно ограничить. И ваша java побыстрее 1С будет.
(89) Я дико извиняюсь, а в каком языке программирования практикуется подход обращения к общим переменным из разных потоков?
(95) Это скорее особенность компилятора. Локальная переменная функции адресуется по контретному смещению (типа [EDI + 0x10h]. Т.о. если 2 процессора выполняют один и тот же код с одним и тем же значением регистра EDI - физически 2 потока будут обращаться к одной и той же ячейке памяти. В принципе, можно для каждого потока использовать свое значение регистра EDI - но тогда для каждого потока придется создавать свою копию всего контекста приложения.
(97) Как минимум в некоторых реализациях C++ локальная переменная не поможет, поскольку она во всех потоках будет иметь одинаковый адрес. Собственно, так я и познакомился с этой особенностью многопоточной работы.
(98) Может быть потому что эта локальная переменная (переменная-член класса) была объявлена, как static?
(0) Все зависит от ситуации.
Если нужно "набрать" несколько значений, то Структурой их очень удобно возвращать.
В другой случае, через параметры принимаем значение, и через них же возвращаем (типа по ссылки).
В функциональном программировании есть такое понятие как функции первого класса (функции которые можно присваивать переменным, передавать в качестве аргументов и возвращать из функции). В 1С это также можно применять, используя небольшую вспомогательную функцию. Далее демо-пример ее использования.
Обработка тестировалась на 1С:Предприятие 8.3 (8.3.13.1513)
Специальные предложения
(11) этим я точно не буду заниматься ))
для меня очевидна высокая эффективность моего решения (для меня лично), с помощью одной маленькой функции (без многоэтажных конструкций), я придал функциональности языку 1С, а именно передавать функцию в аргументы другой функции
пусть это решение с ограничениями, но я это использую
и я не собираюсь это использовать для высоконагруженных систем, поэтому проблема производительности не на первом месте
(1)Согласен! Прелести функционального программирования именно в:
1. Декларативности (ну в большей степени чем классический императивный подход)
2. Развёртке кода (когда компилятор условно декларативные инструкции разворачивает в последовательность простых инструкций, попутно проводя оптимизацию, практически без падения производительности; заодно и распараллеливая выполнение при возможности)
Это позволяет писать алгоритмы достаточно компактно и, зачастую, более понятно (по времени на анализ), чем в императивном стиле (тем более в процедурном).
Эмуляция же этого процесса:
Во-первых, всё-равно будет выглядеть коряво (а не так красиво как это даёт истинный функциональный стиль)
Во-вторых, никакой оптимизиации тут не жди. Та же рекурсия, которая при функциональном программировании почти всегда разворачивается хотя бы в циклы (или даже просто в линейный поток команд, когда число итераций на момент запуска известно и не велико), то тут постоянный вызов операции "Выполнить" рано или поздно заполнит стек, не говоря уже о том, что код постоянно будет компилироваться в рантайме - а это время.
В-третьих, это замечание к операции "Выполнить" - она не поддерживается под iOS и в WEB-Клиенте, а если заменить её на "Вычислить" - всё равно не будет поддерживаться на iOS. Частично, вероятно (сам не проверял) обойти можно заменив её на "ВыполнитьОбработкуОповещения" - но тут тоже свои нюансы, как минимум, будет недоступно в серверном контексте.
В общем - функциональное программирование - это вообще-то очень мощная вещь, особенно с лямда-выражениями, но эмулировать её, по крайней мере вот так - это бред. А, вот, вариант с кодогерерацийе - мог бы быть более интересен: когда в функциональном стиле пишется декларативный код - он читается как строка и на его основе уже кодогенерируется код на языке 1С (или сразу байткод для стековой машины), со всей необходимой оптимизацией.
Т.е. в типовых часто в процедуру передают переменную с которой идет работа внутри этой процедуры. По окончании работы процедуры используется изменная переменная.
Я же привык (по моему так и учили) что нужно стремиться чтобы функции и процедуры были автономны и для возврата параметра лучше использовать функции.
Так как правильно?
(0) Представь что надо несколько параметров обсчитать и изменить в процедуре/функци, все станет понятно.
Как бэ читабельность и понятность первого примера в разы выше, чем второго, хотя правильнее не менять переменную, а возвращать. но обычно это муторнее и неоправдано
А потом потребовалось еще в этой же функции обрабатывать еще 1 переменную. И опаньки. А так - еще один параметр
(4) В чего это она выше? Во втором варианте понятно что с переменной что-то произошло. А в первом нет.
(6) Ну напиши код когда 3 параметра в функции увеличиваются на +1 и возвращаются как структура, и сравни с кодом когда это происходит через параметры процедуры. Раз в 6 строк больше будет.
(9) функция не может называться Заполнить. тогда уж ПолучитьЗаполненноеЗначение, а так когнитивный диссонанс вызывает такая запись. и вообще в методе написано про значение, а в переменной оказалась коллекция O_o
Я почему спросил. Часто при отладки сталкиваюсь с первым примером. Мне не понятно в таком случае изменила ли процедура переменную/ые или нет. Нужно обязательно посмотреть как работает процедура. С функцией все понятно.
(14) Ну тут спорно. Кто как привык. Да и сам понимаешь, часто а читабельность забивают.
Еще стоит помнить про дифференцированные значения аргументов, то же тема.
точнее, должно быть так:
имхо, сложившееся за 18 лет программирования:
1. если функция проста и однозначна (типа математических синусов и проч.) - она должна возвращать результат своей работы - значение, полученное в результате вычислений
2. если функция сложнее простой арифметики - она должна возвращать код результата (ошибка или всё ок), в вот результат своей работы - структуру, значение и проч. - уже через параметры.
код, написанный с таким подходом, надёжен и понятен.
не знаю, как проголосовать сразу за всех (против всех [за себя])? :)))
Привык делать, как в №2, но потом пару раз наткнулся, что нужно возвратить Истину или Ложь, в случае успеха/неуспеха заполнения.
(17) лучше для обработки ошибки юзать ВызватьИсключение и ловить их в Попытке, а то обработка статусов и самописная работа с ошибками усложняет правильную логику сильно
Функция должна возвращать результат своей работы на то она и Функция.
Согласен с (17) если нужно тебе передать ошибку из функции наверх генерируй исключение.
Если функция должна возвратить несколько значений они должны быть упакованы в структуру или иной подходящий объект.
Если вам нужно изменить переданные параметры то используйте процедуру и называйте её понятно
(24) вызов исключения дорогой получается, проще при возможности определения ошибки в коде просто возвращать некий статус
(25) с чего бы он дорогой? и работа со статусами не займет больше времени при разработке и при выполнении?
Просто использовать функции только для того чтобы они возвращали коды ошибок как то некрасиво, они для других целей были придуманы. Вот представь себе конфигурацию в которой все функции возвращают коды ошибок и меняют переданные параметры.
Или вот 1С почитали нашу ветку и думают а что (16) (17) (18) правы давайте будем меять значения переданные в функцию и переделают ТекущаяДата(), Формат(), СокрЛ().
(30) согласен, но всегда можно что нибудь упустить из виду, не зря их не рекомендуют юзать (в книгах совсем не про 1с)
Ещё раз, хотите менять значения параметров используйте Процедуры. Хотите получать функцию от переданых значений используйте функцию. Если внутри Процедуры не получается обработать ошибку бросайте исключение вам должно быть всё равно кто и для чего вас вызвал, вы свою задачу выполнили и сообщили миру что "нешмогла" а дальше это проблемы мира обрабатывать ваше исключение или порушиться
+(30) и вообще как они могут быть заглушены? если есть ошибка, она падает в исключение, где нужно ее обработать
(27) может в 1С это дешевле, но обычно там много всего помещается в стек и алгоритм работы несколько другой нежели обычный возврат значения из функции
так что исключение нужно применять только в соответствующих случаях
(31) как раз в книгах не по 1С видел рекомендации не писать свою обработку ошибок, основанную на возвращении статусов, а юзать try/catch
(33) она может попасть на тот уровень на котором именно это исключение не может быть обработано
а так как в 1С фильтрации по типу исключения нет, то соответственно придется писать достаточно запутанный код
(34) при использовании исключений у нас 2 ветки для работы - основная, когда все ОК, на которой мы концентрируемся, и возникшие ошибки, которые падают в исключения и которые мы обрабатываем отдельно. выглядит это так:
пример без исключений:
Статус = СделатьЧтоТоАдин( Параметры. ТекстОшибки );
Пример с исключением:
(38) ерунда, например (чисто для примера конструкции):
(37) книгу не помню, вроде есть у Макконнелла в Совершенном коде для сей и джавы и в Чистом коде у Роберта Мартина. Не исключаю, что есть у Джоэла Спольски, у Фаулера и у Бека. Конкретно искать сильно впадлу
(38) а ты представь развитие второго варианта?
в 1С нет конструкции, которая описывала бы возможный вариант исключения, соответственно чтобы определить что функция может завершиться с исключительной ситуацией нужно исследовать текст этой функции, иначе ты будешь постоянно натыкаться на проблемы во время выполнения кода вызывающего данные функции
+ если функция часто вызывается и ошибочная ситуация возникает часто, то это очень дорого будет по времени
(36) код становиться менее запутанным, потому что основная логика отдельно, а исключительные ситуации отдельно. а если исключение вылезет пользователю, то или так задуманно (как в типовых) или это такая же ошибка программиста, как и остальные. Это так же, как не писать контроль остатков, потому что есть вероятность там сделать ошибки и чо нить поломать.
(41) просто там скорее всего речь идет о ситуациях, где ты не можешь явно детектировать возникновение ошибочной ситуации . к примеру выделение памяти или чтение файла .
но не ошибочная ситуация, которую можно определить на определенном этапе выполнения
(44) и код будет выглядеть как в (38) первый вариант. или ты предлагаешь узнавать о наличии ошибок внутри процедуры, которая как бэ вообще не должна знать о существовании соседей?
если исключительная ситуация часта, то ее есть смысл обрабатывать как то иначе, потому что это уже не исключительная ситуация. Да и не дорого это, работа с БД в разы дороже
(50) а откуда она знает, что эти ошибки не дадут ей правильно отработать?
(48) тыкни в конкретные посты, чтоле, там конструктива еще меньше, чем тут
(46) там про общую структуру работы с ошибками
(52) ткнул на конкретный пост и ссылки от него идут
(52) я так понял он хотел чтоб при наличии ошибок (неважно каких) она не стала бы отрабатывать
Макконнелла пересматривать не буду
передача неправильного параметра, кстати, в 1С и должна вызывать исключение, но это уже касается разработки неких общих библиотек, что для 1С нехарактерно
(40) Вот круто если у тебя
СделатьЧтоТоАдин выполняется 15 минут, СделатьЧтоТоДва выполняется 10 минут, СделатьЧтоТоТри 15 минут и ошибка у тебя в первой строке "СделатьЧтоТоАдин" пользователь прождет 40 минут и увидит ошибку типа "Ошибка при чтении файла".
(53) на 25ый пост указывает? так там не написано почему плохо использовать для обработки исключительных ситуаций,
в примере (38) во втором случае каждая функция внутри не проверяет контекст на возможность работы изза предыдущих ошибок, а просто делает только то, что должна, вызывая исключение, если не справляется.
(56) и? вызов исключения занимает 0,4/10000 секунды, хочется экономить такие значения, надо писать на чем то более низкоуровневом, а для 1Ски это мгновенно
(60) если произошла ошибка внутри транзакции, то ее надо б откатить, я ж не говорю, что попытку надо юзать для реализации основной логики
против исключений есть только один убедительный довод:
отлаживать заип. ся
попробуйте напременять исключения и потом в этом коде найти ошибку с помощью режима отладчика "останавливаться при ошибке"
(64) нормально все, и с помощью остановки по ошибке очень хорошо ловятся исключительные ситуации в коде, а если ошибка в другом месте, то нормальный код очень редко генерит исключения
Я сталкиваясь с кодом некоторых 1С Программистов прихожу в ярость, это не код это зачастую поток сознания в виде спагети, процедуры читают и меняют глобальные переменные используют их для передачи параметров в другие процедуры, зависят от вызывающего контекста, если потребуется хоть одну процедуру перенести из проекта в другой проект приходится половину переписывать отвязывать от реквизитов формы и обработки через которые организован обмен это пи. ц просто.
С обработкой ошибок это тоже тот ещё цирк если я хочу использовать процедуру я блин должен для неё лично написать обработку её ошибок потому как исключение она не генрит в итоге.
Я думал это только мне не повезло с наследством, как вижу это общий тренд. Печально.
(64) Если у тебя при отладке сыпятся сплошные исключения да ещё и в циклах то есть повод задуматься. Исключения должны быть редки если их дохрена есть повод задуматься.
(66)(67) попытка всегда генерит исключения, если что
(70) так о чем и речь.
исключения это плохой стиль программирования
(72) тебе не хватает фантазии
при отсутствие всяких этических ограничений, возникают программные конструкции типа такой:
Ключевое слово Процедура начинает секцию исходного текста, выполнение которого можно инициировать из любой точки программного модуля, просто указав Имя_процедуры со списком параметров (если параметры не передаются, то круглые скобки, тем не менее, обязательны). Если в модуле обычного приложения, модуле управляемого приложения или общем программном модуле в теле описания процедуры использовано ключевое слово Экспорт , то это означает, что данная процедура является доступной из всех других программных модулей конфигурации.
При выполнении оператора Возврат процедура заканчивается и возвращает управление в точку вызова. Если в тексте процедуры не встретился оператор Возврат , то после выполнения последнего исполняемого оператора происходит выполнение неявного оператора Возврат . Конец программной секции процедуры определяется по оператору КонецПроцедуры .
Переменные, объявленные в теле процедуры в разделе Объявления локальных переменных , являются локальными переменными данной процедуры, поэтому доступны только в этой процедуре (за исключением случая передачи их как параметров при вызове других процедур, функций или методов).
Имя_проц | Назначает имя процедуры. |
Знач | Необязательное ключевое слово, которое указывает на то, что следующий за ним параметр передается по значению, то есть изменение значения формального параметра при выполнении процедуры никак не повлияет на фактический параметр, переданный при вызове процедуры. Если это ключевое слово не указано, то параметр процедуры передается по ссылке, то есть изменение внутри процедуры значения формального параметра приведет к изменению значения соответствующего фактического параметра. |
Парам1 , . ПарамN | Необязательный список формальных параметров, разделяемых запятыми. Значения формальных параметров должны соответствовать значениям передаваемых при вызове процедуры фактических параметров. В этом списке определяются имена каждого из параметров так, как они используются в тексте процедуры. Список формальных параметров может быть пуст. |
= ДефЗнач | Необязательная установка значения параметра по умолчанию. Параметры с установленными значениями по умолчанию можно располагать в любом месте списка формальных параметров. |
Экспорт | Необязательное ключевое слово, которое указывает на то, что данная процедура является доступной из других программных модулей. |
// Объявления локальных переменных | Объявляются локальные переменные, на которые можно ссылаться только в рамках этой процедуры. |
// Операторы | Исполняемые операторы процедуры. |
Возврат | Необязательное ключевое слово, которое завершает выполнение процедуры и осуществляет возврат в точку программы, из которой было обращение к процедуре. Использование данного оператора в процедуре не обязательно. |
КонецПроцедуры | Обязательное ключевое слово, обозначающее конец исходного текста процедуры, завершение выполнения процедуры. Возврат в точку, из которой было обращение к процедуре. |
Функция
Ключевое слово Функция начинает секцию исходного текста функции, выполнение которой можно инициировать из любой точки программного модуля, просто указав Имя_функции со списком параметров (если параметры не передаются, то круглые скобки, тем не менее, обязательны). Если в модуле обычного, управляемого приложения, внешнего соединения, сеанса или общем программном модуле в теле описания функции использовано ключевое слово Экспорт , то это означает, что данная функция является доступной из всех других программных модулей конфигурации.
Функции отличаются от процедур только тем, что возвращают Возвращаемое значение . Конец программной секции функции определяется по оператору КонецФункции .
Вызов любой функции в тексте программного модуля можно записывать как вызов процедуры, то есть в языке допускается не принимать от функции возвращаемое значение .
Переменные, объявленные в теле функции в разделе Объявления локальных переменных , являются локальными переменными данной функции, поэтому доступны только в этой функции (за исключением случая передачи их как параметров при вызове других процедур, функций или методов).
Читайте также: