Имя: Пароль:
1C
1С v8
Запись в 1С 8.2 БП 3.0 из внешнего приложения через OLE
0 alexei_aa
 
22.11.12
09:35
При переходе с 1С 7.7 на 8.2 пришлось переписывать связь с внешним приложением. Интеграция с 1С 7.7 работает замечательно и много где расписана, а вот с 8.2 дела обстоят хуже – информации практически нет.
Но все же: запуск 1С 8.2 реализован, чтение данных из 1С 8.2 реализовать тоже удалось. А вот с записью возникли сложности, поэтому прошу помощи. Произвожу создание и запись контрагентов следующим способом:
var OneSv8Obj, Ware, ObjForm: OleVariant;
...
Ware := OneSv8Obj.Справочники.Контрагенты.СоздатьЭлемент();
Ware.ЮридическоеФизическоеЛицо := OneSv8Obj.Перечисления.ЮридическоеФизическоеЛицо.ЮридическоеЛицо;
Ware.Наименование := edShortName.Text;
Ware.НаименованиеПолное := edFullName.Text;
Ware.ИНН := edINN.Text;
Ware.КПП := edKPP.Text;
Ware.КодПоОКПО := edOKPO.Text;
...
Ware.Записать();

На последнюю строчку ругается: «Ошибка при выполнении обработчика – ‘ПередЗаписью’. Попытка передачи с клиента на сервер мутабельного значения 1-го параметра метода Обмен1СКЗБухгалтерия30ПередЗаписью ()»

Сами данные в 1С из внешнего приложения передаются. Это можно видеть, если запустить форму следующим способом:
ObjForm := Ware1.ПолучитьФорму();
ObjForm.Открыть('ФормаЭлемента');

Всю голову сломал – как побороть не знаю. По всей видимости какие-то настройки 1С.
Help!!!
1 Спящая
 
22.11.12
09:39
(0) как одно из предположений
записывать непосредственно элементы справочников в процедуре с прямым указанием
&НаСервере
2 alexei_aa
 
22.11.12
11:39
Дело в том, что записывать в 1С придется не только в справочники, но и в другие места. Например создавать акты, счета и счета-фактуры.
Просто начал с контрагентов.
Создавать для этого дополнительные процедуры на сервере не совсем логично.
3 Спящая
 
22.11.12
14:17
(2) ну так достаточно одной функции для записи объекта на сервере и просто к ней обращаться при записи любого объекта
что-то типа такого :
&НаСервере
Функция ЗаписьНаСеревере(НужныйОбъект)
   Возврат  НужныйОбъект.Записать()
КонецФункции
4 rinatru
 
22.11.12
14:22
(3) не взлетит. скорее всего там подписка на событие срабатывает при записи. копать надо там
5 alexei_aa
 
22.11.12
15:38
Подписка срабатывает, даже знаю какая:
"Обмен1СКАМИНЗарплатаБухгалтерия30ЗарегистрироватьИзменение"
как раз на событие ПередЗаписью.
В обработчике события у этой подписки "ОбменДаннымиСобытияБП.Обмен1СКЗБухгалтерия30ПередЗаписью".
Процедура Обмен1СКЗБухгалтерия30ПередЗаписью(Источник, Отказ) Экспорт
ОбменДаннымиСобытия.МеханизмРегистрацииОбъектовПередЗаписью("Обмен1С_КАМИН_ЗарплатаБухгалтерия30", Источник, Отказ);
КонецПроцедуры

Процедура МеханизмРегистрацииОбъектовПередЗаписью(ИмяПланаОбмена, Источник, Отказ) Экспорт
МеханизмРегистрацииОбъектов(ИмяПланаОбмена, Источник, Отказ);
КонецПроцедуры

Процедура МеханизмРегистрацииОбъектов(ИмяПланаОбмена,
Объект,
Отказ,
РежимЗаписи = Неопределено,
Замещение = Ложь,
ЭтоРегистр = Ложь,
ЭтоУдалениеОбъекта = Ложь,
ЭтоКонстанта = Ложь
)
ОтключитьМеханизмРегистрацииОбъектов = Ложь;
Если Объект.ДополнительныеСвойства.Свойство("ОтключитьМеханизмРегистрацииОбъектов", ОтключитьМеханизмРегистрацииОбъектов)
И ОтключитьМеханизмРегистрацииОбъектов = Истина Тогда
Возврат; // отказались от выполнения
КонецЕсли;
ОбъектМетаданных = Объект.Метаданные();
Если ОбщегоНазначенияПовтИсп.РазделениеВключено() Тогда
Если Не РазделенныйПланОбмена(ИмяПланаОбмена) Тогда
ВызватьИсключение НСтр("ru = 'Регистрация изменений для неразделенных планов обмена не поддерживается.'");
КонецЕсли;
Если ОбщегоНазначенияПовтИсп.ДоступноИспользованиеРазделенныхДанных() Тогда
Если Не РазделенныеДанные(ОбъектМетаданных) Тогда
ВызватьИсключение НСтр("ru = 'Регистрация изменений неразделенных данных в разделенном режиме.'");
КонецЕсли;
Иначе
Если РазделенныеДанные(ОбъектМетаданных) Тогда
ВызватьИсключение НСтр("ru = 'Регистрация изменений разделенных данных в неразделенном режиме.'");
Иначе
// Для неразделенных данных в неразделенном режиме выполняем регистрацию изменений данных
// на всех узлах разделенных планов обмена.
// Использование механизма правил регистрации в этом режиме не поддерживается.
ТекстЗапроса =
"ВЫБРАТЬ
| ПланОбмена.Ссылка КАК Получатель
|ИЗ
| ПланОбмена.[ИмяПланаОбмена] КАК ПланОбмена
|ГДЕ
| НЕ ПланОбмена.ЭтотУзел
| И НЕ ПланОбмена.ПометкаУдаления";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяПланаОбмена]", ИмяПланаОбмена);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Попытка
Получатели = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Получатель");
Исключение
ТекстЗапроса =
"ВЫБРАТЬ
| ПланОбмена.Ссылка КАК Получатель
|ИЗ
| ПланОбмена.[ИмяПланаОбмена] КАК ПланОбмена
|ГДЕ
| НЕ ПланОбмена.ПометкаУдаления";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяПланаОбмена]", ИмяПланаОбмена);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Получатели = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Получатель");
КонецПопытки;
Для Каждого Получатель Из Получатели Цикл
Попытка
Объект.ОбменДанными.Получатели.Добавить(Получатель);
Исключение
// Обработка исключения не требуется.
// Ожидаемо наличие в параметре "Получатели" преопределенных узлов разделенных планов обмена.
КонецПопытки;
КонецЦикла;
КонецЕсли;
Возврат; // Не ОбщегоНазначенияПовтИсп.ДоступноИспользованиеРазделенныхДанных()
КонецЕсли;
КонецЕсли;
// проверяем актуальность кеша сеанса для МРО
ОбменДаннымиВызовСервера.ПроверитьКэшМеханизмаРегистрацииОбъектов();
Если НЕ ОбменДаннымиВызовСервера.ОбменДаннымиВключен() Тогда
Возврат;
КонецЕсли;
// определяем необходимость регистрации объекта на узле отправителе
РегистрироватьОбъектНаУзлеОтправителе = Ложь;
Если Объект.ДополнительныеСвойства.Свойство("РегистрироватьОбъектНаУзлеОтправителе", РегистрироватьОбъектНаУзлеОтправителе)
И РегистрироватьОбъектНаУзлеОтправителе = Истина Тогда
// обнуляем ссылку на узел отправитель
Объект.ОбменДанными.Отправитель = Неопределено;
КонецЕсли;
// при физическом удалении объекта ВРО не выполняем
ЗарегистрироватьОбъектКВыгрузке = ЭтоРегистр ИЛИ ЭтоУдалениеОбъекта ИЛИ ЭтоКонстанта;
ОбъектМодифицирован = ОбъектМодифицированДляПланаОбмена(Объект, ОбъектМетаданных, ИмяПланаОбмена, РежимЗаписи, ЗарегистрироватьОбъектКВыгрузке);
Если Не ОбъектМодифицирован Тогда
Если ОбменДаннымиПовтИсп.АвтоРегистрацияРазрешена(ИмяПланаОбмена, ОбъектМетаданных.ПолноеИмя()) Тогда
// если объект не модифицирован и он регистрируется автоматически,
// то удаляем все узлы по авторегистрации для текущего плана обмена
СократитьПолучателей(Объект, ВсеУзлыПланаОбмена(ИмяПланаОбмена));
КонецЕсли;
// объект не модифицирован относительно текущего плана обмена
// регистрацию на узлах этого плана обмена не выполняем
Возврат;
КонецЕсли;
Если Не ОбменДаннымиПовтИсп.АвтоРегистрацияРазрешена(ИмяПланаОбмена, ОбъектМетаданных.ПолноеИмя()) Тогда
ПроверятьСсылку = ?(ЭтоРегистр ИЛИ ЭтоКонстанта, Ложь, Не Объект.ЭтоНовый() И Не ЭтоУдалениеОбъекта);
МассивУзловРезультат = Новый Массив;
ВыполнитьПравилаРегистрацииОбъектовДляПланаОбмена(МассивУзловРезультат, Объект, ИмяПланаОбмена, ОбъектМетаданных, ПроверятьСсылку, ЭтоРегистр, ЭтоУдалениеОбъекта, Замещение, РежимЗаписи);
// обработчик "После определения получателей"
ОбменДаннымиПереопределяемый.ПослеОпределенияПолучателей(Объект, МассивУзловРезультат, ИмяПланаОбмена);
ДополнитьПолучателей(Объект, МассивУзловРезультат);
КонецЕсли;
КонецПроцедуры

Куда дальше копать?
6 Hmster
 
22.11.12
15:44
ты к 1С как конектишься?
была похожая трабла с УТ11.
смотреть на галки общего модуля куда ссылается данная подписка
7 alexei_aa
 
22.11.12
16:05
Коннект вот такой:
var Result: OleVariant;
Result := CreateOleObject('V82.Application');
Result.Connect('Srvr="Server";Ref="BaseName";Usr="User1C";Pwd="Password1C"');
Где какие галки смотреть?
8 Hmster
 
22.11.12
16:17
фишка в том что у свойства общего модуля не стоит/ стоит не та галка из возможных (сервер, клиент, внешнее соединение)
9 Hmster
 
22.11.12
16:17
с другой стороны ты как приложение отдельное запускаешь и этого быть не должно
10 Hmster
 
22.11.12
16:19
возможность редактирования включал?
11 Hmster
 
22.11.12
16:23
попробуй
Соединитель = Новый ComОбъект("V82.COMConnector");
БД = Соединитель.Connect(СтрокаСоединения);

строка соединения вроде бы такая же
конвертнешь в свое из 1С сам
12 Hmster
 
22.11.12
16:26
отличия в соединении:
твой вариант - открывается как приложение
вариант (11) - открывается как внешнее соединение
13 alexei_aa
 
22.11.12
16:48
В общих модулях самих модулей слишком много и где какие галки нужны не совсем понятно.
"возможность редактирования включал?" - это как?

Соединение через COM тоже пробовал - там еще больше сложностей. Через OLE уже реализовано чтение необходимых данных.
14 Hmster
 
22.11.12
16:55
ОбменДаннымиСобытия
ОбменДаннымиСобытияБП

какие галки стоят у общих модулей?
возможность вносить изменения включал ?
15 Hmster
 
22.11.12
16:57
попробуй в строке соединения указать параметр подключения в управляемом приложении
16 Hmster
 
22.11.12
16:58
попробуй на этих модулях поставить клиент
17 alexei_aa
 
22.11.12
17:14
ОбменДаннымиСобытия и ОбменДаннымиСобытияБП стоят галки Клиент (управляемое приложение), Сервер и Внешнее соединение. Еще стоит галка "Вызов сервера".
Пробую с RunModeOrdinaryApplication и RunModeManagedApplication
18 alexei_aa
 
22.11.12
17:29
"Параметр подключения в управляемом приложении" не влияет на работу в данном случае - ошибка осталась.
19 acsent
 
22.11.12
17:32
у модуля с подпиской не все нужные галки стоят
20 Hmster
 
22.11.12
17:32
управляемое и обычное приложение когда работают с клиент сервером по разному относятся к объектам.
в обычном приложении сервер не понимает объекты и вываливается.
что самое интресное пробовал эксперимент. открыл в базе 2 формы: обычную и управляемую. пробовал записать обект. обычная форма спотыкалась на подписке событий как у тебя а управялемая нормально работала.
21 acsent
 
22.11.12
17:33
Толстый клиент галка нужна
22 Hmster
 
22.11.12
17:37
галка из (21) есть ?
23 alexei_aa
 
22.11.12
17:55
Есть.
Запускается именно толствый клиент. Пробовал в разных режимах - обычный и управляемый.
Тонкого клиента можно запустить через 'V82c.Application', но там даже чтение не реализовать.
24 Hmster
 
22.11.12
20:33
понавключают тут, а потом не работает!
ваша ошибка есть дело рук того кто включил обычное приложение.
юзать желательно V82.COMConnector. работает намного быстрее.
25 Новиков
 
22.11.12
21:05
ответ в (3) тронул дедушку Новикова, можно сказать, до слез ;)
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс