簡體   English   中英

為什么我在Excel VBA上遇到運行時錯誤

[英]Why Am I getting a run time error on Excel VBA

在我開始之前,我是編程和excel vba的新手,所以請保持友好。 我正在嘗試建立一個程序,根據我們的贏率比率電子表格,自動為星際爭霸2的友好游戲創建平衡的團隊。

這是該電子表格的簡化版

簡化的電子表格

然后,我嘗試使用vba代碼遍歷所有可能的團隊配置,並找到兩個團隊的贏/輸比率之差最小。

這是我的代碼,我希望你能理解所有變量名

        Public Sub Main()
    Dim TotalScore As Integer
    TotalScore = 0
   Dim TargetScore As Integer
    TargetScore = 0
    Dim CurrentScore As Integer
    CurrentScore = 0
    Dim InitialScoreDifference As Integer
    InitialScoreDifference = 0
    Dim ScoreDifference As Integer
    ScoreDifference = 0
   Dim Scores(0 To 7) As Long
    Scores(0) = Worksheets("Sheet1").Cells(2, "D").Value
    Scores(1) = Worksheets("Sheet1").Cells(3, "D").Value
    Scores(2) = Worksheets("Sheet1").Cells(4, "D").Value
    Scores(3) = Worksheets("Sheet1").Cells(5, "D").Value
    Scores(4) = Worksheets("Sheet1").Cells(6, "D").Value
    Scores(5) = Worksheets("Sheet1").Cells(7, "D").Value
    Scores(6) = Worksheets("Sheet1").Cells(8, "D").Value
    Scores(7) = Worksheets("Sheet1").Cells(9, "D").Value
        For x = 0 To Scores(7)
            TotalScore = TotalScore + Scores(x)
        Next x
        TargetScore = Int(TotalScore / 2)
        InitialScoreDifference = (TotalScore)
        Console.WriteLine (TotalScore)
        Console.WriteLine (TargetScore)
        Console.WriteLine (InitialScoreDifference)
        For a = 0 To Scores(7)
            For b = 0 To Scores(7)
                For c = 0 To Scores(7)
                    For d = 0 To Scores(7)
                        CurrentScore = (Scores(a) + Scores(b) + Scores(c) + Scores(d))
                        ScoreDifference = ((TargetScore - CurrentScore) * (TargetScore - CurrentScore))
                        If ScoreDifference <= InitialScoreDifference Then

                            If ((Scores(a) <> Scores(b)) And (Scores(a) <> Scores(c)) And (Scores(a) <> Scores(d)) And (Scores(b) <> Scores(c)) And (Scores(b) <> Scores(d)) And (Scores(c) <> Scores(d))) Then
                                InitialScoreDifference = ScoreDifference
                                Console.WriteLine (Scores(a) & " " & Scores(b) & " " & Scores(c) & " " & Scores(d) & " " & ScoreDifference)
                            End If
                        End If
                    Next d
                Next c
            Next b
        Next a
  End Sub

當我在視覺工作室上運行代碼時,它可以很好地工作,並為我提供4個贏/負得分的組合,這將平衡團隊。 但是,當我在excel vba上運行它時,我總是得到:運行時錯誤“ 9”下標超出范圍

最后,我意識到即時通訊所使用的算法效率很低,我應該對這種東西使用遞歸算法,但是我並沒有真正理解遞歸,所以這是下一個最好的選擇

感謝您抽出寶貴的時間閱讀本文

在VBA中你不能寫

Console.WriteLine (TotalScore)

改寫

Debug.Print TotalScore

您還應該聲明Long而不是Integer以避免溢出,將Option Explicit放在模塊頂部,並聲明所有變量,例如

我認為您正在遍歷整個數組,最好避免硬編碼邊界,​​因為將來您可能會增加數組的大小,因此,假設當前ActiveWorkbook中有一個名為“ Sheet1”的工作表,可能會更好:

Option Explicit

Public Sub Main()
    Dim TotalScore As Long
    Dim TargetScore As Long
    Dim CurrentScore As Long
    Dim InitialScoreDifference As Long
    Dim ScoreDifference As Long

    TotalScore = 0
    TargetScore = 0
    CurrentScore = 0
    InitialScoreDifference = 0
    ScoreDifference = 0

    Dim Scores(0 To 7) As Long
    Scores(0) = Worksheets("Sheet1").Cells(2, "D").Value
    Scores(1) = Worksheets("Sheet1").Cells(3, "D").Value
    Scores(2) = Worksheets("Sheet1").Cells(4, "D").Value
    Scores(3) = Worksheets("Sheet1").Cells(5, "D").Value
    Scores(4) = Worksheets("Sheet1").Cells(6, "D").Value
    Scores(5) = Worksheets("Sheet1").Cells(7, "D").Value
    Scores(6) = Worksheets("Sheet1").Cells(8, "D").Value
    Scores(7) = Worksheets("Sheet1").Cells(9, "D").Value

    Dim x As Long

    For x = LBound(Scores) To UBound(Scores)
        TotalScore = TotalScore + Scores(x)
    Next x

    TargetScore = CLng(TotalScore / 2)
    InitialScoreDifference = (TotalScore)

    Debug.Print "TotalScore: " & TotalScore
    Debug.Print "TargetScore: " & TargetScore
    Debug.Print "InitialScoreDifference: " & InitialScoreDifference

    Dim a As Long, b As Long, c As Long, d As Long

    For a = LBound(Scores) To UBound(Scores)
        For b = LBound(Scores) To UBound(Scores)
            For c = LBound(Scores) To UBound(Scores)
                For d = LBound(Scores) To UBound(Scores)
                    CurrentScore = (Scores(a) + Scores(b) + Scores(c) + Scores(d))
                    ScoreDifference = (TargetScore - CurrentScore) * (TargetScore - CurrentScore)
                    If ScoreDifference <= InitialScoreDifference Then
                        If ((Scores(a) <> Scores(b)) And (Scores(a) <> Scores(c)) And (Scores(a) <> Scores(d)) And (Scores(b) <> Scores(c)) And (Scores(b) <> Scores(d)) And (Scores(c) <> Scores(d))) Then
                            InitialScoreDifference = ScoreDifference
                            Debug.Print (Scores(a) & " " & Scores(b) & " " & Scores(c) & " " & Scores(d) & " " & ScoreDifference)
                        End If
                    End If
                Next d
            Next c
        Next b
    Next a
End Sub
  1. Console.WriteLine是VB.Net語法。 對於VBA,它是像QHarr建議的Debug.Print
  2. 在VB.Net中, Integer可以保存帶符號的32位(4字節)整數,其值的范圍從2,147,483,6482,147,483,647 在VBA中, Integer可以保存從32,76832,767值。 因此,建議在VBA中使用Long
  3. 無需聲明數組並手動填充它。 聲明一個Variant並在運行時填充數組。 例如

     Dim Scores(0 To 7) As Long Scores(0) = Worksheets("Sheet1").Cells(2, "D").Value Scores(1) = Worksheets("Sheet1").Cells(3, "D").Value Scores(2) = Worksheets("Sheet1").Cells(4, "D").Value Scores(3) = Worksheets("Sheet1").Cells(5, "D").Value Scores(4) = Worksheets("Sheet1").Cells(6, "D").Value Scores(5) = Worksheets("Sheet1").Cells(7, "D").Value Scores(6) = Worksheets("Sheet1").Cells(8, "D").Value Scores(7) = Worksheets("Sheet1").Cells(9, "D").Value 

    可以寫成

     Dim Scores As Variant Scores = Worksheets("Sheet1").Range("D2:D9").Value 

    然后您可以將它們用作

     CurrentScore = (Scores(a, 1) + Scores(b, 1) + Scores(c, 1) + Scores(d, 1)) 
  4. 要找到總和,同樣也不需要遍歷數組,您可以使用Application.Evaluate直接找到范圍的總和。 例如

     TotalScore = Application.Evaluate("=SUM(Sheet1!D2:D9)") 

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM