Сбой пользовательских функций (UDF) из запроса на доступ к Excel с использованием VBA OpenRecordset - неопределенная функция - PullRequest
1 голос
/ 26 апреля 2019

Как получить результаты запроса из Access в Excel, если он имеет UDF?

Я получаю следующую ошибку: " Ошибка времени выполнения" 3085': Неопределенная функция' XXXX 'в выражении".Ошибка возникает при открытии набора (запрос доступа) из Excel VBA.Открываемый запрос имеет пользовательскую функцию (UDF), которая вызывает ошибку.

Код находится в Excel Office 365. Запрос находится в Access Office 365.

Я успешно использовалзапрос вызывался (и другие с UDF) в течение примерно двенадцати месяцев, и «внезапно» он больше не работает.Я гуглил и протестировал множество вариантов, но безуспешно.

Большинство потоков говорят, что это невозможно, или не использовать udf, но попробуйте встроенный, который работает.Я оспариваю эти ответы, потому что это работало ранее.Основной udf, который я использую, называется iMax, о котором написано в других постах.Он работает как max () в Excel.( Нет функции max (x, y) в Access )

Я также видел потоки, которые предлагают выполнить это в два этапа: 1 - изменить запрос на запрос make table.2 - перетащить результаты таблицы в Excel.Хотя мне, возможно, и удастся с этим справиться (после долгих переделок), это приведет к тому, что я создам много временных таблиц с тысячами и тысячами строк, и это выглядит не очень гладко.БД без последствий для моей проблемы.

В долгосрочной перспективе я создал фиктивную базу данных с простой публичной функцией udf, которая возвращает число 1, простой запрос, который возвращает три записи и поле для результатов функции.При извлечении в Excel возникает та же ошибка.

Sub RunQuery()
Dim MyDatabase As dao.Database
Dim qdf As dao.QueryDef
Dim rs As dao.Recordset
Dim qryname As object
Dim SheetName As String

Set MyDatabase = DBEngine.OpenDatabase _
("SomePath\SomeFilename.accdb")

For Each qryname In Range("SomeRange")
    Set rs = MyDatabase.OpenRecordset(qryname)      '<<<ERROR IS HERE
    SheetName = "SomeSheetName"
        With Sheets(SheetName)
            .ListObjects(SomeTableName).DataBodyRange.Rows.ClearContents
            .Range("A2").CopyFromRecordset rs
        End With
    Set rs = Nothing
    Set qdf = Nothing
Next qryname

End Sub

Для всех запросов в цикле For, не имеющих udf, результаты извлекаются и выгружаются в серию таблиц в Excel.Любой запрос с ошибкой udf в "Set rs = Mydatabase.OpenRecordset (qryname)

Ответы [ 3 ]

1 голос
/ 26 апреля 2019

Большинство потоков говорят, что это невозможно,

и они правы.

Ваш единственный вариант - использовать автоматизацию, чтобы открыть экземпляр Access и, внутри него, выполнить запрос.

0 голосов
/ 28 апреля 2019

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

Однако, если вы на 100% уверены, что это было и работало одновременно?

Вам необходимо установить режим «песочницы» ядра базы данных JET (теперь ACE).

Служба выражений обычно не позволяет оценивать функции VBA в качестве параметра безопасности для предотвращения внедрения SQL или кода, выполняемого вне Access, чтобы SQL мог запускать + вызывать функции VBA. Когда-то эта функция по умолчанию имела значение «вкл.», Но теперь по умолчанию установлен только доступ.

Вы должны установить папку, в которой приложение Access, как доверенное. Это должно позволить функциям VBA теперь работать. поэтому убедитесь, что вы установили папку как доверенную.

Если местоположение (папка), в которой ваше приложение доступа НЕ является доверенным, то Access будет использовать режим песочницы, а VBA в SQL не будет работать.

Если местоположение является доверенным, то THEN access использует настройки реестра на вашем компьютере.

Я уверен, что расположение не является доверенным, поэтому вы всегда получаете режим песочницы для SQL в Access.

Если вы на 100% уверены, что расположение папки установлено как надежное в Access, и вы по-прежнему получаете ошибки, то вам необходимо изменить параметр реестра для режима Access «песочница».

Настройка в реестре изложена здесь: https://support.office.com/en-us/article/Turn-sandbox-mode-on-or-off-to-disable-macros-8CC7BAD8-38C2-4A7A-A604-43E9A7BBC4FB

Настройки реестра:

для доступа x32 бит:

Software\Microsoft\Office\ClickToRun\Registry\Machine\Software\
Wow6432Node\Microsoft\Office\16.0\Access Connectivity Engine\Engines

Выше для Office 2016

14 = 2010

15 = 2013

16 = 2016

Ключевое значение для режима песочницы: От 0 до 3

0 Режим песочницы всегда отключен.

1 Режим песочницы используется для доступа, но не для программ без доступа.

2 Режим песочницы используется для программ без доступа, но не для доступа.

3 Режим песочницы используется постоянно. Это значение по умолчанию, устанавливаемое при установке Access

Итак, сверху вы хотите установить значение 0.

0 голосов
/ 26 апреля 2019

Если вы выполняете запрос в сеансе приложения Access, как предложил Густав, служба выражений может обрабатывать UDF в вашем запросе.

Вот быстрый проверенный фрагмент Excel VBA, который извлекает данные из запроса, которыйвключает UDF:

Const cstrDbFile As String = "C:\share\Access\Database2.accdb"
Dim objAccess As Object
Dim rs As Object
Dim ws As Worksheet
Dim strSelect As String

Set objAccess = CreateObject("Access.Application")
objAccess.Visible = True ' useful during testing '
objAccess.OpenCurrentDatabase "C:\share\Access\Database2.accdb"
strSelect = "SELECT ID, DummyFunction('a', '', 'c') FROM Dual;"
Set rs = objAccess.CurrentDb.OpenRecordset(strSelect)
If Not rs.EOF Then
    Set ws = ThisWorkbook.Sheets("Sheet1")
    ws.Range("A1").CopyFromRecordset rs
End If
rs.Close
objAccess.Quit
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...