Запрос Access 2007 VBA Показывает данные в Анализаторе запросов, но не в наборе записей, закодированном в VBA
-
05-07-2019 - |
Вопрос
У меня есть функция, которую я написал, которая изначально должна была принимать строковое поле и заполнять значениями электронную таблицу Excel.Эти значения постоянно возвращались к нулю.Я начал отслеживать это вплоть до набора записей и обнаружил, что, несмотря на то, что запрос был действительным и корректно выполнялся через анализатор запросов Access, набор записей был пуст или содержал недостающие поля.
Чтобы проверить проблему, я создал подраздел, в котором создал запрос, открыл набор записей, а затем пролистал значения (выводя их в поле сообщения).Самая запутанная часть проблемы, по-видимому, связана с предложением "WHERE" в запросе.Если я не добавляю предложение "WHERE" в запрос, в наборе записей всегда есть данные, а значения для "DESCRIPTION" являются нормальными.
Если я поставлю что угодно в предложении WHERE набор записей возвращается либо полностью пустым (rs.EOF = true
) или поле Описания полностью пустое, тогда как другие поля имеют значения.Я хочу еще раз подчеркнуть, что если я выполню запрос debug.print, я смогу скопировать / вставить его в анализатор запросов и получить действительные и возвращаемые значения, которые я ожидаю.
Я был бы очень признателен за некоторую помощь в этом.Спасибо!
Private Sub NewTest()
' Dimension Variables
'----------------------------------------------------------
Dim rsNewTest As ADODB.Recordset
Dim sqlNewTest As String
Dim Counter As Integer
' Set variables
'----------------------------------------------------------
Set rsNewTest = New ADODB.Recordset
sqlNewTest = "SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, " & _
"dbo_part.partdescription as Description, dbo_partmtl.qtyper as [Qty Per] " & _
"FROM dbo_partmtl " & _
"LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum " & _
"WHERE dbo_partmtl.mtlpartnum=" & Chr(34) & "3C16470" & Chr(34)
' Open recordset
rsNewTest.Open sqlNewTest, CurrentProject.Connection, adOpenDynamic, adLockOptimistic
Do Until rsNewTest.EOF
For Counter = 0 To rsNewTest.Fields.Count - 1
MsgBox rsNewTest.Fields(Counter).Name
Next
MsgBox rsNewTest.Fields("Description")
rsNewTest.MoveNext
Loop
' close the recordset
rsNewTest.Close
Set rsNewTest = Nothing
End Sub
Редактировать:Кто-то попросил меня опубликовать ОТЛАДКУ.РАСПЕЧАТАТЬ запрос.Вот оно:
SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, dbo_part.partdescription as [Description], dbo_partmtl.qtyper as [Qty Per] FROM dbo_partmtl LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum WHERE dbo_partmtl.mtlpartnum='3C16470'
Я пробовал двойные и одинарные кавычки с использованием символов ASCII и неявно.
Например:
"WHERE dbo_partmtl.mtlpartnum='3C16470'"
Я даже попробовал ваше предложение с chr (39):
"WHERE dbo_partmtl.mtlpartnum=" & Chr(39) & "3C16470" & Chr(39)
Оба возвращают нулевое значение для описания.Однако, если я отлажу.распечатаю запрос и вставлю его в анализатор запросов Access, он отобразится просто отлично.Опять же (в качестве дополнительного примечания), если я выполню оператор LIKE в предложении WHERE , это даст мне полностью пустой набор записей.Что-то здесь действительно не так.
Вот интересный лакомый кусочек.Таблицы связаны с SQL Server
.Если я скопирую таблицы (данные и структуру) локально, приведенный выше код ADO сработает безупречно.Если я использую DAO, это работает нормально.Я уже опробовал этот код на Windows XP
, Access 2003
, и различные версии ADO (2.5, 2.6, 2.8)
. ADO
не будет работать, если таблицы связаны.
В ADO есть некоторый недостаток, который вызывает проблему.
Абсолютно уверен.Помните, что DEBUG.PRINT
запрос, который вы видите, отлично выполняется в анализаторе запросов.Он возвращает следующее:
Job/Sub Rev Description Qty Per 36511C01 A MAIN ELECTRICAL ENCLOSURE 1 36515C0V A VISION SYSTEM 1 36529C01 A MAIN ELECTRICAL ENCLOSURE 1
Однако тот же запрос возвращает пустые значения для Описания (все остальное то же самое) при запуске через набор записей (ошибки messagebox из-за значения "Null").
Я попытался переименовать поле "description" в "testdep", но оно по-прежнему пустое.Единственный способ заставить его отображать данные - это удалить раздел WHERE из запроса.Я начинаю верить, что это проблема с ADO.Может быть, я перепишу его с помощью DAO и посмотрю, какие результаты получу.
Редактировать:Я также пару раз пробовал уплотнять и ремонтировать.Никаких кубиков.
Решение
При использовании ADO LIKE при поиске необходимо использовать% вместо *. Я знаю, * работает в Access, но по какой-то глупой причине ADO не будет работать, если вы не используете% вместо этого. Р>
У меня была та же проблема, и я пытался ее исправить. Замена * на% сработала для меня.
Другие советы
Description - это зарезервированное слово - заключите его в квадратные скобки [] в операторе SELECT
Редактировать
Попробуйте назвать столбец как-нибудь помимо Описания
Также вы уверены, что используете те же значения в предложении where - потому что это левое соединение, поэтому поле Описания будет пустым, если в dbo_part нет соответствующей записи
ОТРЕДАКТИРУЙТЕ ЕЩЕ РАЗ
Если вы получаете забавные результаты - попробуйте создать компактную / восстановленную базу данных - возможно, она повреждена
Ну, я боялся, так и есть. Он работает отлично с DAO, но не ADO.
Вот рабочий код:
Private Sub AltTest()
' Dimension Variables
'----------------------------------------------------------
Dim rsNewTest As DAO.Recordset
Dim dbl As DAO.Database
Dim sqlNewTest As String
Dim Counter As Integer
' Set variables
'----------------------------------------------------------
sqlNewTest = "SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, " & _
"dbo_part.partdescription as [TestDep], dbo_partmtl.qtyper as [Qty Per] " & _
"FROM dbo_partmtl " & _
"LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum " & _
"WHERE dbo_partmtl.mtlpartnum=" & Chr(39) & "3C16470" & Chr(39)
Debug.Print "sqlNewTest: " & sqlNewTest
Set dbl = CurrentDb()
Set rsNewTest = dbl.OpenRecordset(sqlNewTest, dbOpenDynaset)
' rsnewtest.OpenRecordset
Do Until rsNewTest.EOF
For Counter = 0 To rsNewTest.Fields.Count - 1
MsgBox rsNewTest.Fields(Counter).Name
Next
MsgBox rsNewTest.Fields("TestDep")
rsNewTest.MoveNext
Loop
' close the recordset
dbl.Close
Set rsNewTest = Nothing
End Sub
Я нигде не использую DAO в этой базе данных и предпочел бы не запускать. Куда мы идем отсюда?
Я знаю, что прошло некоторое время с тех пор, как начался этот поток, но на случай, если вам интересно, я обнаружил некоторую любопытность в Access 2003, и эта ошибка, возможно, была перенесена на 2007 год (как я вижу, что это так). р>
У меня была похожая проблема с предложением WHERE, потому что мне нужны были записи из поля даты, которые также содержали время, поэтому все содержимое поля выглядело бы как # 6/14/2011 11:50:25 AM # (# добавлено для форматирования).
Та же проблема, что и выше, запрос отлично работает с " WHERE ((tblTransactions.TransactionDate) Like '" & QueryDate & amp; " *'); " в представлении конструктора запросов, но он не будет работать в коде VBA с использованием ADO.
Поэтому я прибег к использованию " WHERE ((tblTransactions.TransactionDate) Like '" & QueryDate & amp; " %%: %%: %%% M'); " в коде VBA, с ADO, и он работает просто отлично. Отображает искомую запись, уловка не в том, чтобы использовать " * " в предложении Like; или, по крайней мере, это была проблема в моем случае.
Я поставил квадратные скобки вокруг слова " Описание " в операторе SELECT, но его поведение остается. Это работает нормально, пока я не помещаю ничего в предложение WHERE. Я обнаружил, что если я добавлю что-либо в предложение where, описание будет пустым (несмотря на то, что оно отображается в анализаторе запросов). Если я использую инструкцию LIKE в предложении WHERE, весь набор записей будет пустым, но он все равно будет работать правильно в Query Analyzer.
В конечном счете, я думаю, что это проблема с запуском ADO 2.8 в Vista 64
Лично я всегда использовал DAO в проектах Access. Р>