Существует несколько способов сделать это с помощью VBA. В этом решении я сначала создаю пользовательский Object с именем Country, с четырьмя свойствами: Name, Index, YR и Quantity. Это не нужно делать; но я недавно работал с ними, и я думаю, что он добавляет некоторую ясность в код.
Затем я считываю исходные данные в массив VBA (который может быть выполнен за один шаг), итерации по массиву для создания коллекции объектов Country.
Затем я просматриваю сборник Country, выводя свойства в массив Results, где я их хочу.
И наконец, массив результатов выводится на рабочий лист - снова, всего на один шаг.
Можно было перейти непосредственно из массива исходных данных в массив Results, но я думаю, что легче увидеть, что происходит с использованием объекта.
Также можно не беспокоиться с массивом VBA, но обрабатывать ячейки непосредственно с одного листа на другой. По моему опыту, этот подход будет по крайней мере на порядок медленнее, чем использование подхода массива VBA.
В зависимости от размера вашей базы данных могут потребоваться уточнения. Обязательно прочитайте комментарии в коде.
Чтобы определить объект Country, вставьте модуль класса и переименуйте его Страна. В этом модуле введите следующий код:
======================================================================================================================================================================== =====
Option Explicit
Private pName As String
Private pIndex As String
Private pYr As Long
Private pQuantity As Double
Public Property Get Name() As String
Name = pName
End Property
Public Property Let Name(Value As String)
pName = Value
End Property
Public Property Get Index() As String
Index = pIndex
End Property
Public Property Let Index(Value As String)
pIndex = Value
End Property
Public Property Get Yr() As Long
Yr = pYr
End Property
Public Property Let Yr(Value As Long)
pYr = Value
End Property
Public Property Get Quantity() As Double
Quantity = pQuantity
End Property
Public Property Let Quantity(Value As Double)
pQuantity = Value
End Property
====================================== =======
Затем вставьте регулярный модуль и поместите этот код там:
======================= ================
Option Explicit
Sub TransformData()
Dim wsSrc As Worksheet 'Data Source
Dim wsRes As Worksheet, rRes As Range 'Results go here
Dim vSrc As Variant 'Actual data goes into this array
Dim vRes() As Variant 'Results will go here before being written to worksheet
Dim cCTY As Country 'User defined object
Dim colCountries As Collection
Dim I As Long, J As Long 'counters
Set wsSrc = Worksheets("Sheet2") '<--change these to whatever
Set wsRes = Worksheets("Sheet3")
Set rRes = wsRes.Range("A1") '<--1st cell of results array
'read data into array
With wsSrc
vSrc = .Range("A1").CurrentRegion '<--many ways to get this depending on your real data setup
End With
'iterate through Source and create collection of results
Set colCountries = New Collection
For I = 2 To UBound(vSrc, 1) '<--Rows
For J = 3 To UBound(vSrc, 2) '<--Columns
Set cCTY = New Country
With cCTY
.Name = vSrc(I, 1)
.Index = vSrc(I, 2)
.Yr = vSrc(1, J)
.Quantity = vSrc(I, J)
End With
colCountries.Add cCTY
Next J
Next I
'Results
ReDim vRes(0 To colCountries.Count, 1 To 4)
'Column Labels
vRes(0, 1) = "Country"
vRes(0, 2) = "Index"
vRes(0, 3) = "Year"
vRes(0, 4) = "Value"
For I = 1 To colCountries.Count
With colCountries(I)
vRes(I, 1) = .Name
vRes(I, 2) = .Index
vRes(I, 3) = .Yr
vRes(I, 4) = .Quantity
End With
Next I
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
rRes.EntireColumn.Clear
rRes = vRes
With rRes.Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
rRes.EntireColumn.AutoFit
End Sub
========================================================================================================================== ====
Убедитесь, что листы и диапазоны правильно определены в соответствии с вашей реальной настройкой и запустите макрос.
Имеет ли порядок строк промежуточного выходного значения? Это что-то делать часто (вы не отметили [excel-vba])? – pnuts
Сколько у вас данных? Если у вас было 100 стран, 100 индексов, более 100 лет, вы бы приблизились к ограничениям строки Excel для этого в одном наборе столбцов. –
Если бы мне пришлось это сделать, я бы использовал 'python' с некоторыми модулями для чтения и записи файлов XLS. –