1с программно выйти из 1с

Обновлено: 02.07.2024

1С 8.3. Как прервать выполнение процедуры (принудительный выход)

Дано : 1С, версия платформы 8.3. Написан определенный код процедуры.

Задача : прервать выполнение процедуры, чтобы не выполнялся определенный код.

Решение : выход из процедуры в 1С такой же, как и из функции, т.е. командой Возврат . Однако в отличие от функции возвращать ничего не нужно, достаточно только написать данную команду. Например:

Процедура ДПВ_ПредставлениеПредставительВузаНачалоВыбора ( Элемент , ДанныеВыбора , СтандартнаяОбработка )

ЭлементПредставительВуза = Элементы . Найти ( "ПредставительВуза" );

Если ЭлементПредставительВуза = Неопределено Тогда Возврат ; КонецЕсли ;

Данную команду можно вызывать в тех местах процедуры, где необходимо завершить дальнейшее выполнение процедуры (возможно не один раз на протяжении процедуры).

Если же нужно прервать выполнение функции без возвращения какого-либо значения, то можно написать так:

Если Вам понравилась статья, пожалуйста, поставьте лайк, сделайте репост или оставьте комментарий. Если у Вас есть какие-либо замечания, также пишите комментарии.

Комментариев нет :

Поиск по этому блогу

Календарь блога


Дано : Excel c числами и суммами в рублях в ячейках. Задача : написать данные числа прописью без использования макросов и каких-либо над.

Дано : Word 2016 (обновляемый по подписке Office 365). Задача : добавить на страницу рисунок (значок) из готовой коллекции рисунков.


Дано : таблица Excel с колонкой, содержащей фамилию, имя и отчество (ФИО). Задача : извлечь при помощи формул из колонки ФИО данные в след.


Дано : Excel 2016. В двух ячейках указаны даты со временем. Задача : необходимо рассчитать количество полных часов между датами . Дата 1.

Дано : 1С, версия платформы 8.3. Написан определенный код процедуры. Задача : прервать выполнение процедуры, чтобы не выполнялся определ.

(8) согласен, с Перейти ж*па у 1С. :)
(6) громоздко получается. да и более одного раза выходить, получается:

(15) Сильно подозреваю, что человек перемудрил с условиями - вот и мучается с проблемой. А когда будет строить пример - сообразит, где у него собака порылась.

и ловить в эксепшенах.

(16) не знаю. я просто вообразил с какой ветряной мельницей борется автор.. Придумал такую:

очевидно, что такое можно решить так:

Это для тех, кому диета (зачеркнуто) рилигия запрещает ходить по меткам.
Клево. надо вспомнить, где это я так прокачал телепатический модуль
(28) на самом деле, нужно не войти с условием, а _выйти при условии_
(0) приведи пожалуйста пример когда надо выйти Если можешь
(31) Вот ничего не понятно. Рискну предположить, что если аккуратно расписать логику алгоритма - никаких выходов не понадобится. По крайней мере, в этом примере необходимости в них не видно.
ого. всё еще не вышел из "если". лабиринт с минотавром какой-то :)
Все предложенные способы не что иное, как эмуляция ГоуТу :(
(13) это тогда на крайняк :)
а то пустая функция ради выхода появится.
(25) а если ошибка внутри запроса будет, который внутри Попытки? а код отлично отработает, и никто не узнает, что результат - полная лажа :)
(26) это как в (23), углубленный ))
(27) под каждым ИначеЕсли тогда (ведь меняется только Условие 2 в этом примере - Условия 3 нет) надо повторять один и тот же код не на одну страницу прокрутки.
Но можно попробовать, может, что-то и получится.
(34) прочитал (27) :))
и потом, если он повторяется для каждого - вынеси его за КонецЕсли.
(49) в (48) я в ответе на (13) уже указал, что появится функция затолько ради выхода, а может и не одна ))
(51) ну как бы код-то под "Если.." должен исполняться при наличии основного условия, а вот выходить из "Если.." - при невыполнении и проблем внутри него.
(37) это как-то вольно с моим кодом обошлись ))
у меня ". " под "Если.." - это код, который должен выполняться при Флаг ))
Вывожу из Если по фотографии.
Отворот, приворот процедур и функций.
Снимаю порчу с циклов.
100% гарантия.
(43) нежелательность Попытка. Исключение я описал в (48)
(46) работал бы он только железно, а не как придется :(
(47) новая функция за ради выхода появится, это смущает.
(59)
Делаю потихоньку, фото Нуралиева не помогает, лучше несколько фото Франклина.
(72) автор просто с дискретной математикой видимо не знаком
(58) "Возврат" куда?
после "Если. " другой исполняемый код в этой функции, общий для "Если. " и "Если НЕ. "
(62) если "выход" - это выход из функции, то строчкой выше (ответ на (58) описал, что не получается.
(69) ну это вариант
"Если .
Если .
Если.
Конец
.
"
(73) с какой математикой не знаком? :)
Мне всего лишь понадобился выход из оператора "Если".
Если есть время, объясните связь математики и условия выше ))

(75) а то. такого ужаса я давно не видел, сэкономила на фотографе :)

2(74)
блин. вот ты тугой. Еще раз:

(0) неправильно построенное Если.
переделай.

(31) это только подтверждает.

(83) глупость - это когда пишут программы не сложнее калькулятора, зато сами. И то в виде виндовского "Режим обычный, функционала нет".
Множественное вложение "Если. Если. " ведет к полной переделке этой большой функции, а переделка чревата ошибками.
(80) это сродни (69):
Проверка валидности переменных до основного их использования.
Но тогда в вашем случае, нахождение и проверку валидности ВСЕХ внутренних ключевых переменных основной конструкции "Если Флаг. " нужно выносить за эту самую "Если Флаг. " и делать до. Т.е.:

При том, что ПеременнаяДва = 0 И ПеременнаяТри = 0 и остальные используются только для "Если ФЛАГ. ", и более нигде не нужны.
А т.к. это тоже код не одной строчкой, и даже не страничкой, зеленить комменты, что и откуда это взялось, и зачем тут нарисовалось.
Опять же, всю эту проверку в отдельную функцию - можно, но осторожно и неудобно из-за принципа объявления и передачи переменных: переменные из локальных для функции превращаются глобальными для модуля, либо гонять их десятком параметров туда-сюда, что опять же усложняет дальнейшее исправление (ну да, в УПП так и сделано, согласен. Но это не есть хорошо :) ).

Лично у меня на релизах от 8.2.9.х до текущего 8.2.12.96 не всегда происходит полное отключение сеансов. Например, устанавливаю обновление, умный конфигуратор мне выдает кнопку "Завершить сеансы и продолжить", после нажатия на которую остается несколько подключенных соединений.

Также в течение дня часто остаются соединения по закрытым сеансам.

Зачем это нужно

Для себя нашел два пути применения:

1. Перед инсталляцией обновлений необходимо отключить пользователей от системы;

2. Регламентное задание, отвечающее за резервное копирование, должно отключить все подключенные сеансы.

В первом случае удобство состоит в том, что есть кнопка в режиме предприятия, нажав на которую происходит полное завершение.

Как это сделать

Первое, что нам нужно - это определить имя базы и сервер, на котором она расположена. Для этого разбираем строку соединения базы.

Если Найти ( СтрокаСоединенияИнформационнойБазы (), "Srvr" ) > 0 Тогда
// серверный вариант
Поиск1 = Найти ( СтрокаСоединенияИнформационнойБазы (), "Srvr color: red;">);
ПодстрокаПоиска = Сред ( СтрокаСоединенияИнформационнойБазы (), Поиск1 + 6 );
ИмяСервера = Лев ( ПодстрокаПоиска , Найти ( ПодстрокаПоиска , """" ) - 1 );
// теперь ищем имя базы
Поиск1 = Найти ( СтрокаСоединенияИнформационнойБазы (), "Ref color: red;">);
ПодстрокаПоиска = Сред ( СтрокаСоединенияИнформационнойБазы (), Поиск1 + 5 );
ИмяБазы = Лев ( ПодстрокаПоиска , Найти ( ПодстрокаПоиска , """" ) - 1 );
Иначе
// для других способов подключения алгоритм не актуален
Возврат;
КонецЕсли;

Для работы с агентом сервера необходимо использовать COM-объект

Коннектор = Новый COMОбъект ( "v82.COMConnector" );

который позволяет подключится к агенту сервера:

Агент = Коннектор . ConnectAgent ( ИмяСервера );

Теперь перебираем все кластеры, в которых учавствует агент:

Кластеры = Агент . GetClusters ();
Для каждого Кластер из Кластеры Цикл

Чтобы получить доступ к процессам кластера, необходимо аутентифицироваться, если для кластера задан администратор:

АдминистраторКластера = "Имя администратора кластера" ;
ПарольКластера = "Пароль администратора кластера" ;
Агент . Authenticate ( Кластер , АдминистраторКластера , ПарольКластера );

если кластер без ограничения доступа, то следует писать так:

Агент . Authenticate ( Кластер , , );

Теперь необходимо получить перечень процессов, которые обрабатывают данный кластер:

Процессы = Агент . GetWorkingProcesses ( Кластер );
Для каждого Процесс из Процессы Цикл

Т.к. к рабочему процессу необходимо подключаться через коннектор, то необходимо вычислить порт, на котором работает данный процесс:

Порт = Процесс . MainPort ;
// теперь есть адрес и порт для подключения к рабочему процессу
РабПроц = Коннектор . ConnectWorkingProcess ( ИмяСервера + ":" + СтрЗаменить ( Порт , Символы . НПП , "" ));

Рабочий процесс необходимо для разрыва соединений. Разрыв сессий происходит через агента. Опишем подробно. Сначала необходимо аутентифицироваться в рабочем процесс по имени и паролю пользователя, у которого в базе данных есть право "Администратор":

РабПроц . AddAuthentication ( "Имя администратора БД" , "Пароль администратора БД" );

На этом этапе есть объект агента и рабочего процесса, который обслуживает текущий кластер. Далее необходимо найти искомую базу данных:

Базы = Агент . GetInfoBases ( Кластер );
Для каждого База из Базы Цикл
Если База . Name = ИмяБазы Тогда
ИнформационнаяБаза = База ;
Прервать;
КонецЕсли;
КонецЦикла;
Если ИнформационнаяБаза = "" Тогда
// база не найдена
КонецЕсли;

Отключение сеансов

Итак у нас есть все необходимые объекты для непосредственного обрыва сессий. При это рекомендую полностью разобраться, какие именно сессии мы будем разрывать, иначе можно отключить сессию, в которой выполняется этот код :

Сеансы = Агент . GetInfoBaseSessions ( Кластер , ИнформационнаяБаза );
Для каждого Сеанс из Сеансы Цикл
Если нРег ( Сеанс . AppID ) = "backgroundjob" ИЛИ нРег ( Сеанс . AppID ) = "designer" Тогда
// если это сеансы конфигуратора или фонового задания, то не отключаем
Продолжить;
КонецЕсли;
Если Сеанс . UserName = ИмяПользователя () Тогда
// это текущий пользователь
Продолжить;
КонецЕсли;
Агент . TerminateSession ( Кластер , Сеанс );
КонецЦикла;

Также у типа "Сеанс" есть ещё много разных свойств, например, имя компьютера, данные о языке, времени и длительности подключения и тп.

Отключение соединений

Отключение соединений происходит через объект рабочего процесса. Обрабатывает соединение тип "Соединение", у которого структура свойств напоминает тип "Сеанс". Итак, как отключенить соединения:

СоединенияБазы = Агент . GetInfoBaseConnections ( Кластер , ИнформационнаяБаза );
// Разорвать соединения клиентских приложений.
Для Каждого Соединение Из СоединенияБазы Цикл
Если нРег ( Соединение . Application ) = "backgroundjob" ИЛИ нРег ( Соединение . Application ) = "designer" Тогда
// если это соединение конфигуратора или фонового задания, то не отключаем
Продолжить;
КонецЕсли;
Если Соединение . UserName = ИмяПользователя () Тогда
// это текущий пользователь
Продолжить;
КонецЕсли;
РабПроц . Disconnect ( Соединение );
КонецЦикла;

Выводы

Получен пример отключения сеансов и соединений с информационной базы. При должном знании свойств каждого типа (рабочий процесс, агент сервера, сеанс, соединение) можно, например, сделать откючение конкретного пользователя по расписанию (однако, совершенно другой вопрос зачем это делать) либо, используя данные конструкции, написать внешнее приложение, которое будет использовать COM-объект "v82.COMConnector".

P.S.

Для понимающих работу с этими типами: код намеренно раздут, для того, чтобы под отладчиком было удобнее просматривать значения всех типов. Да, некоторые места можно написать короче и элегантнее, однако цель была в наглядности кода.

Код целиком

Если Найти ( СтрокаСоединенияИнформационнойБазы (), "Srvr" ) > 0 Тогда
// серверный вариант
Поиск1 = Найти ( СтрокаСоединенияИнформационнойБазы (), "Srvr color: red;">);
ПодстрокаПоиска = Сред ( СтрокаСоединенияИнформационнойБазы (), Поиск1 + 6 );
ИмяСервера = Лев ( ПодстрокаПоиска , Найти ( ПодстрокаПоиска , """" ) - 1 );
// теперь ищем имя базы
Поиск1 = Найти ( СтрокаСоединенияИнформационнойБазы (), "Ref color: red;">);
ПодстрокаПоиска = Сред ( СтрокаСоединенияИнформационнойБазы (), Поиск1 + 5 );
ИмяБазы = Лев ( ПодстрокаПоиска , Найти ( ПодстрокаПоиска , """" ) - 1 );
Иначе
// для других способов подключения алгоритм не актуален
Возврат;
КонецЕсли;

Коннектор = Новый COMОбъект ( "v82.COMConnector" );
Агент = Коннектор . ConnectAgent ( ИмяСервера );
Кластеры = Агент . GetClusters ();
Для каждого Кластер из Кластеры Цикл
АдминистраторКластера = "Имя администратора кластера" ;
ПарольКластера = "Пароль администратора кластера" ;
Агент . Authenticate ( Кластер , АдминистраторКластера , ПарольКластера );
Процессы = Агент . GetWorkingProcesses ( Кластер );
Для каждого Процесс из Процессы Цикл
Порт = Процесс . MainPort ;
// теперь есть адрес и порт для подключения к рабочему процессу
РабПроц = Коннектор . ConnectWorkingProcess ( Имяервера + ":" + СтрЗаменить ( Порт , Символы . НПП , "" ));
РабПроц . AddAuthentication ( "Имя администратора БД" , "Пароль администратора БД" );

Базы = Агент . GetInfoBases ( Кластер );
Для каждого База из Базы Цикл
Если База . Name = ИмяБазы Тогда
ИнформационнаяБаза = База ;
Прервать;
КонецЕсли;
КонецЦикла;
Если ИнформационнаяБаза = "" Тогда
// база не найдена
КонецЕсли;

Сеансы = Агент . GetInfoBaseSessions ( Кластер , ИнформационнаяБаза );
Для каждого Сеанс из Сеансы Цикл
Если нРег ( Сеанс . AppID ) = "backgroundjob" ИЛИ нРег ( Сеанс . AppID ) = "designer" Тогда
// если это сеансы конфигуратора или фонового задания, то не отключаем
Продолжить;
КонецЕсли;
Если Сеанс . UserName = ИмяПользователя () Тогда
// это текущий пользователь
Продолжить;
КонецЕсли;
Агент . TerminateSession ( Кластер , Сеанс );
КонецЦикла;

СоединенияБазы = Агент . GetInfoBaseConnections ( Кластер , ИнформационнаяБаза );
// Разорвать соединения клиентских приложений.
Для Каждого Соединение Из СоединенияБазы Цикл
Если нРег ( Соединение . Application ) = "backgroundjob" ИЛИ нРег ( Соединение . Application ) = "designer" Тогда
// если это соединение конфигуратора или фонового задания, то не отключаем
Продолжить;
КонецЕсли;
Если Соединение . UserName = ИмяПользователя () Тогда
// это текущий пользователь
Продолжить;
КонецЕсли;
РабПроц . Disconnect ( Соединение );
КонецЦикла;
КонецЦикла;
КонецЦикла;

В статье будет рассказано о том, как в 1с открыть форму программно. Все описанное ниже, касается только управляемого приложения. Подробно рассмотрим метод глобального контекста ОткрытьФорму.

Также можете ознакомиться с более простыми, но менее гибкими способами открыть форму по ссылке: Как в 1с открыть ссылку.

Метод ОткрытьФорму по имени

Самый гибкий и настраиваемый способ программного открытия формы в 1с 8. Рассмотрим подробно его параметры, а также разберем несколько примеров его использования.

Следует заметить, что метод ОткрытьФорму является клиентским. Т.е его можно использовать либо в общих модулях с установленным флагом Клиент, либо в процедурах (функциях) форм с директивой &НаКлиенте.

Рассмотрим параметры метода и приведем необходимые примеры.

ИмяФормы

Содержит полный путь к форме. Можно указать, как путь к форме по умолчанию, так и путь к произвольной форме объекта метаданных. Имя формы указывается в следующих двух форматах:

  • ТипОбъекта. Наименование типа объекта метаданных, например: Справочник, Документ, РегистрСведений и т. д.;
  • ИмяОбъекта. Наименование объекта метаданных. Например для справочника: Пользователи, Номенклатура;
  • ИмяФормыПоУмолчанию. Стандартное имя формы, набор имен по умолчанию различается для различных объектов метаданных. Например для документа: ФормаВыбора, ФормаОбъекта, ФормаСписка. Полный набор имен по умолчанию можно найти в синтаксис помощнике, в описании метода ОткрытьФорму;
  • ИмяФормы. Произвольное имя формы, заданное при ее создании. Например у справочника Пользователи, форма СменаПочты.

Пример 1. Путь к форме выбора по умолчанию, справочника Номенклатура.

Пример 2. Путь к форме СменаПочты справочника Пользователи, по ее имени.

Параметры

Содержит Структуру параметров, которые передаются в открываемую форму. Для каждого типа формы, существует набор стандартных параметров, которые не нужно дополнительно обрабатывать в самой форме. Также набор параметров может различаться и для объектов метаданных. Например, параметр Ключ, для форм объектов. В него можно передать ссылку на открываемый объект (если его не передать, будет открыта форма нового объекта).

Подробнее прочитать описание всех возможных стандартных параметров можно в синтаксис помощнике, в ветке Интерфейс (управляемый) -> Форма клиентского приложения (в старых версиях платформы Управляемая форма). Далее в ветках Расширение объектов, Расширение справочника и т. д., можно найти Параметры формы. Там дается полный список возможных стандартных параметров с описаниями.

Также в структуру можно передавать произвольные параметры, которые можно обрабатывать программно, в открываемой форме. Например в обработчике события ПриСозданииНаСервере.

Рассмотрим примеры открытия различных форм с использованием параметров.

Пример 3. Открыть форму объекта справочника Пользователи, используя ссылку на объект.

Пример 4. Открыть форму списка справочника Номенклатура с отбором по реквизиту ВидНоменклатуры и по списку родителей.

Данным способом можно отобрать значения, используя вид сравнения Равно или ВСписке. Для отбора ВСписке следует добавить в структуру Массив, ФиксированныйМассив, либо СписокЗначений. Следует заметить, что отбор ВИерархии установить данным способом не выйдет.

Владелец

В данный параметр передается элемент формы или форма клиентского приложения (управляемая форма) полностью. Используется для указания подчинения открываемой формы.

Это может потребоваться для многих целей, например для:

  • Анализа владельца и выполнения определенных действий в открываемой форме;
  • Корректной работы события ОбработкаЗаписиНового, в форме владельце;
  • Самостоятельной реализации выбора в поле формы.

Пример 5. Реализовать программный выбор элемента Номенклатура, в поле ввода.

В данном случае необходимо:

  • Создать обработчик события НачалоВыбора, для поля ввода;
  • Отменить стандартную обработку выбора;
  • В параметр Владелец передать элемент формы (поле).

Параметр ТекущаяСтрока, позволяет выделять ранее выбранный элемент в форме выбора. Стоит заменить, что в обычной ситуации такой метод выбора значений не применяется. Его применяют только тогда, когда нет возможности настроить форму выбора под условия задачи.

Уникальность

В параметре можно задать ключ уникальности формы произвольного типа. При открытии формы, платформа будет анализировать, есть в текущем сеансе уже открытая форма, с таким же ключом уникальности. Если такая форма будет найдена, то она будет активизирована, а новая не откроется. Этот механизм работает только для одинаковых форм. Если вы будете открывать формы объекта разных документов с одинаковым ключом, то откроются обе.

По умолчанию, платформа сама генерирует ключ уникальности. Поэтому помимо использования собственного ключа, в параметре Уникальность, можно регулировать использование стандартного. Если передать в него значение Ложь, то будет использован стандартный ключ, если значение Истина, то ключ не будет использоваться совсем. Т.е. будет создаваться новая форма, при каждом использовании метода ОткрытьФорму. Значением по умолчанию является Ложь, поэтому специально задавать его не требуется.

Пример 6. Одновременно открыть две формы объекта справочника Пользователи, по одной и той же ссылке.

В параметре можно указать окно, в котором будет открыта новая форма. Тип параметра ОкноКлиентскогоПриложения.

Пример 7. Реализовать программный выбор элемента Номенклатура, в поле ввода. Реализовать выбор в окне формы, на которой расположено поле.

В этом примере мы получаем окно текущей формы и используем его для открытия формы выбора справочника.

НавигационнаяСсылка

Позволяет установить собственную навигационную ссылку для открываемой формы. Устанавливаемая навигационная ссылка должна иметь тип Строка. Значение по умолчанию: Неопределено, при использовании этого значения, навигационная ссылка задается автоматически.

ОписаниеОповещенияОЗакрытии

В параметр передается описание процедуры, которая будет вызвана после закрытия открываемой формы. Тип параметра: ОписаниеОповещения.

Пример 8. В 1с открыть форму программно. Использовать форму объекта справочника Пользователи. После ее закрытия сообщить, что карточка пользователя закрыта.

Используемые в примере параметры описания оповещения:

  • Первый: имя процедуры;
  • Второй: модуль, в котором она расположена (в данном случае текущая форма);
  • Третий: структура дополнительных параметров, которая будет передана в процедуру;

Описанная процедура обязательно должна иметь два параметра:

  • Результат. Значение, которое возвращает форма при закрытии. Форма объекта не возвращает значений (если это специально не прописать), поэтому в данном случае значение параметра будет Неопределено. А вот форма выбора, например, вернет массив выбранных значений.
  • ДопПараметры. Структура параметров, созданная в описании оповещения.

Также описанная процедура должна быть экспортной.

РежимОткрытияОкна

Позволяет указать режим открытия управляемой формы. По умолчанию Неопределено, вручную можно задать одно из значений системного перечисления РежимОткрытияОкнаФормы:

  • БлокироватьВеcьИнтерфейс;
  • БлокироватьОкноВладельца;
  • Независимый.

Метод ОткрытьФорму по форме

Существует еще один вариант синтаксиса метода ОткрытьФорму.

Используется, если вы уже получили форму, произвели с ней какие-то действия и теперь ее необходимо открыть.

Пример 9. Получить форму списка справочника Номенклатура, а затем в 1с открыть форму программно.

Читайте также: