#excel #vba
#excel #vba #сводная #powerquery
Вопрос:
трудно понять, как преобразовать многоколоночный набор данных с повторяющимися строками в уникальные столбцы.
Я провел исследование и нашел несколько сценариев VBA для этого, но это приводит к отсутствию данных, когда я выполняю подсчеты, чтобы подтвердить правильность поворота, и в итоге снова и снова добавляются повторяющиеся столбцы (имя / год рейтинга).
У кого-нибудь есть идеи? Я бы сделал сводную таблицу, но я не могу отобразить фактические значения рейтинга в сводной таблице, только сумму / количество / среднее значение и т. Д…
Комментарии:
1. Запрос мощности, как упоминалось в комментарии к вашему предыдущему вопросу.
Ответ №1:
Вы можете легко сделать это в powerquery.
- Выделите все ваши данные, затем вставьте> добавить таблицу
- вкладка «Данные»> «Получить данные из таблицы»
- выделите два правых столбца> сводные столбцы
- уровень оценки как значения
- дополнительные параметры> не агрегировать
- найдите и замените null на nothing
- сохраните и закройте
Комментарии:
1. Я только что сделал это, и он поворачивает столбцы, но оценки исчезают, просто 1 или 0
2. Вы убедились, что нажали «не агрегировать»?
Ответ №2:
Сводные данные
Код
Option Explicit
Sub pivotData()
' Define Source Range.
Dim rng As Range
Set rng = Range("A1").CurrentRegion
' Get unique values.
Dim prs As Variant
prs = getUniqueColumn1D(rng.Columns(1).Resize(rng.Rows.Count - 1).Offset(1))
Dim yrs As Variant
yrs = getUniqueColumn1D(rng.Columns(2).Resize(rng.Rows.Count - 1).Offset(1))
sort1D yrs
' Source Range to Source Array.
Dim Source As Variant
Source = rng.Value
' Define Target Array.
Dim Target As Variant
ReDim Target(1 To UBound(prs) - LBound(prs) 2, _
1 To UBound(yrs) - LBound(yrs) 2)
' Write from arrays to Target Array.
Target(1, 1) = Source(1, 1)
Dim n As Long
Dim i As Long
i = 1
For n = LBound(prs) To UBound(prs)
i = i 1
Target(i, 1) = prs(n)
Next n
Dim j As Long
j = 1
For n = LBound(yrs) To UBound(yrs)
j = j 1
Target(1, j) = yrs(n)
Next n
For n = 2 To UBound(Source, 1)
i = Application.Match(Source(n, 1), prs, 0) 1
j = Application.Match(Source(n, 2), yrs, 0) 1
Target(i, j) = Source(n, 3)
Next n
' Define Target Range.
Set rng = Range("E1").Resize(UBound(Target, 1), UBound(Target, 2))
' Write from Target Array to Target Range.
rng.Value = Target
' Inform user.
MsgBox "Data transferred.", vbInformation, "Success"
End Sub
' Returns the unique values from a column range.
Function getUniqueColumn1D(ColumnRange As Range, _
Optional ByVal Sorted As Boolean = False) _
As Variant
Dim Data As Variant
Data = ColumnRange.Columns(1).Value
With CreateObject("Scripting.Dictionary")
.CompareMode = vbTextCompare
Dim Key As Variant
Dim i As Long
For i = 1 To UBound(Data, 1)
Key = Data(i, 1)
If Not IsError(Key) And Not IsEmpty(Key) Then
.Item(Key) = Empty
End If
Next i
If .Count > 0 Then
getUniqueColumn1D = .Keys
End If
End With
End Function
' Sorts a 1D array only if it contains values of the same data type.
Sub sort1D(ByRef OneD As Variant, _
Optional ByVal Descending As Boolean = False)
With CreateObject("System.Collections.ArrayList")
Dim i As Long
For i = LBound(OneD) To UBound(OneD)
.Add OneD(i)
Next i
.Sort
If Descending Then
.Reverse
End If
OneD = .ToArray
End With
End Sub