Live-Forum - Die aktuellen Beiträge
Datum
Titel
28.04.2024 20:05:21
28.04.2024 18:33:31
28.04.2024 18:25:12
28.04.2024 14:18:05
Anzeige
Archiv - Navigation
1916to1920
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Marktanteile mit VBA statt per Hand

Marktanteile mit VBA statt per Hand
10.02.2023 11:30:45
Susanne
Liebe VBA-Freunde,

ich bräuchte bitte eine Gedankenstütze, wie ich mich bei folgender Herausforderung vorhanteln kann:
Ich habe eine Export-Datei, in der ich gerne die Marktanteile und Umsatzentwicklung berechnen würde. Normalerweise geschah das per Hand (Spalten einfügen, Formeln eingeben und runterziehen). Jedoch ist der Aufwand mit steigender Anzahl an Exports doch etwas größer und hier würde ich gerne die Automation zu Hilfe ziehen.

Im Anhang habe ich eine exportierte Datei samt Ausgangspunkt (mit Infos) und ein Ergebnis, wie es aussehen sollte.
Nun zur Herangehensweise: Suche ich im Raum nach den "Grand Totals", verwende dann Offsets und eine Laufvariable, die dann in den neu eingefügten Spalten die Berechnung durchführt?
Ich hab da gestern immer Fehler "Überlauf" mit den ganzen Offsets erhalten. Dass auch die Groups mit zusammengefasst werden, macht es nicht gerade einfacher... (Wobei ich die auch mit etwas passendem wie "Grand Total Group 1" überschreiben könnte...)

Ich bitte um Gedankeninputs :)

LG und einen schönen Start ins Wochenende
Su

https://www.herber.de/bbs/user/157768.xlsx

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Marktanteile mit VBA statt per Hand
10.02.2023 13:09:06
ChrisL
Hi
Mal stümperhaft ein paar Formeln eingesetzt:
Sub t()
With ActiveSheet
    .Range("H:O").Insert
    With .Range("I1:I" & .Cells(.Rows.Count, 5).End(xlUp).Row)
        .Offset(1).Resize(.Rows.Count - 1, 1).Formula = "=IF(B2="""",MAX(I$1:I1)+1,"""")"
        .Offset(0, 1).Resize(.Rows.Count, 3).Formula = "=IF(OR($B1="""",$B1=""""),"""",E1/INDEX(E:E,MATCH(MAX($I$1:$I1),$I:$I,0),1))"
        .Offset(0, 1).Resize(.Rows.Count, 6).NumberFormat = "0.0%"
        .Offset(0, 5).Formula = "=IF(B1="""","""",(F1-E1)/E1)"
        .Offset(0, 6).Formula = "=IF(B1="""","""",(G1-F1)/F1)"
    End With
    .Columns(9).Hidden = True
End With
End Sub
cu
Chris
Anzeige
AW: Marktanteile mit VBA statt per Hand
10.02.2023 13:27:23
Susanne
Hallo Chris,
vielen Dank für deinen Input. Damit bin ich jedoch an genau diese Formatierung der Tabelle gebunden. Und es kann ja sein, dass sich um eine Spalte links/rechts verschiebt. Zudem erhalte ich bei den Marktanteilen #Wert! und #DIV/0! Fehler. Aber das kann vermutlich auch an meinem 2013er Excel liegen.
LG,Su
AW: Marktanteile mit VBA statt per Hand
10.02.2023 13:47:40
ChrisL
Hi
Ich lasse die Frage offen. Auch wenn meine Lösung noch nicht perfekt ist, wäre es ein Ansatz, um darauf aufzubauen z.B. Spalten weiter ausserhalb vom Bereich einfügen und danach ein weiteres Makro erstellen, um die überflüssigen Spalten zu identifizieren/löschen. Nicht ideal, aber mir scheint die Lösung einfach verständlich (sind ja eigentlich nur eingesetzte Formeln), woraus man etwas machen könnte.
Der Formelfehler kommt aus der Darstellung im Forum (eckige Klammern wurden als HTML-Tag interpretiert).
.Formula = "=IF(B2=""<Grand Total>"",MAX(I$1:I1)+1,"""")"
.Formula = "=IF(OR($B1=""<Grand Total>"",$B1=""""),"""",E1/INDEX(E:E,MATCH(MAX($I$1:$I1),$I:$I,0),1))"
cu
Chris
Anzeige
AW: Marktanteile mit VBA statt per Hand
10.02.2023 18:22:35
Susanne
Hey Chris,
in der Tat gefällt mir dein Denkansatz immer mehr.
Wie gesagt, ich bin selbst nicht mehr weitergekommen, deswegen wollte ich hier mal ein paar Gedankengänge anzapfen.
Ich dachte ja, ich kann das leicht mit einer Laufvariablen lösen, aber wurde eines besseren belehrt xD
Schönen Abend,
Su
Power Query
10.02.2023 14:06:50
Yal
Hallo Susanne,
Bei Excel 2013 muss man zwar Power Query nachinstallieren, aber es würde sich für diese Aufgabe rentieren, insbesondere, wenn die Quelle eine Textdatei ist, die man zuerst in Excel laden muss.
Damit wurde ich alle Zwischensummen eliminieren, eventuell entpivotieren und ein Pivot auf das Ergebnis stellen.
Wenn das alles Dir nicht sagt, schaue https://excelhero.de/power-query/power-query-ganz-einfach-erklaert
VG
Yal
Anzeige
AW:VBA Gedanken?
10.02.2023 18:27:29
Susanne
Hallo Yal,
die Quelle spuckt mir tatsächlich schon xlsx Dateien aus.
Ich habe mir Power-Query angesehen - denke jedoch, dass es mir ohne lieber wäre, da auch nur 2x im Jahr Daten eingelesen werden (nur eben in vielfacher Anzahl).
Ein paar Gedankengänge zu einer Lösung in VBA hast du nicht zufällig? :)
Ist mein Vorschlag mit einer Kombination aus Laufvariablen und Offset unpassend? Gerne werde ich eines besseren belehrt :)
Schönen Abend,
Su
AW: AW:VBA Gedanken?
10.02.2023 19:47:34
Yal
Hallo Susanne,
mein Gedanke über VBA-Lösung: ja, damit könnte man alle Zwischensummen wegwerfen, sodass man eine stabile Pivottabelle drauf bauen kann.
Zeilen mit Gültigkeitsregel rauszuschmeissen, ist in Power Query nichts anderes als ein Filter setzen.
Man könnte trotzdem eine Pivot auf das gesamt aufbauen, und dann die unerwünschten Zeilen rausschmeissen.
Wenn deine "viele Dateien" alle dieselbe Struktur und in einem Verzeichnis liegen, könntest Du alle Dateien mit einer einzige PQ-Abfrage behandeln.
Es ist nur die Frage: was willst Du am Ende präsentieren? Muss man jede einzelne Datei öffnen, um die Auswertung zu sehen, oder möchtest Du alles in einem Sammeldatei haben?
VG
Yal
Anzeige
AW: AW:VBA Gedanken?
10.02.2023 20:56:09
Susanne
Guten Abend Yal,
also das mit den Zwischensummen ist gar nicht so verkehrt, weil die Tabelle tatsächlich so betrachtet wird, nur eben mit Marktanteilen. Das beantwortet auch deine Frage: Ich möchte die Daten nur so bereitstellen, dass man die Daten direkt so rauslesen kann (ohne groß mit einer Pivot rumspielen zu müssen/können). Also ja, es wird jede Datei einzeln geöffnet ohne Sammelverzeichnis. Ob alle Dateien komplett den selben Aufbau haben, bezweifle ich, weil es verschiedene Kategorien mit unterschiedlich viel Merkmalen gibt - muss ich aber erst noch kontrollieren. Deswegen war ich immer so auf "suchen" und "offset" aus.
LG,Su
Anzeige
Ausgangsblätter variieren
13.02.2023 10:46:55
Susanne
Hallo Yal,
wie befürchtet, das Layout der Ausgangstabellenblätter variiert.
Wenn ich von PQ Abstand halte, würdest du mir eine Herangehensweise empfehlen?
LG, Su
AW: Ausgangsblätter variieren
13.02.2023 11:56:22
Yal
Hallo Susanne,
ich habe folgende Entwurf gestartet. Jedoch ohne der Wahnsinn der Anteile, die prinzipiell in Pivot oder PowerBI vorhanden wären.
Du brauchst nur noch zu prüfen, ob einen Fall "SummeZweiterEbene" und/oder "SummeErsteEbene" vorliegt, diese Summe merken, und die Formeln dementsprechend gestalten.
Dieser Code basiert auf die Annahme, dass
_ der Datenbereich genau zwischen die LetzteZeile (von unten kommend) und die letzte befüllte Zeile nach LetzteZeile (von unten nach oben betrachtet) liegt,
_ die Kopfzeile ist direkt über die oberste Zeile der Datenbereich
_ die Spalte fangen mit dem ersten befüllte Zelle in der Kopfzeile und
_ enden in der letzt befüllte Zelle danach (also erste leere Zelle sagt: hier ist erste Spalte nach letzter Spalte )
Sub Formel_einfügen()
Dim KopfZeile As Long
Dim LetzteZeile As Long
Dim AnzEint As Long 'Anzahl Eintragspalten
Dim ESma As Long 'erste Splate Marktanteil
Dim ESue As Long 'erste Spalte Umsatzentwicklung
Dim z As Long, s As Long 'Zeile und Spalte
Const ES1 = 5 'imer Spalte E
    With ActiveWorkbook.Worksheets(1) 'wir nehmen an, es handelt sich immer um das erste Blatt in der gerade aktiven Arbeitsmappe
    'Suche erste/letzte Zeile
        LetzteZeile = .Cells(Rows.Count, "A").End(xlUp).Row
        KopfZeile = .Cells(LetzteZeile, "A").End(xlUp).Row - 1
    'Suche Eintragbereich
        AnzEint = 1 - ES1 + .Cells(KopfZeile, ES1).End(xlToRight).Column
        ESma = ES1 + AnzEint + 1
        ESue = ES1 + AnzEint * 2 + 2
    'Spalten einfügen
        .Cells(1, ESma).Resize(1, AnzEint + 1).EntireColumn.Insert Shift:=xlToRight
        .Cells(1, ESue).Resize(1, AnzEint).EntireColumn.Insert Shift:=xlToRight
    'Überschrift einfügen
        .Rows(KopfZeile).HorizontalAlignment = xlCenter 'Reset
        With .Cells(KopfZeile, ESma)
            .Value = "Marktanteil"
            .Resize(1, AnzEint).HorizontalAlignment = xlCenterAcrossSelection
        End With
        With .Cells(KopfZeile, ESue)
            .Value = "Umsatzentwicklung"
            .Resize(1, AnzEint - 1).HorizontalAlignment = xlCenterAcrossSelection
        End With
    'Formel einfügen 'Markanteil
        For z = KopfZeile + 1 To LetzteZeile
            'hier muss geprüft werden, ob eine Summe erster Ebene und/oder zweiter Ebene vorliegt
            For s = ESma To ESma + AnzEint
'                If SummeZweiterEbene > 0 Then
'                    .Cells(z, s).FormulaR1C1 = ... Formel für Anteil Wert im Zelle durch SummeZeiterEbene
'                ElseIf summeErsteEbene > 0 Then
'                    .Cells(z, s).FormulaR1C1 = ... Formel für Anteil Wert im Zelle durch SummeZeiterEbene
'                End If
            Next
        Next
    'Formel einfügen 'Umsatzentwicklung
        With .Cells(KopfZeile + 1, ESue).Resize(LetzteZeile - KopfZeile, AnzEint - 1)
            .FormulaR1C1 = "=IFERROR((RC[" & -AnzEint * 2 - 1 & "] - RC[" & -AnzEint * 2 - 2 & "]) / RC[" & -AnzEint * 2 - 2 & "],0)"
            .NumberFormat = "0.0%;-0.0%;-"
        End With
    End With
End Sub
Viel Erfolg
VG
Yal
Anzeige
AW: Ausgangsblätter variieren
13.02.2023 20:23:59
Yal
Letzte Version:
Sub Formel_einfügen()
Dim KopfZeile As Long
Dim LetzteZeile As Long
Dim AnzEint As Long 'Anzahl Eintragspalten
Dim ESma As Long 'erste Splate Marktanteil
Dim ESue As Long 'erste Spalte Umsatzentwicklung
Dim WertSpalte As Long
Dim z As Long, s As Long 'Zeile und Spalte
Dim Eb1_Sum As Double
Dim Eb2_Sum As Double
Const ES1 = 5 'imer Spalte E
    With ActiveWorkbook.Worksheets(1) 'wir nehmen an, es handelt sich immer um das erste Blatt in der gerade aktiven Arbeitsmappe
    'Suche erste/letzte Zeile
        LetzteZeile = .Cells(Rows.Count, "A").End(xlUp).Row
        KopfZeile = .Cells(LetzteZeile, "A").End(xlUp).Row - 1
    'Suche Eintragbereich
        AnzEint = 1 - ES1 + .Cells(KopfZeile, ES1).End(xlToRight).Column
        ESma = ES1 + AnzEint + 1
        ESue = ES1 + AnzEint * 2 + 2
    'Spalten einfügen
        .Cells(1, ESma).Resize(1, AnzEint + 1).EntireColumn.Insert Shift:=xlToRight
        .Cells(1, ESue).Resize(1, AnzEint).EntireColumn.Insert Shift:=xlToRight
    'Überschrift einfügen
        .Rows(KopfZeile).HorizontalAlignment = xlCenter 'Reset
        With .Cells(KopfZeile, ESma)
            .Value = "Marktanteil"
            .Resize(1, AnzEint).HorizontalAlignment = xlCenterAcrossSelection
        End With
        With .Cells(KopfZeile, ESue)
            .Value = "Umsatzentwicklung"
            .Resize(1, AnzEint - 1).HorizontalAlignment = xlCenterAcrossSelection
        End With
    'Formel einfügen 'Markanteil
        For s = ESma To ESma + AnzEint - 1
            WertSpalte = s - ESma + ES1
            For z = KopfZeile + 1 To LetzteZeile
            'hier muss geprüft werden, ob eine Summe erster Ebene und/oder zweiter Ebene vorliegt
                If .Cells(z, 2) = "" Then
                    Eb1_Sum = .Cells(z, WertSpalte).Value
                    .Cells(z, s) = 1
                    .Cells(z, s).NumberFormat = "0.0%___ ;-0.0%___ ;-"
                ElseIf .Cells(z, WertSpalte).Value > "" Then
                    If .Cells(z, 3) = "" Then
                        Eb2_Sum = .Cells(z, WertSpalte).Value
                        .Cells(z, s).Value = CDbl(.Cells(z, WertSpalte)) / Eb1_Sum
                        .Cells(z, s).NumberFormat = "0.0%__ ;-0.0%__ ;-"
                    Else
                        If .Cells(z, 3) = "" And .Cells(z, WertSpalte) > "" Then 'Summe Ebene 1: es wird ein Ratio zu Eb1_Sum berechnet
                            .Cells(z, s).Value = CDbl(.Cells(z, WertSpalte)) / Eb1_Sum
                            .Cells(z, s).NumberFormat = "0.0%_ ;-0.0%_ ;-"
                        Else
                            .Cells(z, s).Value = CDbl(.Cells(z, WertSpalte)) / Eb2_Sum
                            .Cells(z, s).NumberFormat = "0.0%;-0.0%;-"
                        End If
                    End If
                End If
            Next
        Next
    'Formel einfügen 'Umsatzentwicklung
        With .Cells(KopfZeile + 1, ESue).Resize(LetzteZeile - KopfZeile, AnzEint - 1)
            .FormulaR1C1 = "=IFERROR((RC[" & -AnzEint * 2 - 1 & "] - RC[" & -AnzEint * 2 - 2 & "]) / RC[" & -AnzEint * 2 - 2 & "],0)"
            .NumberFormat = "0.0%;-0.0%;-"
        End With
    End With
End Sub
Mit der Zahlenformatierung ist es noch ein Bischen holprig.
VG
Yal
Anzeige
AW: Ausgangsblätter variieren
17.02.2023 23:06:03
Susanne
Hallo Yal,
vielen Dank für dein Mitwirken. Leider muss ich dir mitteilen, dass ich am Montag aufgrund von Budgetkürzungen gekündigt und auch freigestellt worden bin.
So traurig - die Makros hätten so viel Kosten einsparen können...
Ich bleibe den Makros aber dennoch treu und versuche im nächsten Job mein Wissen einzubauen.
Liebe Grüße und nochmal Danke für deine Unterstützung!
Su

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige