Excel 列出>;3输入
我想创建一个列表,列出不同数量股票之间所有可能的百分比分割(这是建立适当的投资机会集所必需的任务)。我能够为3种不同的输入创建一个定制的宏(代码如下) 是否可以升级该宏,使其自动考虑输入(即股票行情)的数量,而无需每次调整代码?因此,如果输入是5个标记而不是3个标记,它将为5个标记创建所有可能拆分的列表 电子表格的布局很简单:在第1行中,我在每列中都有一个单独的标记(目前有3个标记),拆分如下:Excel 列出>;3输入,excel,vba,Excel,Vba,我想创建一个列表,列出不同数量股票之间所有可能的百分比分割(这是建立适当的投资机会集所必需的任务)。我能够为3种不同的输入创建一个定制的宏(代码如下) 是否可以升级该宏,使其自动考虑输入(即股票行情)的数量,而无需每次调整代码?因此,如果输入是5个标记而不是3个标记,它将为5个标记创建所有可能拆分的列表 电子表格的布局很简单:在第1行中,我在每列中都有一个单独的标记(目前有3个标记),拆分如下: ColumnA ColumnB ColumnC row1 Ticker1 Ticker2
ColumnA ColumnB ColumnC
row1 Ticker1 Ticker2 Ticker3
row2 0 0 100
row3 0 1 99
etc.
以下是我使用的3个输入:
Sub PercentageSplits()
Dim Lastcol As Integer
Lastcol = Sheet1.Cells(1, Columns.Count).End(xlToLeft).Column
Sheet1.Cells(1, Lastcol + 1).Value = "Total"
Sheet1.Cells(1, Lastcol + 1).Font.Bold = True
Dim row As Integer: row = 2
Dim i As Integer, j As Integer, k As Integer
For i = 0 To 100: For j = 0 To 100: For k = 0 To 100
If i + j + k = 100 Then
Sheet1.Cells(row, 1).Value = i
Sheet1.Cells(row, 2).Value = j
Sheet1.Cells(row, 3).Value = k
Sheet1.Cells(row, Lastcol + 1).Value = i + j + k
row = row + 1
End If
Next: Next: Next
End Sub
我把一个快速的程序放在一起计算这些结果,在5个股票代码中,总共有100个,我得到了450多万个结果(准确地说是4598126)。这太多了,不能放在Excel表格上 为了确保输出符合Excel表格的要求,我计算了5个标记的组合,加上50,然后将结果加倍,从而将精度减半。这给出了316251个结果 如果您需要完全精确,那么您可以调整代码,以每个工作表100万行的块形式输出数据 我不经常在VBA中使用递归,但它似乎是回答这个特定问题的明显方法。我将在代码下面解释一些细节:
Option Explicit
' We'll store each result here
Dim splitList As Collection
Sub main()
Dim splitResult As Variant
Dim splitArray As Variant
Dim splitEntry As Variant
Dim outputArray() As Variant
Dim outputRow As Long
Dim outputCol As Long
' Initial set-up
Const TOTAL_TO_SPLIT As Integer = 50
Const NO_OF_TICKERS As Integer = 5
Set splitList = New Collection
' Generate the list
findSplit TOTAL_TO_SPLIT, 1, NO_OF_TICKERS, ""
MsgBox splitList.Count
' Output the list
ReDim outputArray(1 To splitList.Count, 1 To NO_OF_TICKERS)
outputRow = 1
With Worksheets("Sheet1")
.UsedRange.Clear
For Each splitResult In splitList
outputCol = 1
If Len(splitResult) > 0 Then
splitArray = split(splitResult, ";")
For Each splitEntry In splitArray
outputArray(outputRow, outputCol) = splitEntry * 2
outputCol = outputCol + 1
Next splitEntry
End If
outputRow = outputRow + 1
Next splitResult
.Cells(2, 1).Resize(splitList.Count, NO_OF_TICKERS).Value = outputArray
End With
End Sub
' This sub is intended to be called recursively and will add an entry
' to splitList after each recursion concludes
Sub findSplit(amountToSplit As Integer, currentTicker As Integer, _
totalTickers As Integer, resultSoFar As String)
Dim i As Integer
' Call DoEvents to prevent Excel from showing as "Not Responding"
DoEvents
' Check if this is the last ticker
If (currentTicker = totalTickers) Then
splitList.Add resultSoFar & amountToSplit
Else
For i = 0 To amountToSplit
' Otherwise, generate all the possible splits by recursion
findSplit (amountToSplit - i), (currentTicker + 1), _
totalTickers, (resultSoFar & i & ";")
Next i
End If
End Sub
注:
- 这不会很快实现。我建议您在运行宏之前在Visual Basic编辑器中打开“局部变量”窗口(视图>局部变量窗口),以便定期使用Ctrl-Break检查进度
- 您可以消除集合,直接写入2D数组,但我试图使代码的递归部分尽可能简单
- 如果这是最后一个代码,则将剩余的代码分配给该代码
- 如果这不是最后一个股票代码,请尝试所有可能分配给该股票代码的内容,并将剩余的内容传递给下一个股票代码
在主子程序中的代码使用Split和For Each。。。下一个循环将集合中存储的字符串转换为二维数字数组,我们可以将其直接放到工作表中。很抱歉没有早点回复,我出差去了。我还没有机会尝试你的建议,尽管背后的逻辑似乎很可靠。真的很想谢谢你花时间帮我!当我有机会在excel中运行它时,我会回复!嗨,barrowc,终于有时间尝试一下你的代码了——工作起来很有魅力。而且速度也非常快!最长为30秒,具体取决于报价器数量/拆分百分比。更新了一点,使股票的数量成为一个变量,所以非常感谢你!