1с объект модифицирован для плана обмена попытка исключение

Обновлено: 05.07.2024

В чем суть этого оператора? В ходе выполнения программы часто могут возникать ошибки, такие как деление на ноль, корень из отрицательного числа и прочие. Эти ошибки приводят к «крушению» программы – это значит, что программа прекратит свою работу и ни какие операторы после ошибки выполняться не будут. Чтобы обойти исключительную ситуацию и продолжить выполнение программы, в языке программирования 1С существует оператор Попытка…Исключение.

Рассмотрим его синтаксис.

Попытка

//операторы попытки

Исключение

//операторы исключения.

КонецПопытки

Разберем этот синтаксис.

Ключевое слово Попытка открывает список операторов, выполнение которых может привести к исключительной ситуации, все операторы между ключевыми словами Попытка и Исключение это Операторы попытки.

Ключевое слово Исключение открывает список операторов, которые будут выполняться в том случае, если вызвана исключительная ситуация операторами попытки. Т.е. если во время выполнения программы один из операторов попытки вызвал ошибку выполнения программы (исключительную ситуацию), то выполнение данного оператора прерывается и управление передается на первый Оператор исключения. Причем обращаю Ваше внимание, что управление будет передано и в том случае, если исключительную ситуацию вызвали функции и процедуры, разработанные программистом и применяемые в качестве операторов попытки. Естественно, что если ошибка произошла в процедуре или функции, то ее выполнение будет прервано.

Описание ошибки в 1С

В коде выше я использовал собственное выражение для описания ошибки, но можно использовать метод ОписаниеОшибки(), который возвращается описание ошибки с точки зрения разработчиков платформы 1С. Это функция, которая возвращает текст с описанием ошибки. Например, код выше можно переделать так:

Тогда, при выполнении выйдет «стандартизированное» описание ошибки.

Использование метода ОписаниеОшибки

Оператор ВызватьИсключение в 1С

Использование оператора ВызватьИсключение

Оператор ВызватьИсключение можно использовать отдельно для «эмуляции» вызова исключение. Например, при выполнении этой команды формы:

Будет вызвано исключение.

Использование оператора ВызватьИсключение

Причём, в открывавшемся окне можно посмотреть место в коде, где было вызвано исключение.

Использование оператора ВызватьИсключение

Попытка внутри попытки в 1С

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

Реквизиты управляемой формы 1С

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

И результат работы этой обработки:

Попытка внутри попытки в 1С

Программировать в 1С за 11 шагов

  1. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  2. Научитесь понимать архитектуру 1С;
  3. Станете писать код на языке 1С;
  4. Освоите основные приемы программирования;
  5. Закрепите полученные знания при помощи задачника.

Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.

Основы разработки в 1С такси

  1. Очень доступный и понятный язык изложения
  2. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  3. Поймете идеологию управляемого приложения 1С
  4. Узнаете, как разрабатывать управляемое приложение;
  5. Научитесь разрабатывать управляемые формы 1С;
  6. Сможете работать с основными и нужными элементами управляемых форм
  7. Программирование под управляемым приложением станет понятным

Эти книги, плюс книга по программированию оперативного учета имеются в едином комплекте: комплект книг по разработке в 1С.
Только для читателей моего блога,
промо-код на скидку в 300 рублей на весь комплект: blog


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

можно оплатить вручную:

Перехват исключений в коде

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

2. Тем не менее, необходимость перехвата исключений в коде все же возникает. Например, для того чтобы уточнить текст ошибки, дополнив его прикладной, понятной конечному пользователю, информацией. Однако при этом необходимо фиксировать причину ошибки в журнале регистрации для того, чтобы системный администратор имел возможность выполнить диагностику проблемы и при необходимости передать информацию об ошибке в службу технической поддержки.

3. Частные случаи некорректного использования и перехвата исключений.

Область применения (уточнение): управляемое приложение, обычное приложение.

3.1. Если имеется некоторая серверная бизнес-логика, которая вызывается с клиента при интерактивной работе пользователя:

&НаСервере
Процедура ВыполнитьОперацию()
// код, приводящий к вызову исключения
.
КонецПроцедуры

то неправильно маскировать от пользователя и администратора исходную проблему:

// на клиенте
Попытка
ВыполнитьОперацию();
Исключение
ПоказатьПредупреждение(,НСтр("ru = 'Операция не может быть выполнена.'"));
КонецПопытки;

&НаСервере
Процедура ВыполнитьОперацию()
Попытка
// код, приводящий к вызову исключения
.
Исключение
// Запись события в журнал регистрации для системного администратора.
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка.
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры

и тогда на клиенте:

Не следует использовать функцию ОписаниеОшибки , т.к. она неинформативна для разработчика, потому что не возвращает стек в тексте ошибки.

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

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

КодОшибки = ЗагрузитьФайлИзИнтернета(. );
Если КодОшибки = 12345 Тогда
.
ИначеЕсли .

правильно применять строковые литералы (например, "Успешно", "НетМестаНаДиске", "Отменено" и т.п.):

РезультатЗагрузки = ЗагрузитьФайлИзИнтернета(. );
Если РезультатЗагрузки = "Успешно" Тогда
.
ИначеЕсли .

Строковые литералы кодов ошибок не локализуются.

Исключение составляют случаи работы с веб-сервисами и другими внешними системами, где коды ошибок не доступны, а результат работы транслируется в вызывающий код прикладной конфигурации в виде исключений.

3.3. Если имеется некоторая клиентская бизнес-логика (код выполняется полностью на клиенте):

&НаКлиенте
Процедура СоздатьФайлНаДиске()
// код, приводящий к вызову исключения
.
КонецПроцедуры

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

&НаСервереБезКонтекста
Процедура ЗаписатьОшибкуРаботыСФайлами(. )
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка.
ПодробноеПредставлениеОшибки);
КонецПроцедуры

3.4. Недопустимо перехватывать любые исключения, бесследно для системного администратора:

Попытка
// код, приводящий к вызову исключения
.
Исключение // перехват любых исключений
КонецПопытки;

Как правило, подобная конструкция скрывает реальную проблему, которую впоследствии невозможно диагностировать.
Правильно:

Попытка
// код, приводящий к вызову исключения
.
Исключение
// Пояснение причин перехвата всех исключений "незаметно" от пользователя.
// .
// И запись события в журнал регистрации для системного администратора.
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка.
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

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

Процедура ПередЗаписью(Отказ)
Если Не ЗарегистрироватьИзмененияНаУзлахПлановОбмена() Тогда
ВызватьИсключение НСтр("ru = 'Не удалось зарегистрировать изменения на узлах планов обмена. Обратитесь к администратору.'");
КонецЕсли;
.
КонецПроцедуры

Подробнее см. пп. 1.1 и 1.3 стандарта Информирование пользователя.

3.6. Недопустимо делать проверки наличия у объекта реквизитов, методов, макетов и т.п., используя для этого исключения, т.к. это может привести к сложно диагностируемым ошибкам, а также затрудняет отладку в режиме «Останавливаться по ошибке».
Вместо перехвата исключений в этом случае рекомендуется:

  • использовать механизмы работы с метаданными, чтобы явным образом проверять наличие или отсутствие реквизита (макета и т.п.);
  • если различия связаны с особенностями встраивания библиотек – описывать особенности явным образом в переопределяемых модулях (см. Переопределяемые и поставляемые объекты);
  • пересмотреть логику работы методов, использующих перехват исключений. Например, можно предусмотреть параметры, которые определяются в вызывающем коде и указывают нужно или нет обращаться к какому-либо методу или свойству объекта.

Попытка
КонтекстЭДОСервер.ПолучитьМакет("КомпонентаОбмена");
ПутьВК = КонтекстЭДОСервер.ПутьКОбъекту + ".Макет.КомпонентаОбмена";
Исключение
КонецПопытки;

МакетКомпонентыОбмена = КонтекстЭДОСервер.Метаданные().Макеты.Найти("КомпонентаОбмена");
Если МакетКомпонентыОбмена <> Неопределено Тогда
ПутьКМакету = КомпонентаОбмена.ПолноеИмя()
КонецЕсли;

3.7. Порядок обработки исключений при использовании транзакций описан в стандарте Транзакции: правила использования.

3.8. Неправильно использовать исключения для приведения значения к типу. Для таких операций необходимо использовать возможности объекта ОписаниеТипов .

Попытка
КоличествоДнейРазрешения = Число(Значение);
Исключение
КоличествоДнейРазрешения = 0; // значение по умолчанию
КонецПопытки;

ОписаниеТипа = Новый ОписаниеТипов("Число");
КоличествоДнейРазрешения = ОписаниеТипа.ПривестиЗначение(Значение);

Автор статьи - Виктор Сахнов (Asmody)

Сразу замечу, что все нижеследующее относится к релизу платформы 8.0.7.36 и выше.

Шаг 1. Создание плана обмена

Создаем в конфигурации план обмена. Называем его, например "РаспределеннаяБаза". Обязательно в
свойствах плана обмена ставим флажок "Распределенная информационная база".

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

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

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

В принципе, этих действий достаточно, чтобы РБД заработала в "ручном" режиме. Для этого запускаем
Предприятие, открываем наш план обмена через меню "Операции". В плане обмена всегда присутствует
предопределенный узел "с точкой". Это описание текущего узла. Его нужно открыть и заполнить. В нашем
случае будут доступны поля "Код" и "Наименование". Присвоим нашему узлу код "AA" и назовем
"Центральная". Добавим в план обмена один узел. Присвоим ему код "ВВ" и назовем "Периферийная".

Теперь мы можем создать образ периферийной базы. Делается это нажатием кнопки "Создать начальный
образ". В списке узлов должна быть выбрана периферийная база. Образ базы создается в виде готовой ИБ
в каталоге или на сервере 1С:Предприятия. (в отличие от 7.7, где образ ИБ создавался как файл
выгрузки). Далее созданную базу можно перенести в нужное место, просто скопировав файлик 1CV8.1CD
(для файлового варианта), либо через Конфигуратор через выгрузку-загрузку данных.

Если Вы откроете план обмена в периферийной ИБ, то Вы увидите, что узлом "с точкой", т.е. текущим
узлом стал узел "Периферийная", а иконка у узла "Центральная" стала красного цвета, т.е. узел
"Центральная" является главным узлом по отношению к текущему.

Обмен в "ручном" режиме можно производить при помощи кнопок "Записать изменения" и "Прочитать
изменения". В первом случае будет предложено выбрать файл, куда изменения будут записаны, во втором
- файл, откуда изменения будут считаны. Обмен ведется в формате xml. Изменения записываются для
выбранного узла.

Шаг 2. Выгрузка изменений в XML-файл и отправка по электронной почте

Итак мы создали план обмена, создали периферийную ИБ и даже научились переносить данные между
базами. Теперь наша задача научить базы обмениваться по электронной почте.

Процедуру для работы с электронной почтой сделаем универсальной, т.е. сделаем возможным
использование как MAPI (отправка-получение через почтового клиента, например, MS Outlook), так и
прямое обращение к SMTP/POP3 серверам.

Добавим в конфигурацию несколько констант:

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

Добавим общий модуль, назовем его "рбРаспределеннаяБаза". В нем пишем:

Рекомендую в интерфейс добавить дополнительную панель, на одну из кнопок которой повесить вызов этой
процедуры. Теперь осталось запустить Предприятие, настроить электронный адрес периферийной ИБ,
поставить галку "Выполнять обмен", нажать на кнопку процедуры на панели и бежать получать почту для
указанного эл. адреса. Должно придти письмо с темой "1С:Обмен AA_BB" и вложенным файлом
"Message_AA_BB.xml".

Шаг 3. Получение обновлений по электронной почте и запись их в ИБ

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

В параметры сеанса добавим параметр "ИдетОбменРаспределеннойБазы" типа Булево. Ниже я объясню его
назначение.

Добавим в общий модуль рбРаспределеннаяБаза такую процедуру:

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

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

Добавим константу ИнтервалАвтообменаРаспределеннойБазы типа Число(5,0).

В настройки пользователя добавим параметр ВыполнятьОбменРаспределенныхБаз. Для конфигурации
"Управление торговлей" это делается так:

* В план видов характеристик "НастройкиПользователей" добавим предопределенную
характеристику ВыполнятьОбменРаспределенныхБаз типа Булево.
* В форме элемента справочника "Пользователи" настраиваем изменение этого параметра (как это
сделать можно посмотреть в модуле формы, по аналогии с остальными параметрами).

В модуль рбРаспределеннаяБаза добавляем процедуру:

в модуль приложения:

в процедуру ПриНачалеРаботыСистемы() модуля приложения добавим такие строки:

(после подключения торгового оборудования)
.

Добавим на нашу панель еще пару кнопок для управления процессом: на одну вешаем процедуру
ПроверитьПодключениеАвтообмена(), на другую - ОтключитьАвтообмен()

Запускаем предприятие, настраиваем свойства пользователя и интервал автообмена и все!

Теперь при заходе в базу под этим-самым-настроенным пользователем будет запускаться обработчик
ожидания ВыполнитьАвтообмен(). Естественно, в периферийной базе тоже нужно настроить пользователя
для обмена.

Еще одно маленькое, но важное замечание:

1cv8.exe CONFIG /F<путь к ИБ> /N<Пользователь> /P<Пароль> /UpdateIBCfg


Планы обмена используются для организации обменов данными между различными системами. Это может быть как обмен между двумя базами на платформе 1С, так и обмен между базой на 1С и какой-нибудь внешней системой, например с сайтом.

В целом план обмена похож на справочник, он обладает почти теми же самыми свойствами и методами. Поэтому в данной статье будет рассмотрена только та функциональность, которая касается обмена данными.

В пользовательском режиме создаются элементы плана обмена, которые называются узлами обмена:

План обмена

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

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

Состав плана обмена

При создании нового плана обмена нужно определить состав данных, которыми будут обмениваться системы. Например, в текущей конфигурации может быть 20 справочников, 10 документов, 5 регистров сведений, но в другую базу нужно выгружать только 5 справочников и 2 документа.

Для настройки состава плана обмена на закладке Основные нужно нажать на кнопку Состав:

Состав плана обмена

Будет открыто окно, в котором можно флажками отметить те объекты, которыми можно будет обмениваться с помощью данного плана обмена:

Состав плана обмена

В состав плана обмена можно включить следующие объекты:

  • Константы
  • Справочники, документы, планы видов характеристик, планы счетов, планы видов расчета, бизнес-процессы, задачи
  • Все наборы записей: регистры сведений, регистры накопления, регистры бухгалтерии, регистры расчета, перерасчеты, последовательности.

Также у данных видов объектов метаданных есть закладка Обмен данными, где можно отметить те планы обмена, в состав которых будет входить данный объект метаданных:

Обмен данными

При сохранении конфигурации базы данных для каждого из отмеченных объектов будет создана таблица с тремя колонками:

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

Отображать таблицы изменений

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

Служба регистрации изменений

Служба регистрации изменений позволяет получить список измененных объектов для определенного узла плана обмена. В дальнейшем данный список объектов можно выгрузить в файл.

Алгоритм работы данной службы:

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

Авторегистрация

Рассмотрим данный алгоритм на примере.

В базе-источнике есть 3 узла плана обмена, один из которых является текущей базой (Основная база):

Узлы плана обмена

В состав плана обмена включен только один справочник Номенклатура и для него разрешена автоматическая регистрация:

автоматическая регистрация

На данный момент таблица регистрации изменений пустая:

Создадим новую номенклатуру Стул. В результате в таблицу будет добавлено 2 новые строки, по одной для каждого узла плана обмена (кроме узла текущей базы):

Создадим еще одну номенклатуру Шкаф:

В таблицу было добавлено 2 строки для шкафа.

Создадим еще одну номенклатуру Стол:

После этого была выполнена выгрузка сразу в оба узла:

Затем у стула был изменен артикул и он был перезаписан:

Из данного примера можно сделать следующие выводы:

  • Объект будет выгружаться в файл обмена до тех пор, пока из приемника не придет ответ (квитанция) о том, что данный объект был успешно загружен.
  • Если после выгрузки объекта он был изменен, то после загрузки квитанции изменения не будут потеряны.
  • Для каждого объекта можно узнать выгружался он или нет, но только до загрузки квитанции. После загрузки квитанции история выгрузки не сохраняется.

В данном примере был рассмотрен пример двухстороннего обмена. При этом из второй базы может выгружаться только квитанция, а может квитанция + данные.

Основной отбор регистра сведений

У регистра сведений в свойствах измерения есть флаг Основной отбор:

Основной отбор

А если регистр сведений периодический, то на закладке Основные есть флаг Основной отбор по периоду:

Основной отбор по периоду

По умолчанию данные флаги установлены.

С помощью них определяется минимальная гранула для регистрации на узлах плана обмена.

Если оставить как есть, то при изменении одной записи регистра сведений будет регистрироваться только она.

Если снять данный флаг у одного из измерений, то оно перестанет входить в гранулу для регистрации, в результате при изменении одной записи может зарегистрироваться сразу несколько записей.

Лучше всего объяснить на примере. Пусть есть регистр сведений со следующей структурой:

регистр сведений

И в нем содержатся следующие данные:

регистр сведений

Если все измерения входят в основной отбор, то при изменении оптовой цены для шкафа в таблицу регистрации попадет только одна запись, она же будет выгружена в файл обмена:

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

Тогда при выгрузке в файл, из регистра будут отобраны все записи, где Номенклатура = Шкаф и Период = 05.10.21, то есть сразу 2 записи: с оптовой и розничной ценой.

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

Удаление объекта

При непосредственном удалении объекта из базы данных в таблицу регистрации изменений записывается объект Удаление объекта.

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

ЭтотУзел

Один из узлов плана обмена должен указывать на текущую базу. В списке узлов он выделяется специальной пиктограммой:


Чтобы получить текущий узел можно воспользоваться методом ЭтотУзел. Данный метод вернет ссылку на узел плана обмена:

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