我正在try 用VB.NET在Dapper中的MS Access数据库中执行顺序数据透视

我有下面的代码,但这仍然是错误的.

还有没有别的办法,请给我带路

谢谢

Public Class Form2
    Dim tps As New Tableproductservice()

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DataSource = tps.Loaddata("A")
    End Sub
End Class

Public Class Tableproductservice
    Private connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\transposerowtocolumnsqlmsaccessvbnet.accdb;Persist Security Info=False"

    Public Function Loaddata(CodeProduct As String) As IEnumerable(Of Tableproduct)
        Dim sql = <sql>
                              TRANSFORM Sum(Tableproduct.[Qty]) AS SumOfQty
        SELECT Tableproduct.Codeproduct AS [CodeProduct], Tableproduct.Colour AS [Colour], Sum(Tableproduct.Qty) AS [Total]
        FROM Tableproduct INNER JOIN SizeProduct ON Tableproduct.Size = SizeProduct.Size
        WHERE Tableproduct.Codeproduct = 'A'
        GROUP BY Tableproduct.Codeproduct, Tableproduct.Colour
        PIVOT SizeProduct.Size;
                          </sql>.Value
        Using _conn = New OleDbConnection(connectionString)
            Return _conn.Query(Of Tableproduct)(sql, New With {Key .CodeProduct = CodeProduct}).ToList()
        End Using
    End Function
End Class

Public Class Tableproduct
    Public Property CodeProduct() As String
    Public Property Colour() As String
    Public Property Size() As String
    Public Property Qty() As Integer
    Public Property Total() As Integer
End Class

Public Class SizeProduct
    Public Property Size() As String
    Public Property Sequence() As Integer
End Class

但是datagridview中的结果没有旋转,有什么不对劲的吗,请指导我 下面是数据网格视图中的结果屏幕截图

Screenshot_datagridviewQueryCodeProductA

但在vb.net中使用相同的SQL,MS Access数据库中的结果已被透视,但尚未按顺序排列. 以下是MS-Access数据库中的结果屏幕截图

Screenshot_QueryCodeProductA

Screenshot_QueryCodeProductB

样本数据:

TableProduct

CodeProduct colored颜色 大小 数量
A 白色 S 15
A 黑色 M 20
A 白色 L 10
B 蓝色 S 20
B 白色 XL 15

Sizeproduct

尺寸产品 序号
S 1
M 2
L 3
XL 4

预期结果:

Codeproduct的位置:A

CodeProduct colored颜色 S M L 合计
A 黑色 20 20
A 白色 15 10 25

Codeproduct的位置:B

产品代码 colored颜色 S XL
B 蓝色 20 20
B 白色 15 15

结果来自@OlivierJacot-Descomes的datagridview回答

answerdatagridviewQueryCodeProductA

answerdatagridviewQueryCodeProductB

推荐答案

你的Loaddata方法总是返回Tableproduct个对象,这是你的DataGridView唯一能看到的东西.您必须创建一个表示透视结果的类,并从Loaddata方法返回它.

Public Class PivotedProduct
    Public Property CodeProduct() As String
    Public Property Colour() As String

    Public Property S() As Integer
    Public Property M() As Integer
    Public Property L() As Integer
    Public Property XL() As Integer

    Public Property Total() As Integer
End Class

当然,这将始终显示网格中的所有大小列.我不确定你所说的"顺序"是什么意思.如果你的意思是按产品分组,那么DataGridView就无法实现这一点.但也有一些支持分组的第三方网格.

如果您希望只显示每个分组产品的相关大小列,那么使用网格控件将很难或不可能做到这一点.但通过一个报告工具和一些逻辑来解决这个问题是可能的.

下面是一个在网格中加载数据并隐藏空列的示例(但一次只针对一个产品).我创建了一个服务,加载一些用于测试的假测试数据:

Public Class PivotedProductService
    Public Function LoadData(CodeProduct As String) As IEnumerable(Of PivotedProduct)
        Return New List(Of PivotedProduct) From {
            New PivotedProduct With {.CodeProduct = "B", .Colour = "Blue", .S = 20, .Total = 20},
            New PivotedProduct With {.CodeProduct = "B", .Colour = "White", .XL = 15, .Total = 15}
        }
    End Function
End Class

我的表单代码如下所示:

Public Class Form1
    Dim pps As New PivotedProductService

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DataSource = pps.LoadData("B")
        HideEmptySizeColumns()
    End Sub

    Private Sub HideEmptySizeColumns()
        For i As Integer = 2 To 5
            Dim allZeros = True
            For Each row As DataGridViewRow In DataGridView1.Rows
                If row.Cells(i).Value <> 0 Then
                    allZeros = False
                    Exit For
                End If
            Next
            If allZeros Then
                DataGridView1.Columns(i).Visible = False
            End If
        Next
    End Sub
End Class

结果看起来是这样的:

enter image description here


使用LINQ可以简化隐藏列的代码,如下所示

Private Sub HideEmptySizeColumns()
    For i As Integer = 2 To 5
        Dim allZeros = Not (From row In DataGridView1.Rows
                            Where row.Cells(i).Value <> 0).Any()
        If allZeros Then
            DataGridView1.Columns(i).Visible = False
        End If
    Next
End Sub

Sql相关问答推荐

如何从上一个值减go 值

SQL Oracle条件分组依据

仅在特定字符串之后提取两个圆括号之间的计量单位文本

Ffltter&;Dart SQL Lite包:是否可以在一个查询中执行多条更新语句(每次执行不同的WHERE参数)

如何在PostgreSQL中的一列中添加两个文本?

获得第三名或最老的记录

使用多个嵌套数组查询JSON数据

如何使用SQL Server中的Nodes()方法执行与OPENXML相同的操作

根据时间值提取记录

我需要在 ASP.NET C# 中获取 2 个 SQL 查询结果的平均值

具有多个表 JOINS 的 STRING_AGG 的替代方法 (SQL Server 2016)

在SQL中实现表格数据透视类型报表

如何创建一个递归计数器来查找一个元素有多少父级和子级?

在 SQL 查询中创建滚动日期

为数组中的每个元素从表中收集最大整数

SQL - 使用子查询返回多行的 LIKE 命令

使用 JSON_BUILD_OBJ 从 Postgres 返回 JSON

snowflake插入覆盖行为

从多个连接返回 1 行到同一个表 - SQL Server

如何在 Trino/Presto 中过滤掉 map 中的某些键?