2012-10-21 3 views
0

내 Access 데이터베이스의 데이터에 액세스하는 데 사용하는 내부 결합 문에 문제가 있습니다. 내가 기대하는 것은 각 제품에 대한 레코드 세트를 실행한다는 것입니다. 제품을 한 번 더 주문하면 Excel 시트에 제품을 추가하지 말고 주문 번호와 총 비용을 늘립니다.Excel VBA - 내부 조인 문제

내가 겪고있는 문제는 위에서 설명한대로 작동하는 대신 주문할 때마다 Excel 시트에 제품을 추가하는 것입니다. 나는 그들이 주문한 순서대로 (OrderID로) 내 코드에 포함되어 있지 않은 제품을 인쇄하고 있다는 것을 발견했다.

어떤 도움이 필요합니까?

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 ...'더하기 기호는 널 (null)에 문제를 일으킬 수 있으므로 대개 특수한 경우에만 사용됩니다. – Fionnuala

답변

1

나는이 점을 놓치고 경우 잘 모르겠어요 : 여기

는 코드입니다. 하지만 최종 목표를 명확히 할 수 있습니까? Excel VBA를 통해 수행해야합니까?

달성하고자하는 작업은 각 공급 업체가 주문한 탭으로 제품 당 하나의 행과 해당 제품에 대한 총체적 상태가있는 경우 데이터베이스 자체에 쿼리를 만들고 공급자 ID 매개 변수를 전달하는 것이 좋습니다 및 기타 매개 변수를 쿼리에 추가합니다. 그런 다음 쿼리는 집계 쿼리이므로 제품 및 quatity의 그룹화 및 계산을 처리 할 수 ​​있습니다.

이렇게하면 각 탭과 wrtie VBA에서 새로 고침 할 수있는 쿼리를 사용하여 필요에 따라 개별적으로 또는 모두 함께 새로 고칠 수 있습니다.

저는 항상 복잡한 VBA 코딩을 피하려고 애 쓰고 있습니다. 시간이 많이 걸렸을 때 버그가 있고 배포가 어려울수록 유지 보수가 어려워집니다.

또 다른 옵션은 모든 제품 데이터를 VBA를 통해 숨기고 SUMPRODUCT와 같은 수식을 사용하여 다양한 탭에 정보를 표시 할 수있는 다른 탭으로 가져 오는 것입니다. 또는 콤보 스타일 상자를 사용하여 공급자를 선택하고 결과 집합을 동적으로 변경할 수 있습니다.

내가 처음에 말했듯이 나는 그 요점을 놓칠 수도 있지만, 그렇지 않다면 내 선택 사항에 대한 도움을 원할 것입니다. 그리고 제가 당신의 질문을 명확히 해주십시오.

INNER JOIN 문제인 경우 stright forward select가 아닌 agregate 쿼리를 사용해야합니다. 이것은 데이터베이스 (가정)가 동일한 제품을 두 번 이상 주문할 수있는 하나의 공급자 (일대 다 관계), 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 

하지만 데이터는 다음과 같이 반환 된 경우 확인되지 않을 것 :

ProductName, Quantity 

foo, 7 
bar, 3 
foo, 4 

당신은 ORDER BY 절을 사용할 수 있습니다 현재 매크로로 작업하지만 다른 사람들이 지적했듯이 SQL을 사용하여 데이터를 결합하면 더 간단한 솔루션이됩니다.