0

アクセスデータベースのデータにアクセスするために使用している内部結合ステートメントに問題があります。私が期待していることは、各製品のレコードセットを実行することです。製品が2回以上注文された場合、Excelシートに追加せず、代わりに注文数と合計コストを増やします。

私が抱えている問題は、上記のように機能するのではなく、注文するたびに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
4

2 に答える 2

1

ポイントを逃しているかどうかはわかりません。しかし、最終目標を明確にしていただけますか? Excel VBAで行う必要がありますか?

あなたが達成しようとしているのが、各サプライヤーが注文したタブで、製品ごとに1行とその製品の合計数量がある場合、データベース自体にクエリを作成し、サプライヤーIDパラメーターとその他のパラメーターを渡すことを検討しますクエリに。これは集計クエリになるため、クエリは製品と数量のグループ化とカウントを処理できます。

このようにして、各タブで更新可能なクエリを作成し、VBA を書き込み、それらを個別に更新するか、必要に応じてまとめて更新することができます。

私は常に複雑な VBA コーディングを避けるようにしています。

別のオプションは、すべての製品データを別のタブにプルして、VBA で非表示にし、SUMPRODUCT などの式を使用してさまざまなタブに情報を表示することです。または、コンボ スタイル ボックスを使用してサプライヤを選択し、結果セットを動的に変更します。

最初に言ったように、私は要点を見落としているかもしれませんが、もしそうでなく、私のオプションについて助けが必要な場合は、私に知らせてください。

INNER JOIN の問題については、単純な前方選択ではなく、集計クエリを使用する必要があります。これは、データベース (私が想定) に、同じ製品を複数回注文できる (1 対多の関係) 1 つのサプライヤーを含めることができるためです。 ID は、同じサプライヤーからの 2 つ以上の別々の注文からのものです。これはクエリの例です。テーブル名にエイリアスを付けることも検討してください。これにより、コードを簡単にたどることができます。

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

よろしくケビン

于 2012-10-22T00:10:53.267 に答える
0

現在の製品名をワークシートに追加された最後の行と比較するだけですが、SQL クエリには結果の順序を強制するものはありません。

データが次のように返された場合、これは問題ありません。

ProductName, Quantity

foo, 7
foo, 4
bar, 3

ただし、データが次のように返された場合は問題ありません。

ProductName, Quantity

foo, 7
bar, 3
foo, 4

ORDER BY 句を使用して現在のマクロを操作することもできますが、他の人が指摘したように、SQL を使用してデータを組み合わせることができ、これはより簡単な解決策になるはずです。

于 2012-10-28T02:59:16.800 に答える