使用Excel ADODB.Connection来访问数据库性能改进

时间:2013-02-14 16:49:34

标签: performance excel ms-access adodb recordset

我们已经创建了一个访问数据库,并且一个开发人员已经在excel中创建了一个函数来访问该数据库中的数据。 连接通过ADDB.Connection完成。 该公式返回1个数字,它是考虑到某些参数的Access数据库中的卷总和。 当我们在一个单元格中运行公式时,它可以完美地工作,但是因为我们的报告包含多个具有此公式的单元格(大约160个单元格)。报告的运行速度很慢。

我们的Access专家检查数据库,他没有看到任何错误。

有人会知道如何对此进行排序吗? 我们应该在Excel中打勾以使其正常工作? 我们今天在MS Excel& amp; Access 2003(我知道我们已经超龄)但我有机会升级到Excel&访问2007(什么是进步;-)),它会有帮助吗?

这是我们在Excel中的vba代码的详细信息

'The function is called GetMarketData
Function GetMarketData(Optional ProductLine As String, Optional country As String, Optional CountryGroup As String, Optional Market As String, Optional startMonth As Long, Optional endMonth As Long, Optional Brand As String, Optional Model As String, Optional Segment As String, Optional EngineSegment As String)

'This is the declaration of variables
Dim con As ADODB.Connection
Dim rsQuery As ADODB.Recordset
Dim i As Integer
Dim iCount As Integer
Dim resVar As Integer
Dim query1 As String, query2 As String, query3 As String, query4 As String
Dim parametres As String, param1 As String, param2 As String, param3 As String, param4     As String, param5 As String, param6 As String, param7 As String, param8 As String, param9 As String, param10 As String


' Query cut in 3 parts (will be regrouped later on)
query1 = "SELECT Sum(T_MARKET.Volume) "
query2 = "FROM T_COUNTRY_GROUP INNER JOIN (T_TIME_PERIOD INNER JOIN (T_SELECTED_MARKET INNER JOIN (T_SEGMENT INNER JOIN (T_PRODUCT_LINE INNER JOIN ((T_BRAND INNER JOIN T_MODEL ON T_BRAND.ID_Brand = T_MODEL.FK_Brand) INNER JOIN ((T_COUNTRY INNER JOIN T_MARKET ON T_COUNTRY.ID_Country = T_MARKET.FK_Country) INNER JOIN ((T_ENGINE_SEGMENT INNER JOIN T_PRODUCT ON T_ENGINE_SEGMENT.ID_Engine_Segment = T_PRODUCT.FK_Engine_Segment) " _
         & "INNER JOIN T_SEGMENT_FINAL ON T_ENGINE_SEGMENT.ID_Engine_Segment = T_SEGMENT_FINAL.FK_Engine_Segment) ON (T_PRODUCT.ID_Product = T_MARKET.FK_Product) AND (T_COUNTRY.ID_Country = T_SEGMENT_FINAL.FK_Country)) ON T_MODEL.ID_Model = T_PRODUCT.FK_Model) ON T_PRODUCT_LINE.ID_Product_Line = T_SEGMENT_FINAL.FK_Product_Line) ON (T_SEGMENT.ID_Segment = T_SEGMENT_FINAL.FK_Segment) AND (T_SEGMENT.ID_Segment = T_PRODUCT.FK_Segment)) ON T_SELECTED_MARKET.ID_Selected_Market = T_SEGMENT_FINAL.FK_Selected_Market) ON T_TIME_PERIOD.ID_Period = T_MARKET.FK_Time_period) ON T_COUNTRY_GROUP.ID_Country_Groupe = T_COUNTRY.FK_Country_Group "
query3 = "WHERE ("

    param1 = "((T_PRODUCT_LINE.Product_Line)='" & ProductLine & "')"
    param2 = " AND ((T_COUNTRY.Country)='" & country & "')"
    param3 = " AND ((T_COUNTRY_GROUP.Country_Group)='" & CountryGroup & "')"
    param4 = " AND ((T_SELECTED_MARKET.Selected_Market)='" & Market & "')"
    param5 = " AND ((T_TIME_PERIOD.Cal_FullDate)>=" & startMonth & ")"
    param6 = " AND ((T_TIME_PERIOD.Cal_FullDate)<=" & endMonth & ")"
    param7 = " AND ((T_BRAND.Brand)='" & Brand & "')"
    param8 = " AND ((T_MODEL.Model)='" & Model & "')"
    param9 = " AND ((T_SEGMENT.Segment)='" & Segment & "')"
    param10 = " AND ((T_ENGINE_SEGMENT.Engine_Segment)='" & EngineSegment & "')"

    parametres = param1

    If country <> "" Then
        parametres = parametres & param2
    End If
    If CountryGroup <> "" Then
        parametres = parametres & param3
    End If
    If Market <> "" Then
        parametres = parametres & param4
    End If
    If startMonth <> 0 Then
        parametres = parametres & param5
    End If
    If endMonth <> 0 Then
        parametres = parametres & param6
    End If
    If Brand <> "" Then
        parametres = parametres & param7
    End If
    If Model <> "" Then
        parametres = parametres & param8
    End If
    If Segment <> "" Then
        parametres = parametres & param9
    End If
    If EngineSegment <> "" Then
        parametres = parametres & param10
    End If


query4 = ");"

'Connexion with the Access database
Set con = New ADODB.Connection
con.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & URL_Base & ";"

'Open a recordset based on the query
Set rsQuery = New ADODB.Recordset
Set rsQuery.ActiveConnection = con
rsQuery.Open query1 & query2 & query3 & parametres & query4

' Give back the value from the query
GetMarketData = rsQuery.Fields(0).Value

'Clear variables
rsQuery.Close
Set rsQuery = Nothing
con.Close
Set con = Nothing

结束功能

1 个答案:

答案 0 :(得分:1)

在大多数情况下,DAO比用于MS Access的ADODB快得多。这是在Excel中测试的。请注意Like *不包含Null,因此这只是一个示例。您还可以在VBA中构建临时查询并为其分配参数,但它们可能比存储的查询慢。

Function DAOMarket(Optional ProductLine As String, Optional country As String, _
Optional CountryGroup As String, Optional Market As String, Optional startMonth As Long, _
Optional endMonth As Long, Optional Brand As String, _
Optional Model As String, Optional Segment As String, Optional EngineSegment As String)

'Reference: Microsoft Office x.x Access Database Engine Object Library
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim sDb As String
Dim sSQL As String
Dim qdf As QueryDef
Dim rs As DAO.Recordset

sDb = "Z:\Docs\Test.accdb"

Set ws = DBEngine.Workspaces(0)
Set db = ws.OpenDatabase(sDb)

''A stored query, see below
Set qdf = db.QueryDefs("GetMarket")

qdf.Parameters![@ProductLine] = IIf(ProductLine & "" = "", "*", ProductLine)
qdf.Parameters![@Country] = IIf(country & "" = "", "*", country)
qdf.Parameters![@Country_Group] = IIf(CountryGroup & "" = "", "*", CountryGroup)
qdf.Parameters![@Selected_market] = IIf(Market & "" = "", "*", Market)
qdf.Parameters![@CalStart] = IIf(startMonth & "" = "", 1, startMonth)
qdf.Parameters![@CalEnd] = IIf(endMonth & "" = "", 12, endMonth)
qdf.Parameters![@Brand] = IIf(Brand & "" = "", "*", Brand)
qdf.Parameters![@Model] = IIf(Model & "" = "", "*", Model)
qdf.Parameters![@Segment] = IIf(Segment & "" = "", "*", Segment)
qdf.Parameters![@Engine_Segment] = IIf(EngineSegment & "" = "", "*", EngineSegment)
Set rs = qdf.OpenRecordset(dbOpenSnapshot)
DAOMarket = rs.Fields(0)
End Function

SQL

SELECT SUM([t_market].[volume]) AS MarketVolume
FROM   ((t_selected_market
         INNER JOIN (t_product_line
                     INNER JOIN ((t_brand
                                  INNER JOIN t_model
                                          ON t_brand.id_brand =
                                 t_model.fk_brand)
                                 INNER JOIN ((t_engine_segment
                                              INNER JOIN t_product
                                                      ON
                                              t_engine_segment.id_engine_segment
                                              =
                                              t_product.fk_engine_segment)
                                             INNER JOIN t_segment_final
                                                     ON
                                             t_engine_segment.id_engine_segment
                                             =
                                             t_segment_final.fk_engine_segment)
                                         ON t_model.id_model =
                                            t_product.fk_model)
                             ON t_product_line.id_product_line =
                                t_segment_final.fk_product_line)
                 ON t_selected_market.id_selected_market =
                    t_segment_final.fk_selected_market)
        INNER JOIN t_segment
                ON t_segment_final.fk_segment = t_segment.id_segment)
       INNER JOIN (t_country_group
                   INNER JOIN (t_time_period
                               INNER JOIN (t_country
                                           INNER JOIN t_market
                                                   ON t_country.id_country =
                                                      t_market.fk_country)
                                       ON t_time_period.id_period =
                                          t_market.fk_time_period)
                           ON t_country_group.id_country_groupe =
                              t_country.fk_country_group)
               ON t_product.id_product = t_market.fk_product
WHERE  ( ( ( t_product_line.product_line ) LIKE [@productline] )
         AND ( ( t_country.country ) LIKE [@country] )
         AND ( ( t_country_group.country_group ) LIKE [@country_group] )
         AND ( ( t_selected_market.selected_market ) LIKE [@selected_market] )
         AND ( ( t_time_period.cal_fulldate ) BETWEEN [@calstart] AND [@calend]
             )
         AND ( ( t_brand.brand ) LIKE [@brand] )
         AND ( ( t_model.model ) LIKE [@model] )
         AND ( ( t_segment.segment ) LIKE [@segment] )
         AND ( ( t_engine_segment.engine_segment ) LIKE [@engine_segment] ) );