Excel può generare un grafico percentuale da una colonna con valori CSV? Come?


2

Non sono sicuro che ciò sia possibile. È come segue, immagina il seguente foglio Excel:

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

Ora da qualche parte sul foglio o sulla cartella di lavoro, voglio generare percentuali di ciò che ogni tag è costituito rispetto al valore totale. Ad esempio, mi mostrerebbe (generato dinamicamente in base ai valori "TAGS" utilizzati):

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

Il primo (e unico) metodo che viene in mente è avere un'istruzione if per ogni possibile valore 'TAG'. Tuttavia, questo è lungo, ingombrante, sporco, inefficiente e non dinamico. Sicuramente c'è un modo migliore? Preferirei una soluzione rigorosamente Excel; ma se non fosse possibile - VBA dovrebbe essere suppongo ...

// Modifica> VBA non funzionante che ho in questa fase. Non faccio VBA; quindi scusa il codice scadente. Attualmente, questo tenta di generare un elenco nella 5a / 6a colonna dei campi tag univoci e di sommarli con un campo percentuale nella 7a colonna. Non funziona nello stato corrente perché prende l'intero campo tag come un singolo valore.

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

Sì, scusa, hai ragione, modificherò la domanda ...
— SupaMonkey,

Risposte:


3

È possibile utilizzare SUMIFS con caratteri jolly:

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

inserisci qui la descrizione dell'immagine


Grazie; comunque di rendere questo generato dinamicamente però? Vale a dire, X, Y, Z sono valori noti, quindi li hai "hardcoded" nella colonna E. Tuttavia, voglio poter aggiungere i tag in 'C' a piacimento e avere l'elenco in 'E' adattarsi dinamicamente mentre aggiungo / rimuovo i tag nella colonna 'C'.
— SupaMonkey,

Ciò richiederebbe una formula di array estesa, quindi vba sarebbe meglio.
— Scott Craner,

Ho pensato che VBA sarebbe stato necessario; non pensi che dovrei ripubblicarlo in Stack Overflow anche se forse hai la risposta?
— SupaMonkey,

1
No, verrebbe votato e chiuso. Qui e là piace vedere cosa hai provato. Ho una soglia più bassa per le formule. Ma vba, è necessario un problema specifico con il codice esistente quando si pone una domanda.
— Scott Craner,

Aggiunto l'attuale codice VBA che ho che manca un pezzo del puzzle ... Non sei sicuro che ci sia un modo per "esplodere" un valore in Excel?
— SupaMonkey,

0

Ok, quindi ho trovato la mia risposta. Il suo VBA e io non facciamo VBA come ho detto sopra, quindi il codice qui sotto sono sicuro che è ben lungi dall'essere una soluzione perfetta ma fa il trucco.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.