使用VBA过滤和更新Excel中的列

发布于 2025-01-27 08:36:01 字数 219 浏览 1 评论 0 原文

我有四列:姓名,代码,被雇用和射击。 代码列中的值是唯一的。 一年中可以雇用和开除几次,但我只需要第一次被录用,而只是最后一次被解雇。 我可以使用VBA过滤和更新这些列吗?

我所拥有的是从A到D的列中的值。我想要的是从i到l的列中的值

。 > “在此处输入图像说明”

I have four columns: Name, Code, Hired and Fired.
The Value in the Code columns is unique.
Someone can be hired and fired several times during the year, but I need only the first time that someone is hired and only the last time that someone is fired.
Can I filter and update these columns using vba?

What I have are the values in columns from A to D. What I want are the values in columns from I to L.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫腻 2025-02-03 08:36:01

如果您有Office 365,则可以使用其他答案之一中概述的公式来执行此操作。

这也可以使用电源查询来完成,该电源查询可在Windows Excel 2010+和Excel 365(Windows或Mac)中使用,

以使用电源查询

  • 选择数据表中的一些单元格
  • data =>获取& transform =>从表/范围从表格中
  • 打开时: home =>高级编辑器
  • 在第2行中的表格名称
  • 粘贴下面的M代码,以代替您看到的
  • 第2行中的表名称回到最初生成的内容。
  • 阅读评论并探索应用步骤以了解算法

m代码

let

//Read in data
//   Change table name in next line to your actual table name
    Source = Excel.CurrentWorkbook(){[Name="EmplTbl"]}[Content],

//Set the column data types
    #"Changed Type" = Table.TransformColumnTypes(Source,{
        {"NAME", type text}, {"CODE", type text}, {"HIRED", type date}, {"FIRED", type date}}),

//Group by Name and ID
//  Then aggregate by minimum HIRED and maximum FIRED to get results
    #"Grouped Rows" = Table.Group(#"Changed Type", {"CODE", "NAME"}, {
        {"Hired", each List.Min([HIRED]), type nullable date}, 
        {"Fired", each List.Max([FIRED]), type nullable date}
        })
in
    #"Grouped Rows"

If you have Office 365, you can do this with formulas as outlined in one of the other answers.

This can also be accomplished using Power Query, available in Windows Excel 2010+ and Excel 365 (Windows or Mac)

To use Power Query

  • Select some cell in your Data Table
  • Data => Get&Transform => from Table/Range or from within sheet
  • When the PQ Editor opens: Home => Advanced Editor
  • Make note of the Table Name in Line 2
  • Paste the M Code below in place of what you see
  • Change the Table name in line 2 back to what was generated originally.
  • Read the comments and explore the Applied Steps to understand the algorithm

M Code

let

//Read in data
//   Change table name in next line to your actual table name
    Source = Excel.CurrentWorkbook(){[Name="EmplTbl"]}[Content],

//Set the column data types
    #"Changed Type" = Table.TransformColumnTypes(Source,{
        {"NAME", type text}, {"CODE", type text}, {"HIRED", type date}, {"FIRED", type date}}),

//Group by Name and ID
//  Then aggregate by minimum HIRED and maximum FIRED to get results
    #"Grouped Rows" = Table.Group(#"Changed Type", {"CODE", "NAME"}, {
        {"Hired", each List.Min([HIRED]), type nullable date}, 
        {"Fired", each List.Max([FIRED]), type nullable date}
        })
in
    #"Grouped Rows"

enter image description here

我一向站在原地 2025-02-03 08:36:01

使用词典与最大和最小的唯一

Sub CreateHireFireReport()
    
    Const sName As String = "Sheet1"
    Const sFirstCellAddress As String = "A1"
    Const uCol As Long = 2
    Const hCol As Long = 3
    Const fCol As Long = 4
    
    Const dName As String = "Sheet1"
    Const dFirstCellAddress As String = "I1"
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
    Dim srg As Range: Set srg = sws.Range(sFirstCellAddress).CurrentRegion
    If srg.Rows.Count < 2 Then Exit Sub ' no data or just headers
    Dim srCount As Long: srCount = srg.Rows.Count
    Dim cCount As Long: cCount = srg.Columns.Count
    
    Dim sData As Variant: sData = srg.Value
    
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare
    
    Dim Key As Variant
    Dim sr As Long
    
    For sr = 2 To srCount
        Key = sData(sr, uCol)
        If Not IsError(Key) Then
            If Len(Key) > 0 Then
                dict(Key) = Empty
            End If
        End If
    Next sr
    If dict.Count = 0 Then Exit Sub ' only blanks and error values
    
    Dim drCount As Long: drCount = dict.Count + 1
    Dim dData As Variant: ReDim dData(1 To drCount, 1 To cCount)
    Dim ddr As Long: ddr = 1
    
    Dim dr As Long
    Dim c As Long
    
    ' Write headers.
    For c = 1 To cCount
        dData(1, c) = sData(1, c)
    Next c
    
    ' Write data.
    For sr = 2 To srCount
        Key = sData(sr, uCol)
        If Not IsError(Key) Then
            If Len(Key) > 0 Then
                If dict(Key) = Empty Then
                    ddr = ddr + 1
                    dr = ddr
                    dict(Key) = ddr
                    For c = 1 To cCount
                        dData(dr, c) = sData(sr, c)
                    Next c
                Else
                    dr = dict(Key)
                    If IsDate(sData(sr, hCol)) Then
                        If IsDate(dData(dr, hCol)) Then
                            If sData(sr, hCol) < dData(dr, hCol) Then
                                dData(dr, hCol) = sData(sr, hCol)
                            End If
                        Else
                            dData(dr, hCol) = sData(sr, hCol)
                        End If
                    End If
                    If IsDate(sData(sr, fCol)) Then
                        If IsDate(dData(dr, fCol)) Then
                            If sData(sr, fCol) > dData(dr, fCol) Then
                                dData(dr, fCol) = sData(sr, fCol)
                            End If
                        Else
                            dData(dr, fCol) = sData(sr, fCol)
                        End If
                    End If
                End If
            End If
        End If
    Next sr
    
    Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
    
    With dws.Range(dFirstCellAddress).Resize(, cCount)
        ' Format unique column as text.
        .Resize(drCount, 1).Offset(, uCol - 1).NumberFormat = "@"
        ' Write result.
        .Resize(drCount).Value = dData
        ' Clear below.
        .Resize(dws.Rows.Count - .Row - drCount + 1).Offset(drCount).Clear
        ' Apply other formatting.
        .Font.Bold = True ' headers
        .EntireColumn.AutoFit
    End With

    MsgBox "Hire-fire-report created.", vbInformation
    
End Sub

Unique With Max and Min Using a Dictionary

Sub CreateHireFireReport()
    
    Const sName As String = "Sheet1"
    Const sFirstCellAddress As String = "A1"
    Const uCol As Long = 2
    Const hCol As Long = 3
    Const fCol As Long = 4
    
    Const dName As String = "Sheet1"
    Const dFirstCellAddress As String = "I1"
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
    Dim srg As Range: Set srg = sws.Range(sFirstCellAddress).CurrentRegion
    If srg.Rows.Count < 2 Then Exit Sub ' no data or just headers
    Dim srCount As Long: srCount = srg.Rows.Count
    Dim cCount As Long: cCount = srg.Columns.Count
    
    Dim sData As Variant: sData = srg.Value
    
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare
    
    Dim Key As Variant
    Dim sr As Long
    
    For sr = 2 To srCount
        Key = sData(sr, uCol)
        If Not IsError(Key) Then
            If Len(Key) > 0 Then
                dict(Key) = Empty
            End If
        End If
    Next sr
    If dict.Count = 0 Then Exit Sub ' only blanks and error values
    
    Dim drCount As Long: drCount = dict.Count + 1
    Dim dData As Variant: ReDim dData(1 To drCount, 1 To cCount)
    Dim ddr As Long: ddr = 1
    
    Dim dr As Long
    Dim c As Long
    
    ' Write headers.
    For c = 1 To cCount
        dData(1, c) = sData(1, c)
    Next c
    
    ' Write data.
    For sr = 2 To srCount
        Key = sData(sr, uCol)
        If Not IsError(Key) Then
            If Len(Key) > 0 Then
                If dict(Key) = Empty Then
                    ddr = ddr + 1
                    dr = ddr
                    dict(Key) = ddr
                    For c = 1 To cCount
                        dData(dr, c) = sData(sr, c)
                    Next c
                Else
                    dr = dict(Key)
                    If IsDate(sData(sr, hCol)) Then
                        If IsDate(dData(dr, hCol)) Then
                            If sData(sr, hCol) < dData(dr, hCol) Then
                                dData(dr, hCol) = sData(sr, hCol)
                            End If
                        Else
                            dData(dr, hCol) = sData(sr, hCol)
                        End If
                    End If
                    If IsDate(sData(sr, fCol)) Then
                        If IsDate(dData(dr, fCol)) Then
                            If sData(sr, fCol) > dData(dr, fCol) Then
                                dData(dr, fCol) = sData(sr, fCol)
                            End If
                        Else
                            dData(dr, fCol) = sData(sr, fCol)
                        End If
                    End If
                End If
            End If
        End If
    Next sr
    
    Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
    
    With dws.Range(dFirstCellAddress).Resize(, cCount)
        ' Format unique column as text.
        .Resize(drCount, 1).Offset(, uCol - 1).NumberFormat = "@"
        ' Write result.
        .Resize(drCount).Value = dData
        ' Clear below.
        .Resize(dws.Rows.Count - .Row - drCount + 1).Offset(drCount).Clear
        ' Apply other formatting.
        .Font.Bold = True ' headers
        .EntireColumn.AutoFit
    End With

    MsgBox "Hire-fire-report created.", vbInformation
    
End Sub
段念尘 2025-02-03 08:36:01

因此,如果您不知道如何编写 vba代码,那么您也可以尝试使用 excel formulas ,您肯定需要访问 o365 o365 o365内部人员beta版本

“

•cell f2 f2 < /code>获得 唯一名称 &amp; 代码

=UNIQUE(A2:B20)

•在单元格> H2 中使用的公式

=MINIFS(C2:C20,A2:A20,F2:F6,B2:B20,G2:G6)

•cell i2

=MAXIFS(D2:D20,A2:A20,F2:F6,B2:B20,G2:G6)

使用 let()更容易读取 Leaws

Cell

=LET(u,UNIQUE(A2:A20),
c,UNIQUE(B2:B20),
CHOOSE({1,2,3,4},u,c,
MINIFS(C2:C20,A2:A20,u,B2:B20,c),
MAXIFS(D2:D20,A2:A20,u,B2:B20,c)))

•使用 f9 使用 lambda()函数to ,•公式创建 自定义 可重复使用 功能,并通过 友好名称 lambda() name manager 中使用的功能 定义的名称 aS hirefire 带有语法在

=HireFire(array,header)

其中,

HireFire = LAMBDA(array,header,
VSTACK(TAKE(header,1,4),
LET(a,INDEX(array,,1),
b,INDEX(array,,2),
c,INDEX(array,,3),
d,INDEX(array,,4),
u,UNIQUE(a),
uc,UNIQUE(b),
HSTACK(u,uc,
MINIFS(c,a,u,b,uc),
MAXIFS(d,a,u,b,uc)))))(A2:D20,A1:D1)

•因此,在 f15 中使用的公式,

=HireFire(A2:D20,A1:D1)

由于您尚未提及excel版本,因此您可能正在使用 excel 2019 2016 代码>或 2013 因此,因此,如下所示的替代方案,

“

•cell f2 中使用的公式

=IFERROR(INDEX(A$2:A$20,MATCH(0,COUNTIF($F$1:F1,A$2:A$20),0)),"")

>上述公式,是一个数组公式,需要按 ctrl + shift + ENTER 基于您的Excel版本,

•cell g2 中使用的

=IF($F2="","",VLOOKUP($F2,$A$2:$D$20,2,0))

公式单元 H2 - &GT; 适用于Excel 2019&amp;上面

=MINIFS(C$2:C$20,$A$2:$A$20,$F2,$B$2:$B$20,$G2)

如果不使用上述任何一个版本,则

=MIN(IF(($F2=$A$2:$A$20)*($G2=$B$2:$B$20),$C$2:$C$20,""))

其数组公式,因此需要按 ctrl + shift> shift> shift + enter 填写!

•单元格中使用的公式 i2 - &gt; 适用于Excel 2019&amp;上面

=MAXIFS(D$2:D$20,$A$2:$A$20,$F2,$B$2:$B$20,$G2)

如果不使用上述任何一个版本,则

=MAX(IF(($F2=$A$2:$A$20)*($G2=$B$2:$B$20),$D$2:$D$20,""))

其数组公式,因此需要按 ctrl + shift> shift> shift + enter 填写!

So, if you are not aware of how to write VBA Code, then you may try using Excel Formulas as well, however for the following formulas, you definitely need to have access either to O365 or O365 Insiders Beta Version

FORMULA_SOLUTION

• Formula used in cell F2 to get the Unique Name & Codes,

=UNIQUE(A2:B20)

• Formula used in cell H2

=MINIFS(C2:C20,A2:A20,F2:F6,B2:B20,G2:G6)

• Formula used in cell I2

=MAXIFS(D2:D20,A2:A20,F2:F6,B2:B20,G2:G6)

Using LET() makes easier to read and understand,

• Formula used in cell F9

=LET(u,UNIQUE(A2:A20),
c,UNIQUE(B2:B20),
CHOOSE({1,2,3,4},u,c,
MINIFS(C2:C20,A2:A20,u,B2:B20,c),
MAXIFS(D2:D20,A2:A20,u,B2:B20,c)))

Using LAMBDA() Function to create a custom, reusable function and refer them by a friendly name, LAMBDA() Function used in Name Manager with a Defined Name as HireFire with syntax as

=HireFire(array,header)

Where,

HireFire = LAMBDA(array,header,
VSTACK(TAKE(header,1,4),
LET(a,INDEX(array,,1),
b,INDEX(array,,2),
c,INDEX(array,,3),
d,INDEX(array,,4),
u,UNIQUE(a),
uc,UNIQUE(b),
HSTACK(u,uc,
MINIFS(c,a,u,b,uc),
MAXIFS(d,a,u,b,uc)))))(A2:D20,A1:D1)

• Therefore, Formula used in cell F15

=HireFire(A2:D20,A1:D1)

Since you have not mentioned your Excel Version, it may happen you are using either Excel 2019 or 2016 or 2013 so on so forth, hence, alternatives shown below,

FORMULA_SOLUTION

• Formula used in cell F2

=IFERROR(INDEX(A$2:A$20,MATCH(0,COUNTIF($F$1:F1,A$2:A$20),0)),"")

The above formula, is an array formula and needs to press CTRL + SHIFT + ENTER based on your Excel Versions,

• Formula used in cell G2

=IF($F2="","",VLOOKUP($F2,$A$2:$D$20,2,0))

• Formula used in cell H2 --> Applicable To Excel 2019 & Above

=MINIFS(C$2:C$20,$A$2:$A$20,$F2,$B$2:$B$20,$G2)

If not using either of the above version then,

=MIN(IF(($F2=$A$2:$A$20)*($G2=$B$2:$B$20),$C$2:$C$20,""))

Its an array formula, hence needs to press CTRL + SHIFT + ENTER and fill down!

• Formula used in cell I2 --> Applicable To Excel 2019 & Above

=MAXIFS(D$2:D$20,$A$2:$A$20,$F2,$B$2:$B$20,$G2)

If not using either of the above version then,

=MAX(IF(($F2=$A$2:$A$20)*($G2=$B$2:$B$20),$D$2:$D$20,""))

Its an array formula, hence needs to press CTRL + SHIFT + ENTER and fill down!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文