Может ли Excel сгенерировать процентную диаграмму из столбца со значениями CSV? Как?

2

Не уверен, что это вообще возможно. Представьте себе следующий лист Excel:

STOCK|VALUE|TAGS
ABCDE|10000|Z,X  
FGHIJ|20000|X,Y
KLMNO|30000|X,Y,Z
PQRST|10000|Z,Y
Total|70000|

Теперь где-нибудь на листе или в книге я хочу сгенерировать проценты того, из чего состоит каждый тег, по отношению к общему значению. Так, например, он покажет мне (динамически генерируется на основе используемых значений 'TAGS'):

X = 60,000 / 85.71%
Y = 60,000 / 85.71%
Z = 50,000 / 71.43%

Первый (и единственный) метод, который приходит на ум, - это оператор if для каждого возможного значения 'TAG'. Однако это долго, громоздко, грязно, неэффективно и не динамично. Конечно, есть лучший способ? Предпочел бы строго решение Excel; но если это невозможно - VBA это должно быть, я полагаю ...

// Редактировать & gt; Нерабочий VBA, который у меня есть на данном этапе. Я не делаю VBA; так что извините за плохой код. В настоящее время он пытается создать список в 5-м / 6-м столбце полей уникальных тегов и суммировать их с процентным полем в 7-м столбце. Он не работает в текущем состоянии, потому что он принимает все поле тега как одно значение.

Sub ProcessData1()

Dim dict As Dictionary
Dim i As Integer
Dim targetRow As Integer
Dim stock As String
Dim value As Double
Dim more As Boolean

Set dict = New Dictionary

more = True
'Row Start
i = 2
targetRow = 1

While more
    tags = Worksheets("holdings").Cells(i, 3).value

    If dict.Exists(tags) Then
        value = Worksheets("holdings").Cells(dict.Item(tags), 6) + Worksheets("holdings").Cells(i, 2).value
        Worksheets("holdings").Cells(dict.Item(tags), 6) = value
        'Assumes Total value on Row 21
        Worksheets("holdings").Cells(dict.Item(tags), 7) = value * 100 / Worksheets("holdings").Cells(21, 2)
    Else
        targetRow = targetRow + 1
        Worksheets("holdings").Cells(targetRow, 5) = Worksheets("holdings").Cells(i, 3).value
        Worksheets("holdings").Cells(targetRow, 6) = Worksheets("holdings").Cells(i, 2).value
        Worksheets("holdings").Cells(targetRow, 7) = Worksheets("holdings").Cells(i, 2).value * 100 / Worksheets("holdings").Cells(21, 2)
        dict.Item(tags) = targetRow
    End If

    i = i + 1

    If Len(Worksheets("holdings").Cells(i, 1)) = 0 Then more = False
Wend

End Sub
SupaMonkey
источник
Да, извините - вы правы - я отредактирую вопрос ...
SupaMonkey

Ответы:

3

Вы можете использовать SUMIFS с подстановочными знаками:

=SUMIFS(B:B,C:C,"*" & E1 & "*")/$B$5

enter image description here

Scott Craner
источник
Спасибо; в любом случае сделать это динамически генерируется, хотя? То есть X, Y, Z являются известными значениями, поэтому вы жестко закодировали их в столбце E. Тем не менее, я хочу иметь возможность добавлять теги в «C» по своему желанию и динамически адаптировать список в «E» по мере добавления / удаления тегов в столбце «C».
SupaMonkey
Это потребует обширной формулы массива, так что VBA будет лучше.
Scott Craner
Я думал, что VBA будет необходимо; не думаю, что я должен опубликовать это в переполнении стека, хотя, если у вас, возможно, есть ответ?
SupaMonkey
1
Нет, вас бы не голосовали и закрыли. И здесь, и там нравится видеть, что вы попробовали. У меня есть более низкий порог для формул. Но vba, при задании вопроса нужна конкретная проблема с существующим кодом.
Scott Craner
Добавлен текущий код VBA, который у меня есть, но в нем не хватает части головоломки ... Не уверен, есть ли способ «взорвать» значение в Excel?
SupaMonkey
0

Итак, я придумала свой собственный ответ. Это VBA, и я не делаю VBA, как я уже сказал выше, поэтому приведенный ниже код, я уверен, далек от идеального решения, но он справляется.

Sub ProcessData1()

Dim dict As Dictionary
Dim i As Integer
Dim j As Integer
Dim targetRow As Integer
Dim stock As String
Dim value As Double
Dim more As Boolean
Dim tags() As String
Dim tag As String

Set dict = New Dictionary

more = True
'Row Start
i = 2
targetRow = 1

While more
    tags() = Split(Worksheets("holdings").Cells(i, 3).value, ",")

    For j = LBound(tags) To UBound(tags)
        tag = tags(j)
        'MsgBox tag

        If dict.Exists(tag) Then
            value = Worksheets("holdings").Cells(dict.Item(tag), 6) + Worksheets("holdings").Cells(i, 2).value
            Worksheets("holdings").Cells(dict.Item(tag), 6) = value
            'Assumes Total value on Row 21
            Worksheets("holdings").Cells(dict.Item(tag), 7) = value * 100 / Worksheets("holdings").Cells(21, 2)
        Else
            targetRow = targetRow + 1
            Worksheets("holdings").Cells(targetRow, 5) = tag
            Worksheets("holdings").Cells(targetRow, 6) = Worksheets("holdings").Cells(i, 2).value
            Worksheets("holdings").Cells(targetRow, 7) = Worksheets("holdings").Cells(i, 2).value * 100 / Worksheets("holdings").Cells(21, 2)
            dict.Item(tag) = targetRow
        End If
    Next j

    i = i + 1

    If Len(Worksheets("holdings").Cells(i, 1)) = 0 Then more = False
Wend

End Sub
SupaMonkey
источник