Суть проблемы
Существует интересная проблема — соединяясь с платформой 8.х по OLE или COM-соединению из платформы 7.7 мы можем получить значение «Истина» как число «-1» и «Ложь» как число «0», но вернуть в 8.х как булевое обратно не можем. Получаем ошибку несоответствия типов.
Например, присвоение ДокументОбъект.ОбменДанными.Загрузка = 0 работать не будет. Важным моментом является так же то, что во многих случаях может быть нежелательным редактировать конфигурацию 8.х, в которую нужно передать значение «Истина»/»Ложь», назовем ее конфигурацией-приемником.
Детально сабж обсуждался здесь:
http://1cniku.ru/Articles/V8OLE.html#trabl1
http://www.forum.mista.ru/topic.php?id=149298
Решение проблемы
Не найдя решения проблемы без модификации конфигурации-приемника, я решил данную проблему при помощи новой конфигурации 8.х содержащей процедуры, которые заворачивают присваивание булевого значения «Истина»/»Ложь» необходимому реквизиту или свойству.
Для демонстрации данного решения я использовал платформу 8.1 и создал 2 конфигурации:
Demo81 –конфигурация-приемник, которую нельзя изменять, с одним документом «Док».
Wrapper – искусственная конфигурация, которая «умеет» присваивать булевое значение «Истина» нужному свойству или реквизиту
Метод присвоения выглядит следующим образом:
Процедура УстановитьЗначениеИстина(Объект, Флаг) Экспорт
Если Флаг = 0 Тогда
Объект.ОбменДанными.Загрузка = Ложь;
Иначе
Объект.ОбменДанными.Загрузка = Истина;
КонецЕсли;
КонецПроцедуры
Для того, чтобы данный метод можно было вызывать по COM-соединению, достаточно сделать его экспортным и поместить в модуль внешнего соединения. Аналогично, для вызова из OLE-соединения достаточно сделать его экспортным и поместить в модуль приложения.
Управляет соединениями с этими конфигурациями обработка для 7.7 Test.ert с модулем следующего содержания:
//*******************************************
Процедура Сформировать()
//COM
V81 = СоздатьОбъект(«V81.COMConnector»);
СоединениеВрапперCOM = «»;
Попытка
СоединениеВрапперCOM = V81.Connect («File=»»»+СокрЛП(ПутьКВрапперу)+«»»;»);
Исключение
Сообщить(«Ошибка подключения к Врапперу»,«!!!»);
Возврат;
КонецПопытки;
//OLE
СоединениеВрапперOLE =СоздатьОбъект(«V81.Application»);
Результат = СоединениеВрапперOLE.Connect («File=»»»+СокрЛП(ПутьКВрапперу)+«»»;»);
Если Результат = 0 Тогда
Сообщить(«Ошибка подключения к Врапперу»,«!!!»);
Возврат;
КонецЕсли;
//Test
СоединениеПриемник = «»;
Попытка
СоединениеПриемник = V81.Connect («File=»»»+СокрЛП(ПутьКПриемнику)+«»»;»);
Исключение
Сообщить(«Ошибка подключения к Примнику»,«!!!»);
Возврат;
КонецПопытки;
ДокПриемник = СоединениеПриемник.Документы.Док.СоздатьДокумент();
Сообщить(ДокПриемник.ОбменДанными.Загрузка); //По-умолчанию значение Ложь, вернется 0
СоединениеВрапперCOM.УстановитьЗначениеИстина(ДокПриемник, —1); //Успешно присваиваем значение Истина
Сообщить(ДокПриемник.ОбменДанными.Загрузка); //Получим числовое значение Ложь, вернется -1
СоединениеВрапперOLE.УстановитьЗначениеИстина(ДокПриемник, 0); //Успешно присваиваем значение Ложь
Сообщить(ДокПриемник.ОбменДанными.Загрузка); //Получим числовое значение Ложь, вернется 0
ДокПриемник.ОбменДанными.Загрузка = 0; //Здесь получим ошибку несоответствия типов
СоединениеПриемник = «»;
СоединениеВрапперCOM = «»;
СоединениеВрапперOLE = «»;
КонецПроцедуры
ПутьКВрапперу = «D:1CBASEWrapper»; //Путь к конфигурации-заворачивателю
ПутьКПриемнику = «D:1CBASEDemo81»; //Путь к конфигурации-приемнику
Таким образом, можно присваивать булевое значение не редактируя конфигурацию-приемник.
Можно реализовать присвоение Истина/Ложь и при помощи внешней компоненты, но у данного подхода есть свои плюсы:
- Не нужно регистрировать внешнюю компоненту т.к. объекты «V81.COMConnector» и «V81.Application» уже зарегистрированы в системе (по условию проблемы).
- Очень простая реализация заворачивателя.
- Для доработки этого решения не требуются никакие IDE, кроме конфигуратора.
Демонстрационная обработка и конфигурации доступны для скачивания.
А вот так не проще:
Было бы проще, если бы работало 🙂
Правое значение 1С 7.7 преобразует в -1 или 0 и в результате получишь ошибку «Несоответствие типов».
Уже после статьи придумал более изящное решение, правда не универсальное, так не передашь Истину, скажем функции, но зато без доп. конфигураций :
Показать
Я вообще не понял, зачем такой велосипед, когда можно написать
Объект.ОбменДанными.Загрузка = 1; //Истина
Объект.ОбменДанными.Загрузка = 0; // Ложь
?
…
Собственно, зачем изобретать такой велосипед описано в разделе «Суть проблемы» и во внешних ссылках на данный сабж.
(2)
Было бы проще, если бы работало 🙂
Я вообще-то код проверял. У меня работает.См. (7)Странно. Может в новых релизах 1С что-то улучшили.
У меня не работает в связке 1С 7.70.025 — 1С 8.1.15.14.
Хм.. Беру свои слова назад. Описываемая мной конструкция работает при присвоении значений свойствам объекта типа Булево (как впрочем и то, что описано в (3), но для данного случая действительно не работает — видимо косяк в платформе. Тогда плюс за публикацию.
(4)
Может для 8.0-8.1 это и проблема, на 8.2 установка 1 или 0 прекрасно работает и не возникает никакого несоответствия типов
(8) Alxd,
Конвертнул прикрепленную к публикации конфигурацию-приемник «Demo81» в 8.2. Попробовал на релизе 8.2.13.219 в режиме совместимости с 8.1 и без. Эффект из 7.7 оба раза одинаковый:
(9) Ну вообще забавно конечно. Скорее тут частный случай какой-то
ДокПриемник.Отменен = 1; // Все хорошо (Отменен — Тип: Булево)
ДокПриемник.ОбменДанными.Загрузка = 1; // Несоответствие типов
Кстати, как альтернативный вариант — засунуть процедуру УстановитьЗначениеИстина(Объект, Флаг) в модуль объекта внешней обработки с ключевым словом Экспорт. Тогда вызов будет:
Кстати, как альтернативный вариант — засунуть процедуру УстановитьЗначениеИстина(Объект, Флаг) в модуль объекта внешней обработки с ключевым словом Экспорт. Тогда вызов будет…
Да, тоже можно взять на заметку 🙂
А почему бы не так?
ДокПриемник.ОбменДанными.Загрузка = СоединениеВрапперOLE.Вычислить(«ИСТИНА»);
ДокПриемник.ОбменДанными.Загрузка = СоединениеВрапперOLE.Вычислить(«ЛОЖЬ»);