Строка, действующая ненормально в цикле For Each в коде VBA в MSAccess - PullRequest
0 голосов
/ 29 декабря 2008

Хорошо, поэтому я начал с вопроса и внес много изменений в код, основываясь на предложениях этого сайта и других, поэтому я решил, что должен создать новый вопрос.

Несмотря на то, что мой код короче и эффективнее, такая же проблема сохраняется; Я использую строку с именем strSQL, которая содержит инструкцию INSERT, которую я хочу выполнить. У меня есть цикл FOR EACH, который проходит через каждый элемент управления в моей форме MSAcess (гарантирует, что это текстовое поле, раскрывающийся список или флажок) и определяет, было ли изменено поле. Если он есть, он генерирует строку запроса для регистрации изменений и сохраняет ее в strSQL.

Проблема в том, что один и тот же запрос выполняется снова и снова. Я добавил оператор DEBUG.PRINT до и после строки, которая выполняет строку запроса, и отладчик показывает, что строка CHANGED! Да, вы правильно прочитали, это кажется невозможным, но я сделал скриншоты.

Сначала мой код:

Private Sub Form_BeforeUpdate(Cancel As Integer)
    Dim C As Control
    For Each C In Controls
        Select Case C.ControlType
            Case acTextBox, acComboBox, acCheckBox
                Dim strOriginalValue, strCurrentValue, strSQL As String

                strOriginalValue = IIf(IsNull(C.OldValue), "", IIf(C.OldValue = vbTrue Or C.OldValue = vbFalse, IIf(C.OldValue = vbTrue, "Yes", "No"), C.OldValue))
                strCurrentValue = IIf(IsNull(C.Value), "", IIf(C.Value = vbTrue Or C.Value = vbFalse, IIf(C.Value = vbTrue, "Yes", "No"), C.Value))

                If strOriginalValue <> strCurrentValue Then
                    strSQL = "INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'" & ThisUserName() & "','Edit'," & [id] & ",0,'" & C.ControlSource & "','Administrator','" & Replace(strOriginalValue, "'", "") & "','" & Replace(strCurrentValue, "'", "") & "')"
                    Debug.Print "Before: " & strSQL
                    CurrentDb.Execute strSQL, dbFailOnError
                    Debug.Print "After: " & strSQL
                End If
        End Select
    Next
End Sub

Вот результаты работы отладчика:

Before: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'indoor_performers_tab','Administrator','No','Yes')
After: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'indoor_performers_tab','Administrator','No','Yes')
Before: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'volunteers_tab','Administrator','No','Yes')
After: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'volunteers_tab','Administrator','No','Yes')

Во-вторых, мои скриншоты ... во-первых, отладчик: 1 & 2 , а во-вторых, результаты: здесь - обратите внимание, что отладчик слишком широк, поэтому Я сделал два снимка экрана, и его результаты закрашены рядом, поскольку это никак не связано с этой проблемой.

Обратите внимание, что единственным столбцом, который должен отличаться в приведенном мной примере, должен быть столбец "field_affered".

Я в полной растерянности, я понятия не имею, почему он выведет правильную строку в отладчик и выполнит что-то еще.

РЕДАКТИРОВАТЬ: Перед использованием CurrentDb.Execute я использовал DoCmd.RunSQL, но это потребовало от меня отключить, а затем снова включить предупреждения. Поскольку результат был одинаковым для обоих (одна и та же ошибка), я использовал однострочное решение вместо трехстрочного.

ОБНОВЛЕНИЕ: Привет shahkalpesh за помощь в понимании того, что данные действительно вставляются правильно, и я вижу их в студии управления SQL Server, но MS Access по-прежнему отображает их неправильно ... вопрос почему?

ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Исправлено добавлением в таблицу целочисленного столбца идентификаторов / автоинкрементов. Я подозреваю, что отсутствие различных значений полей сбивало с толку MSAccess (хотя на самом деле нет причин для этого) - мораль здесь это M $ глупо

Ответы [ 7 ]

1 голос
/ 29 декабря 2008

Если вы можете перейти к конкретной таблице SQL Server (с помощью Query Analyzer или Enterprise Mgr) и посмотреть, работает ли она так, как вы ожидаете. Я сомневаюсь, что связанная таблица в VBA может показывать вам неправильную картинку.

Редактировать: Если у вас есть SQL Profiler, посмотрите, что там выполняется, чтобы подтвердить ваши сомнения в том, что выполняется тот же запрос.

1 голос
/ 29 декабря 2008

Связана ли рассматриваемая форма с источником данных? Это наиболее распространенный способ использования Access, и если бы вы были, вероятно, не нужно было бы обновлять через SQL.

Form_BeforeUpdate () обычно используется, когда форма связана с источником данных. Обычно вы не используете это событие, чтобы определить, изменились ли значения элементов управления и нужно ли записывать обратно в БД ...

0 голосов
/ 02 января 2009

Я должен сказать, что обсуждение этого вопроса сводит меня с ума. С ODBC связанными таблицами вы начинаете со связанных форм. Нет просто никаких причин использовать пул соединений. Если вы враждебны к реализации Access, как это сделать, ПРЕКРАТИТЕ ИСПОЛЬЗОВАТЬ ДОСТУП.

0 голосов
/ 29 декабря 2008

Исправлено добавлением столбца первичного ключа с автоинкрементом в таблицу изменений.

Глупый доступ ...

0 голосов
/ 29 декабря 2008

Ах, вы тоже используете SQL Server. Мне очень повезло с использованием триггеров для аудита изменений данных в Access. Есть несколько причуд, но связывание таблиц через ODBC с использованием доверенной аутентификации делает это очень простым.

ОК, так что вы не можете или не хотите использовать триггеры. Когда интерфейсный SQL с Access, я обычно использую объекты ADO в своем коде VBA для такого рода вещей. Связанные таблицы с ODBC отлично подходят для связанных форм, но ничто не сравнится с ADO для прямого перехода на SQL Server.

Хотите получить дополнительную информацию о связывании таблиц с использованием доверенной аутентификации или помочь с использованием ADO для работы с SQL Server?

0 голосов
/ 29 декабря 2008

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

0 голосов
/ 29 декабря 2008

Вы запускаете эти запросы для currentdb (который, я полагаю, является access-db), но на самом деле используете базу данных сервера SQL, где вы хотите, чтобы изменения произошли?

Связаны ли эти таблицы на сервере sql с таблицами в access-db или какой метод вы используете?

...