2012-10-21 69 views
0

我遇到了用於從Access數據庫訪問數據的Inner Join語句的問題。我期望發生的事情是我通過每個產品的記錄集。當產品多次訂購時,我不會將其添加到Excel表格,而是增加訂購的數量和總成本。Excel VBA - INNER JOIN問題

我遇到的問題是,它不是按照上面描述的方式工作,而是每次訂購時都向Excel表添加產品。我發現它是按照他們訂購的順序(通過他們的訂單ID)打印產品,而這些未包含在我的代碼中。

任何幫助?

下面是代碼:

Public Sub WorksheetLoop() 


Dim cn As New ADODB.Connection 
Dim rs As New ADODB.Recordset 
Dim stDB As String, stSQL As String, stSQLTwo As String, stProvider As String 
Dim sheetName As String, stProdName As String 
Dim suppNum As Integer, prodNum As Integer 
Dim WS_Count As Integer 
Dim I As Integer 

suppNum = 1 
prodNum = 1 

stDB = "Data Source= " & ThisWorkbook.Path & "\obsDatabase.accdb" 
stProvider = "Microsoft.ACE.OLEDB.12.0" 

'Opening connection to database 
With cn 

    .ConnectionString = stDB 
    .Provider = stProvider 
    .Open 

End With 


' Set WS_Count equal to the number of worksheets in the active 
' workbook. 
WS_Count = ActiveWorkbook.Worksheets.Count 

' Begin the loop. 
For I = 2 To WS_Count 

    ActiveWorkbook.Worksheets(I).Range("A1") = "Company Name - " + ActiveWorkbook.Worksheets(I).Name + "" 
    ActiveWorkbook.Worksheets(I).Range("A2") = "Item Number" 
    ActiveWorkbook.Worksheets(I).Range("B2") = "Description" 
    ActiveWorkbook.Worksheets(I).Range("C2") = "Unit" 
    ActiveWorkbook.Worksheets(I).Range("D2") = "Cost Per Unit" 
    ActiveWorkbook.Worksheets(I).Range("E2") = "Quantity" 
    ActiveWorkbook.Worksheets(I).Range("F2") = "Total Cost" 
    ActiveWorkbook.Worksheets(I).Range("G2") = "Amount Remaining" 

    'Function to retrieve info! 

    stSQL = "SELECT Products.ProductID, Products.ProductName, Products.ProductDescription, Products.ProductUnit, LineItems.UnitPrice, LineItems.Quantity, LineItems.TotalPrice " & _ 
    "FROM Products INNER JOIN LineItems ON LineItems.ProductID = Products.ProductID WHERE Products.SupplierID = " & suppNum & " " 
    rs.Open stSQL, cn 

    With rs 

     Do Until .EOF 


      If ActiveWorkbook.Worksheets(I).Range("A65536").End(xlUp) = rs.Fields("ProductName") Then 

       If ActiveWorkbook.Worksheets(I).Range("D65536").End(xlUp) = rs.Fields("UnitPrice") Then 

        ActiveWorkbook.Worksheets(I).Range("E65536").End(xlUp) = ActiveWorkbook.Worksheets(I).Range("E65536").End(xlUp) + rs.Fields("Quantity") 
        ActiveWorkbook.Worksheets(I).Range("F65536").End(xlUp) = ActiveWorkbook.Worksheets(I).Range("F65536").End(xlUp) + rs.Fields("TotalPrice") 

       End If 

      Else 

       ActiveWorkbook.Worksheets(I).Range("A65536").End(xlUp).Offset(1, 0) = rs.Fields("ProductName") 
       ActiveWorkbook.Worksheets(I).Range("B65536").End(xlUp).Offset(1, 0) = rs.Fields("ProductDescription") 
       ActiveWorkbook.Worksheets(I).Range("C65536").End(xlUp).Offset(1, 0) = rs.Fields("ProductUnit") 
       ActiveWorkbook.Worksheets(I).Range("D65536").End(xlUp).Offset(1, 0) = rs.Fields("UnitPrice") 
       ActiveWorkbook.Worksheets(I).Range("E65536").End(xlUp).Offset(1, 0) = rs.Fields("Quantity") 
       ActiveWorkbook.Worksheets(I).Range("F65536").End(xlUp).Offset(1, 0) = rs.Fields("TotalPrice") 

      End If 
      rs.MoveNext 

     Loop 

    End With 


    rs.Close 
    suppNum = suppNum + 1 

    ActiveWorkbook.Worksheets(I).Columns("A:A").EntireColumn.AutoFit 
    ActiveWorkbook.Worksheets(I).Columns("B:B").EntireColumn.AutoFit 
    ActiveWorkbook.Worksheets(I).Columns("C:C").EntireColumn.AutoFit 
    ActiveWorkbook.Worksheets(I).Columns("D:D").EntireColumn.AutoFit 
    ActiveWorkbook.Worksheets(I).Columns("E:E").EntireColumn.AutoFit 
    ActiveWorkbook.Worksheets(I).Columns("F:F").EntireColumn.AutoFit 
    ActiveWorkbook.Worksheets(I).Columns("G:G").EntireColumn.AutoFit 

Next I 

cn.Close 


End Sub 
+2

工作表是否已包含數據?如果沒有,爲什麼你不使用TransferSpreadsheet和分組查詢?您可以遍歷供應商列表(+1不是一個好主意),並將查詢的sql更改爲每個供應商的expoer。 VBA中的連接符是&,不是+,所以''公司名稱 - 「&Activ ...'加號可能導致空值問題,所以它通常只用於特殊情況。 – Fionnuala

回答

1

我不知道如果我錯過了點。但是,你能澄清你的最終目標嗎?它是否必須通過Excel VBA完成?

如果您試圖實現的是每個供應商訂單上的一個選項卡,每個產品一行,並且該產品的總數量,那麼我會考慮在數據庫本身中創建一個查詢並傳遞供應商ID參數和查詢的任何其他參數。然後查詢可以處理產品和數量的分組和計數,因爲這將是聚合查詢。

通過這種方式,您可以在每個選項卡上添加一個可刷新的查詢,並使用VBA單獨或全部刷新它們,以滿足您的需求。

我總是試圖避免複雜的VBA編碼,因爲它在最好的時候是越野車,一旦分佈就變得難以維護。

另一種選擇是將所有產品數據拖入另一個標籤,您可以通過VBA隱藏並使用像SUMPRODUCT這樣的公式在各個標籤上顯示信息。或者使用組合樣式框來選擇您的供應商並動態更改結果集。

正如我在開始時說的,我可能會忽略這一點,但如果不是這樣,並且您希望幫助我的選項,請告訴我,如果我請澄清您的問題。

對於您的INNER JOIN問題,您需要使用agregate查詢而不是stright forward select。這是因爲您的數據庫(我假設)可以有一個供應商可以多次訂購同一產品(一對多關係),從您提供的產品中您在LineItems表中有一個數量列,因此我假設重複產品ID來自同一供應商的兩份或更多單獨訂單。這裏是查詢的一個例子,也考慮別名表的名稱,它使得代碼更容易。

SELECT 
p.ProductID 
,p.ProductName 
,p.ProductDescription 
,p.ProductUnit 
,SUM(l.UnitPrice) 
,SUM(l.Quantity) 
,SUM(l.TotalPrice) 
FROM Products p 
INNER JOIN LineItems l 
ON l.ProductID = p.ProductID 
WHERE p.SupplierID = 1 
GROUP BY 
p.ProductID 
,p.ProductName 
,p.ProductDescription 
,p.ProductUnit 

問候 凱文

0

你當前的產品名稱永遠只能比較最後一行添加到工作表,但沒有在您的SQL查詢強制任何排序的結果。

如果數據返回這樣這將是確定:

ProductName, Quantity 

foo, 7 
foo, 4 
bar, 3 

但如果數據返回喜歡這不會是OK:

ProductName, Quantity 

foo, 7 
bar, 3 
foo, 4 

你可以使用一個ORDER BY子句並與您當前的宏一起工作,但正如其他人指出的那樣,您可以使用SQL來組合數據,這應該是一個更簡單的解決方案