Итак, имеется две базы 1С (Бухгалтерия и Автосервис, на базе УНФ) с настроенным двусторонним обменом.
Задача состоит в том, чтобы при проведении документа "ПриходнаяНакладная" оперативно отразить данные по приходу товара в другой базе, чтобы этот товар можно было уже вносить в Заказ-наряды. Товар поступает к нам примерно 3-4 раза в день.
Итак, товар приходуем в одной базе 1С (Бухгалтерия), затем оперативно перегружаем приход в другую базу 1С(Автосервис).
На данный момент, ручная синхронизация(обмен) по данной задаче работает. Наша цель - Автоматизировать.
....
Когда я копал, каким же мне методом это сделать... друг подсказал реализовать через WEB-Сервисы. Копал я WEB-Сервисы, но был вариант такой, что подключаюсь к базе Бухгалтерия, где создана "ПриходнаяНакладная" читаю данные и загружаю в базу Автосервис, т.е. необходимо было перегружать сами данные.
Я так подумал... почему бы мне после проведения документа не запустить Синхронизацию программно. Ну хорошо, синхронизацию в Бухгалтерии я запущу, а как ее запустить в Автосервис. Вот для этого и мне и пригодились WEB-Сервисы.
В итоге все свелось к таким пунктам:
1. Проведение документа "ПриходнаяНакладная" и запуск синхронизации в 1С:Бухгалтерия.
Почему с задержкой? Я подумал, что выполнение синхронизации и запись в файл занимает некоторое время, поэтому чтобы все успелось записаться, беру время с запасом. Потом я время уменьшил до 45 сек.
....
1. Проведение документа "ПриходнаяНакладная" и запуск синхронизации в 1С:Бухгалтерия.
Запуск синхронизации(обмена) сводится к запуску самого сценария синхронизации данных. В 1С:Бухгалтерия в документе "ПриходнаяНакладная" в модуле документа в событии ПослеЗаписиНаСервере пишу сценарий запуска сценария обмена с 1С:Автосервис в данной конфигурации:
&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
Отказ = Ложь;
// Запускаем выполнение обмена в Бухгалтерии.
СценарийОбменаСсылка = Справочники.СценарииОбменовДанными.НайтиПоНаименованию("Сценарий синхронизации для Автосервис 1.6");
ОбменДаннымиСервер.ВыполнитьОбменДаннымиПоСценариюОбменаДанными(Отказ, СценарийОбменаСсылка);
// Обновляем данных табличной части сценария обмена.
ОбновитьСостоянияОбменовДанными(СценарийОбменаСсылка);
КонецПроцедуры
Наименование нужного нам сценария синхронизации данных можно найти в справочнике "Сценарии синхронизации данных".
Данный код был взят из справочника "СценарииОбменовДанными" из модуля формы элемента, за основу была взята процедура "ВыполнитьОбменДаннымиПоСтрокеНастройки"
Процедура ОбновитьСостоянияОбменовДанными была взята также из этого модуля и модифицированна: а) Добавляем параметр в процедуру "ОбновитьСостоянияОбменовДанными" (необходимо передать ссылку на нужный нам сценарий для выполнения) б) в самом вызове процедуры ставим аргумент. в) Для загрузки получаем объект сценария
При этом сам запрос не меняется.
Итоговый код процедуры ОбновитьСостоянияОбменовДанными:
&НаСервере
Процедура ОбновитьСостоянияОбменовДанными(СценарийОбменаСсылка)
ТекстЗапроса = "
|ВЫБРАТЬ
| СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы,
| СценарииОбменовДаннымиНастройкиОбмена.ВидТранспортаОбмена,
| СценарииОбменовДаннымиНастройкиОбмена.ВыполняемоеДействие,
| ВЫБОР
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена ЕСТЬ NULL
| ТОГДА 0
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято)
| ТОГДА 2
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями)
| ТОГДА 2
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Выполнено)
| ТОГДА 0
| ИНАЧЕ 1
| КОНЕЦ КАК РезультатВыполненияОбмена
|ИЗ
| Справочник.СценарииОбменовДанными.НастройкиОбмена КАК СценарииОбменовДаннымиНастройкиОбмена
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
| ПО СостоянияОбменовДанными.УзелИнформационнойБазы = СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = СценарииОбменовДаннымиНастройкиОбмена.ВыполняемоеДействие
|ГДЕ
| СценарииОбменовДаннымиНастройкиОбмена.Ссылка = &Ссылка
|УПОРЯДОЧИТЬ ПО
| СценарииОбменовДаннымиНастройкиОбмена.НомерСтроки ВОЗР
|";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Ссылка", СценарийОбменаСсылка);
// Получаем объект сценария
СценарийОбменаОбъект = СценарийОбменаСсылка.ПолучитьОбъект();
СценарийОбменаОбъект.НастройкиОбмена.Загрузить(Запрос.Выполнить().Выгрузить());
КонецПроцедуры
Для автоматического запуска сценария синхронизации в 1С:Автосервис понадобились WEB-Сервисы. Т.е суть в том, что в 1С-Автосервис создаем WEB-Сервис, публикуем базу, затем он становится доступен для использования внешними приложениями (мне напомнил принцип работы API). Наверное это и есть своего рода API в 1С.
Создание WEB-Сервиса.
WEB-Сервис я создавал в расширении. Назвал ObmenWS с одной единственной функцией запускаемой сценарий обмена (ЕxchangeStart). Параметры функция не имеет. Возвращаемое значение Истина, всегда.
На вкладке Прочее задал данные настройки:
Свойства Функции ЕxchangeStart:
Проваливаясь в процедуру ЕxchangeStart:
Функция ЕxchangeStart()
Отказ = Ложь;
// Запускаем выполнение обмена.
СценарийОбменаСсылка = Справочники.СценарииОбменовДанными.НайтиПоНаименованию("Сценарий синхронизации для Бухгалтерия предприятия 2.1");
ОбменДаннымиСервер.ВыполнитьОбменДаннымиПоСценариюОбменаДанными(Отказ, СценарийОбменаСсылка);
// Обновляем данных табличной части сценария обмена.
ОбновитьСостоянияОбменовДанными(СценарийОбменаСсылка);
Возврат Истина;
КонецФункции
&НаСервере
Процедура ОбновитьСостоянияОбменовДанными(СценарийОбменаСсылка)
ТекстЗапроса = "
|ВЫБРАТЬ
| СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы,
| СценарииОбменовДаннымиНастройкиОбмена.ВидТранспортаОбмена,
| СценарииОбменовДаннымиНастройкиОбмена.ВыполняемоеДействие,
| ВЫБОР
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена ЕСТЬ NULL
| ТОГДА 0
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято)
| ТОГДА 2
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями)
| ТОГДА 2
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Выполнено)
| ТОГДА 0
| ИНАЧЕ 1
| КОНЕЦ КАК РезультатВыполненияОбмена
|ИЗ
| Справочник.СценарииОбменовДанными.НастройкиОбмена КАК СценарииОбменовДаннымиНастройкиОбмена
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
| ПО СостоянияОбменовДанными.УзелИнформационнойБазы = СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = СценарииОбменовДаннымиНастройкиОбмена.ВыполняемоеДействие
|ГДЕ
| СценарииОбменовДаннымиНастройкиОбмена.Ссылка = &Ссылка
|УПОРЯДОЧИТЬ ПО
| СценарииОбменовДаннымиНастройкиОбмена.НомерСтроки ВОЗР
|";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Ссылка", СценарийОбменаСсылка);
СценарийОбменаОбъект = СценарийОбменаСсылка.ПолучитьОбъект();
СценарийОбменаОбъект.НастройкиОбмена.Загрузить(Запрос.Выполнить().Выгрузить());
КонецПроцедуры
Данный код я также беру из справочника "СценарииОбменовДанными" из модуля формы элемента, за основу была взята процедура "ВыполнитьОбменДаннымиПоСтрокеНастройки" но только уже в конфигурации 1С:Автосервис.
Процедура ОбновитьСостоянияОбменовДанными была взята также из этого модуля и модифицированна как в прошлом случае.
....
Публикация базы.
Итак, WEB-Сервис создан, осталось опубликовать базу. У меня она опубликована была уже, поэтому нужно только переопубликовать. Но перед публикацией поставьте галочку "Публиковать WEB-Сервисы расширений по умолчанию". Тогда наш WEB-Сервис из расширения будет работать.
Проверка доступности WEB-Сервиса.
После публикации проверим работоспособность WEB-Сервиса: запускаем строку https://*здесь ссылка на нашу базу*/ws/ObmenWS.1cws?wsdl Браузер должен вернуть XML-Строку. Может еще потребовать ввести логин и пароль - это от базы 1С.
Когда у нас все работает, тогда мы можем его уже дергать из другого приложения. Т.е он доступен и работает. Ура!
Вызов WEB-Сервиса из 1С:Бухгалтерия
Необходимо:
2. Создать регламентное(фоновое) задание.
3. Модифицировать процедуру ПослеЗаписиНаСервере нашего документа "ПриходнаяНакладная"
В 1С:Бухгалтерия в расширении я создаю новую WS-Ссылку. При создании указываю туда ссылку на мой созданный в 1С:Автосервис WEB-Сервис (https://*здесь ссылка на нашу базу*/ws/ObmenWS.1cws?wsdl). Если потребует ввести логин и пароль, то это от 1С (под кем будет запускаться обмен). Делаю по инструкции из ИТС https://its.1c.ru/db/v8doc#content:71:1:issogl2_17.3.1.%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9ws-%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8
Это статическая ссылка для подключения к WEB-Сервису.
Создать регламентное(фоновое) задание
Когда я думал над тем как же мне выполнить запуск WEB-Сервиса через 1 мин искал методы типа Sleep в 1С и тп. Но подумал почему бы не создать фоновое задание и каждый раз при проведении менять время выполнения (выполнять единократно). Итак, создаем регламентное задание. Свойства регламентного задания:
А метод регламентного задания выглядит так:
Процедура ВыполнениеОбменаАвтосервис() Экспорт
Прокси = WSСсылки.WSПодключениеАвтосервис.СоздатьWSПрокси("1.1.1.1", "ObmenWS", "ObmenWSSoap");
// Пользователь 1С под которым запускаем обмен (я создал отдельного с правами Админ)
Прокси.Пользователь = "Обмен1С";
Прокси.Пароль = "1111";
// Выполняем функцию обмена, возвращает Истина
СинхронизацияАвтосервисВыполнена = Прокси.ЕxchangeStart();
КонецПроцедуры
Модифицировать процедуру ПослеЗаписиНаСервере нашего документа "ПриходнаяНакладная"
Протестировав, понял, что 1 мин много, поставил 45 сек. Время можно подгонять под ваши нужды.
&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
Отказ = Ложь;
// Запускаем выполнение обмена в Бухгалтерии.
СценарийОбменаСсылка = Справочники.СценарииОбменовДанными.НайтиПоНаименованию("Сценарий синхронизации для Автосервис 1.6");
ОбменДаннымиСервер.ВыполнитьОбменДаннымиПоСценариюОбменаДанными(Отказ, СценарийОбменаСсылка);
// Обновляем данных табличной части сценария обмена.
ОбновитьСостоянияОбменовДанными(СценарийОбменаСсылка);
// Запускаем выполнение обмена в Автосервис
РеглЗад = РегламентныеЗадания.НайтиПредопределенное("ВыполнениеОбменаАвтосервис");
//создаем новое расписание
//единократно, в заданное время
НовоеРасп = Новый РасписаниеРегламентногоЗадания;
НовоеРасп.ПериодПовтораДней = 0;
// на 45 сек позже
НовоеРасп.ВремяНачала = ТекущаяДата() + 45;
РеглЗад.Расписание = НовоеРасп;
РеглЗад.Записать();
КонецПроцедуры
ИТОГ: После записи документа происходит синхронизация в текущей конфигурации 1С:Бухгалтерия и устанавливается регламентное задание на 45 сек позже. Регламентное задание дергает WEB-Сервис, который находится в 1С:Автосервис и запускает процедуру синхронизации там. Итак мы в течении 45 секунд получаем актуальную информацию в 1С:Автосервис.
....
Не претендую на идеал, т.к опыт работы с 1С небольшой.