2015-07-15 8 views
0

Предположим, у Билла Гейтса есть фонд, который, в свою очередь, владеет фондом, который, в свою очередь, владеет акциями Microsoft. На финансовом рынке это очень распространено, это может пойти еще дальше (x владеет y, которому принадлежит z, которому принадлежит ...). Проблема в том, как рекурсивно извлекать данные с последнего узла на первый узел? То есть, как узнать, сколько акций Microsoft Билл Гейтс принадлежит? В SQL можно использовать JOIN, а затем попробовать немного взломать его, но даже тогда это будет только показать, что Билл владеет фондом. Окончательное соединение, то есть один из фондов Bills, принадлежит Microsoft Shares, не будет подключен (он показал бы, что y принадлежит x, но эта информация не будет связана с y, принадлежащей z). Итак, каков наилучший подход к решению этого вопроса в excel? Я полностью открыт для таких предложений, как «лучше преобразовать его в csv, а затем попробовать эту предложенную команду SQL». Ниже приведена диаграмма для лучшего понимания проблемы. enter image description hereАгрегирование данных в Excel

Вот диаграмма для еще лучшего понимания: enter image description here

+0

вы ищете решение VBA? –

+0

Я потерял @JohnColeman, поэтому любое решение приветствуется. Я могу обрабатывать любой язык. –

+0

Просто, чтобы сказать что-то о SQL, так как вы упомянули об этом, вы бы использовали рекурсивный CTE, и это было бы очень просто сделать. (смотря на превосходство сейчас) –

ответ

0

Вот вид дикой идеей, вдохновленный диаграмме. Создайте следующие, казалось бы, бессмысленные функции в VBA:

Function Owns(Owner As String, ParamArray assets() As Variant) As String 
    Owns = Owner 
End Function 

The - написать макрос для замены строк в столбце А по формулам в соответствии с логикой, проявленный:

enter image description here

(очевидно - - вводятся только формулы в A2-A6 - текст в A8-A12 - это только мой комментарий). Чтобы получить их, пропустите столбец A - посмотрите, что они собой представляют, перейдя к столбцу C. Если строка в столбце C также находится в столбце A - поместите весь столбец A (но без столбца C) ссылки на этот актив в качестве аргументов to Owns(). Это относится к первым трем элементам в столбце A. Если актив находится только в столбце C - поместите ссылку на столбец C для этой строки. Это относится к последним двум записям в A.

Зачем вам это нужно ?. Хорошо - выберите ячейку, содержащую Билла Гейтса, перейдите на вкладку «Формула» и повторно вызывайте Trace Precedents. Вы должны увидеть:

enter image description here

Изюминка: VBA Range объекты имеют метод .Precedents(), которые дают эти клетки в качестве объекта диапазона. Ключами-предшественниками в столбце C являются листья дерева-прецедента. Существует также метод .DirectPrecedents(), который может использоваться для обработки уровня дерева по уровню. Независимо от того, полезно ли мне в этом случае, я честно не знаю, но это похоже на хороший способ получить древовидную структуру для ваших данных, которую можно манипулировать в VBA.

On edit: Отслеживание иждивенцев может вернуть вас обратно от T-Bonds к Биллу Гейтсу. Есть два метода VBA, которые соответствуют этому. Кроме того, существуют такие методы, как .ShowPrecedents, которые можно использовать для анимации стрелок, чтобы пользователь мог видеть поток иждивенцев. Я также экспериментировал с методом (используя вторую фиктивную функцию в некоторых ячейках в C), которая будет иметь ячейки в столбце A, непосредственно связанные с ячейками в столбце C, которые, в свою очередь, связаны с ячейками в столбце A таким образом, что ShowPrecedents будет отображать обратный и четвертый поток данных - но я думаю, что это добавило бы лишние уровни в дерево.

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

1) Создайте два именованных диапазона. «Владелец», который является столбцом имен владельцев (A2: A6 в этом примере игрушек) и «Asset», который является соответствующей частью столбца активов (C2: C6 здесь).

2) Включите ссылку на Microsoft Scripting Runtime (Инструменты/Ссылки в редакторе VBA), чтобы словари могли использоваться.

Для полноты ради я добавляю код «владеет» снова, а также к югу под названием «восстановить», который заменит добавленные формулы струнами, которые отображаются (которые должны быть оригинальные строки):

Функция владеет (Владелец As String, ParamArray активы() As Variant) As String владеет = Владелец End Function

Sub tag() 
    Dim Owner As Range, Asset As Range 
    Dim OwnerAddress As New Dictionary 
    Dim OwnerFormula As New Dictionary 
    Dim OwnerRange As Range 
    Dim ocell As Range, acell As Range 
    Dim owner_name As Variant, asset_name As String 
    Dim formula As String 
    Dim shift As Long 

    Set Owner = Range("Owner") 
    Set Asset = Range("Asset") 
    shift = Asset.Column - Owner.Column '2 now, but user might move columns around 

    For Each ocell In Owner 
     owner_name = LCase(Trim(ocell.Value)) 
     If OwnerAddress.Exists(owner_name) Then 
      OwnerAddress(owner_name) = OwnerAddress(owner_name) & ", " & ocell.Address 
     Else 
      OwnerAddress(owner_name) = ocell.Address 
     End If 
    Next ocell 

    For Each owner_name In OwnerAddress.Keys 
     Set OwnerRange = Range(OwnerAddress(owner_name)) 'e.g. all ocells containing "Bill's Fund" 
     formula = "=Owns(" & """" & OwnerRange.Cells(1).Value & """" 
     For Each ocell In OwnerRange 
      Set acell = ocell.Offset(0, shift) 
      asset_name = LCase(Trim(acell.Value)) 
      If OwnerAddress.Exists(asset_name) Then 
       formula = formula & "," & OwnerAddress(asset_name) 
      Else 
       formula = formula & "," & acell.Address 
      End If 
     Next ocell 
     formula = formula & ")" 
     OwnerFormula.Add owner_name, formula 
    Next owner_name 

    For Each ocell In Owner 
     ocell.formula = OwnerFormula(LCase(Trim(ocell.Value))) 
    Next ocell 
End Sub 
+0

ты мой герой !!!! Это было так умно, я бы никогда не подумал об использовании прецедентов таким образом! Это именно то отношение, которое я хотел бы видеть. СПАСИБО –

Смежные вопросы