Eoleexception неопознанная ошибка directum

Обновлено 27.08.2022

ошибка

Добрый день! Уважаемые читатели IT блога Pyatilistnik.org, в прошлый раз мы с вами разобрали за, что отвечает библиотека vcruntime140.dll и на сколько она важна для работы многих программ. Сегодня я хочу вам рассказать, об интересном случае, когда специализированный софт может не получить доступ к удаленному компьютеры по RPC протоколу из-за новых политик безопасности DCOM. В логах будет фигурировать событие об ошибке DCOM ID 10036 «политика уровня проверки подлинности на стороне сервера не разрешает пользователю». Давайте смотреть в чем дело.

❌Описание ошибки DCOM ID 10036 (EOleException)

Обратился ко мне мой коллега с просьбой показать ему, как отправлять сообщение всем пользователям терминального хоста. Я предложил ему бесплатную утилиту Terminal Services Manager и подумал, что задача выполнена, но не тут то было. Коллега сказал, что у него не подключается к RDSH хосту и высвечивается ошибка доступа. Я решил так же проверить данную ситуацию.

Запустив Terminal Services Manager, в логе я увидел вот такую ошибку подключения:

EOleException

Сразу отмечу, что права на удаленный сервер у меня были и сетевая доступность присутствовала. Первым делом я полез на сам сервер, куда не удавалось произвести подключение. В логах системы я обнаружил массовую ошибку:

ID 10036: Политика уровня проверки подлинности на стороне сервера не разрешает пользователю ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) с адреса 10.11.11.210 для активации DCOM-сервера. Повысьте уровень проверки подлинности активации, чтобы RPC_C_AUTHN_LEVEL_PKT_INTEGRITY в клиентском приложении. («The server-side authentication level policy does not allow the user ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) from address 10.11.11.210 to activate DCOM server. Please raise the activation authentication level at least to RPC_C_AUTHN_LEVEL_PKT_INTEGRITY in client application.»)

ID 10036

Давайте выяснять в чем дело и как это можно обойти.

⚙️Причина ошибки DCOM ID 10036

Первое, что я стал изучать, что такое RPC_C_AUTHN_LEVEL_PKT_INTEGRITY. В итоге я наткнулся на статью Microsoft о константах уровня аутентификации.

Константы уровня аутентификации представляют собой уровни аутентификации, передаваемые различным функциям времени выполнения. Эти уровни перечислены в порядке возрастания аутентификации. Каждый новый уровень добавляет к аутентификации, обеспечиваемой предыдущим уровнем. Если библиотека времени выполнения RPC не поддерживает указанный уровень, она автоматически обновляется до следующего более высокого поддерживаемого уровня.

В итоге есть вот такой список констант:

  • RPC_C_AUTHN_LEVEL_DEFAULT — Использует уровень проверки подлинности по умолчанию для указанной службы проверки подлинности.
  • RPC_C_AUTHN_LEVEL_NONE — Не выполняет аутентификацию.
  • RPC_C_AUTHN_LEVEL_CONNECT — Аутентифицируется только тогда, когда клиент устанавливает связь с сервером.
  • RPC_C_AUTHN_LEVEL_CALL — Выполняет аутентификацию только в начале каждого вызова удаленной процедуры, когда сервер получает запрос. Не применяется к удаленным вызовам процедур, выполненным с использованием последовательностей протоколов на основе соединения (тех, которые начинаются с префикса «ncacn»). Если последовательность протокола в дескрипторе привязки представляет собой последовательность протокола на основе соединения, и вы указываете этот уровень, эта процедура вместо этого использует константу RPC_C_AUTHN_LEVEL_PKT.
  • RPC_C_AUTHN_LEVEL_PKT — Аутентифицирует только то, что все полученные данные получены от ожидаемого клиента. Не проверяет сами данные.
  • RPC_C_AUTHN_LEVEL_PKT_INTEGRITY — Аутентифицирует и проверяет, что никакие данные, передаваемые между клиентом и сервером, не были изменены.
  • RPC_C_AUTHN_LEVEL_PKT_PRIVACY — Включает все предыдущие уровни и гарантирует, что данные в открытом виде могут быть видны только отправителю и получателю. В локальном случае это предполагает использование безопасного канала. В удаленном случае это включает шифрование значения аргумента каждого удаленного вызова процедуры.

Теперь стало понятно, за что отвечает RPC_C_AUTHN_LEVEL_PKT_INTEGRITY и видимо Microsoft, ужесточила какую-то политику безопасности, я стал изучать вопрос дальше. Поиск ошибки DCOM ID 10036 привел меня ну обсуждение нового обновления KB5004442, которое как я выяснил и вызывает эту ситуацию.

KB5004442 призвана усилить защиту DCOM объектов. Удаленный протокол модели распределенных компонентов (DCOM) — это протокол для предоставления объектов приложений с помощью удаленных вызовов процедур (RPC). DCOM используется для связи между программными компонентами сетевых устройств. Многие из нас на самом деле не понимают этого, и мы не можем диагностировать ошибки DCOM в наших журналах событий, которые, по-видимому, не оказывают серьезного влияния на наши сети. Эта технология представляет собой протокол для предоставления объектов приложения с помощью удаленных вызовов процедур (RPC).

RPC являются ключевой частью Windows. RPC — это клиент-серверный протокол, который разработчики приложений могут использовать для вызова процедур на локальном или удаленном узле в сети. Детали подключения и сортировка данных выполняются за кулисами на уровне RPC, что дает разработчикам средства для прямого подключения клиентских приложений к удаленному компьютеру. Это позволяет разработчикам не беспокоиться о знании деталей того, как данные передаются между двумя машинами и как вызываются процедуры.

С обновлениями безопасности от 14 июня 2022 г. RPC_C_AUTHN_LEVEL_PKT_INTEGRITY на серверах DCOM теперь включен по умолчанию. Клиент, которому это необходимо, может отключить его с помощью раздела реестра RequireIntegrityActivationAuthenticationLevel.

Согласно бюллетеню, злоумышленник сначала воспользуется уязвимостью, предложив клиенту DCOM каким-либо образом подключиться к специально созданному серверу, как правило, отправив пользователю фишинговое электронное письмо, чтобы завладеть системой. Затем злоумышленник использует эту информацию для доступа к серверу DCOM, а затем скомпрометирует его. Патч исправляет и усиливает аутентификацию, используемую между клиентами и серверами DCOM.

Я проверил RDSH хосты и действительно там прилетело данное обновление. Microsoft пока полностью не закрутило данную политику безопасности и ее еще можно обойти, но самое правильное, это доделать приложение, чтобы оно при обращении к серверу и запросе данных выполняло все требования вендора. На текущий момент есть вот такой график внедрения:

  1. 8 июня 2021 г. — Изменения защиты отключены по умолчанию, но с возможностью включить их с помощью ключа реестра.
  2. 14 июня 2022 г. — Защитные изменения включены по умолчанию, но с возможностью отключить их с помощью ключа реестра.
  3. 14 марта 2023 г.Усиление изменений включено по умолчанию, отключить их невозможноК этому моменту вы должны решить все проблемы совместимости с усиливающими изменениями и приложениями в вашей среде.

Еще список обновлений несущих данное изменение: Windows Server 2022 — KB5005619, KB5005568. Windows 10, version 2004, Windows 10, version 20H2, Windows 10, version 21H1 — KB5005101. Windows Server 2019, Windows 10, version  1809 — KB5005102. Windows Server 2016, Windows 10, version 1607 — KB5005573. Windows Server 2012 R2 and Windows 8.1 — KB5006714. Данный список всегда меняется, так что смотрите в каталоге центра обновлений, что чем заменяется (https://www.catalog.update.microsoft.com/).

Сведения об обновлении

Так же помимо события ID 10036, есть еще два:

ID 10037: «Приложение %1 с PID %2 запрашивает активацию CLSID %3 на компьютере %4 с явно заданным уровнем аутентификации %5. Минимальный уровень аутентификации активации, требуемый DCOM, — 5 (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). Чтобы повысить уровень аутентификации активации, пожалуйста, обратитесь к поставщику приложения». («Application %1 with PID %2 is requesting to activate CLSID %3 on computer %4 with explicitly set authentication level at %5. The lowest activation authentication level required by DCOM is 5(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). To raise the activation authentication level, please contact the application vendor.»)

ID 10038: «Приложение %1 с PID %2 запрашивает активацию CLSID %3 на компьютере %4 с уровнем аутентификации активации по умолчанию %5. Минимальный уровень аутентификации активации, требуемый DCOM, — 5 (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). Чтобы повысить уровень аутентификации активации, пожалуйста, обратитесь к поставщику приложения». («Application %1 with PID %2 is requesting to activate CLSID %3 on computer %4 with default activation authentication level at %5. The lowest activation authentication level required by DCOM is 5(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). To raise the activation authentication level, please contact the application vendor.»)

  • %1 — путь к приложению
  • %2 — PID приложения
  • %3 — CLSID класса COM, который приложение запрашивает для активации
  • %4 — имя компьютера
  • %5 — значение уровня аутентификации

💡Как устранить ошибку ID 10036

Первое, что вы должны сделать, это установить все доступные обновления, как на стороне сервера, куда идет подключение, так и на стороне системы откуда идет подключение. Напоминаю, что последнего можно найти в тексте ошибки:

ID 10036: Политика уровня проверки подлинности на стороне сервера не разрешает пользователю ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) с адреса 10.11.11.210 для активации DCOM-сервера. Повысьте уровень проверки подлинности активации, чтобы RPC_C_AUTHN_LEVEL_PKT_INTEGRITY в клиентском приложении.

Тут IP-адрес откуда идет подключение 10.11.11.210, там и нужно установить все возможные обновления безопасности.

Установка обновлений Windows 10

Как только я обновился, ошибка EOleException ушла и мой Terminal Services Manager успешно подключился к серверу.

Terminal Services Manager успешное подключение

Если по каким, то причинам ваше приложение не заработало, а вам нужно, то есть лазейка до 2023 года в виде ключа реестра, который вы должны добавить на сервере, куда вы пытаетесь производить подключение. Запустите реестр Windows и перейдите в раздел:

HKEY_LOCAL_MACHINESOFTWARE MicrosoftOleAppCompat

И создайте там ключ реестра с типом REG_DWORD (32-бита) с именем RequireIntegrityActivationAuthenticationLevel.

  • RequireIntegrityActivationAuthenticationLevel = 0x00000000 выключает политику
  • RequireIntegrityActivationAuthenticationLevel = 0x00000001 включает политику

не забываем после создания ключа в реестре Windows произвести перезагрузку сервера

RequireIntegrityActivationAuthenticationLevel

Если и данный метод вам не помог, то как крайняя мера может быть, это удаление обновления. Посмотрите список установленных обновлений командой:

wmic qfe list

После чего просто прочитайте инструкцию, как это сделать. Надеюсь, что вам оказалась полезна данная статья, и вы устранили ошибку EOleException. Если остались вопросы, то пишите их в комментариях. С вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.

Дополнительные ссылки

  • https://docs.microsoft.com/en-us/windows/win32/rpc/authentication-level-constants
  • https://support.microsoft.com/en-us/topic/kb5004442-manage-changes-for-windows-dcom-server-security-feature-bypass-cve-2021-26414-f1400b52-c141-43d2-941e-37ed901c769c
  • https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26414

Обновлено 27.08.2022

ошибка

Добрый день! Уважаемые читатели IT блога Pyatilistnik.org, в прошлый раз мы с вами разобрали за, что отвечает библиотека vcruntime140.dll и на сколько она важна для работы многих программ. Сегодня я хочу вам рассказать, об интересном случае, когда специализированный софт может не получить доступ к удаленному компьютеры по RPC протоколу из-за новых политик безопасности DCOM. В логах будет фигурировать событие об ошибке DCOM ID 10036 «политика уровня проверки подлинности на стороне сервера не разрешает пользователю». Давайте смотреть в чем дело.

❌Описание ошибки DCOM ID 10036 (EOleException)

Обратился ко мне мой коллега с просьбой показать ему, как отправлять сообщение всем пользователям терминального хоста. Я предложил ему бесплатную утилиту Terminal Services Manager и подумал, что задача выполнена, но не тут то было. Коллега сказал, что у него не подключается к RDSH хосту и высвечивается ошибка доступа. Я решил так же проверить данную ситуацию.

Запустив Terminal Services Manager, в логе я увидел вот такую ошибку подключения:

EOleException

Сразу отмечу, что права на удаленный сервер у меня были и сетевая доступность присутствовала. Первым делом я полез на сам сервер, куда не удавалось произвести подключение. В логах системы я обнаружил массовую ошибку:

ID 10036: Политика уровня проверки подлинности на стороне сервера не разрешает пользователю ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) с адреса 10.11.11.210 для активации DCOM-сервера. Повысьте уровень проверки подлинности активации, чтобы RPC_C_AUTHN_LEVEL_PKT_INTEGRITY в клиентском приложении. («The server-side authentication level policy does not allow the user ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) from address 10.11.11.210 to activate DCOM server. Please raise the activation authentication level at least to RPC_C_AUTHN_LEVEL_PKT_INTEGRITY in client application.»)

ID 10036

Давайте выяснять в чем дело и как это можно обойти.

⚙️Причина ошибки DCOM ID 10036

Первое, что я стал изучать, что такое RPC_C_AUTHN_LEVEL_PKT_INTEGRITY. В итоге я наткнулся на статью Microsoft о константах уровня аутентификации.

Константы уровня аутентификации представляют собой уровни аутентификации, передаваемые различным функциям времени выполнения. Эти уровни перечислены в порядке возрастания аутентификации. Каждый новый уровень добавляет к аутентификации, обеспечиваемой предыдущим уровнем. Если библиотека времени выполнения RPC не поддерживает указанный уровень, она автоматически обновляется до следующего более высокого поддерживаемого уровня.

В итоге есть вот такой список констант:

  • RPC_C_AUTHN_LEVEL_DEFAULT — Использует уровень проверки подлинности по умолчанию для указанной службы проверки подлинности.
  • RPC_C_AUTHN_LEVEL_NONE — Не выполняет аутентификацию.
  • RPC_C_AUTHN_LEVEL_CONNECT — Аутентифицируется только тогда, когда клиент устанавливает связь с сервером.
  • RPC_C_AUTHN_LEVEL_CALL — Выполняет аутентификацию только в начале каждого вызова удаленной процедуры, когда сервер получает запрос. Не применяется к удаленным вызовам процедур, выполненным с использованием последовательностей протоколов на основе соединения (тех, которые начинаются с префикса «ncacn»). Если последовательность протокола в дескрипторе привязки представляет собой последовательность протокола на основе соединения, и вы указываете этот уровень, эта процедура вместо этого использует константу RPC_C_AUTHN_LEVEL_PKT.
  • RPC_C_AUTHN_LEVEL_PKT — Аутентифицирует только то, что все полученные данные получены от ожидаемого клиента. Не проверяет сами данные.
  • RPC_C_AUTHN_LEVEL_PKT_INTEGRITY — Аутентифицирует и проверяет, что никакие данные, передаваемые между клиентом и сервером, не были изменены.
  • RPC_C_AUTHN_LEVEL_PKT_PRIVACY — Включает все предыдущие уровни и гарантирует, что данные в открытом виде могут быть видны только отправителю и получателю. В локальном случае это предполагает использование безопасного канала. В удаленном случае это включает шифрование значения аргумента каждого удаленного вызова процедуры.

Теперь стало понятно, за что отвечает RPC_C_AUTHN_LEVEL_PKT_INTEGRITY и видимо Microsoft, ужесточила какую-то политику безопасности, я стал изучать вопрос дальше. Поиск ошибки DCOM ID 10036 привел меня ну обсуждение нового обновления KB5004442, которое как я выяснил и вызывает эту ситуацию.

KB5004442 призвана усилить защиту DCOM объектов. Удаленный протокол модели распределенных компонентов (DCOM) — это протокол для предоставления объектов приложений с помощью удаленных вызовов процедур (RPC). DCOM используется для связи между программными компонентами сетевых устройств. Многие из нас на самом деле не понимают этого, и мы не можем диагностировать ошибки DCOM в наших журналах событий, которые, по-видимому, не оказывают серьезного влияния на наши сети. Эта технология представляет собой протокол для предоставления объектов приложения с помощью удаленных вызовов процедур (RPC).

RPC являются ключевой частью Windows. RPC — это клиент-серверный протокол, который разработчики приложений могут использовать для вызова процедур на локальном или удаленном узле в сети. Детали подключения и сортировка данных выполняются за кулисами на уровне RPC, что дает разработчикам средства для прямого подключения клиентских приложений к удаленному компьютеру. Это позволяет разработчикам не беспокоиться о знании деталей того, как данные передаются между двумя машинами и как вызываются процедуры.

С обновлениями безопасности от 14 июня 2022 г. RPC_C_AUTHN_LEVEL_PKT_INTEGRITY на серверах DCOM теперь включен по умолчанию. Клиент, которому это необходимо, может отключить его с помощью раздела реестра RequireIntegrityActivationAuthenticationLevel.

Согласно бюллетеню, злоумышленник сначала воспользуется уязвимостью, предложив клиенту DCOM каким-либо образом подключиться к специально созданному серверу, как правило, отправив пользователю фишинговое электронное письмо, чтобы завладеть системой. Затем злоумышленник использует эту информацию для доступа к серверу DCOM, а затем скомпрометирует его. Патч исправляет и усиливает аутентификацию, используемую между клиентами и серверами DCOM.

Я проверил RDSH хосты и действительно там прилетело данное обновление. Microsoft пока полностью не закрутило данную политику безопасности и ее еще можно обойти, но самое правильное, это доделать приложение, чтобы оно при обращении к серверу и запросе данных выполняло все требования вендора. На текущий момент есть вот такой график внедрения:

  1. 8 июня 2021 г. — Изменения защиты отключены по умолчанию, но с возможностью включить их с помощью ключа реестра.
  2. 14 июня 2022 г. — Защитные изменения включены по умолчанию, но с возможностью отключить их с помощью ключа реестра.
  3. 14 марта 2023 г.Усиление изменений включено по умолчанию, отключить их невозможноК этому моменту вы должны решить все проблемы совместимости с усиливающими изменениями и приложениями в вашей среде.

Еще список обновлений несущих данное изменение: Windows Server 2022 — KB5005619, KB5005568. Windows 10, version 2004, Windows 10, version 20H2, Windows 10, version 21H1 — KB5005101. Windows Server 2019, Windows 10, version  1809 — KB5005102. Windows Server 2016, Windows 10, version 1607 — KB5005573. Windows Server 2012 R2 and Windows 8.1 — KB5006714. Данный список всегда меняется, так что смотрите в каталоге центра обновлений, что чем заменяется (https://www.catalog.update.microsoft.com/).

Сведения об обновлении

Так же помимо события ID 10036, есть еще два:

ID 10037: «Приложение %1 с PID %2 запрашивает активацию CLSID %3 на компьютере %4 с явно заданным уровнем аутентификации %5. Минимальный уровень аутентификации активации, требуемый DCOM, — 5 (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). Чтобы повысить уровень аутентификации активации, пожалуйста, обратитесь к поставщику приложения». («Application %1 with PID %2 is requesting to activate CLSID %3 on computer %4 with explicitly set authentication level at %5. The lowest activation authentication level required by DCOM is 5(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). To raise the activation authentication level, please contact the application vendor.»)

ID 10038: «Приложение %1 с PID %2 запрашивает активацию CLSID %3 на компьютере %4 с уровнем аутентификации активации по умолчанию %5. Минимальный уровень аутентификации активации, требуемый DCOM, — 5 (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). Чтобы повысить уровень аутентификации активации, пожалуйста, обратитесь к поставщику приложения». («Application %1 with PID %2 is requesting to activate CLSID %3 on computer %4 with default activation authentication level at %5. The lowest activation authentication level required by DCOM is 5(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). To raise the activation authentication level, please contact the application vendor.»)

  • %1 — путь к приложению
  • %2 — PID приложения
  • %3 — CLSID класса COM, который приложение запрашивает для активации
  • %4 — имя компьютера
  • %5 — значение уровня аутентификации

💡Как устранить ошибку ID 10036

Первое, что вы должны сделать, это установить все доступные обновления, как на стороне сервера, куда идет подключение, так и на стороне системы откуда идет подключение. Напоминаю, что последнего можно найти в тексте ошибки:

ID 10036: Политика уровня проверки подлинности на стороне сервера не разрешает пользователю ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) с адреса 10.11.11.210 для активации DCOM-сервера. Повысьте уровень проверки подлинности активации, чтобы RPC_C_AUTHN_LEVEL_PKT_INTEGRITY в клиентском приложении.

Тут IP-адрес откуда идет подключение 10.11.11.210, там и нужно установить все возможные обновления безопасности.

Установка обновлений Windows 10

Как только я обновился, ошибка EOleException ушла и мой Terminal Services Manager успешно подключился к серверу.

Terminal Services Manager успешное подключение

Если по каким, то причинам ваше приложение не заработало, а вам нужно, то есть лазейка до 2023 года в виде ключа реестра, который вы должны добавить на сервере, куда вы пытаетесь производить подключение. Запустите реестр Windows и перейдите в раздел:

HKEY_LOCAL_MACHINESOFTWARE MicrosoftOleAppCompat

И создайте там ключ реестра с типом REG_DWORD (32-бита) с именем RequireIntegrityActivationAuthenticationLevel.

  • RequireIntegrityActivationAuthenticationLevel = 0x00000000 выключает политику
  • RequireIntegrityActivationAuthenticationLevel = 0x00000001 включает политику

не забываем после создания ключа в реестре Windows произвести перезагрузку сервера

RequireIntegrityActivationAuthenticationLevel

Если и данный метод вам не помог, то как крайняя мера может быть, это удаление обновления. Посмотрите список установленных обновлений командой:

wmic qfe list

После чего просто прочитайте инструкцию, как это сделать. Надеюсь, что вам оказалась полезна данная статья, и вы устранили ошибку EOleException. Если остались вопросы, то пишите их в комментариях. С вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.

Дополнительные ссылки

  • https://docs.microsoft.com/en-us/windows/win32/rpc/authentication-level-constants
  • https://support.microsoft.com/en-us/topic/kb5004442-manage-changes-for-windows-dcom-server-security-feature-bypass-cve-2021-26414-f1400b52-c141-43d2-941e-37ed901c769c
  • https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26414

 
Василич

 
(2002-09-19 19:16)
[0]

Здравствуйте ! Подскажите, пожалуйста, вследствие чего появляется ошибка «EOLEException. Не удается найти строку для обновления. Некоторые значения могли быть изменены со времени ее последнего чтения». Ошибка выдается после метода Post или Requery. Везде искал, не могу найти даже описания ошибки.


 
Василич

 
(2002-09-20 10:29)
[1]

Ребята, ну неужто никто не знает ?


 
Johnmen

 
(2002-09-20 10:40)
[2]

Так поищи в этой конфе…

Данный вопрос задается с завидной регулярностью…:))))


 
Василич

 
(2002-09-20 11:35)
[3]

Подобный вопрос отсутствует. Самое интересное, что трассировка запроса с помощью SQL Profiler ничего не дает !


 
Юрий Жуков

 
(2002-09-20 13:09)
[4]

Я так понимаю ты на ADO пишеь?

Тогда тебе идти на королевство Дельфи.

Читать здесь:

http://www.delphikingdom.com/helloworld/ado01.htm

http://www.delphikingdom.com/helloworld/ado02.htm

http://www.delphikingdom.com/helloworld/ado03.htm

Тригера в таблицах есть?


 
Василич

 
(2002-09-20 15:25)
[5]

Recordset.Properties[«Update Resync»].Value := adResyncNone;;

Recordset.Properties[«Update Criteria»].Value := adCriteriaAllCols;

Все равно не работает !!!


 
Юрий Жуков

 
(2002-09-20 16:00)
[6]

А тригера в таблицах есть? А автоинкрементные поля?

А первичный ключ? А подумай сам чего ты еще утаил?

И лучше используй так:

Recordset.Properties[«Update Criteria»].Value := adCriteriaKey

А еще лучше пропиши

Recordset.Properties[«Resync Command»].Value := » бла — бла…»


 
Василич

 
(2002-09-20 16:04)
[7]

Триггеров нет, автоинкрементное поле есть. Таблица представляет из себя кучу полей типа ID, связана с другими, дочерними таблицами. Редактирование делается простым присваиванием FieldByName(«FieldName»).AsString :=»бла-бла»

Recordset.Properties[«Update Resync»].Value := adResyncAutoIncrement + adResyncInserts;;

Recordset.Properties[«Update Criteria»].Value := adCriteriaAllCols;

if not InTransaction then

BeginTrans;

Edit;

FieldByName(«Field1»).AsString := ComboBox1.Text;

………………………

Post;

CommitTrans;

Requery();

и после Post вылетает эта ошибка.


 
Юрий Жуков

 
(2002-09-20 16:40)
[8]

Ну я тебе почти правильно сказал:

Recordset.Properties[«Update Criteria»].Value := adCriteriaKey

Обовлять запись будет по первичным ключам

Если это не поможет, то ставь

Recordset.Properties[«Resync Command»].Value := » бла — бла…»

Ну если это не поможет то разве что можно на запрос посмотреь..


 
Василич

 
(2002-09-20 16:47)
[9]

И что мне писать в это «bla-bla» ?


 
Василич

 
(2002-09-20 18:06)
[10]

Это все, к сожалению, не помогает.


 
Юрий Жуков

 
(2002-09-20 19:15)
[11]

Хм, ссылку я вроде бы давал, но вдидать ты не очень внимательно прочитал:

http://www.delphikingdom.com/helloworld/ado03.htm

Цитата:

в этом свойстве задается команда, с помощью которой должна быть обновлена текущая строка, основываясь на значении колонок из таблицы, имя которой заданно свойством «Unique Table»

Ну а апдейты к D6 стоят? Что еще посоветовать не знаю, может сам еще чего скажешь?


 
Василич

 
(2002-09-23 09:45)
[12]

DataModule1.ADODataset1.Properties["Update Resync"].Value := adResyncInserts + adResyncUpdates;

DataModule1.ADODataset1.Properties["Update Criteria"].Value := adCriteriaKey;

DataModule1.ADODataset1.Properties["Unique Table"].Value := "Computers";

DataModule1.ADODataset1.Properties["Resync Command"].Value := ResyncCommand;

ResyncCommand := "SELECT C.ComputerID AS "


 
Василич

 
(2002-09-23 10:40)
[13]

Я немного понял. Для того, чтобы Update отрабатывался нормально,
ВСЕ поля в таблице должны быть заполнены (не равны NULL). Может, следует каким-то образом изменить запрос ?


 
Василич

 
(2002-09-23 11:15)
[14]

А это результат трассировки запроса. Никаких ошибок, никаких предупреждений…

exec sp_executesql N"UPDATE "Mspi"."dbo"."Computers" SET "ComputerID"=@P1,"Address"=@P2,"Cabinet"=@P3 WHERE "KeyField"=@P4", N"@P1 bigint,@P2 nvarchar(10),@P3 int,@P4 int", 545445, N"Ленина, 57", 21, 12

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Xeroxes" SET "Xerox"=@P1 WHERE "XeroxID" IS NULL", N"@P1 varchar(1)", ""

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Scanners" SET "Scanner"=@P1 WHERE "ScannerID"=@P2", N"@P1 varchar(4),@P2 int", "UMAX", 6

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Printers" SET "Printer"=@P1 WHERE "PrinterID"=@P2", N"@P1 varchar(29),@P2 int", "Hewlett-Packard LaserJet 1100", 4

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Monitors" SET "Monitor"=@P1 WHERE "MonitorID"=@P2", N"@P1 varchar(19),@P2 int", "SAMSUNG Samtron 75E", 3

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."EtherCards" SET "EtherCard"=@P1 WHERE "EtherCardID"=@P2", N"@P1 varchar(16),@P2 int", "Surecom 100 Mbit", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."SoundBlasters" SET "SoundBlaster"=@P1 WHERE "SoundBlasterID" IS NULL", N"@P1 varchar(1)", ""

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."CDROMs" SET "CDROM"=@P1 WHERE "CDROMID"=@P2", N"@P1 varchar(8),@P2 int", "ASUS 50x", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."HDDs" SET "HDD"=@P1 WHERE "HDDID"=@P2", N"@P1 varchar(14),@P2 int", "IBM DTLA 30 Gb", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."VideoCards" SET "VideoCard"=@P1 WHERE "VideoCardID"=@P2", N"@P1 varchar(22),@P2 int", "GeForce 4 Ti4600 64 Mb", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."RAMs" SET "RAM"=@P1 WHERE "RAMID"=@P2", N"@P1 smallint,@P2 int", 32, 5

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Motherboards" SET "Motherboard"=@P1 WHERE "MotherboardID"=@P2", N"@P1 varchar(4),@P2 int", "Abit", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Processors" SET "Processor"=@P1 WHERE "ProcessorID"=@P2", N"@P1 varchar(35),@P2 int", "Intel Celeron 333 Mhz", 16

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Faculties" SET "Faculty"=@P1 WHERE "FacultyID"=@P2", N"@P1 nvarchar(29),@P2 int", N"Кафедра, 18

go

SELECT N"Testing Connection..."

go

EXECUTE msdb.dbo.sp_sqlagent_get_perf_counters

go

Блин, что делать-то ?


 
MOA

 
(2002-09-23 13:05)
[15]

1.А вот это:

exec sp_executesql N»UPDATE «Mspi».»dbo».»Xeroxes» SET «Xerox»=@P1 WHERE «XeroxID» IS NULL», N»@P1 varchar(1)», «»

нормально («XeroxID» IS NULL)?

2. У Вас действительно при апдейте детайл-таблицы должны обновляться ВСЕ мастер-таблицы? Так и задумано?


 
Юрий Жуков

 
(2002-09-23 13:22)
[16]

Ну по крайней мере видно, что вот здесь точно будет ошибка:

exec sp_executesql N»UPDATE «Mspi».»dbo».»Xeroxes» SET «Xerox»=@P1 WHERE «XeroxID» IS NULL», N»@P1 varchar(1)», «»

Да ты прав, в этом результирующем запросе все поля должны быть заполнены, что-бы АДО мог пострить по ним SQL для Update для всех подчиненных таблиц (ты ведь нигде не указал UniqueTable). Насколько я знаю нельзя указать несколько уникальных таблиц для ADODATASET.

Думаю тебе следует исользовать Uniquetable:=»Faculties»;

А редактирование всех остальных датасетов оформить в виде справочников


 
Василич

 
(2002-09-23 14:53)
[17]

Редактирование остальных датасетов и так оформлено в виде справочников. Я же на самом деле редактирую не справочник (т.е. не таблицу Xeroxes), а сводную, в которой находится XeroxID.

>MOA

По идее, мастер-таблицы обновляться не должны. Пытался снять у таблицы опцию Enforce relationship for INSERTS and UPDATES, толку никакого.

Как бы там ни было, мне все-таки требуется, чтобы в некоторые поля можно было воткнуть NULL (не во всех кабинетах есть ксероксы, образно говоря). Не подскажете ли Вы, как избавиться от принудительного обновления мастер-таблиц и уничтожить в корне эту проклятую ошибку ?


 
MOA

 
(2002-09-23 15:22)
[18]

>уничтожить в корне эту проклятую ошибку

Я бы сделал так:

1.Запрос:

«SELECT C.ComputerID AS «


 
Юрий Жуков

 
(2002-09-23 15:42)
[19]

очень странно…

так ты говоришь поставил свойство

Properties[«Unique Table»].Value := «Computers»?

Но судя по логу профайлера ADO все равно пытается апдейтить все таблицы.


 
Василич

 
(2002-09-26 14:05)
[20]

Ничего у меня не получается. Для интереса создал уникальный индекс во всех родительских таблицах, последовал всем советам MOA, и ничего не работает !!! Судя по вылетающей в этот раз ошибке («Cannot insert duplicate key») SQL Server действительно пытается засунуть записи в родительские таблицы, хотя ясно указаны все динамические свойства типа Resync Command и Unique Table. Подскажите, как избавиться от этой нездоровой тенденции SQL-сервера апдейтить таблицы, которые совершенно не нужно апдейтить !


 
Юрий Жуков

 
(2002-09-26 14:32)
[21]

Эт тебе не SQL сервер надо укрощать, а ADO.

И бороть нужно свойство «Unique table».

Попробуй компонент TBetterAdoDataSet (
http://web.orbitel.bg/vassil/), там можно его disign-time задать.


 
MOA

 
(2002-09-26 15:10)
[22]

Может, так:?

1. Если не хочется отказываться от VIEW — добавить отдельные DataSet-ы на вставку — обновление — удаление и перехватывать соответсвующие события, не давая «основному» датасету вставлять-удалять-обновлять

Или

2. В «Основном» датасете обращаться к детайл-таблице, оформив поля из мастер-таблиц как Lookup поля. Понадобится дополнительно столько датасетов, сколько мастер-таблиц — но обновления-удаления-вставки будут работать как ожидается + бонус — автоматом появится возможность юзеру выбирать нужные значения из Lookup-ов.

Любая таблица должна иметь PRIMARY KEY. И мастер — тоже. И это — ключ для ссылки из детайл.

А дублирующиеся ключи — это точно не ключи в детайл-таблице?

Удачи!


 
MOA

 
(2002-09-26 15:25)
[23]

И еще.

1.У Вас пользователи вводят НАЗВАНИЯ? Из, возможно, формируемого программой списка? — Если так, то так не надо бы…

2.У Вас стоит у VIEW опция VIEW_METADATA?

Удачи!


 
MOA

 
(2002-09-26 16:04)
[24]

Sorry, забыл, что у Вас не VIEW, a SELECT.

НО все же — попробуйте в SELECT выбирать только ссылки на мастер-таблицы (ID), а не названия.

Удачи!


 
Василич

 
(2002-09-26 16:08)
[25]

Похоже, этот кошмар никогда не кончится. Сделал все по вашим советам: lookup-поля, куча датасетов, по одному на каждую таблицу, даже не датасеты, а BetterADODataSets, черт бы их побрал. Насмотрелся на кучу новых ошибок, как например, сверхинформативное сообщение «Не удается вставить или обновить столбцы из нескольких таблиц», или, «При вызове ITransaction::Commit или ITransaction::Abort объект не отвечает на запросы». Короче, пора переквалифицироваться в дворники, всем спасибо за оказанную помощь.


 
MOA

 
(2002-09-26 16:13)
[26]

Покажите, пожалуйста, Ваш новый «основной» запрос.


 
Василич

 
(2002-09-26 16:16)
[27]

>MOA

Не совсем понятно, что в данном контексте означает «Названия» , вот запрос для сводной таблицы:

SELECT TOP 100 PERCENT C.ComputerID AS [Серийный номер компьютера], F.Faculty AS [Факультет/Отдел], P.Processor AS Процессор,

M.Motherboard AS [Материнская плата],

R.RAM AS [Оперативная память], V.VideoCard AS Видеоадаптер,

H.HDD AS [Жесткий диск], D.CDROM AS [Привод компакт-дисков],

S.SoundBlaster AS [Звуковая карта],

E.EtherCard AS [Сетевая карта], O.Monitor AS Монитор,

N.Printer AS Принтер, A.Scanner AS Сканер, X.Xerox AS Ксерокс,

B.Address AS Адрес, Cabinet AS Кабинет

FROM dbo.Computers C LEFT OUTER JOIN

dbo.Faculties F ON F.FacultyID = C.FacultyID LEFT OUTER JOIN

dbo.Processors P ON P.ProcessorID = C.ProcessorID LEFT OUTER JOIN

dbo.Motherboards M ON M.MotherboardID = C.MotherBoardID LEFT OUTER JOIN

dbo.RAMs R ON R.RAMID = C.RAMID LEFT OUTER JOIN

dbo.VideoCards V ON V.VideoCardID=C.VideoCardID LEFT OUTER JOIN

dbo.HDDs H ON H.HDDID = C.HDDID LEFT OUTER JOIN

dbo.CDROMs D ON D.CDROMID = C.CDROMID LEFT OUTER JOIN

dbo.SoundBlasters S ON S.SoundBlasterID = C.SoundBlasterID LEFT OUTER JOIN

dbo.EtherCards E ON E.EtherCardID = C.EtherCardID LEFT OUTER JOIN

dbo.Monitors O ON O.MonitorID = C.MonitorID LEFT OUTER JOIN

dbo.Printers N ON N.PrinterID = C.PrinterID LEFT OUTER JOIN

dbo.Scanners A ON A.ScannerID = C.ScannerID LEFT OUTER JOIN

dbo.Xeroxes X ON X.XeroxID=C.XeroxID LEFT OUTER JOIN

dbo.Addresses B ON B.AddressID = C.AddressID

ORDER BY F.Faculty

Сначала это был VIEW, потом я от него отказался и впихнул этот чудовищный запрос прямо в CommandText. Пытаюсь вставлять/редактировать его обычными методами типа Append/Edit/Post, и вылетают вышеназванные ошибки. От названий полей в данном случае отказаться не могу, а то получится не нормальный пользовательский интерфейс, а черт знает что.


 
MOA

 
(2002-09-26 16:35)
[28]

1. Русские названия полей = приключения. Воспользуйтесь Display label в свойстве поля.

2. Попробуйте такой запрос:

SELECT TOP 100 PERCENT C.ComputerID, C.FacultyID, C.ProcessorID,

C.MotherboardID, C.RAMID, C.VideoCardID, C.HDDID, C.CDROMID, C.SoundBlasterID, C.EtherCardID, C.MonitorID, C.PrinterID, C.ScannerID, C.XeroxID, C.AddressID, C.Cabinet

FROM dbo.Computers CORDER BY F.Faculty

Русские названия полей сделайте через Display label. Добавьте в получившийся датасет дополнительно Lookup поля для Faculity, Processor и т.д., поля с ID, соответственно, скройте от юзера (Display=False).

Всё должно поехать. Именно это я и имел в виду.

Удачи!


 
MOA

 
(2002-09-26 16:36)
[29]

Русские названия, конечно же, Вам понадобятся только для созданных Вами Lookup полей. Наверное, не нужно юзеру знать русское название поля ProcessorID, например.

Удачи!


I have a Delphi 6 professional program that is calling COM object methods belonging to an MSVC 2008 COM DLL. The DLL’s Type Library imported without error into Delphi. I can call one of the method’s without error, but most of the others lead to an EOleException error with the message «An unexpected exception was raised», which corresponds to the EOleException error code: 0x80040205,
EVENT_E_INTERNALEXCEPTION:

http://msdn.microsoft.com/en-us/library/cc704587(v=prot.10).aspx

I am calling CoInitialize before making the call:

var
    intfMsvcComObj: IMsvcComObject;

begin
    if not Succeeded(CoInitialize(nil)) then
        raise Exception.Create('Coinitialize failed.');

    intfMsvcComObj := CoMsvcComObject.Create;

    try
        // EOleException occurs when I make this call.
        intfMsvcComObj.doSomething;
    finally
        CoUninitialize;
    end;
end;

Next I tried turning of FPU exceptions because that sometimes is an issue when calling into MSVC DLLS using Set8087CW($133f) and then I tried again with Set8087CW(Get8087CW or $3f), but neither of those operations helped.

Any ideas on how to fix/diagnose this?

I have a Delphi 6 professional program that is calling COM object methods belonging to an MSVC 2008 COM DLL. The DLL’s Type Library imported without error into Delphi. I can call one of the method’s without error, but most of the others lead to an EOleException error with the message «An unexpected exception was raised», which corresponds to the EOleException error code: 0x80040205,
EVENT_E_INTERNALEXCEPTION:

http://msdn.microsoft.com/en-us/library/cc704587(v=prot.10).aspx

I am calling CoInitialize before making the call:

var
    intfMsvcComObj: IMsvcComObject;

begin
    if not Succeeded(CoInitialize(nil)) then
        raise Exception.Create('Coinitialize failed.');

    intfMsvcComObj := CoMsvcComObject.Create;

    try
        // EOleException occurs when I make this call.
        intfMsvcComObj.doSomething;
    finally
        CoUninitialize;
    end;
end;

Next I tried turning of FPU exceptions because that sometimes is an issue when calling into MSVC DLLS using Set8087CW($133f) and then I tried again with Set8087CW(Get8087CW or $3f), but neither of those operations helped.

Any ideas on how to fix/diagnose this?

Я сделал два компонента ActiveX в Delphi XE2 в отдельных проектах. Один из компонентов работает отлично, и каждое исключение, которое он выдает, маскируется как EOleException. На другом компоненте ActiveX исключения не маскируются, они генерируются как исходный тип. Клиент представляет собой программу delphi XE.

Когда компонент ActiveX выдает исходное исключение, следующий вызов любого другого метода из компонента выдает исключение нарушения прав доступа в тех местах, где он не должен, например, установка локальной строковой переменной со значением. Это очень странное поведение.

Я сравнил оба проекта: файл .ridl, параметры компиляции, файл .dproj и не смог найти виновника.

Кто-нибудь знает причину этой разницы/странного поведения?

благодаря

Изменить: какой-то код

Компонент 1, который работает (маскирует все исключения для EOleException)

TspdMyClassX = class(TActiveXComponent, MyInterface)

initialization


TActiveXComponentFactory.Create(
    ComServer,
    TspdMyClassX,
    CLASS_spdMyClassX,
    1,
    '',
    0,
    tmBoth);

Другой компонент, который не генерирует EOleException, имеет другой интерфейс, но остальная часть кода такая же (инициализация, родительский класс TActiveXComponent).

A Windows service when trying to access the .Body property of a MSMQ message object throws an EOleException — but only when the Xml document contained in this message has an empty list node.

The EOleException message complains about insufficient memory (exception code -2147024882). Since the exception only occurs with the smallest possible Xml document, memory cannot be the real issue. The next thing that comes to mind is a problem with access rights but then again all «good» messages (as described below) are processed without problems.

The exception can be reproduced under any thinkable condition («bad» message first, many «good» messages first — then «bad» message, run in debugger or just logging the exception); it doesn’t matter if the code shown below is run as a service or as a simple excecutable.

Using the same COM object (MSMQ.MSMQQueueInfo) from within a VBScript on the same machine does not produce any errors.

Accessing any other properties apart from .Body doesn’t throw an exception so the message object instance seems to be received sucessfully. Also the transaction receiving the message can be comitted sucessfully if the .Body property is not accessed.


Windows Service code

//...
qInfo    := CreateOleObject('MSMQ.MSMQQueueInfo');
qTxDisp  := CreateOleObject('MSMQ.MSMQTransactionDispenser');
//...
qTx := qTxDisp.BeginTransaction;
qMessage := qQueue.Receive(qTx, False, True, 0);
//...
sBody := qMessage.Body; //throws EOleException

The qMessage.BodyLength property returns the value 165 for «bad» messages as shown below.

«Bad» message

<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
    <query>
        <entrylist count="0">
        </entrylist>
    </query>
</response>

This message reliably makes the service code throw an EOleExecption.

«Good» message

<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
    <query>
        <entrylist count="2">
            <entry>
                <abc>123</abc>
                <def>456</def>
            </entry>
            <entry>
                <abc>789</abc>
                <def>000</def>
            </entry>
        </entrylist>
    </query>
</response>

This message is reliably processed without problems.

The problem first occured when moving the service from a Win2003 machine to a Win2008 (32-bit Standard).

Эта тема


  • Везде

  • Эта тема
  • Этот форум

  • Расширенный поиск

Поиск

A Windows service when trying to access the .Body property of a MSMQ message object throws an EOleException — but only when the Xml document contained in this message has an empty list node.

The EOleException message complains about insufficient memory (exception code -2147024882). Since the exception only occurs with the smallest possible Xml document, memory cannot be the real issue. The next thing that comes to mind is a problem with access rights but then again all «good» messages (as described below) are processed without problems.

The exception can be reproduced under any thinkable condition («bad» message first, many «good» messages first — then «bad» message, run in debugger or just logging the exception); it doesn’t matter if the code shown below is run as a service or as a simple excecutable.

Using the same COM object (MSMQ.MSMQQueueInfo) from within a VBScript on the same machine does not produce any errors.

Accessing any other properties apart from .Body doesn’t throw an exception so the message object instance seems to be received sucessfully. Also the transaction receiving the message can be comitted sucessfully if the .Body property is not accessed.


Windows Service code

//...
qInfo    := CreateOleObject('MSMQ.MSMQQueueInfo');
qTxDisp  := CreateOleObject('MSMQ.MSMQTransactionDispenser');
//...
qTx := qTxDisp.BeginTransaction;
qMessage := qQueue.Receive(qTx, False, True, 0);
//...
sBody := qMessage.Body; //throws EOleException

The qMessage.BodyLength property returns the value 165 for «bad» messages as shown below.

«Bad» message

<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
    <query>
        <entrylist count="0">
        </entrylist>
    </query>
</response>

This message reliably makes the service code throw an EOleExecption.

«Good» message

<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
    <query>
        <entrylist count="2">
            <entry>
                <abc>123</abc>
                <def>456</def>
            </entry>
            <entry>
                <abc>789</abc>
                <def>000</def>
            </entry>
        </entrylist>
    </query>
</response>

This message is reliably processed without problems.

The problem first occured when moving the service from a Win2003 machine to a Win2008 (32-bit Standard).

Материал подготовлен совместно с
Петром Федотовым

В этой статье мы постараемся рассмотреть основные ошибки, возникающие при обмене данными через коннектор 1С, способы их расследования и варианты решения.

Иногда возникает ситуация, что коннектор настроен, определены справочники,  участвующие в обмене и ключевые реквизиты, настроены фильтры, а обмен не идет. Что делать в такой ситуации? С чего начать? Первым делом нужно проверить
параметры подключения к интегрированной системе: 

Убедитесь, что вы правильно указали параметры подключения: имя сервера, имя базы данных, логин, пароль и имя плана обмена. Параметр
InitiateDataExchangeIn1C должен быть установлен в значение «Да», для того чтобы
автоматически запустился процесс обмена данными в системе 1С после формирования файлов с данными по плану, заданному в параметре
ExchangePlan

Если параметры подключения указаны правильно, а обмен не идет, то стоит проверить настройки плана обмена в конфигураторе 1С: 

Убедитесь, что объекты 1С, с которым вы настроили обмен, присутствует в списке выбранных объектов плана обмена. Также убедитесь, чтобы не стояло галочки «Распределенная информационная база». Излишне полный план обмена увеличивает
количество выгружаемых данных, что очень сильно влияет на скорость обмена данными. Поэтому нужно стараться максимально облегчить план обмена только необходимыми объектами. Например, на приведенном выше скриншоте в плане обмена оставлены только необходимые
для интеграции объекты 1С (4 справочника и 1 план видов характеристик).

Еще одной распространенной причиной того, что обмен не работает, является то, что забыли пометить в 1С данные к выгрузке вручную или с помощью сценария «Выполнить подготовку объектов 1С к загрузке в DIRECTUM». Сценарий выполняет
регистрацию изменений всех настроенных объектов для выбранной интегрированной системы 1С. Регистрация изменений всех настроенных объектов 1С необходима для того, чтобы коннектор учитывал все данные этих объектов, в том числе и измененные до создания плана
обмена. Обычно это необходимо при самом первом обмене данными между 1С и DIRECTUM. Если необходимости выгружать все данные нет, то можно просто пересохранить запись справочника 1С или DIRECTUM, чтобы она попала в тестовый обмен. 

Иногда после настройки коннектора 1С и попытке провести первый обмен, в логах обмена появляется ошибка вида:

07.04.2011 09:52:12 Начало выгрузки данных справочников системы DIRECTUM
07.04.2011 09:52:13 Экспорт ДГВ 175128 Change 
07.04.2011 09:52:13 Экспорт ОРГ 175126 Change 
07.04.2011 09:52:14 Завершение выгрузки данных справочников системы DIRECTUM
07.04.2011 09:52:14 Начало загрузки данных объектов в систему "1С81"
07.04.2011 09:52:26 ERROR    Ошибка преобразования данных из формата DIRECTUM в формат системы или загрузки данных в интегрированную систему. (Ошибка преобразования данных XML: [file://C:/DIREXCHANGE1C/Message_002_001.xml][2,3861] Функция "Connector1C81ImportDataToIntegratedSystem": ошибка в строке 176.
Функция "ConnectorImportDataToIntegratedSystem": ошибка в строке 3.
Функция "ConnectorImportDataToIntegratedSystem": ошибка в строке 14.)
07.04.2011 09:52:26 Завершение загрузки данных объектов в систему "1С81"

Причина появления данной ошибки в том, что мы пытаемся загрузить в 1С неправильно сформированный XML-файл с данными обмена. Первым делом необходимо проверить настройки обмена на вкладке «Дополнительные настройки»:

Если все настройки сделаны правильно, а ошибка все равно появляется, то попробуем определить ошибочную запись в XML-файле обмена. В нашем случае это файл Message_002_001.xml. Наименование файлов обмена формируется по принципу Message_КодУзлаСистемыИсточника_КодУзлаСистемыПриемника: 

У меня, в отличие от приведенного выше скриншота, коды узлов были наоборот (001 — Узел 1С, 002 – Узел DIRECTUM), чтобы вы не путались в дальнейшем. Таким образом, видим, что у нас в качестве источника выступает DIRECTUM, а в качестве
приемника 1С. Откроем этот файл обмена в Visual Studio и отформатируем его: 

В результате наш отформатированный XML-файл обмена будет выглядеть так:

Сохраним его и попробуем загрузить в 1С с помощью сценария:

  IntegratedSystemCode = "1C81"
  FullFileName = "C:/DIREXCHANGE1C/Message_002_001.xml"
  
  V8App = Connector1C81Get1C80Application(IntegratedSystemCode)
  // Проверить все ли объекты включены в необходимый план обмена
  Object.Environment.SetVar("V8App"; V8App)    
  ExchangePlanName = GetIntegratedSystemParam(IntegratedSystemCode; "ExchangePlan")

  // Создать и проинициализаровать объект ЧтениеХМL
  // Используется VBScript, так как на ISBL невозможно вызывать метод V8App.NewObject("XMLReader")
  ScriptControl = CreateObject("MSScriptControl.ScriptControl")
  ScriptControl.Language = "VBScript"
  ScriptControl.Reset
  ScriptControl.AddObject("V8App"; V8App)    
  XMLReader = ScriptControl.Eval('V8App.NewObject("XMLReader")')
  XMLReader.OpenFile(FullFileName)
  // Создать объект ЧтениеСообшенияОбмена 
  // и начать чтение сообщения
  MessageReader = V8App.ExchangePlans.CreateMessageReader
  MessageReader.BeginRead(XMLReader)
  V8App.ExchangePlans.DeleteChangeRecords(MessageReader.Sender; MessageReader.ReceivedNo)     
  // Читаем данные из сообщения
  while V8App.CanReadXML(XMLReader)
    Data = V8App.ReadXML(XMLReader) 
    Data.ОбменДанными.Отправитель = MessageReader.Sender
    Data.ОбменДанными.Загрузка = TRUE
    Data.Write()
  endwhile    
  // Закончить чтение сообщения и чтение XML
  MessageReader.EndRead() 
  XMLReader.Close
  V8App = NIL
  окно("Загрузка завершена!")

В переменной IntegratedSystemCode нужно указать код интегрированной системы, а в переменной
FullFileName путь до сформированного XML-файла с данными для обмена. Сценарий можно доработать, добавив запрос переменной
IntegratedSystemCode через InputDialog, FullFileName получать из табличной части по коду системы и добавить обработку исключений, т.к. мы ждем, что появится ошибка. Я по своей натуре существо очень ленивое, поэтому оставил его в таком виде.
В результате работы сценария мы получим ошибку: 

Теперь мы видим строку и столбец «[4369,2]» с ошибочными данными в XML-файле обмена Message_002_001.xml. Снова открываем этот файл в Visual Studio и переходим к указанной в ошибке строке: 

Тут сразу видно, что с этой записью что-то не то, но чтобы убедиться в этом окончательно, выгрузим данные из 1С с помощью внешней обработки ВыгрузкаЗагрузкаДанныхXML.epf, которую можно найти на диске ИТС или в интернете. Для этого
запускаем 1С Предприятие и через пункт меню ФайлОткрыть открываем обработку ВыгрузкаЗагрузкаДанныхXML.epf. Указываем имя файла для выгрузки, отмечаем какой объект 1С необходимо выгрузить и нажимаем кнопку «Выгрузить данные». 

На скриншоте не указан период выгрузки, т.к. у меня база 1С была почти пустая. Если у вас в интегрируемых объектах 1С скопилось много данных (например, за несколько лет), то период выгрузки стоит обязательно указать, иначе такой
выгрузкой можно очень сильно подвесить систему. Как правило, чтобы оценить правильность формирования XML-файла с данными, достаточно выгрузить 2-3 записи.

После того, как данные будут выгружены, открываем сформированный XML-файл с выгруженными данными и начинаем сравнивать, чем наша неправильно сформированная запись отличается от выгруженных из 1С. В моем случае правильно сформированная
запись для выгрузки должна выглядеть так: 

Сравнив её с ошибочной записью, видим, что почему-то не заполнены некоторые реквизиты значениями по умолчанию:

Для реквизита типа справочник, вместо пустого значения должны были быть нули «00000000-0000-0000-0000-000000000000», для реквизита типа число должен стоять «0», а не пустая строка, для логического реквизита вместо пустой строки
должно быть «true» или «false».

Далее можно действовать исходя из поставленной перед вами задачи:

  1. Удалить ошибочную запись из XML-файла обмена, провести загрузку данных с помощью сценария указанного выше и скорректировать «Время последней выгрузки» в настройках интегрированной системы на текущее (чтобы эта запись в обмен больше
    не попадала).
  2. Дополнить ошибочную запись XML-файла обмена недостающими данными, провести загрузку данных с помощью сценария указанного выше и скорректировать «Время последней выгрузки» в настройках интегрированной системы на текущее (чтобы
    эта запись в обмен больше не попадала).
  3. Попытаться найти причину, почему XML-файл сформировался неправильно, и устранить её.

Чтобы найти причину, почему XML-файл формируется неправильно, потребуется добавить отладочную информацию в функции коннектора и в XSL-шаблон преобразования. Об этом поговорим более подробно в следующем материале. 

ВыгрузкаЗагрузкаДанныхXML_для_1С81.zip (65,86 Кб)

ВыгрузкаЗагрузкаДанныхXML_для_1С82.zip (67,53 Кб)


Форум программистов Vingrad

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> EOleException, как перехватить ошибку ? 

V

   

Опции темы

comtat
  Дата 11.1.2007, 13:56 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

Подключаюсь через ADO к MS_Access

Код

str := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID='+Login+';';
str := str + 'Data Source='+IniDir+Database+';Mode=ReadWrite;';
str := str + 'Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";';
str := str + 'Jet OLEDB:Database Password="'+Pass+'";Jet OLEDB:Engine Type=5;';
str := str + 'Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;';
str := str + 'Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";';
str := str + 'Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;';
str := str + 'Jet OLEDB:Don''t Copy Locale on Compact=False;';
str := str + 'Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False';
ADOConnection1.ConnectionString := str;
ADOConnection1.Connected := true;
...

Необходимо проводить анализ ошибок таких как неверный путь к БД, неверный логин или пароль и т.д.
Как можно перехватить код ошибки ?

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
ТоляМБА
Дата 11.1.2007, 14:05 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Котэ
***

Профиль
Группа: Завсегдатай
Сообщений: 1607
Регистрация: 15.12.2004
Где: Трансильвания

Репутация: 3
Всего: 252

Код

try
...твой код...
except
on e:Exception do
    begin
  ShowMessage(e.Message);
  ...твои действия в случае если твой код вызвал ошибку...
    end;
end;

PM   Вверх
comtat
Дата 11.1.2007, 14:18 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

То, что ты написал у меня уже готово.
Возможно я не правильно сформулировал вопрос, но мне небходимы коды ошибок, чтобы в зависимости он них
выводит соответствующие рекоммендации для юзера  smile 

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
SergeBS
Дата 12.1.2007, 09:50 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22

comtat
ADOConnection.Errors.Count — сколько.
ADOConnection.Errors[i], i=0…ADOConnection.Errors.Count-1 — сами ошибки.
Это правда не коды ошибок, а сами сообщения. Переведешь на русский язык в меру желания.

PM MAIL   Вверх
comtat
Дата 12.1.2007, 10:16 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

SergeBS ТоляМБА  спасибо за помощь ! smile 
Вот что у меня получилось

Код

  str := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID='+Login+';';
  str := str + 'Data Source='+IniDir+Database+';Mode=ReadWrite;';
  str := str + 'Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";';
  str := str + 'Jet OLEDB:Database Password="'+Pass+'";Jet OLEDB:Engine Type=5;';
  str := str + 'Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;';
  str := str + 'Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";';
  str := str + 'Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;';
  str := str + 'Jet OLEDB:Don''t Copy Locale on Compact=False;';
  str := str + 'Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False';
  ADOConnection1.ConnectionString := str;
  try
    try
      ADOConnection1.Connected := true;
    except
      on E: EOleException do
        begin
          // Не верный путь к БД
          if (E.ErrorCode=-2147467259) then
            {Обработка ошибки}
          // Не верный логин или пароль
          if (E.ErrorCode=-2147217843) then
            {Обработка ошибки}
        end;
    end;
  finally
    {если все гуд}
  end;

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
SergeBS
Дата 12.1.2007, 10:47 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22

comtat
Ошибочка: 26 строка — это совсем не {если все гуд}. Это {а все равно бабахну}. А {если все гуд} — сразу после 13 и перед except. Там можешь выставить флажок насчет гуд и по нему выпускать юзера в базу.

PM MAIL   Вверх
comtat
Дата 12.1.2007, 14:31 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

SergeBS пасиб  smile 
Еще тагды вопрос в тему если выложить БД на локальной машины, то со своей машины я могу подключиться,
а остальные не могут говорит, что не верный путь к БД хотя все верно.

Бд и exe писал на своей машине, в чем может быть проблема ?? 

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
SergeBS
Дата 12.1.2007, 15:04 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22

comtat

Цитата
если выложить БД на локальной машины, то со своей машины я могу подключиться,
а остальные не могут говорит, что не верный путь к БД хотя все верно.

Я в таких случаях стряпаю udl-файл и пытаюсь подключиться им. Вообще:
1. Права доступа к файлам на машине. 
2. Блокировка другим приложением — ты открыл в исключительном режиме — остальные отдыхают. 
3. Просто блокировка при записи. Access 97 например строчной блокировки не имеет.

Вообще — не советую так делать. Если несколько юзеров одновременно будут одну Access-базу как файл подключать, то рано или поздно произойдет БАХ! И база сдохнет. Возможно — насмерть, т.е. без восстановления даже части данных.
Если нужно несколько юзеров — в 2000 и новее Офисе спрятана MSDE — младшая (по возможностям)  сестрица MS SQL server. Базу Access съест влегкую. И база у тебя тогда рухнет только вместе с винтом smile. Или запускай НА ОДНОЙ машине MS Jet (движок Access) и уже с ним работай юзерами — гимору больше, но будет многопользовательская.

PM MAIL   Вверх
comtat
Дата 13.1.2007, 12:05 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

Трабла была с правами к БД

К одной БД базе будет коннектится только одно приложение, т.к. у заказчика нет возможности дылать локалку. А потом данные нуна будет как-то реплицировать. А Access позволяет делать репликации ? 

 smile 
Я бы и сам непротив бы пользоваться MSDE, но заказчик настаивает на Access типа эт круто  smile

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
SergeBS
Дата 15.1.2007, 09:35 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22

comtat

Цитата
А Access позволяет делать репликации ? 

Репликация != объединению.

PM MAIL   Вверх
comtat
Дата 15.1.2007, 13:25 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

Цитата(SergeBS @  15.1.2007,  09:35 Найти цитируемый пост)
Репликация != объединению

Я в курсе  smile 
но все же Access поддерживает репликацию ?? 

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
SergeBS
Дата 15.1.2007, 14:40 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22

comtat

Цитата
но все же Access поддерживает репликацию ?? 

Понятия не имею. Он мне по большому счету неинтересен. Да и в твоей задаче это неважно — сети-то нет. Значит все равно ручками файл тащить, через флэшку/RW-шку и т.п. 

PM MAIL   Вверх
comtat
Дата 15.1.2007, 15:17 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: 1
Всего: 71

SergeBS , а прав ведь, как сам запамятил . Спасибо !!  smile 

———————

Рожденный в СССР !!!
ExtJS — мой фреймворк 

PM   Вверх
Evenstain
Дата 5.3.2010, 12:34 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

Профиль
Группа: Участник
Сообщений: 30
Регистрация: 13.11.2008

Репутация: 1
Всего: 0

такая вот проблема: пытаюсь перехватить ошибки класса EOleException. но delphi ругается, говорит, что

Цитата(Delphi)
[Error] Unit3.pas(107): Undeclared identifier: ‘EOleException’

использую код типа:

Код

try
  .............
  .............
except
  on EOleException do 
begin
.................
.................
end
  ...
end;

объясните, что я делаю не так

PM MAIL   Вверх
pseud
Дата 5.3.2010, 16:48 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Экспёрт Тыдыщ
***

Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

Репутация: 16
Всего: 40

Evenstain, смотри свою тему там ответил

Цитата

Цитата(Evenstain @  4.3.2010,  16:13 Найти цитируемый пост)
P.S. написал в разделе type: EOleException = class(Exception); вроде работает, но ошибку не ловит. что я делаю не так??

читаем хелп:

Цитата
EOleException is the exception class for OLE automation errors that occur in methods or properties of an object.
Unit
ComObj

не создавай свой класс EOleException (не справшивай почему), а в uses пропиши ComObj.

———————

Испытание чужого терпения можно считать успешным, если оно лопнуло…

PM MAIL   Вверх



















Ответ в темуСоздание новой темы
Создание опроса
Правила форума «Delphi: Базы данных и репортинг»
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) — крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 

0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »

Понравилась статья? Поделить с друзьями:
  • Eol 1 ошибка частотника
  • Epc ошибка сеат леон
  • Epc ошибка на приборке
  • Eof when reading line python ошибка
  • Eocapp exe ошибка приложения divinity original sin 2