Зависает доступ к источнику записей Subform, установленному на SQL из VBA

У меня есть форма «Поиск» в моей базе данных, которая принимает строку, разбивает ее на массив и строит строку SQL на основе выбранного типа соединения (переключатели «Или», «И» или «Точная фраза»). Мой код отлично работает 95% времени, но каждый раз, когда база данных зависает, когда я переключаюсь между различными типами соединения и запросами. Я подтвердил, что SQL создается правильно, и я думаю, что проблема связана с попыткой изменить источник записей подчиненной формы, пока она все еще загружается.

Моя поисковая форма работает следующим образом:

  1. Пользователь помещает поисковый запрос / фразу в текстовое поле.
  2. При событии «After Update» текстового поля VBA создает строку SQL и сохраняет ее в скрытом текстовом поле (получившем название «ModifiedSearchValue»).
  3. Если пользователь изменяет тип соединения (радиокнопки с опциями «Или», «И» или «Точная фраза»), событие «После обновления» в группе вызывает подпрограмму VBA (как в № 2), и VBA создает строку SQL. который хранится в скрытом текстовом поле (получившем название "ModifiedSearchValue")
  4. Когда пользователь нажимает кнопку «Поиск», VBA устанавливает для RecordSource подчиненной формы значение «ModifiedSearchValue» следующим образом:

    Я! Results.Form.RecordSource = Me.ModifiedSearchValue

Опять же, это работает отлично большую часть времени, но если вы введете поисковый запрос, нажмите «Поиск», затем измените тип соединения и снова нажмите «Поиск», это приведет к зависанию базы данных примерно в 5% случаев.

Мой основной код VBA выглядит следующим образом

    Private Sub SearchString()
Dim SearchString, SearchStringTitle, SearchStringName, SearchStringDescription, SearchStringInvestigator, JoinValue, j, SQLString As String, SearchArray, varValue As Variant

    SearchString = Trim(Me.SearchValue)

    If Not IsNull(SearchString) Then
        SearchArray = Split(SearchString, " ")

        SQLString = "SELECT tbl_Studies.StudyID, tbl_Studies.Study_Short_Title, tbl_Studies.Study_Name, tbl_Studies.Study_Description, [qry_General:FullName_FMLD].FullName AS Investigator, tbl_Studies.Project_Type, IIf([Project_Type]=1,[tbl_Studies:Status]![Status],[tbl_Studies:NR_Status]![NR_Status]) AS Overall_Status, tbl_Studies.Date_Submitted, tbl_Studies.Date_Updated, tbl_Studies.Results_Summary, tbl_Studies.Inactive " & _
                    "FROM ([tbl_Studies:NR_Status] RIGHT JOIN ([tbl_Studies:Status] RIGHT JOIN tbl_Studies ON [tbl_Studies:Status].StatusID = tbl_Studies.Status) ON [tbl_Studies:NR_Status].NR_StatusID = tbl_Studies.NR_Status) LEFT JOIN [qry_General:FullName_FMLD] ON tbl_Studies.Investigator = [qry_General:FullName_FMLD].PersonID " & _
                    "WHERE "

        If Me.Join_Type <> 3 Then

            If Me.Join_Type = 1 Then
                JoinValue = "OR"
            ElseIf Me.Join_Type = 2 Then
                JoinValue = "AND"
            Else
                JoinValue = " "
            End If

    '--
            SearchStringTitle = "(("
            For Each varValue In SearchArray
                j = Trim(varValue)
                SearchStringTitle = SearchStringTitle & "(tbl_Studies.Study_Short_Title) Like ""*" & j & "*"""

                If varValue <> SearchArray(UBound(SearchArray)) Then
                    SearchStringTitle = SearchStringTitle & " " & JoinValue & " "
                End If
            Next varValue
            SearchStringTitle = SearchStringTitle & "))"

    '--
            SearchStringName = "(("
            For Each varValue In SearchArray
                j = Trim(varValue)
                SearchStringName = SearchStringName & "(tbl_Studies.Study_Name) Like ""*" & j & "*"""

                If varValue <> SearchArray(UBound(SearchArray)) Then
                    SearchStringName = SearchStringName & " " & JoinValue & " "
                End If
            Next varValue
            SearchStringName = SearchStringName & "))"

    '--
            SearchStringDescription = "(("
            For Each varValue In SearchArray
                j = Trim(varValue)
                SearchStringDescription = SearchStringDescription & "(tbl_Studies.Study_Description) Like ""*" & j & "*"""

                If varValue <> SearchArray(UBound(SearchArray)) Then
                    SearchStringDescription = SearchStringDescription & " " & JoinValue & " "
                End If
            Next varValue
            SearchStringDescription = SearchStringDescription & "))"

    '--
            SearchStringInvestigator = "(("
            For Each varValue In SearchArray
                j = Trim(varValue)
                SearchStringInvestigator = SearchStringInvestigator & "([qry_General:FullName_FMLD].FullName) Like ""*" & j & "*"""

                If varValue <> SearchArray(UBound(SearchArray)) Then
                    SearchStringInvestigator = SearchStringInvestigator & " " & JoinValue & " "
                End If
            Next varValue
            SearchStringInvestigator = SearchStringInvestigator & "))"

            SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
        Else
            SearchStringTitle = "(((tbl_Studies.Study_Short_Title) Like ""*" & SearchString & "*""))"
            SearchStringName = "(((tbl_Studies.Study_Name) Like ""*" & SearchString & "*""))"
            SearchStringInvestigator = "((([qry_General:FullName_FMLD].FullName) Like ""*" & SearchString & "*""))"
            SearchStringDescription = "(((tbl_Studies.Study_Description) Like ""*" & SearchString & "*""))"

            SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
        End If

        SearchString = SQLString & SearchString & ";"

        Me.ModifiedSearchValue.Value = SearchString
    End If
End Sub

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

Заранее благодарим за любую информацию / помощь!


person coffejor    schedule 26.10.2012    source источник
comment
Что такое [tbl_Studies:Status]![Status]? Является ли tbl_Studies: Status именем таблицы? Если да, то почему вы используете челку (!) Вместо точки (.)? Поместите построенный запрос (SQLString) в пустой запрос и выполните его, чтобы проверить, работает ли он. Поместите точку останова в последнюю строку, затем введите? SQLString в непосредственном окне, чтобы получить SQL.   -  person Olivier Jacot-Descombes    schedule 27.10.2012
comment
Здравствуйте, спасибо за ответ! Использование челки вместо точки является доказательством моей лени: я быстро собрал ядро ​​строки SQL в конструкторе запросов и скопировал ее в VBA. Я вернулся и очистил код. Чтобы ответить на ваше предложение, я проверил, что создаваемые строки SQL действительны во многом так, как вы предложили. Проблема не в недопустимом SQL. Еще раз спасибо за ваши предложения; какие-нибудь другие мысли?   -  person coffejor    schedule 27.10.2012
comment
Я только что понял, что не ответил на ваш первоначальный вопрос: да tbl_Studies: Статус - это имя таблицы. Еще раз спасибо!   -  person coffejor    schedule 28.10.2012
comment
Почему вы храните строку поиска в текстовом поле? Сохраните его в переменной уровня класса (переменная, определенная перед первым Sub или Function в форме. Или, что еще лучше, создайте строку поиска только тогда, когда пользователь нажимает Search. Тогда больше не будет необходимости хранить ее постоянно.   -  person Olivier Jacot-Descombes    schedule 29.10.2012
comment
Мне очень нравится идея построения строки только тогда, когда пользователь нажимает кнопку поиска. Метод, который я сейчас использую, снова показывает мою лень: пока я разрабатывал код для построения строки, я использовал текстовое поле для визуализации и тестирования вывода. Сегодня я потрачу некоторое время на переписывание своего кода и сообщу вам, решит ли он проблему. Спасибо за предложения!   -  person coffejor    schedule 29.10.2012
comment
Хорошо, я переписал свой код на основе ваших предложений: теперь строка создается и устанавливается в RecordSource подчиненной формы, когда пользователь выполняет поиск, без сохранения ее в отдельном поле. К сожалению, проблема не устранена. Я заметил, что могу заставить базу данных зависать, не меняя поисковый запрос или тип соединения, например если я отправлю поиск, дождусь результатов, повторно отправлю поиск, дождусь результатов ... (* n) Иногда база данных зависает после третьей повторной отправки, иногда требуется больше, но, похоже, в конечном итоге она всегда зависает. Еще раз спасибо за помощь!   -  person coffejor    schedule 29.10.2012
comment
Возможно ли, что разные процедуры обработчика событий вызывают друг друга? Иногда код в одном обработчике событий может вызвать другое событие, которое, в свою очередь, выполняет код, который снова запускает первое событие ...   -  person Olivier Jacot-Descombes    schedule 29.10.2012
comment
Это отличное предложение, о котором я определенно не подумал. Чтобы проверить это, я создал совершенно новую форму поиска и подчиненную форму результатов, свободную от каких-либо обработчиков событий, кроме события OnClick кнопки поиска. Я проверил результат и столкнулся с той же проблемой ... :(. Спасибо, что остались со мной по этой проблеме и за ваши предложения!   -  person coffejor    schedule 29.10.2012
comment
Еще одно предложение: определите источник записи без предложения where и не меняйте его. Затем измените фильтрацию, установив предложения Filter и FilterOn. Где Filter будет соответствовать вашему предложению Where без слова Where, а FilterOn будет либо True, либо False. (Таким образом, вы даже можете сохранить часть SELECT FROM как запрос Access, что упростит ее редактирование и понимание.)   -  person Olivier Jacot-Descombes    schedule 30.10.2012
comment
Привет. Еще раз спасибо за все ваши предложения. Я использовал метод фильтрации поиска, как вы предложили. Этот метод отлично работает, но у меня возникает та же проблема, что и с методом RecordSource: после многократного поиска базы данных происходит сбой (вместо зависания, как это было с RecordSource). Когда я открываю базу данных после сбоя и увеличиваю SQL в источнике подчиненной формы, база данных снова падает. Когда я восстанавливаюсь из резервной копии (созданной до сбоя поиска), я могу убедиться, что исходный файл подчиненной формы увеличился нормально. Любое понимание? : S Еще раз спасибо за все!   -  person coffejor    schedule 31.10.2012
comment
Хранятся ли данные в mdb доступа? Если да, сожмите и отремонтируйте mdb. Вы можете сделать то же самое с веб-интерфейсом (приложением).   -  person Olivier Jacot-Descombes    schedule 31.10.2012
comment
Данные хранятся в Access MDB, и я выполнил сжатие и восстановление. Я также запустил утилиту MS JetComp для восстановления базы данных, если резервная копия изначально повреждена. Я попытаюсь восстановить базу данных завтра, скопировав все в новый файл базы данных, и повторно применю ваши предложения. Еще раз спасибо за все, Оливье, вы очень помогли.   -  person coffejor    schedule 31.10.2012
comment
Я полностью перестроил базу данных и повторно уплотнил / отремонтировал. К сожалению, здесь та же проблема, что и раньше: когда я нажимаю «Поиск» несколько раз (обычно больше трех раз), давая поисковой форме достаточно времени для загрузки между щелчками, происходит сбой базы данных. Может ли это быть ошибкой в ​​Access? Если это поможет, я сохраню базу данных в режиме Access 2000.   -  person coffejor    schedule 31.10.2012
comment
Просто выстрел из темноты: все ли ваши таблицы имеют первичные ключи? Вы заменили все челки (!) Точками (.) Для доступа к полям (даже в qry_General:FullName_FMLD)? Вы вызываете некоторые функции VBA в qry_General:FullName_FMLD?   -  person Olivier Jacot-Descombes    schedule 31.10.2012
comment
Оливье: Вы были правы на 100%! Я звонил на VBA в qry_General:FullName_FMLD, чтобы я мог связать имя человека с его соответствующими степенями. Как только я переключился на запрос qry_General:FullName_FML (который не включает степень и, следовательно, VBA), проблема была решена. Теперь я могу нажимать «Поиск» столько раз, сколько мне нужно, без сбоя базы данных. Я предполагаю, что корень проблемы был в том, что форма пыталась применить фильтр до того, как запрос вернул результат, тем самым создав поврежденную строку фильтра. Еще раз спасибо!   -  person coffejor    schedule 01.11.2012


Ответы (1)


Согласно предложениям Оливье, истинной причиной проблемы был вызов VBA как часть запроса [qry_General:FullName_FMLD]; переход на [qry_General:FullName_FML] (который не вызывает никакого VBA) устранил все проблемы. Я предполагаю, что корень проблемы был в том, что форма пыталась применить фильтр до того, как запрос вернул результат, тем самым создав поврежденную строку фильтра.

Вот обновленный код, использующий метод фильтрации и заменяющий все челки точками:

Private Sub Search_Click()
    On Error GoTo Err_Search_Click

    Dim SearchString, SearchStringTitle, SearchStringName, SearchStringDescription, SearchStringInvestigator, JoinValue, j, SQLString As String, SearchArray, varValue As Variant

        Me.Results.Form.FilterOn = True
        SearchString = Trim(Me.SearchValue)

        If Not IsNull(SearchString) Then
            SearchArray = Split(SearchString, " ")

            If Me.Join_Type <> 3 Then

                If Me.Join_Type = 1 Then
                    JoinValue = "OR"
                ElseIf Me.Join_Type = 2 Then
                    JoinValue = "AND"
                Else
                    JoinValue = " "
                End If

        '--
                SearchStringTitle = "(("
                For Each varValue In SearchArray
                    j = Trim(varValue)
                    SearchStringTitle = SearchStringTitle & "(tbl_Studies.Study_Short_Title) Like ""*" & j & "*"""

                    If varValue <> SearchArray(UBound(SearchArray)) Then
                        SearchStringTitle = SearchStringTitle & " " & JoinValue & " "
                    End If
                Next varValue
                SearchStringTitle = SearchStringTitle & "))"

        '--
                SearchStringName = "(("
                For Each varValue In SearchArray
                    j = Trim(varValue)
                    SearchStringName = SearchStringName & "(tbl_Studies.Study_Name) Like ""*" & j & "*"""

                    If varValue <> SearchArray(UBound(SearchArray)) Then
                        SearchStringName = SearchStringName & " " & JoinValue & " "
                    End If
                Next varValue
                SearchStringName = SearchStringName & "))"

        '--
                SearchStringDescription = "(("
                For Each varValue In SearchArray
                    j = Trim(varValue)
                    SearchStringDescription = SearchStringDescription & "(tbl_Studies.Study_Description) Like ""*" & j & "*"""

                    If varValue <> SearchArray(UBound(SearchArray)) Then
                        SearchStringDescription = SearchStringDescription & " " & JoinValue & " "
                    End If
                Next varValue
                SearchStringDescription = SearchStringDescription & "))"

        '--
                SearchStringInvestigator = "(("
                For Each varValue In SearchArray
                    j = Trim(varValue)
                    SearchStringInvestigator = SearchStringInvestigator & "([qry_General:FullName_FML].FullName) Like ""*" & j & "*"""

                    If varValue <> SearchArray(UBound(SearchArray)) Then
                        SearchStringInvestigator = SearchStringInvestigator & " " & JoinValue & " "
                    End If
                Next varValue
                SearchStringInvestigator = SearchStringInvestigator & "))"

                SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
            Else
                SearchStringTitle = "(((tbl_Studies.Study_Short_Title) Like ""*" & SearchString & "*""))"
                SearchStringName = "(((tbl_Studies.Study_Name) Like ""*" & SearchString & "*""))"
                SearchStringInvestigator = "((([qry_General:FullName_FML].FullName) Like ""*" & SearchString & "*""))"
                SearchStringDescription = "(((tbl_Studies.Study_Description) Like ""*" & SearchString & "*""))"

                SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
            End If

            Me.Results.Form.Filter = SearchString
        End If

    Exit_Search_Click:
        Exit Sub

    Err_Search_Click:
        MsgBox ("There are no active records to review.")
        Resume Exit_Search_Click
End Sub

И снова заслуга в этом решении принадлежит Оливье Жако-Дескому - спасибо за вашу помощь и предложения!

person coffejor    schedule 01.11.2012