2016-06-08 4 views
1

Я делаю работу с базой данных с excel как для базы данных, так и для драйвера базы данных с помощью макросов с vba. Я создал функцию, которая должна анализировать список записей базы данных с полями testID. Я хотел отображать каждый тест только один раз на основе его testID, но способ настройки базы данных означает, что мне нужно устранить дубликаты testID. Я делаю это путем итерации через набор записей и проверки текущего теста по сравнению с предыдущим, прежде чем показывать в списке. Проблема, с которой я сталкиваюсь, заключается в том, что функция мучительно медленная. Всего 12 тестов в базе данных занимает около 3 секунд, чтобы отобразить их в электронной таблице. Мне бы хотелось услышать некоторые идеи о том, как оптимизировать время выполнения. Вот функция:Нужна помощь в оптимизации функции отображения vba

Public Function showAllTests() 
Dim conn As ADODB.Connection 
Dim rs As ADODB.Recordset 
Dim cstring, sql As String 
Dim r, c As Integer 
Dim testsAr As Variant 
Dim inAr As Boolean 

cstring = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source=I:\DBtrials.xlsx; Extended Properties=""Excel 12.0 Xml; HDR=YES;ReadOnly=False"";" 

sql = "SELECT [TestID], [Status], [PFIBox], [WireType], [StartingDia], [Customer], [numSamples], [Assigned] FROM [Tests$]" 

Set conn = New ADODB.Connection 
Set rs = New ADODB.Recordset 

Call conn.Open(cstring) 
Set rs = conn.Execute(sql) 

If rs.EOF Then 
    Range("C6:J1000").ClearContents 
End If 

r = 6 
count = 0 
'Iterates through the recordset, eliminating duplicates and populating cells in the tests sheet 
While Not rs.BOF And Not rs.EOF 
     Dim prevID, currID As String 
     Dim currCell As Range 

     inAr = False 

     If Not count = 0 Then 
      prevID = ActiveWorkbook.Sheets("Tests").Cells(r - 1, 3).Value 
      currID = CStr(rs(0)) 
      If prevID = currID Then 
       inAr = True 
      End If 
     End If 

     For c = 3 To (rs.Fields.count + 2) 

      Set currCell = ActiveWorkbook.Sheets("Tests").Cells(r, c) 

      If Not IsNull(rs(c - 3).Value) And inAr = False Then 
       currCell.Value = CStr(rs(c - 3)) 
       ElseIf IsNull(rs(c - 3).Value) Then currCell.Value = "" 
        Else: 
         Exit For 
      End If 
     Next c 

     If inAr = False Then 
      r = r + 1 
     End If 
     rs.MoveNext 

     count = count + 1 
Wend 



conn.Close 
Set conn = Nothing 

End Function

ответ

1

Использование GROUP BY

SQL = «SELECT [TestID], [Статус], [PFIBox], [WireType], [StartingDia], [Заказчик ], [numSamples], [Assigned] FROM [Tests $] GROUP BY [TestID] "

Также некоторые из этих драйверов - Microsoft.ACE.OLEDB.12.0 и т. д. имеют ужасную производительность в VBA. иногда я получаю лучшее перфорансирование от OBDC 6.2, чем ADO

Смежные вопросы