Определение соответствия записей электронной таблицы записям столбцов базы данных

#sql #excel #ms-access-2007 #vba

#sql #excel #ms-access-2007 #vba

Вопрос:

Один из аспектов моего проекта заключается в сравнении номера детали, введенного оператором, с заранее определенным списком номеров деталей в столбце базы данных. Прямо сейчас моя программа сообщает мне, что каждый номер детали, введенный в электронную таблицу (50 ), не соответствует ни одному из них в базе данных, что, как я проверил, неверно. Я проверил, что и номер элемента электронной таблицы, и номер элемента базы данных имеют строковый тип данных. Я дважды проверил, что моя логика цикла хороша, и мне кажется, что она должна работать. Насколько мне известно, ни в ячейках базы данных, ни в ячейках электронной таблицы нет скрытых символов. На данный момент я совершенно не понимаю, почему моя программа не обнаруживает совпадений между электронной таблицей и базой данных. Ниже приведен подраздел, содержащий код для проверки соответствия номеров деталей:

 Sub CheckPN()
  'Connect to the E2 database
   Call SetPNConnection
  'Open a recordset
   Set PNRecordset = New ADODB.Recordset
   PNRecordset.Open "EstimRpt", PNConnection, adOpenKeyset, adLockOptimistic, adCmdTable
   PNSQLCmd = "SELECT DISTINCT [PartNo] FROM EstimRpt;"
  'Loop through data, comparing part numbers to E2 database part number records
   TotalBadPNCount = 0
   With PNRecordset
      For DataRowCount = 2 To TrackingLastRow
         PNCount = 0
         Part_Number = Tracking.Sheets("Operator Data").Range("A" amp; DataRowCount).Value
        'MsgBox "The datatype for " amp; Part_Number amp; " is " amp; VarType(Part_Number) amp; "."
         Do Until .EOF
           'MsgBox "The datatype for " amp; .Fields("PartNo").Value amp; " is " amp; VarType(.Fields("PartNo").Value) amp; "."
            If Part_Number = .Fields("PartNo").Value Then
           'If .Fields("PartNo").Value = Part_Number Then
               MsgBox Part_Number amp; " is a match."
               PNCount = PNCount   1
            End If
            .MoveNext
         Loop
         If PNCount < 1 Then
            MsgBox "The P/N " amp; Part_Number amp; " entered in cell A" amp; DataRowCount amp; " is incorrect.  Please correctly enter the P/N and re-run the program."
            TotalBadPNCount = TotalBadPNCount   1
         End If
      Next DataRowCount
      If TotalBadPNCount >= 1 Then
         Exit Sub
      End If
   End With
   PNRecordset.Close
   Set PNRecordset = Nothing
   PNConnection.Close
   Set PNConnection = Nothing
End Sub
  

Кроме того, я бы хотел, чтобы вся программа прекратила выполнение, если номер детали не совпадает, а не только непосредственный подраздел. В настоящее время только этот подраздел завершается, если номер детали не совпадает.

Спасибо за помощь по обоим этим вопросам.

Иордания

Ответ №1:

Я бы предложил не использовать цикл для сравнения записей из вашего пользовательского набора данных с вашей постоянной таблицей. Вместо этого загрузите отправленный пользователем набор данных во временную таблицу в вашей БД и используйте SQL для сравнения 2 таблиц.

Вы можете попробовать что-то в этом роде:

 'Load spreadsheet into temp table
<your code here>

'open recordset in order to compare PartNos
Dim db As Database
Set db = CurrentDb
Dim rs As Recordset

sSQL = "select count(*) as [count] from temp " _ 
        amp; " where temp.PartNo not in (select distinct EstimRpt.PartNo from EstimRpt)"
Set rs = db.OpenRecordset(sSQL)

ctRecords = rs![Count]

'if records are found in temp table that do not exist 
'in the perm table, then end execution of everything.
if ctRecords > 0 then
    End
else
    'run the rest of your code
    <your code here>
end if

'Drop temp table
<your code here>
  

Комментарии:

1. Есть ли особая причина, по которой сравнение записей в моем пользовательском наборе данных Excel с моей таблицей постоянного доступа не будет работать? Альтернатива этому маршруту кажется довольно громоздкой, условно говоря. Если записи Access и Excel имеют тип string, почему не совпадают те, которые должны совпадать? Есть ли какая-то «скрытая» разница между двумя записями? Спасибо за вашу помощь.

2. Я не могу сказать, почему ваше текущее сравнение не работает, не имея доступа к вашим файлам. Если между версиями Excel / Access существуют какие-либо проблемы с совместимостью, извлечение данных Excel в Access перед запуском сравнения выявит эти проблемы (проверьте типы данных столбцов Excel после их импорта в Access). Как только данные доступны, вы можете запустить сравнение на основе наборов без использования RBAR , что значительно повышает производительность при работе с большими наборами данных.

3. База данных, из которой я читаю, — это та, в которой мне обязательно не изменять / изменять / модифицировать каким-либо образом (это большая база данных, используемая для программы управления магазином).). Поэтому я хочу только считывать данные из него, а не что-либо еще. Итак, исключив это, я снова убедился, что оба значения являются строками, и, согласно окнам сообщений в моей программе Excel, моя программа Excel считывает / интерпретирует значения базы данных точно так, как они записаны в Excel. Похоже, это указывает на то, что мои данные хороши, но мой цикл имеет недостатки, но для меня он выглядит хорошо. Предложения Ant?

4. Хорошо — удачи! Я ничего не могу предложить, потому что я не вижу, что на самом деле происходит «под капотом» в ваших файлах Excel и Access. Если вы не хотите создавать какие-либо новые объекты в существующей базе данных Access, вы можете создать отдельную базу данных, которая извлекает данные из «основной» и выполняет сравнение там.

Ответ №2:

Наконец-то я нашел свою проблему. Сравнение записей между базой данных и электронной таблицей теперь работает. Мне пришлось внести следующие изменения в свой код:

Вместо:

 Do Until .EOF
  

Мне нужно:

 Do Until .EOF = True
  

Мне также нужно было добавить следующее сразу после объявления цикла For:

 .MoveFirst
  

Теперь мой код повторяется правильно.