Excel 2007 - 动态重复数据

发布于 2024-12-09 03:35:16 字数 1744 浏览 0 评论 0原文

我有这个 Excel 工作簿,它基本上应该是每个员工工作服的数据表。我想要的是为每个人(名字和姓氏)准备一张表,然后为每件可用的衣服准备一张表。

然后用一张纸将它们合并在一起。但是,这将涉及每个名称的重复次数,其次数与独特的布料类型相同。很难解释,但我可以在这里下载一本工作簿: http://www.mediafire.com/?dxurbdjq340su6j

Sheet2(Users) 包含每个的简单列表唯一用户。 Sheet3(文章)包含每件独特服装文章的列表。最后我们有了第一个工作表(摘要),其中包含所有内容的合并列表。基于此摘要表,我稍后将创建一个数据透视表。但首先我需要这里的功能是动态的。每当添加或删除新用户或服装时,我只想在 Sheet2 或 Sheet3 中执行此操作。 Sheet1 中的任何内容都应该动态收集数据。

有什么想法吗?我需要创建一个宏来执行此操作吗?

编辑:好的,所以我创建了一个包含两个公共词典的模块。这是我到目前为止得到的代码:

ThisWorkbook

Private Sub Workbook_Open()
    ' Create dictionaries
    Set dictName = New Dictionary
    Set dictClothItems = New Dictionary

    ' Collect data
    collectDictName
    collectDictClothItems
End Sub

Module1:

Public dictName As Dictionary
Public dictClothItems As Dictionary

Public Sub collectDictName()
Dim v As Variant
Dim rngName As Range

    ' Add values

    With ThisWorkbook.Sheets(2)
        Set rngName = .Range("A2", .Range("A" & Rows.Count).End(xlUp))

        For Each strName In rngName
            dictName.Add strName, ""
        Next
    End With
End Sub

Public Sub collectDictClothItems()
Dim v As Variant
Dim rngName As Range

    ' Add values

    With ThisWorkbook.Sheets(3)
        Set rngName = .Range("A2", .Range("A" & Rows.Count).End(xlUp))

        For Each strClothName In rngName
            dictClothItems.Add strClothName, ""
        Next
    End With
End Sub

所以,我在这里收集数据并将它们存储在一个数组中。我不确定如何从范围中收集数据,因此我使用了 For Each strName In rngName。看起来它还收集了我真正不需要的其他数据。也许可以通过创建一个字符串变量并将我想要的值分配给它来解决这个问题。然后将该字符串添加到字典中。无论如何,现在数据已经收集完毕,我现在需要进行比较并将其添加到实际的摘要表中。知道从哪里开始吗?

So I have this Excel workbook which basically is supposed to be a data sheet for work clothes for each employee. What I want is to have one sheet for each person (first name and last name), then one sheet for each clothing available.

Then one sheet to merge it all together. But, this would involve a repeat of each name as many times as there are unique cloth types. Hard to explain, but I've got a workbook available for download here:
http://www.mediafire.com/?dxurbdjq340su6j

Sheet2(Users) contains a simple list of each unique user. Sheet3(Articles) contains a list of each unique clothing article. And then finally we have the first Sheet(Summary) which contains a merged list of it all. Based on this Summary sheet, I'm gonna create a pivot table later. But first I need the functionality here to be dynamic. Whenever a new user or clothing is added or deleted, I only want to do this in Sheet2 or Sheet3. Whatever is in Sheet1 should collect the data dynamically.

Any idea? Would I have to create a macro to do this?

Edit: Ok, so I've created a module with two public Dictionaries. Here's the code I've got so far:

ThisWorkbook

Private Sub Workbook_Open()
    ' Create dictionaries
    Set dictName = New Dictionary
    Set dictClothItems = New Dictionary

    ' Collect data
    collectDictName
    collectDictClothItems
End Sub

Module1:

Public dictName As Dictionary
Public dictClothItems As Dictionary

Public Sub collectDictName()
Dim v As Variant
Dim rngName As Range

    ' Add values

    With ThisWorkbook.Sheets(2)
        Set rngName = .Range("A2", .Range("A" & Rows.Count).End(xlUp))

        For Each strName In rngName
            dictName.Add strName, ""
        Next
    End With
End Sub

Public Sub collectDictClothItems()
Dim v As Variant
Dim rngName As Range

    ' Add values

    With ThisWorkbook.Sheets(3)
        Set rngName = .Range("A2", .Range("A" & Rows.Count).End(xlUp))

        For Each strClothName In rngName
            dictClothItems.Add strClothName, ""
        Next
    End With
End Sub

So, here I collect the data and store these in an array. I wasn't sure how to collect the data from the range, so I used For Each strName In rngName. Looks like it collects other data that I really don't need as well. Can probably fix that up by creating a string variable and assigning the value I'm after to that. And then adding that string to the Dictionary. Anyways, now that the data's collected, I need to compare and add it to the actual Summary sheet now. Any idea on where to begin?

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

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

发布评论

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

评论(1

问题改述

所以基本上,你想要的是:

每次您在 Sheet2(用户)或 Sheet3(衣服)上添加新值时,您希望 Excel 在 Sheet1(摘要)上为每个动态添加一个新行强>另一张纸上的值(用户或衣服取决于更改的那张)

顺便说一句,金额来自哪里?

回答

然而,要回答你的问题,最简单的方法是使用 VBA 来回答,这样它就会是动态的。

您可以执行以下操作:

  • 在 Sheet2 和 Sheet3 上添加事件 Worksheet_Change() (请参阅 Chip Pearson 网站 如何操作)
  • 此程序将监视这些表上的每个更改。每次用户添加值时,您应该循环另一个工作表 从另一个工作表获取值并填充一个数组(衣服或用户取决于值)
  • 恕我直言,合并数据的最简单方法是create循环创建的数组(或使用字典将每个新行附加到数组中
  • 最终,您可以将数组添加到您的Summary

如果您需要更多信息,请毫不犹豫地询问;如果您仍然遇到困难,请针对您尝试过的内容提出一个新问题。


[编辑2]这是一个完整的文章工作解决方案(很容易适应用户)

Sheet3上的代码(文章)

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
Dim aSum() As String
Dim sArticle As String, sPrice As Long
Dim i As Integer, iLastrow As Integer

If Intersect(Range("A:B"), Target) Is Nothing Then Exit Sub
'if no price, exit sub
If Not Intersect(Range("A:A"), Target) Is Nothing Then
    If Target.Offset(0, 1).Value = Empty Then Exit Sub
    sArticle = Target.Value
    sPrice = CLng(Target.Offset(0, 1).Value)
End If
'if no name, exit sub
If Not Intersect(Range("B:B"), Target) Is Nothing Then
    If Target.Offset(0, -1).Value = Empty Then Exit Sub
    sArticle = Target.Offset(0, -1).Value
    sPrice = CLng(Target.Value)
End If

'get the names in an array        
collectNames
'store the data in a new array so to map these values in the end
ReDim aSum(UBound(vNames) - 1, 3)
For i = 0 To UBound(vNames) - 1
    aSum(i, 0) = vNames(i + 1, 1)
    aSum(i, 1) = sArticle
    aSum(i, 3) = sPrice
Next

'store the data back to the Summary sheet
With ThisWorkbook.Sheets("Summary")
    iLastrow = .Range("A" & Rows.Count).End(xlUp).Row + 1
    .Range("A" & iLastrow & ":D" & iLastrow + UBound(vNames) - 1).Value = aSum
End With
End Sub

模块中的代码

Option Explicit

Public vNames As Variant
Public vClothes As Variant

Public Sub collectNames()
With ThisWorkbook.Sheets(2)
    vNames = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
End With
End Sub

Public Sub collectClothItems()
With ThisWorkbook.Sheets(3)
    vClothes = .Range("A2", .Range("B" & Rows.Count).End(xlUp))
End With
End Sub

我没有使用字典(也许@Issun 可能在这里有一个想法,他是一个字典专家)但是数组,因为它更容易映射到工作表范围。

Question rephrasing

So basically, what you want is:

Each time you add a new value on either Sheet2 (Users) or Sheet3 (Clothes), you want Excel to dynamically add on Sheet1 (Summary) a new row for each value on the other Sheet (Users or Clothes depending on the one that was changed)

Btw, where does the amount come from?

Answer

Yet, to answer your question, the easiest way is to do it with VBA so it will be dynamic.

Here is what you can do:

  • add en event Worksheet_Change() on both Sheet2 and Sheet3 (see on Chip Pearson website how to do it)
  • this procedure will watch every change on these sheets. Every time a user add a value, you should loop over the other Sheet get the value from the other sheet and populate an array (Clothes or User depending on the value)
  • IMHO, the easiest way to consolidate the data is to create loop over your created array (or use a dictionary) and append every new row to your array
  • eventually, you can add the array in your Summary sheet

Don't hesitate to ask for some more information if you need or ask a new question with what you've tried if you are still stuck.


[EDIT 2] Here is a full working solution for articles (easily adaptable for users)

Code on Sheet3 (Articles)

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
Dim aSum() As String
Dim sArticle As String, sPrice As Long
Dim i As Integer, iLastrow As Integer

If Intersect(Range("A:B"), Target) Is Nothing Then Exit Sub
'if no price, exit sub
If Not Intersect(Range("A:A"), Target) Is Nothing Then
    If Target.Offset(0, 1).Value = Empty Then Exit Sub
    sArticle = Target.Value
    sPrice = CLng(Target.Offset(0, 1).Value)
End If
'if no name, exit sub
If Not Intersect(Range("B:B"), Target) Is Nothing Then
    If Target.Offset(0, -1).Value = Empty Then Exit Sub
    sArticle = Target.Offset(0, -1).Value
    sPrice = CLng(Target.Value)
End If

'get the names in an array        
collectNames
'store the data in a new array so to map these values in the end
ReDim aSum(UBound(vNames) - 1, 3)
For i = 0 To UBound(vNames) - 1
    aSum(i, 0) = vNames(i + 1, 1)
    aSum(i, 1) = sArticle
    aSum(i, 3) = sPrice
Next

'store the data back to the Summary sheet
With ThisWorkbook.Sheets("Summary")
    iLastrow = .Range("A" & Rows.Count).End(xlUp).Row + 1
    .Range("A" & iLastrow & ":D" & iLastrow + UBound(vNames) - 1).Value = aSum
End With
End Sub

Code in a module

Option Explicit

Public vNames As Variant
Public vClothes As Variant

Public Sub collectNames()
With ThisWorkbook.Sheets(2)
    vNames = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
End With
End Sub

Public Sub collectClothItems()
With ThisWorkbook.Sheets(3)
    vClothes = .Range("A2", .Range("B" & Rows.Count).End(xlUp))
End With
End Sub

I didn't use dictionaries (maybe @Issun may have an idea here, he is a dict-expert) but arrays because it was easier to map to the sheet ranges.

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