При разработке механизмов интеграции между различными базами данных 1С программисты часто сталкиваются с ситуацией, когда код, идеально работающий в файловом варианте информационной базы, внезапно перестает функционировать при переходе на клиент-серверную архитектуру. Одной из самых коварных ошибок является сообщение: «Значение не является значением объектного типа (NewObject)». Рассмотрим детально, почему это происходит, и проанализируем шаги, необходимые для настройки серверной среды.
Первым делом разберем механику возникновения проблемы. Ошибка Значение не является значением объектного типа (NewObject) применительно к коду инициализации COM-соединения означает, что объект, к которому вы обращаетесь (в данном случае переменная, содержащая подключение к базе), имеет значение Неопределено. Проанализируем типичный фрагмент кода, который вызывает это исключение:
Попытка
ПараметрыСоед = "Srvr=""ServerName"";Ref=""BaseName"";Usr=""Admin"";Pwd=""Password"";";
V83COMConnector = Новый COMОбъект("V83.COMConnector");
БазаБух = V83COMConnector.Connect(ПараметрыСоед);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
// Ошибка возникает здесь, если БазаБух = Неопределено
Запрос = БазаБух.NewObject("Запрос");
Ситуация осложняется тем, что в файловом варианте инициализация проходит успешно, так как она выполняется в контексте текущего пользователя Windows. В клиент-серверном варианте код выполняется на стороне сервера 1С:Предприятие. Следовательно, попытка создания COM-объекта и последующее соединение происходят от имени системной учетной записи, под которой запущена служба 1C:Enterprise 8.3 Server Agent (обычно это USR1CV8). Если у этой учетной записи недостаточно прав или окружение Windows настроено некорректно для работы с DCOM, метод Connect возвращает пустое значение, не генерируя при этом исключение, которое можно было бы перехватить блоком Попытка...Исключение.
Прежде чем переходить к тонким настройкам прав, нам необходимо убедиться, что библиотека comcntr.dll правильно зарегистрирована в операционной системе сервера. Важно помнить о разрядности: если ваш сервер 1С 64-битный, то и библиотека должна быть зарегистрирована из соответствующего каталога платформы. Проанализируем последовательность действий для регистрации:
regsvr32 "C:\Program Files\1cv8\номер_версии\bin\comcntr.dll".regsvr32 "C:\Program Files (x86)\1cv8\номер_версии\bin\comcntr.dll".Если регистрация прошла успешно, операционная система сообщит об этом. Однако в современных версиях Windows Server одной регистрации часто бывает недостаточно из-за политик безопасности.
Рассмотрим наиболее эффективный способ решения проблем с правами доступа — создание приложения COM+. Это позволяет запускать COM-объект в отдельном процессе dllhost.exe под конкретной учетной записью. Выполним следующие действия:
Компьютеры -> Мой компьютер -> Приложения COM+.Создать -> Приложение.1Cv8_COMConnector) и выберите тип «Серверное приложение».Проанализируем ситуацию, описанную пользователями на форумах: по умолчанию новое приложение COM+ пытается запускаться от имени «Интерактивного пользователя». Это означает, что если в данный момент на сервере никто не залогинен через консоль или RDP, COM-объект просто не сможет инициализироваться. Это и объясняет, почему база «падает» в серверном режиме.
Чтобы исправить это, выполните следующее:
После этого необходимо добавить саму библиотеку в приложение. Внутри вашего созданного приложения найдите папку «Компоненты», нажмите «Создать -> Компонент» и выберите файл comcntr.dll из каталога bin платформы 1С.
Разберем дополнительные факторы, которые могут блокировать соединение. Пользователь, под которым работает служба сервера 1С (USR1CV8) или пользователь, указанный в настройках COM+, должен иметь:
bin установленной платформы 1С.HKEY_CLASSES_ROOT, связанных с V83.COMConnector.После того как инфраструктурная часть настроена, посмотрим, как правильно работать с объектами подключенной базы. Важно понимать, что типы данных в текущей базе и в базе COM — это разные типы, даже если они называются одинаково. Рассмотрим пример безопасного выполнения запроса:
// Устанавливаем параметры запроса, используя объекты внешней базы
Запрос = БазаБух.NewObject("Запрос");
Запрос.Текст =
"ВЫБРАТЬ
| Хозрасчетный.СчетДт,
| Хозрасчетный.Сумма
|ИЗ
| РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
|ГДЕ
| Хозрасчетный.Период МЕЖДУ &НачДата И &КонДата";
// Важно: передаем простые типы (Дата, Число, Строка) напрямую
Запрос.УстановитьПараметр("НачДата", НачалоДня(Отчет.НачДата));
Запрос.УстановитьПараметр("КонДата", КонецДня(Отчет.КонДата));
// Если нужно передать ссылку, получаем её через COM-соединение
СчетСсылка = БазаБух.ПланыСчетов.Хозрасчетный.НайтиПоКоду("68.01");
Запрос.УстановитьПараметр("Счет68", СчетСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Обработка данных
КонецЦикла;
Обратите внимание, что метод БазаБух.ПланыСчетов.Хозрасчетный.НайтиПоКоду("68.01") выполняется внутри контекста внешней базы, и возвращаемая ссылка понятна для объекта Запрос, созданного там же. Попытка передать в параметр ссылку из текущей (ложной) базы приведет к ошибке несоответствия типов.
Подводя итог, можно сказать, что стабильность COM-соединения в клиент-серверном варианте 1С на 90% зависит от настроек операционной системы Windows. Основные действия сводятся к:
comcntr.dll нужной разрядности.Соблюдение этих правил позволит вам избежать неочевидных ошибок и обеспечит надежный обмен данными между информационными системами.