【问题标题】:How to output results set of every iteration in VBA?如何在 VBA 中输出每次迭代的结果集?
【发布时间】:2020-09-20 07:07:38
【问题描述】:

如何在工作表的新行中输出每次迭代的结果集?即遍历 (i,j,k,l,m) 的所有可能组合

avg protein1 = (0,j,k,l,m) 
avg protein2 = (1,j,k,l,m) 
avg protein3 = (2,j,k,l,m) ... 
.. . 
avg protein (n-2) = (i,j,k,l,0) 
avg protein (n-1) = (i,j,k,l,1) 
avg protein (n) = (i,j,k,l,2)

这是修改后的背包优化问题的代码(代码有效)。它最大化 5 个不同 bin 的 avg 蛋白质值,每个 bin 受到边距约束。

Option Explicit

Sub ProteinCalc()
    
    Dim limit As Double, tol As Double, Protein As Double, Margin As Double, averageprotein As Double, maximumMargin As Double
    Dim i, j, k, l, m As Integer
    
    Dim Proteini, Proteinj, Proteink, Proteinl, Proteinm As Double
    Dim Margini, Marginj, Margink, Marginl, Marginm As Double
    
    
    Worksheets("simplecalc").Range("B19:H23").ClearContents
    Worksheets("simplecalc").Range("B4:F4").ClearContents
    
    
    limit = Range("D6").Value                   'declare max protein target on blend
    tol = Range("G6").Value                     'declare tolarance on protein blend to get close to max protien target
    
    maximumMargin = Range("G8").Value          'declare minimum margin $/MT want to make
    
    Proteini = Range("B2").Value
    Proteinj = Range("C2").Value
    Proteink = Range("D2").Value
    Proteinl = Range("E2").Value
    Proteinm = Range("F2").Value
    
    Margini = Range("B3").Value
    Marginj = Range("C3").Value
    Margink = Range("D3").Value
    Marginl = Range("E3").Value
    Marginm = Range("F3").Value
    
    For i = 0 To 2                                                         'loop up to 2 to signify a possible double spot for train at station i
        For j = 0 To 2
            For k = 0 To 2
                For l = 0 To 2
                    For m = 0 To 2
                            Protein = (Proteini * i + Proteinj * j + Proteink * k + Proteinl * l + Proteinm * m) / 5        'linear avg of 5 stations
                            Margin = (Margini * i + Marginj * j + Margink * k + Marginl * l + Marginm * m) / 5              ' linear avg of margin from 5 stations
                            
                            If Margin > maximumMargin And Protein <= limit Then
                                Range("B4").Value = i
                                Range("C4").Value = j
                                Range("D4").Value = k
                                Range("E4").Value = l
                                Range("F4").Value = m
                                averageprotein = Protein
                                maximumMargin = Margin
                              Debug.Print i
                              
                        End If
                                If m >= 0 And m <= 2 Then
                                Worksheets("simplecalc").Range("B23").Value = averageprotein
                                Worksheets("simplecalc").Range("C23").Value = Proteini
                                Worksheets("simplecalc").Range("D23").Value = Proteinj
                                Worksheets("simplecalc").Range("E23").Value = Proteink
                                Worksheets("simplecalc").Range("F23").Value = Proteinl
                                Worksheets("simplecalc").Range("G23").Value = Proteinm
                                Worksheets("simplecalc").Range("H23").Value = m
                                Worksheets("simplecalc").Range("i23").Value = l
                                Worksheets("simplecalc").Range("j23").Value = k
                                Worksheets("simplecalc").Range("k23").Value = j
                                Worksheets("simplecalc").Range("l23").Value = i
                                
                                End If
                            
                            
                    Next m
                            If l >= 0 And l <= 2 Then
                            Worksheets("simplecalc").Range("B22").Value = averageprotein
                            Worksheets("simplecalc").Range("C22").Value = Proteini
                            Worksheets("simplecalc").Range("D22").Value = Proteinj
                            Worksheets("simplecalc").Range("E22").Value = Proteink
                            Worksheets("simplecalc").Range("F22").Value = Proteinl
                            Worksheets("simplecalc").Range("G22").Value = Proteinm
                            Worksheets("simplecalc").Range("H22").Value = l
                            End If
                    
                Next l
                        If k >= 0 And k <= 2 Then
                        Worksheets("simplecalc").Range("B21").Value = averageprotein
                        Worksheets("simplecalc").Range("C21").Value = Proteini
                        Worksheets("simplecalc").Range("D21").Value = Proteinj
                        Worksheets("simplecalc").Range("E21").Value = Proteink
                        Worksheets("simplecalc").Range("F21").Value = Proteinl
                        Worksheets("simplecalc").Range("G21").Value = Proteinm
                        Worksheets("simplecalc").Range("H21").Value = k
                        End If
                    
            Next k
                    If j >= 0 And j <= 2 Then
                    Worksheets("simplecalc").Range("B20").Value = averageprotein
                    Worksheets("simplecalc").Range("C20").Value = Proteini
                    Worksheets("simplecalc").Range("D20").Value = Proteinj
                    Worksheets("simplecalc").Range("E20").Value = Proteink
                    Worksheets("simplecalc").Range("F20").Value = Proteinl
                    Worksheets("simplecalc").Range("G20").Value = Proteinm
                    Worksheets("simplecalc").Range("H20").Value = j
                    End If
            
        Next j
                If i >= 0 And i <= 2 Then
                Worksheets("simplecalc").Range("B19").Value = averageprotein
                Worksheets("simplecalc").Range("C19").Value = Proteini
                Worksheets("simplecalc").Range("D19").Value = Proteinj
                Worksheets("simplecalc").Range("E19").Value = Proteink
                Worksheets("simplecalc").Range("F19").Value = Proteinl
                Worksheets("simplecalc").Range("G19").Value = Proteinm
                Worksheets("simplecalc").Range("H19").Value = i
                End If
            
    Next i
    
    Range("B6").Value = averageprotein
    Range("B8").Value = maximumMargin
    
End Sub

【问题讨论】:

  • 由于VBA代码很慢,我会使用SQL(有没有不能用SQL轻松解决的问题;),好吧有一些;()照常创建一个cartesian product并删除查询条件中不需要的欺骗。这应该比大多数减少循环数的优化要快得多。结果可以分配给带有CopyFromRecordset的工作表
  • 我不确定我是否明白你在问什么,但你可以用 81 * i + 27 * j + 9 * k + 3 * l + m + 1 计算线
  • @Zer0Kelvin 想要为循环中的每次迭代输出“平均蛋白质 = 蛋白质”值。整数 i,j,k,l,m 公式循环通过您可以将它们视为该公式中的权重。这有意义吗?
  • @ComputerVersteher 希望我知道 SQL...一般编程新手(如您所想)
  • 将一些示例数据添加为格式为table 的文本和预期的输出。如果新手使用数据 sql 是一个完美的开始,因为与“普通”编程相比,基础知识要简单得多。如果您从 Ms Acccess 开始,则不需要编程,并且您稍后会受益,因为大多数 Excel 用户不使用它(因为他们不知道),但它使许多问题易于解决,并且如果您知道如何避免许多问题使用数据。只需搜索一些“ms 访问查询教程”(没有来自、报告或代码)。

标签: excel vba loops optimization


【解决方案1】:

在将值写入工作表之前,您需要在每次迭代中增加行号。所以,声明一个迭代计数器变量:

Dim itrCount As Long

然后改变这个:

If m >= 0 And m <= 2 Then
   Worksheets("simplecalc").Range("B23").Value = averageprotein
   Worksheets("simplecalc").Range("C23").Value = Proteini

到这里:

If m >= 0 And m <= 2 Then
   itrCount = itrCount + 1
   Worksheets("simplecalc").Range("B23").Offset(itrCount).Value = averageprotein
   Worksheets("simplecalc").Range("C23").Offset(itrCount).Value = Proteini

相应地在每个循环中。

这是使其工作所需的最低要求,您可以在此处应用其他改进。

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2018-06-11
    • 1970-01-01
    • 2018-11-21
    相关资源
    最近更新 更多