Вопрос или проблема
Я недавно купил книгу “Microsoft Excel VBA и макросы” Билла Джелена и Трейси Сирстад, чтобы расширить свои базовые знания о VBA. Работая над их разделами в главе 18, я пытаюсь присвоить QueryTable объектной переменной, и это не работает.
Вот процедура из раздела 18.4, с которой у меня возникли проблемы (как я ее написал, переписывая их текст, я не вижу явных ошибок):
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim id As String
Dim ThisArtist As String
Dim ThisAlbum As String
Dim qtArtistAlbums As QueryTable
Dim qtAlbumTracks As QueryTable
If Target.Cells.Count = 1 Then
If Target.Column <= 3 Then
If Target.Row > 3 Then
ThisArtist = Cells(Target.Row, 1).Value
If Trim(ThisArtist) <> "" Then
id = "ArtistAlbums"
Set qtArtistAlbums = ActiveSheet.ListObjects(id).QueryTable
If Not qtArtistAlbums.Refreshing Then
ThisWorkbook.Queries(id).Formula = "let Result = " & "fnGetAlbums(""" &_ ThisArtist & """) in Result"
qtArtistAlbums.Refresh False
Application.Goto Range("E4")
End If
End If
End If
ElseIf Target.Column >= 4 And Target.Column <= 7 Then
If Target.Row > 3 Then
ThisAlbum = Cells(Target.Row, 5)
If Trim(ThisAlbum) <> "" Then
id = "AlbumTracks"
Set qtAlbumTracks = ActiveSheet.ListObjects(id).QueryTable
If Not qtAlbumTracks.Refreshing Then
ThisWorkbook.Queries(id).Formula = "let Result =" & "fnGetTracks(""" &_ ThisAlbum & """) in Result"
qtAlbumTracks.Refresh False
Application.Goto Range("J5")
End If
End If
End If
End If
End If
End Sub
Код зависает на этой строке:
If Not qtArtistAlbums.Refreshing Then
или здесь (в зависимости от случая):
If Not qtAlbumTracks.Refreshing Then
IntelliSense сообщает, что qtBlaBla = ничего. Я предполагаю, что строки выше не присваивают qtBlaBla QueryTable, с этим у меня основные проблемы (так я думаю).
У меня также есть очень похожая строка кода в 18.3, которая выглядит так:
Dim qtSearchArtist As QueryTable
id = "SearchArtist"
Set qtSearchArtist = ThisWorkbook.Worksheets("Sheet1").ListObjects(id).QueryTable
… и она работает нормально. Поэтому я попытался использовать ThisWorkbook.Worksheets(“Sheet1”), но безуспешно.
В модуле книги я попробовал следующее и не смог назначить qt как QueryTable, код завис на debug.print, но qt = ничего в строке выше.
Private Sub test()
Dim id As String
Dim sheet As Worksheet
Dim lo As ListObject
Dim qt As QueryTable
Set sheet = ThisWorkbook.Sheets("Sheet1")
id = "ArtistAlbums"
Set lo = sheet.ListObjects(id)
Set qt = lo.QueryTable
Debug.Print (qt.Name)
End Sub
Также изменил
Set lo = sheet.ListObjects(id)
на
Set lo = Range(id).ListObject
в той же тестовой процедуре и не смог назначить qt как QueryTable.
Мысли?
Ответ или решение
Проблема, с которой вы столкнулись, связана с тем, что при попытке присвоить объект QueryTable
переменной (в данном случае qtArtistAlbums
и qtAlbumTracks
), этот объект, возможно, не существует или не был корректно создан на листе. Ваша ошибка указывает на то, что переменная qtArtistAlbums
или qtAlbumTracks
равна Nothing
, что означает, что присвоение не прошло успешно.
Вот несколько шагов и рекомендаций, которые могут помочь вам решить данную проблему:
-
Проверьте наличие ListObject: Убедитесь, что объект
ListObject
с идентификатором, заданным в переменнойid
(например, "ArtistAlbums" или "AlbumTracks"), действительно существует на файловом листе. Если он не существует, попытка обращения к его свойствуQueryTable
вернётNothing
. -
Идентификаторы объектов: Проверьте, правильно ли вы указали идентификаторы. Убедитесь, что в вашей таблице данных в Excel существует
ListObject
с таким же именем. Чтобы проверить это:- Перейдите на лист "Sheet1".
- Убедитесь, что ваша таблица имеет соответствующее имя. Вы можете сделать это, кликнув на таблицу, а затем выйдя в свойствах таблицы, чтобы увидеть ее имя.
-
Использование
ThisWorkbook.Worksheets
: Когда вы хотите обратиться кListObject
, лучше использовать полное обращение к конкретному рабочему листу. Например:Set qtArtistAlbums = ThisWorkbook.Worksheets("Sheet1").ListObjects(id).QueryTable
-
Проверка на наличие ошибки при выполнении: Добавьте обработку ошибок для того, чтобы записать в журнал ошибки, если
ListObject
не найден. Например:On Error Resume Next Set qtArtistAlbums = ThisWorkbook.Worksheets("Sheet1").ListObjects(id).QueryTable If qtArtistAlbums Is Nothing Then Debug.Print "QueryTable не удалось установить для " & id End If On Error GoTo 0
-
Убедитесь в том, что QueryTable существует: Убедитесь, что у вашего
ListObject
действительно есть связаннаяQueryTable
. Не всеListObject
имеютQueryTable
, это зависит от того, как они были созданы. Можно также попробовать вывести список всехQueryTables
в вашем файле, чтобы убедиться, что он здесь есть:Dim qt As QueryTable For Each qt In ThisWorkbook.Worksheets("Sheet1").QueryTables Debug.Print qt.Name Next qt
-
Проверка текущего состояния: Попробуйте отладить вашу подпрограмму и просмотреть значения переменных, чтобы понять, в какой момент всё идет не так. Вы можете использовать
Debug.Print
для проверки значений перед строками, где вы сталкиваетесь с ошибкой.
Если вы будете следовать этим шагам, это должно помочь вам выявить источник проблемы и правильно установить объект QueryTable
. Удачи в решении вашей задачи!