开发者

Excel 2007 - Repeat data dynamically

开发者 https://www.devze.com 2023-04-11 17:36 出处:网络
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 s

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 ta开发者_运维技巧ble 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?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号