VBA: Использование определенных массивов / диапазонов в цикле - PullRequest
0 голосов
/ 15 апреля 2020

Я довольно новичок в VBA, отсюда моя нынешняя борьба и неуклюжий код. В своем коде я пытаюсь определить некоррелированные акции для учебного проекта. Идея состоит в том, что мой макрос генерирует корреляционную матрицу, ограничивает имена акций, а затем перебирает строки за строкой, возвращая наиболее «некоррелированные» запасы для базового образца. Однако в настоящее время я не знаю, есть ли просто проблема со ссылками в моем коде или есть какая-то фундаментальная проблема. Любая помощь будет высоко ценится

Найдите ниже соответствующую часть сценария:

Sub Test()

Dim Names As Variant

Dim Ref As Variant

Set Names = Worksheets("Correlation Matrix").Range(Cells(1, 3), Cells(1, Stocks))

For i = 1 To Stocks

    Worksheets("Correlation Matrix").Activate

        Ref = Worksheets("Correlation Matrix").Range(Cells(i + 1, 3), Cells(i + 1, Stocks)).Value

    Worksheets("Main").Activate

        Worksheets("Main").Cells("O" & i + 4).FormulaArray = "=Index(" & Names.Address & ",MATCH(MIN(ABS(" & Ref.Address & " - 0),ABS(" & Names.Address & "- 0),0))"

Next i

End Sub

Рабочий лист "Матрица корреляции" выглядит следующим образом:

           Disney        Microsoft     Apple         sp500 
Disney     1             0.764790855   0.737566223   0.832602399 
Microsoft  0.764790855   1             0.754724823   0.827980429
Apple      0.737566223   0.754724823   1             0.90982066
sp500      0.832602399   0.827980429   0.90982066    1

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Рассмотрим этот подход:

В матрице корреляции нам нужно только взглянуть на числа либо «выше», либо «ниже» диагональной линии «1» с. Все остальные значения являются просто зеркальным отображением, смотреть на них было бы пустой тратой времени.

Поэтому мы пытаемся взглянуть на треугольник координат:

   A (1)      B (2)         C (3)         D (4)         E (5)
1             Disney        Microsoft     Apple         sp500 
2  Disney     1             0.764790855   0.737566223   0.832602399 
3  Microsoft  0.764790855   1             0.754724823   0.827980429
4  Apple      0.737566223   0.754724823   1             0.90982066
5  sp500      0.832602399   0.827980429   0.90982066    1

Excel также считает столбцы из 1, это то, что цифры в скобках. Координаты столбца строки, которые мы хотим проверить, могут быть «нижней» половиной, например так («x» обозначает диагональные ячейки со значением 1):

  A (1)      B (2)         C (3)         D (4)         E (5)
1
2            x
3            (3,2)         x
4            (4,2)         (4,3)         x
5            (5,2)         (5,3)         (5,4)         x

Вложенный l oop может создать эти пары координат. L oop работает для строк 3..5 и столбцов 2..4 соответственно, но исключает любые столбцы за пределами "треугольника":

Sub LeastCorrelated(NumStocks As Integer)
  Dim corrMatrix As Worksheet
  Dim minimumCell As Range, cell As Range
  Dim r As Integer, c As Integer
  Dim stock1 As String, stock2 As String

  Set corrMatrix = Worksheets("Correlation Matrix")
  Set minimumCell = corrMatrix.Cells(2, 2) ' the top-left cell containing "1"

  For r = 3 To NumStocks + 1
    For c = 2 To r - 1
      Set cell = corrMatrix.Cells(r, c)
      If cell.Value < minimumCell.Value Then Set minimumCell = cell
    Next
  Next

  minimumCell.Select
  stock1 = corrMatrix.Cells(1, minimumCell.Column).Value
  stock2 = corrMatrix.Cells(minimumCell.Row, 1).Value

  Debug.Print stock1 & " / " & stock2
End Sub

Когда вызывается как

LeastCorrelated 4

печатает

Disney / Apple

и выбирает ячейку A4.

0 голосов
/ 15 апреля 2020

Измерение переменных как Range объектов. Variant является типом перехвата всех данных и не имеет свойства .Name.

См. Ниже. Я также изменил переменную Names, поскольку .Names относится к именованным диапазонам.

Sub Test()

Dim theNames As Range
Dim Ref As Range

Set theNames = Worksheets("Correlation Matrix").Range(Cells(1, 3), Cells(1, Stocks))

For i = 1 To Stocks

    'Worksheets("Correlation Matrix").Activate - no need to activate sheet

    Set Ref = Worksheets("Correlation Matrix").Range(Cells(i + 1, 3), Cells(i + 1, Stocks)).Value

    'Worksheets("Main").Activate - no need to activate sheet

    Worksheets("Main").Cells("O" & i + 4).FormulaArray = "=Index(" & theNames.Address & ",MATCH(MIN(ABS(" & Ref.Address & " - 0),ABS(" & theNames.Address & "- 0),0))"

Next i

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