Доступ к VBA, неэкранированные одинарные кавычки, Replace () и null - PullRequest
0 голосов
/ 01 августа 2011

Работа над сценарием в Microsoft VBA для извлечения массивной плоской базы данных и разделения ее примерно на 20 различных таблиц.Сценарий состоит в основном из открытия таблицы, проверки каждой строки в плоской базе данных, чтобы убедиться, что она не является дубликатом, а затем добавления необходимых полей.Повторите для каждой таблицы.

При первом запуске все шло хорошо, пока я не попытался обработать имя O'Malley.Я думаю, что очевидно, что пошло не так.Быстрый поиск в Google обнаружил этот связанный пост StackOverflow .Я воспользовался их советом и добавил Replace(str, "'", "''") к каждому полю, прежде чем вводить его в новые таблицы.Теперь я столкнулся с новой проблемой, и Google менее полезен.

Replace(null, "'", "''") вызывает ошибку во время выполнения, и плоская база данных просто пронизана нулевыми значениями.Я могу добавить дополнительную строку выше каждый Replace() вызов для проверки IsNull() и, если это так, поместить null в базу данных вместо Replace(str, "'", "''"), хотя я бы предпочел решение, которое может вписаться водна строка, если это возможно.Есть ли какой-нибудь более элегантный способ решить эту дилемму, или мне понадобятся 216 If операторов в моем коде?

EDIT -

Еще одна причина, по которой я ищу более элегантное решениемой дублирующий контрольный код.На данный момент у меня есть что-то вроде следующего:

        'Check for duplicates
        'Assume student is duplicate if it shares:
        '   (StudentName and School) or SSN
        Set rstDuplicate = CurrentDb.OpenRecordset("select * from Student where (StudentName = '" & Replace(rstFrom("Student").Value, "'", "''") & "' AND School = '" & Replace(rstFrom("School").Value, "'", "''") & "') OR SSN = '" & Replace(rstFrom("Social").Value, "'", "''") & "'")
        If rstDuplicate.RecordCount = 0 Then
            'Duplicate was not found
            rstTo.AddNew
            ' Add fields to the new table
            rstTo.Update
        End If

Поскольку вызовы Replace() встроены в проверку дублирования, если бы вместо этого я использовал операторы If для проверки null, тогда япришлось бы либо сохранить результат в строку или обновить в плоской базе данных.Функция, которая возвращает Replace(str, "'", "''") ИЛИ null без необходимости в дополнительных переменных, была бы идеальной.

Ответы [ 3 ]

1 голос
/ 01 августа 2011

Краткий, но ужасный маленький драгоценный камень, переданный мне много веков назад:

Replace(str & "", "'", "''")

Добавление пустой строки к нулевому значению возвращает пустую строку в VBA и не изменяет непустая строка.

1 голос
/ 01 августа 2011

Access 'ядро базы данных будет принимать одинарные или двойные кавычки в качестве разделителей для строковых значений в запросах.Поэтому вместо ...

SELECT * FROM Student WHERE StudentName = 'O''Malley'

... вы можете сделать это ...

SELECT * FROM Student WHERE StudentName = "O'Malley"

Это позволит вам обрабатывать входные данные, содержащие апострофы.OTOH, если ваши строковые входы также содержат двойные кавычки, это сломается.

Я подозреваю, что у вас может быть нечто большее, чем просто проблема с апострофами, но я не понимаю вашу общую картину.Похоже, вы открываете третий набор записей DAO для каждой записи в rstFrom, чтобы проверить, существует ли совпадение в таблице Student.Я бы использовал DCount () .

Dim strCriteria As String
strCriteria = "StudentName = ""O'Malley"" AND School = ""foo"""
If DCount("*", "Student", strCriteria) = 0 Then
    'no match found --> add it '
End If
1 голос
/ 01 августа 2011

Если вы хотите, чтобы все было встроено, вы можете использовать немедленную функцию If (IIf):

IIf(IsNull(rstFrom("Student").Value), " Is Null", "= " & Replace(rstFrom("Student").Value)

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

Function CompFld(Val As Variant) As String
    If IsNull(Val) Then
        CompFld = " Is Null "
    Else
        CompFld = "= '" & Replace(Val, "'", "''") & "' "
    End If
End Function

Используйте это так:

Dim SQL As String
SQL = "SELECT * FROM Student " & _
      "WHERE (StudentName " & CompFld(rstFrom("Student").Value) & " AND " & _
      "       School " & CompFld(rstFrom("School").Value) & ") " & _
      "   OR (SSN " & CompFld(rstFrom("Social").Value) & ") "
Set rstDuplicate = CurrentDb.OpenRecordset(SQL)
If rstDuplicate.RecordCount = 0 Then
    'Duplicate was not found
    rstTo.AddNew
    ' Add fields to the new table
    rstTo.Update
End If
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...