简体   繁体   English

Excel VBA:如何根据数据库名称对行进行分组并根据特定的组名称添加值?

[英]Excel VBA: How to group rows based on database name and add value based on specific group name?

I have a database in the sheet called "Database" as below: Column A refers to the specific type of data and B refers to the group.我在表格中有一个名为“数据库”的数据库,如下所示:A 列指的是特定类型的数据,B 列指的是组。 For example, X-1 is part of X so it's grouped as X and so forth.例如,X-1 是 X 的一部分,因此它被分组为 X 等等。

Sheet "Database"工作表“数据库”

A一个 B
X-1 X-1 X X
X-2 X-2 X X
X-3 X-3 X X
X-4 X-4 X X
Y-1 Y-1 Y
Y-2 Y-2 Y
Y-3 Y-3 Y
Z-1 Z-1 Z Z
Z-2 Z-2 Z Z
Z-3 Z-3 Z Z

Next, I have another set of tables in the "Tables" sheet.接下来,我在“表格”表中有另一组表格。 So far, only columns A, B, and C exist, but I want to fill in the values in column D and E using the database dictionary above.到目前为止,只有 A、B 和 C 列存在,但我想使用上面的数据库字典填写 D 和 E 列中的值。 Column A is the type of data, B is the block number, and C is the value of A. D will be the group of column A and E will be the sum of all data in for each group within that block number. A 列是数据类型,B 是块号,C 是 A 的值。D 将是 A 列的组,E 将是该块号内每个组中所有数据的总和。

Sheet "Table"表“表”

| A | B | C |D|E
|:---- |:------:| -----:| -----:| -----:|
| X-1  |  Block 1    | 50 ||
| X-2  | Block 1    | 10 ||
| X-3  | Block 1    | 35 ||
| Y-1  | Block 1    | 45 ||
| Z-1  | Block 1    | 15 ||
| Y-2  | Block 1    | 5 ||
| X-4  | Block 1    | 50 ||
|  | Block 1 Total    | 210 |

I ultimately want to make my tables look like the below.我最终想让我的表格如下所示。 It's important that the group data in column D comes at the beginning.重要的是 D 列中的组数据位于开头。 Also, please note that sometimes the data in A are not in order.另外,请注意,有时 A 中的数据不是按顺序排列的。 For example, Y-2 comes after Z-1.例如,Y-2 在 Z-1 之后。

A一个 B C C D D E
X-1 X-1 Block 1区块 1 50 50 X X 145 145
X-2 X-2 Block 1区块 1 10 10
X-3 X-3 Block 1区块 1 35 35
Y-1 Y-1 Block 1区块 1 45 45 Y 50 50
Z-1 Z-1 Block 1区块 1 15 15 Z Z 15 15
Y-2 Y-2 Block 1区块 1 5 5
X-4 X-4 Block 1区块 1 50 50
Block 1 Total区块 1 总计 210 210
A一个 B C C D D E
X-1 X-1 Block 2第 2 座 10 10 X X 80 80
X-2 X-2 Block 2第 2 座 70 70
Y-1 Y-1 Block 2第 2 座 15 15 Y 20 20
Y-2 Y-2 Block 2第 2 座 5 5
Z-1 Z-1 Block 2第 2 座 100 100 Z Z 600 600
Z-2 Z-2 Block 2第 2 座 200 200
Z-3 Z-3 Block 2第 2 座 300 300
Block 2 Total区块 2 总计 700 700

So far my script looks like this:到目前为止,我的脚本如下所示:


    Dim lastrow As Integer
    Dim cell As Range
    Dim i, J, K As Integer
    Dim NumRows As Integer
    
    lastrow = Worksheets("Table").Range("A" & Rows.Count).End(xlUp).Row
    NumRows = Worksheets("Database").Range("A2").End(xlDown).Row
    
    For i = lastrow To 2 Step -1
    
            FundName_T = Worksheets("Table").Range("A" & i).Value
    
            For K = 2 To NumRows
                FundName_D = Worksheets("Database").Range("A" & K).Value
        
        If Cells(i, "A") <> "" And FundName_T = FundName_D Then
            GroupName = Worksheets("Database").Range("B" & K).Value
            Cells(i, "H") = GroupName
    
        End If
    
            Next K
    Next i

The above will make the table look like this:以上将使表格如下所示:

A一个 B C C D D E
X-1 X-1 Block 2第 2 座 10 10 X X
X-2 X-2 Block 2第 2 座 70 70 X X
Y-1 Y-1 Block 2第 2 座 15 15 Y
Y-2 Y-2 Block 2第 2 座 5 5 Y
Z-1 Z-1 Block 2第 2 座 100 100 Z Z
Z-2 Z-2 Block 2第 2 座 200 200 Z Z
Z-3 Z-3 Block 2第 2 座 300 300 Z Z
Block 2 Total区块 2 总计 700 700

Can someone please help?有人可以帮忙吗?

You can do this using Power Query , available in Windows Excel 2010+ and Office 365.您可以使用 Windows Excel 2010+ 和 Office 365 中的Power Query来执行此操作。

  • Ensure your data is in "Tables" and that you have the Names of those tables确保您的数据在“表格”中,并且您拥有这些表格的名称
    • I assumed, as you show, that your Table columns do not have headers.正如您所展示的,我假设您的 Table 列没有标题。
    • That being the case, the system will add headers with names like Column n在这种情况下,系统将添加名称为Column n的标题
  • Select some cell in one of the tables and Data => Get&Transform => from Table/Range Select 表格之一中的某个单元格和Data => Get&Transform => from Table/Range
  • When the PQ UI opens, navigate to Home => Advanced Editor and paste the M Code below into that window当 PQ UI 打开时,导航到Home => Advanced Editor并将下面的M 代码粘贴到 window
  • Replace the table names in Lines 2 and 3 of the code with the appropriate names for your tables on your Database and Table sheets ( and the order is important )将代码第 2 行和第 3 行中的表名替换为DatabaseTable工作表上表的适当名称(并且顺序很重要
  • Examine the Applied Steps window and the comments to understand the methodology.检查Applied Steps window 和注释以了解方法。

M Code M代码

let

//Change table names to your actual table names
    Source = Excel.CurrentWorkbook(){[Name="Database"]}[Content],
    Source2 = Excel.CurrentWorkbook(){[Name="Table"]}[Content],

//Remove Block Totals
//It will be easier to just calculate them later
    #"Filtered Rows" = Table.SelectRows(Source2, each ([Column1] <> null and [Column1] <> "")),

//Join with Group Column to match up with Column1
//then expand the nested join
    grpCol = Table.AddJoinColumn(#"Filtered Rows","Column1",Source,"Column1","with Group"),
    #"Expanded with Group" = Table.ExpandTableColumn(grpCol, "with Group", {"Column2"}, {"with Group.Column2"}),

//Rename columns for clarity
    #"Renamed Columns" = Table.RenameColumns(#"Expanded with Group",{
        {"Column1", "Part"}, 
        {"Column2", "Block"}, 
        {"Column3", "Units"}, 
        {"with Group.Column2", "Group"}
        }),

//Group by "Block" and "Group"
//Calculate Subtotal for each Group (within each Block)
//Add Index column to subTable -- to be used so Group Name and Total for group only appear on first line
    #"Grouped Rows" = Table.Group(#"Renamed Columns", {"Block", "Group"}, {
            {"Amt", each List.Sum([Units]), type number}, 
            {"All", each _, type table [Part=text, Block=text, Units=number, Group=text]},
            {"Idx", each Table.AddIndexColumn(_,"Index",0,1)}
            }),

//Remove unneeded column of tables and Expand the column of tables with Index column added
    #"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"All"}),
    #"Expanded Idx" = Table.ExpandTableColumn(#"Removed Columns1", "Idx", {"Part", "Units", "Index"}, {"Part", "Units", "Index"}),

//Add columns for Group and Group Total, showing only on the first entry of the Group Name
//then remove unneeded columns
    #"Added Custom1" = Table.AddColumn(#"Expanded Idx", "Group.1", each if [Index] = 0 then [Group] else null),
    #"Added Custom2" = Table.AddColumn(#"Added Custom1", "Group Total", each if [Index] = 0 then [Amt] else null),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Group", "Amt", "Index"}),

#"Renamed Columns1" = Table.RenameColumns(#"Removed Columns",{{"Group.1", "Group"}}),

//Group by Block
//Add Block subtotal row to each block group
    #"Grouped Rows1" = Table.Group(#"Renamed Columns1", {"Block"}, {
        {"blockGroup", each _, type table [Block=text, Part=text, Units=number, Group=nullable text, Group Total=nullable number]},
        {"Block Total", each Table.InsertRows(_, Table.RowCount(_),
            {[Block=null, Part=[Block]{0} & " Total", Units=List.Sum([Units]), Group=null,Group Total=null]})}       
        }),

//Remove unneeded column and expand the table
    #"Removed Columns3" = Table.RemoveColumns(#"Grouped Rows1",{"blockGroup", "Block"}),
    #"Expanded Block Total" = Table.ExpandTableColumn(#"Removed Columns3", "Block Total", {"Block", "Part", "Units", "Group", "Group Total"}, {"Block", "Part", "Units", "Group", "Group Total"})
in
    #"Expanded Block Total"

Database数据库

在此处输入图像描述

Table桌子

在此处输入图像描述

Results结果

在此处输入图像描述

If you require the Results Part column to be sorted in the same order as the original table, that can be done, but would require extra steps如果您需要按照与原始表相同的顺序对结果部分列进行排序,可以这样做,但需要额外的步骤

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM