Связь между двумя базами 1С 8
Доброго времени суток, уважаемые форумчане!

Прошу вас проконсультировать меня по одному теоретическому вопросу.
Есть две базы 1С 8.3. Между ними налажено оперативное взаимодействие в реальном времени.
При проведении в первой базе документа "ЗаказКлиента" обработчик события проведения документа с помощью веб-сервиса
обращается ко второй базе и создать в ней документ "ЗаказКлиента" - копию проводимого в первой базе.
При этом в первую базу функция обращения к веб-сервису возвращает информацию о том, удалось ли создать во второй базе документ.
Эта информация никак не должна влиять на ход проведения документа в первой базе, но желательно,
чтобы, если во второй базе при создании заказа возникла ошибка, информация об этом была выведена на экран пользователю первой базы.
Первая база - УТ11.4, работает в клиент-серверном режиме. Операция проведения отрабатывает на сервере, и на сервере же идет обращение
ко второй базе. Я никак не могу сообразить, как сделать, чтобы ответ из второй базы отобразить на экране пользователю первой базы.
В УТ11.4 при ошибке проведения заказа сообщение об ошибке выдается с помощью процедуры СообщениеПользователю.Сообщить( ).
Но там ситуация другая - при ошибке проведения форма заказа остается открытой, и в ней сообщение и отображается.
А в моей ситуации форма заказа после проведения сразу закрывается - ошибка возникает во второй базе и обнаруживается в серверной процедуре обработки проведения заказа.
И вопрос - можно ли как-нибудь отобразить на экране сообщение об ошибке во второй базе.

Заранее благодарю.
---
Нет, зачем? Можно запустить глобальный обработчик оповещения в модуле управляемого приложения, а в обработчике проверять записи регистра и при необходимости показывать свою форму с сообщением, открывая ее независимо от других (или же блокируя интерфейс).
---
у вас получается пользователь инициирует вызов при проведении. Если форма закрывается, то вывести сообщение не получится. Т.к. оно привязывается к объекту.
Выходит вам нужно как и написали создать 2 регистра. В первом писать сообщение, что данные не записаны в базе приемнике.
Во втором писать, что не записалось из базы источника. А далее читать регистры и обрабатывать в ручном режиме.
---
Xershi, чтение в ручном режиме подразумевает, что это чтение должен инициировать пользователь, правильно?
А на это как раз и не хотелось бы завязываться. Пользователь, согласно концепции, существо неразумное, он сам эти регистры проверять не будет, ему именно надо, чтобы выскочило сообщение на экран перед глазами.
Аналогичная задача у меня была при обратно передаче документов, из второй базы в первую. Но вторая база - это УПП, обычные формы. И там эта проблема сразу решилась путем вызова Сообщить( ).
А вот как быть в управляемом интерфейсе - понять не могу.
---
на ОФ процессы, которые запускает пользователь выполняются на клиенте. Контекст сервера есть только в регламентных заданиях.
В вашем случае нужно в процедуре перед записью или при записи вызвать ваш сервис. После его отработки, если есть ошибки задать пользователю вопрос и показать ошибки. Далее уже ответив на вопрос пользователь все пропустит или отменит запись и повторит операцию.
Судя по описанию, то что вам нужно.
---
Сохраняете массив сообщений в хранилище, потом получайте и сообщайте
---
ПоказатьОповещениеПользователя(). Справа в углу на панели задач появится
---
ПоказатьОповещениеПользователя() работает только на клиенте (толстом или тонком), а обращение ко второй базе идет в серверной процедуре.
(2) А как организовать получение информации? ВЕдь это должна быть обработка ожидания в какой-либо клиентской форме, и не факт, что пользовательеё откроет
---
Да регистр сведений. И все :) Чистить его после просмотра сообщений и все тут
---
danjer74, я понимаю, что хранить эту информацию надо будет в регистре сведений. Проблема в том, как организовать вывод это информации на экран, чтобы сообщения появлялись на экране сами, независимо от того, заглянет ли пользователь в этот регистр (он, конечно, туда смотреть не будет)
---
ВызватьИсключение(Сообщение об ошибке); ///Или не обязательно об ошибке

      ВызватьИсключение(Провелось Успешно!);
---
Будет немного "не красиво", но задачу решит )

P.S. Если у пользователя нет полных прав, то кнопка "Подробно" будет скрыта по идее )
---
При проведении в первой базе документа
создать переменную
АдресХранилища = ....
и отправить ее параметром куралесить на сервер

после завершения куралесий
Проверить, что содержится по АдресХранилища и если там массив
то сообщаем
---
VmvLer, у меня сделано несколько иначе - функция, вызывающая веб-сервис второй базы, возвращает значение с текстом сообщения об ошибке. Но происходит это на сервере, и сообщение вывести некуда - процедура Сообщить( ) не отрабатывает. Вернее, отрабатывает, но сообщение никуда не выводится
(7) Если я поставлю ВызватьИсключение( ), то отменится проведение заказа в первой базе, чего быть не должно
---
Если я поставлю ВызватьИсключение( ), то отменится проведение заказа в первой базе, чего быть не должно

Поставь после проведения документа, не должно отменятся ...
---
ПоказатьОповещениеПользователя() - тоже рабочий вариант, вы же как то вызываете серверную процедуру ...
---
user5300, Серверная процедура вызывается из ОбработкаПроведения( ) модуля объекта документа-заказа. Я привязался именно к этой процедуре, поскольку провести заказ пользователь может не только из формы заказа, но из формы списка заказов через контекстное меню "Провести"

(16) Xershi, к сожалению, "если есть ошибки задать пользователю вопрос и показать ошибки. Далее уже ответив на вопрос пользователь все пропустит или отменить запись и повторит операцию" - это не вариант. Проблема в том, что ошибка создания документа во второй базе НЕ ДОЛЖНА влиять на проведение документа в первой базе. Т.е. диалогового окна, на время отработки которого приостанавливается процесс проведения документа в первой базе с последующим повторением операции, быть не должно - документ по любому должен провестись сразу. Просто каким-то образом должно выйти на экран сообщение об ошибке во второй базе, если она будет.

(17) starjevschik, "ОбщегоНазначенияКлиентСервер.СообщитьПользователю()" - именно она у меня и не сработала. Когда я писал, что Сообщить( ) ничего не выводит, я эту процедуру и имел в виду - Сообщить( ) вызвана оттуда.
---
Можно переменную добавить...

```1c
    Процедура ОбработкаПроведения( )
    Сообщение = ";
    ПровестиВДругойБазе(Сообщение );
    Сообщить(Сообщение);
    Конецпроцедуры

    Процедура ПровестиВДругойБазе( Сообщение )
    ....
    Сообщение = ОбмнеПоWS();
    .....
    Конецпроцедуры
```
---
user5300, так проблема в том, что сообщение не выведется - форма проведения закроется
(22) dhurricane, спасибо, это вариант, но только для случая, когда документ проводится из формы. Там можно менять предопределенные процедуры и реализовать Ваш алгоритм. А вот что делать, если документ проводится из формы списка заказов - там ведь привязываться не к чему. Правда, можно проведение из формы списка запретить путем редактирования списка команд формы - что, если сделать так? Учитывая, что из формы списка по правой кнопке документы проводят только особо одаренные пользователи? А в модуле формы реализовать Ваш вариант.
---
Так в форме списка ничего дополнительно делать и не нужно. Она же не закрывается, стало быть пользователь увидит свои сообщения.
---
dhurricane, Вы правы - при проведении из списка сообщение отображается. Тогда получается, что Ваш вариант не пройдет только в случае, если пользователь откроет документ-заказ из формы списка, а потом эту форму списка закроет, а с заказом будет работать.
Тогда получается, что можно вывести сообщения во все открытые формы? Не очень хорошо, конечно, но другого варианта я не вижу

Кроме того, Вы пишете:
"Решение довольно громоздкое. Плюс Вам необходимо решить еще две проблемы:
1. Наличие признака, что после записи объекта форма действительно будет закрыта. Иначе нет смысла переопределять идентификатор назначения сообщений. Если пользуетесь УТ и команды проведения не типовые, то они должны передавать признак "ПринудительноЗакрытьФорму" в параметрах записи."

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

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

А это как раз и есть случай открытия из журнала документов. Владелец - таблица формы списка, а родитель владельца - сама форма списка.
---
Все на Ваше усмотрение. Если сообщение действительно столь критично, что его необходимо гарантировано вывести пользователю, даже в столь редком сценарии, как закрытие формы владельца, то я бы таки рекомендовал последовать совету работать с новым регистром и обработчиком оповещения. Да еще и форму для сообщения свою создать, чтобы пользователь кнопку "Все понял" нажал, иначе окно откроется чуть позже повторно.
---
Так это оповещение должно опять же в какой-то форме ловиться. Получается, его надо прописывать во всех возможных формах? Ведь мы не значем, какую форму пользователь откроет следующую
---
Нет, зачем? Можно запустить глобальный обработчик оповещения в модуле управляемого приложения, а в обработчике проверять записи регистра и при необходимости показывать свою форму с сообщением, открывая ее независимо от других (или же блокируя интерфейс).
---
dhurricane, огромное Вам спасибо, это, действительно, единственно возможное решение! Так и реализую.
---
Так же недавно реализовывал задачу. Оповещение формировалось пользователям с определенной ролью, появлялось с определенной периодичностью пока пользователь не нажимал кнопку "ознакомлен". Записи в регистре формировались программно, в зависимости от событий. так же система отслеживала, чтобы оповещения не дублировались по одному и тому же объекту.
---
Ну и, конечно, не закрыть случай, когда проведение заказа выполнено программным путем откуда-нибудь
---
Форма проведения из какой формы вызывается ??
---
Кстати можно проверку добавить, т.е. если проведен успешно то

```1c
    Процедура ОбработкаПроведения( )
    Результат = РезультатWS(); ///Возвращаемый результат из 2 базы
    Если Результат = Истина Тогда ///Либо так: Если Лев(Результат,7) = "Успешно" Тогда
    Объект.Записать(РежимЗаписи.Проведение);
    Конецесли
    ВызватьИсключение(Результат );
    Конецпроцедуры
```

Либо только ошибку выводить:

```1c
    Процедура ОбработкаПроведения( )
    Результат = РезультатWS(); ///Возвращаемый результат из 2 базы
    Если Результат = ложьТогда ///Либо так: Если Лев(Результат,5) = "Ошибка" Тогда
    ВызватьИсключение(Результат ); ///Если документ не провелся во 2 базе, по сути он и не должен провестись в этой
    Конецесли
    Конецпроцедуры
```
---
тогда в (12) все написано. Как вам писать алгоритмы решайте сами.
Про СВ вам еще написали. Но это функциональность КОРП. Возможно технически не получится использовать.
---
Есть еще один подход, возможно он Вам подойдет. Не самое изящное, но тем не менее.

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

```1c
    ЭтотОбъект.ДополнительныеСвойства.Вставить("ЧтоТоПошлоНеТак", Истина);
```

2. В обработчике "ПослеЗаписиНаСервере" формы анализируете наличие ключа, и если он есть, получаете сформированные сообщения пользователю и отправляете их на клиент.

```1c
    Если ТекущийОбъект.ДополнительныеСвойства.Свойство("ЧтоТоПошлоНеТак") Тогда
    МассивСообщений = ПолучитьСообщенияПользователю(Истина);
    ПараметрыЗаписи.Вставить("МассивСообщений", МассивСообщений);
    КонецЕсли;
```

3. Наконец в клиентском обработчике формы "ПослеЗаписи" обрабатываете полученный массив:

```1c
    Если ПараметрыЗаписи.Свойство("МассивСообщений") И ВладелецФормы <> Неопределено Тогда
    Для каждого ПерехваченноеСообщение Из ПараметрыЗаписи.МассивСообщений Цикл
    ПерехваченноеСообщение.ИдентификаторНазначения = ВладелецФормы.УникальныйИдентификатор;
    ПерехваченноеСообщение.Сообщить();
    КонецЦикла;
    КонецЕсли;
```

Решение довольно громоздкое. Плюс Вам необходимо решить еще две проблемы:
1. Наличие признака, что после записи объекта форма действительно будет закрыта. Иначе нет смысла переопределять идентификатор назначения сообщений. Если пользуетесь УТ и команды проведения не типовые, то они должны передавать признак "ПринудительноЗакрытьФорму" в параметрах записи.
2. Владельцем формы может оказаться не только форма, но некий элемент формы, например таблица. В этом случае нужно рекурсивно "подняться" вверх по родителям элементов, чтобы таки добраться до самой управляемой формы.
---
И почему сервер взаимодействия так не любят? Удобнейшая вещь.
---
в стандартных конфигурациях есть процедура
ОбщегоНазначенияКлиентСервер.СообщитьПользователю()
---
при закрытии формы, пользователь ничего не увидит. Код вызывается в модуле формы.
Если переписать код на другой объект. то сработает.