VBA Создать график на отфильтрованных данных - PullRequest
0 голосов
/ 08 февраля 2019

Я объединяю наборы данных из разных источников в одну таблицу Excel, и моя цель - автоматически создать диаграмму.Однако, в зависимости от состояния флажка на листе, диаграмма должна в обоих состояниях включать только отфильтрованный набор таблицы.

Чтобы получить лучшее впечатление, моя таблица выглядит следующим образом: enter image description here

Поэтому, когда флажок установлен, отфильтруйте данные в столбце G, чтобы построить диаграмму из оставшихся строк.Если флажок не установлен, отфильтруйте другие числа и т. Д.

Значения в столбце S рассчитываются по формулеИтак, в целом мой подход выглядит следующим образом:

Sub Analysis()

Dim ws As Worksheet
Set ws = ActiveSheet

'Clear worksheet data
ws.Range("A2:R" & CStr(ws.UsedRange.Rows.Count)).Clear

'Copy data from source files to active sheet

Dim lngRows as long
lngRows = ws.UsedRange.Rows.Count

'##########################################################################
'Apply filters according to checkbox on sheet
'If only supplier parts checked, filter according to column "Beschaffungsart"

'Has checkbox been checked to only regard parts from supplier?
Dim onlySupplierParts As Boolean
onlySupplierParts = CBool(ws.Cells(9, ColC2N("U")).Text = "WAHR")

If onlySupplierParts Then
    ws.Range("$A$1:$S$" & CStr(lngRows).AutoFilter Field:=1
    ws.Range("$A$1:$S$" & CStr(lngRows).AutoFilter Field:=17, Criteria1:="F"
Else
    'don't filter for supplier parts, only filter empty rows
    ws.Range("$A$1:$S$" & CStr(lngRows).AutoFilter Field:=17
    ws.Range("$A$1:$S$" & CStr(lngRows).AutoFilter Field:=1, Criteria1:="<>"

    'ATTENTION: if not filtered for supplier parts, filter accordingly
    ws.Range("$A$1:$S$" & CStr(lngRows).AutoFilter Field:=7, Criteria1:=Array("101", "102", "103"), Operator:=xlFilterValues
End If
'##########################################################################


'Sort retrieved data according to date column
[...]

'Apply sum formula to column S
Range("S2").Select
ActiveCell.FormulaR1C1 = "=RC[-7]"
Range("S3").Select
ActiveCell.FormulaR1C1 = "=R[-1]C+RC[-7]"
Range("S3").Select
Selection.AutoFill Destination:=Range("S3:S" & CStr(Worksheets("Warenbewegungen").UsedRange.Rows.Count - 4)), Type:=xlFillDefault

'Delete old chart
Dim chtobj As ChartObject
For Each chtobj In ws.ChartObjects
   chtobj.Delete
Next chtobj

'Add chart
Dim rng As Range
Set rng = ws.Range("B6:P70")
Set chtobj = ws.ChartObjects.Add(Left:=rng.Left, Width:=rng.Width, Top:=rng.Top, Height:=rng.Height)
chtobj.Chart.ChartType = xlLine
chtobj.Chart.HasTitle = True
chtobj.Chart.ChartTitle.Text = "Verlauf Lagerbestand"

With chtobj.Chart.SeriesCollection.NewSeries
   .Name = "Progress over time"
   .Values = ws.Range("S2:S" & CStr(lngRows))
   .XValues = ws.Range("I2:I" & CStr(lngRows))
End With

End Sub

Теперь моя проблема в том, что диапазон, включенный в диаграмму, не ограничивается ячейками, которые все еще видны после применения фильтров.

Я думал о том, чтобы сохранить весь набор данных в массиве и отфильтровать его «вручную», но у меня есть ощущение, что это невероятно неэффективно.Исследования по этой теме показали, что должно быть какое-то решение с использованием xlSpecialCells, однако мне не совсем понятно, как это будет выглядеть в этом случае: /

Я уверен, что есть элегантное решение, яцени любые намеки.Спасибо за ваше время и помощь!

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Я решил отфильтровать весь лист, сохранить оставшиеся данные в массиве, очистить данные и снова вставить массив на лист.По пути я впервые использовал

ws.Range("A1:S" & CStr(lngRows)).AutoFilter Field:=7, Criteria1:=Array("101", "601", "643"), Operator:=xlFilterValues

'save current data in array, ONLY VISIBLE DATA!
filteredSet = ws.Range("A1:R" & lngRows).SpecialCells(xlCellTypeVisible)

'Clear worksheet data, then paste filteredSet to worksheet
ws.Range("A1:S" & lngRows).ClearContents
ws.Range("A1:R" & CStr(UBound(filteredSet, 1))).value = filteredSet

Однако SpecialCells (xlCellTypeVisible) в некоторых случаях кажется нерелевантным (источник, например, здесь ), так как он не возвращает правильно отфильтрованный набор данных,После некоторых исследований я заменил его следующим образом:

ws.Range("A1:S" & lngRows).AutoFilter Field:=7, Criteria1:=Array("101", "601", "643"), Operator:=xlFilterValues

'save current data in array, ONLY VISIBLE DATA!
filteredSet = VisibleCells(ws.Range("A2:S" & lngRows))

'Clear worksheet data, then paste filteredSet to worksheet
ws.Range("A1:S" & lngRows).AutoFilter Field:=7
ws.Range("A2:S" & lngRows).Clear
ws.Range("A2:S" & CStr(UBound(filteredSet, 1))).value = filteredSet



Private Function VisibleCells(rng As Range) As Range
Dim r As Range
For Each r In rng.Rows
    If r.EntireRow.Hidden = False Then
        If VisibleCells Is Nothing Then
            Set VisibleCells = r
        Else
            Set VisibleCells = Union(VisibleCells, r)
        End If
    End If
Next r
End Function

Но все же отфильтрованный набор в большинстве случаев не является данными, которые все еще видны при применении фильтров.Что я делаю не так?

0 голосов
/ 12 февраля 2019

По умолчанию диаграмма не будет отображать данные в скрытых строках таблицы.Просто создайте диаграмму, используя все строки таблицы, и когда таблица фильтруется, некоторые строки скрыты, и эти строки не отображаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...