访问2013多列到行

时间:2015-06-09 12:05:10

标签: sql vba ms-access

好的我正在使用Access 2013并使用包含以下字段的平面表连续表单:

OrderDate \ Ref \ ItemSize1 \ ItemSize 2 \ ItemSize 3 \ Qty 1 \ Qty 2 \ Qty 3

因此,例如数据看起来像这样:

09/06/15  \ PO123 \ ABC_S   \     ABC_M   \    ABC_L   \  2    \ 6     \ 8
09/06/15 \ PO123 \ XYZ_8     \   XYZ_10   \    XYZ_12  \ 3     \ 2     \  7

但是,我正在构建一个以此格式需要的导出文件;

OrderDate \ Ref \ Item \ Qty

因此结果数据如下所示:

09/06/15 \ PO123 \ ABC_S \ 2
09/06/15 \ PO123 \ ABC_M \ 6
09/06/12 \ PO123 \ ABC_L \ 8

等...... 注意事项:

  • 项目大小1使用数量1的数量,项目大小2使用数量等

  • 我只对项目大小有数量感兴趣。因此,如果ItemSize 2在数量2中没有数量,我需要错过它

我尝试了一个Union查询但由于某种原因它没有对大小进行排序。结果文件需要按大小顺序排列项目(ItemSize1,ItemSize2等)

Access中还有哪些方法可以实现这一目标?

感谢您的帮助。

迈克尔

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作:

SELECT UnionQueries.val FROM (
  SELECT tmpTEST.Ref as ref, tmpTEST.S1 as val, 1 as col FROM tmpTEST UNION 
  SELECT tmpTEST.Ref as ref, tmpTEST.S2 as val, 2 as col FROM tmpTEST UNION 
  SELECT tmpTEST.Ref as ref, tmpTEST.S3 as val, 3 as col FROM tmpTEST UNION 
  SELECT tmpTEST.Ref as ref, tmpTEST.S4 as val, 4 as col FROM tmpTEST) AS UnionQueries 
ORDER BY UnionQueries.ref, UnionQueries.col ASC

答案 1 :(得分:0)

我完全同意krish,您的解决方案是使数据结构更具弹性。

真正的解决方案 :(可以改进很多)

首先创建两个表ProductsInvoice

Products
````````
productID - AutoNumber (PK)
productCategory - Text
productSize - Text

Invoice
```````
invoiceID - AutoNumber (PK)
invoiceDate - DateT/Time
productID - Number (FK)
invoiceQuantity - Number

现在ProductsInvoice之间的关系是一对多,其中一个产品可以有多个发票。例如,一种尺寸/颜色的T恤可以有很多订单。

现在,Products表将包含您在数据库中可用的产品的信息。一些样本将是。

productID   |   productCategory |   productSize
------------+-------------------+---------------
1           |   Tee Shirt       |   S
2           |   Tee Shirt       |   M
3           |   Polo            |   L
4           |   Vest            |   S
5           |   Vest            |   M

现在,Invoice表应该具有特定尺寸的特定产品的订单。

invoiceID   |   invoiceDate |   productID   |   invoiceQuantity
------------+---------------+---------------+--------------------
1           |   09/06/2015  |   1           |   10
2           |   09/06/2015  |   2           |   5
3           |   09/06/2015  |   3           |   10
4           |   09/06/2015  |   5           |   3

现在,一旦数据转换为正确的结构,您的查询就会是。

SELECT
    productCategory,
    productSize,
    invoiceDate,
    invoiceQuantity
FROM
    Products 
    INNER JOIN
    Invoice
    ON 
    Products.productID = Invoice.productID

您的结果集将是,

productCategory |   productSize |   invoiceDate |   invoiceQuantity
----------------+---------------+---------------+--------------------
Tee Shirt       |   S           |   09/06/2015  |   10
Tee Shirt       |   M           |   09/06/2015  |   5
Polo            |   L           |   09/06/2015  |   10
Vest            |   M           |   09/06/2015  |   3

现在,您应该能够理解,简单的数据重组可以使您的查询变得如此简单和易于实现。

临时修复

虽然我很难告诉你应该重组你的桌子,但这并不意味着你无法实现你想要的。虽然解决方案可行,但甚至可能看起来不错。实际上并非如此。涉及的内存太多,效率很差。您可以创建和删除记录,不断升级数据库。如此多的缺点,但要把事情放在一起。

Public Sub createTempForm()
    Dim sqlStr As String
    Dim tmpRS As DAO.Recordset, tmpRS2 As DAO.Recordset, tmpDB As DAO.Database

    Set tmpDB = CurrentDB()
    sqlStr = "SELECT OrderDate, Ref, ItemSize1, ItemSize2, ItemSize3, Qty1, Qty2, Qty3 " & _
             "FROM yourTableName"

    Set tmpRS = tmpDB.OpenRecordset(sqlStr)

    tmpDB.Execute "DELETE * FROM tmpTbl"

    'Make sure this table - tmpTbl, is created (just the skeleton, data will be added every time you run this query.)
    Set tmpRS2 = tmpDB.OpenRecordset("tmpTbl")

    Do While Not tmpRS.EOF
        'Go through all records to create the data you wish to see. 
        With tmpRS2
            'This will add as many records to the tmpTbl
            For iCtr = 1 to 3
                If Len(tmpRS.Fields("ItemSize" & iCtr) & vbNullString) > 0 Then
                    'Create a record only if the fields are not null.
                    .AddNew
                    .Fields("OrderDate") = tmpRS.Fields("OrderDate")
                    .Fields("Ref") = tmpRS.Fields("Ref")
                    .Fields("Item") = .Fields("ItemSize" & iCtr)
                    .Fields("Qty") = .Fields("Qty" & iCtr)
                    .Update
                End If
            Next
            tmpRS.MoveNext
        End With
    Loop

    Set tmpRS = Nothing
    Set tmpDB = Nothing

    'This report should be based on the tmpTbl. 
    DoCmd.OpenReport "yourReportName"

    'If you prefer to Export the table as Excel file, you are welcome to do so. Saves designing report. 
    'DoCmd.Outputto acOutputTable, "tmpTbl", acFormatXLS, "C:\testData.xls"
End Sub

现在我使用VBA而不是luk2302的UNION查询的原因是,通过一些修改,上面的查询实际上可以用来将您的平面表数据转换为您应该拥有的结构。

所以考虑一下,我相信你永远不会后悔。祝你好运!