При использовании системы 1С:Предприятие в качестве OLE Automation сервера следует учитывать следующую особенность: механизмы OLE Automation не допускают наличия у объекта свойств и методов, имеющих одинаковые имена. В то же время система 1С:Предприятие допускает ситуацию, когда один из реквизитов объекта (справочника, документа и т. п.) имеет имя, совпадающее с именем одного из его методов. В этом случае при попытке доступа через OLE Automation к объекту системы 1С:Предприятие, у которого имеет место такое совпадение имен может произойти конфликт. Например, имеется конфигурация системы 1С:Предприятие, в которой определен справочник Контрагенты. И у этого справочника имеется реквизит с именем Выбран. И данный факт не вызывает никаких проблем при работе с этим справочником непосредственно из встроенного языка системы 1С:Предприятие. И приведенный ниже фрагмент модуля будет работать вполне корректно:
Справ = СоздатьОбъект("Справочник.Контрагенты");
Справ.ВыбратьЭлементы();
Пока Справ.ПолучитьЭлемент() = 1
Цикл Если Справ.Выбран = 1 Тогда
// Некоторые действия
КонецЕсли;
Иное дело, если подобного рода действия попробовать осуществить из другой программы, используя механизмы OLE Automation . Предположим, что доступ через OLE Automation будет осуществляться из другого экземпляра системы 1С:Предприятие. Тогда фрагмент модуля в этом другом экземпляре должен иметь вид:
... v7 = СоздатьОбъект ("V77.Application");
init = v7.Initialize(v7.RMTrade, КоманднаяСтрока , "");
Справ = v7.EvalExpr("СоздатьОбъект(""Справочник.Контрагенты"")");
Справ.ВыбратьЭлементы();
Пока Справ.ПолучитьЭлемент() = 1 Цикл
Если Справ.Выбран = 1 Тогда
// Некоторые действия
КонецЕсли;
КонецЦикла; ...
В общем, приведенный фрагмент подобен предыдущему, за исключением того, что запускается другой экземпляр системы 1С:Предприятие и объект "Справочник.Контрагенты" создается в этом самом другом экземпляре. И в этом случае корректная работа данного фрагмента модуля невозможно. Все дело в том, что у справочника имеется метод Выбран(). И в данном случае механизм OLE Automation не сможет правильно отработать обращение к реквизиту Выбран и результат вычисления выражения Справ.Выбран в общем случае не определен. Таким образом для обеспечения работоспособности доступа к объектам системы 1С:Предприятие c использованием механизмов OLE Automation не следует допускать ситуаций, когда у одного объекта имеются реквизиты и методы с совпадающими именами.
При передаче параметров числовых значений системы 1С:Предприятие через механизмы OLE Automation следует помнить, что в этих случаях может происходить потеря точности числовых значений. Данное явление связано с тем, что числовые значения в системе 1С:Предприятие представляются в десятичной форме с фиксированной точкой, что обеспечивает лучшую точность при вычислениях в экономических задачах. В то же время при передаче числовых значений через механизмы OLE Automation , эти значения преобразуются в двоичную форму с плавающей точкой. А в двоичной форме с плавающей точкой не любое десятичное число может быть представлено абсолютно точно. Рассмотрим пример. Предположим, в глобальном модуле содержится функция, производящая некоторые вычисления и возвращающая результат этих вычислений:
Функция Вычисление() Экспорт
// Некоторые действия
Возврат Рез ;
КонецФункции
Данная функция может быть вызвана из другого экземпляра системы 1С:Предприятие через механизмы OLE Automation с помощью следующего фрагмента модуля:
...
v7 = СоздатьОбъект ("V77.Application");
init = v7.Initialize(v7.RMTrade, КоманднаяСтрока , "");
Результ = v7.EvalExpr("Вычисление()");
...
И если при такой форме вызова перед возвратом управления из функции Вычисление() ее переменная Рез будет иметь значение 1365.86, то переменная Результ вызывающего модуля будет иметь значение 1365.85999999999.
Потеря точности числа произошла по причине преобразований между десятичной формой представления числа с фиксированной точкой и двоичной формой с плавающей точкой. Как видно два этих числа отличаются незначительно, но этого различия достаточно, чтобы появилось неожиданное поведение операций сравнения, начались неожиданные искажения при вычислениях и т. п.. В данном случае потенциальных неприятностей можно избежать, если в вызывающем модуле округлить результат функции Вычисление() до требуемой точности.
Например:
...
Результ = Окр(Результ, 4);
...
Выполнение данного оператора приведет к тому, что переменная Результ примет значение 1365.86, что соответствует желаемому. Также следует помнить, что если бы результат функции Вычисление присваивался бы реквизиту формы, или атрибуту какого-либо объекта, имеющего числовой тип со специфицированной длиной и точностью, то необходимое округление было бы произведено автоматически.
При использовании механизмов OLE Automation для организации взаимодействия между двумя экземплярами системы 1С:Предприятие временами возникает необходимость в передаче между этими экземплярами значений таких типов, как справочник, документ, счет бухгалтерского учета и т. п.. То есть значений, типы которых определяются конфигурацией, а сами значения хранятся в информационной базе. Передать такие значения через OLE Automation напрямую невозможно, так как они определены только в пределах "своей" информационной базы, а за ее рамками могут быть бессмысленными.
В то же время в реальной жизни встречаются "родственные" информационные базы, имеющие либо одинаковую, либо очень похожую конфигурацию. И между этими информационными базами необходимо наладить обмен данными. Например, синхронизировать справочники или периодически передавать вновь введенные документы из одной информационной базы в другую. Для решения таких задач бывает весьма заманчиво использовать средства OLE Automation . Очевидно, что реквизиты справочников, а тем более документов могут иметь типы Справочник, Документ и т. п. . И тут возникает вопрос: а как быть со значениями этих типов при использовании OLE Automation ? Ведь значения таких типов, как было отмечено выше, не могут быть непосредственно переданы через OLE Automation . Рассмотрим пример возможного решения этой проблемы:
Имеются две информационные базы. В обоих определены справочники Товары, Склады, Организации и документ РасхНакл. Указанные справочники и документ имеют в обеих информационных базах одинаковую структуру. Состав справочников в обеих информационных базах совпадает. Задача состоит в том, чтобы написать обработку, которая запускалась бы в одной информационной базе, открывала другую с использованием OLE Automation и переносила из нее документ "Расходная накладная" с указанным номером. При этом в той информационной базе, в которую переносится документ должны быть восстановлены все ссылки на элементы справочников, на которые ссылался исходный документ. Ниже приведен текст модуля обработки, который решает эту задачу (предполагается, что конфигурация совпадает с методической конфигурацией).
v7 = СоздатьОбъект ("V77.Application");
init = v7.Initialize(v7.RMTrade, "/d с :\its\metodcfg ", "");
ДокТам = v7.EvalExpr("СоздатьОбъект(""Документ.РасхНакл"")");
Если ДокТам.НайтиПоНомеру(НомерДок) = 1 Тогда
Док = СоздатьОбъект("Документ.РасхНакл");
Док.Новый();
Док.НомерДок = Док.НомерДок;
Док.Покупатель = ЗначениеИзСтроки(v7.ЗначениеВСтроку(ДокТам.Покупатель));
Док.Склад = ЗначениеИзСтроки(v7.ЗначениеВСтроку(ДокТам.Склад));
ДокТам.ВыбратьСтроки();
Пока ДокТам.ПолучитьСтроку() = 1 Цикл
Док.НоваяСтрока();
Док.Товар = ЗначениеИзСтроки(v7.ЗначениеВСтроку(ДокТам.Товар));
Док.Количество = ДокТам.Количество;
Док.Сумма = ДокТам.Сумма;
КонецЦикла;
Док.Записать();
Иначе Сообщить("Документ не найден!");
КонецЕсли
...
В данном фрагменте модуля для доступа к информационной базе, из которой предполагается перенести документ, через механизм OLE Automation запускается экземпляр системы 1С:Предприятие. И в этом экземпляре создается объект типа "Документ.РасхНакл" (ДокТам). С помощью этого объекта делается попытка найти документ с заданным номером (реквизит формы обработки НомерДок). Если документ найден, то в "этой" информационной базе создается новый документ типа РасхНакл (Док) и реквизиты этого документа заполняются значениями, взятыми из реквизитов исходного документа. Особый интерес представляют реквизиты Покупатель, Склад и Товар. Данные реквизиты имеют типы Справочник.Организации, Справочник.Склады и Справочник.Товары соответственно. Для передачи значений указанных типов через OLE Automation используются строковые значения, полученные из исходных с помощью функции ЗначениеВСтроку(). Полученное строковое значение без потерь передается через OLE Automation , а на принимающей стороне с помощью функции ЗначениеИзСтроки() из переданной строки восстанавливается значение, соответствующее исходному. И здесь важно, чтобы на принимающей стороне справочники, соответствующие типам реквизитов документа по составу соответствовали справочникам исходной информационной базы. В противном случае значения соответствующих реквизитов документа могут оказаться незаполненными или заполненными неправильными значениями.