1

私はVBAに非常に慣れていません。ベクトルの中央値を計算しようとしました。次のコードは、「End if なしでブロックする」という警告を受け取り続けます。「End IF」の場所を変えてみたのですが、「Block end if without if」という別の警告が出てしまいました。ご意見をお待ちしております。ありがとう。

Sub CalculateMedian()

    DoCmd.SetWarnings False

    Dim db As DAO.Database
    Dim onet As DAO.Recordset

    Dim Ocode As String
    Dim ag As DAO.Recordset
    Dim agMedian As Integer

    Set db = CurrentDb

    'select one variable in current database
    Set onet = db.OpenRecordset("SELECT DISTINCT ONetCode FROM Single WHERE LEN(ONetCode)>8")

    Do While Not onet.EOF

        'assigning value to a variable does not need a "SET"
        Ocode = onet.Fields("ONetCode")
        'any data meet the criterion--&Ocode& can vary
        Set ag = db.OpenRecordset("SELECT AG FROM Single WHERE ONetCode='" & Ocode & "' ORDER BY AG")

        'using .recordcount needs to use .movelast first
        ag.MoveLast
        ag.MoveFirst
        If ag.RecordCount Mod 2 = 1 Then
            agMedian = ((ag.RecordCount + 1) / 2)
            thecount = 0
            Do While Not ag.EOF
                thecount = thecount + 1
                If thecount = agMedian Then
                    'inset the result into a new table, and need to create a new table in advance
                    DoCmd.RunSQL ("INSERT INTO PCImedian(onetcode, agMedian) VALUES('" & Ocode & "'," & ag("AG") & ");")
                    Exit Do
        End If

       If ag.RecordCount Mod 2 = 0 Then
            agMedian = ag.RecordCount / 2
            thecount = 0
            Do While Not ag.EOF
                thecount = thecount + 1
                If thecount = agMedian Then
                    m1 = ag("AG")
                ElseIf thecount = agMedian + 1 Then
                    m2 = ag("AG")
                    DoCmd.RunSQL ("INSERT INTO PCImedian(onetcode, agMedian) VALUES('" & Ocode & "'," & ((m1 + m2) / 2) & ");")
                    Exit Do
        End If

    Loop

    DoCmd.SetWarnings True

End Sub
4

2 に答える 2

1

コードの最初のブロックで exit の後に do を実行すると、終了が欠落しているように見えます。そこには 2 つあるはずです。1 つは最後の if ステートメントを閉じるためのもので、もう 1 つは最初のブロックを閉じるためのものです。

Sub CalculateMedian()

    DoCmd.SetWarnings False

    Dim db As DAO.Database
    Dim onet As DAO.Recordset

    Dim Ocode As String
    Dim ag As DAO.Recordset
    Dim agMedian As Integer

    Set db = CurrentDb

    'select one variable in current database
    Set onet = db.OpenRecordset("SELECT DISTINCT ONetCode FROM Single WHERE LEN(ONetCode)>8")

    Do While Not onet.EOF

        'assigning value to a variable does not need a "SET"
        Ocode = onet.Fields("ONetCode")
        'any data meet the criterion--&Ocode& can vary
        Set ag = db.OpenRecordset("SELECT AG FROM Single WHERE ONetCode='" & Ocode & "' ORDER BY AG")

        'using .recordcount needs to use .movelast first
        ag.MoveLast
        ag.MoveFirst
        If ag.RecordCount Mod 2 = 1 Then
            agMedian = ((ag.RecordCount + 1) / 2)
            thecount = 0
            Do While Not ag.EOF
                thecount = thecount + 1
                If thecount = agMedian Then
                    'inset the result into a new table, and need to create a new table in advance
                    DoCmd.RunSQL ("INSERT INTO PCImedian(onetcode, agMedian) VALUES('" & Ocode & "'," & ag("AG") & ");")


                   End If 'ends the If thecount = agMedian if statement -- will continue to iterate until EOF

                    Exit Do 'EOF hit.


        End If 'ends the If ag.RecordCount Mod 2 = 1 block

       If ag.RecordCount Mod 2 = 0 Then
            agMedian = ag.RecordCount / 2
            thecount = 0
            Do While Not ag.EOF
                thecount = thecount + 1
                If thecount = agMedian Then
                    m1 = ag("AG")
                ElseIf thecount = agMedian + 1 Then
                    m2 = ag("AG")
                    DoCmd.RunSQL ("INSERT INTO PCImedian(onetcode, agMedian) VALUES('" & Ocode & "'," & ((m1 + m2) / 2) & ");")
                    Exit Do
        End If 'thecount = agMedian if statement
        End If 'end ag.RecordCount Mod 2 = 0

    Loop

    DoCmd.SetWarnings True

End Sub
于 2013-08-16T17:00:38.713 に答える
1

コードに複数の がありませんでしたEnd IfLoopまた、欠落しているステートメント が 2 つあります。

コードが複雑すぎてブロック終了ステートメントを整理するのが難しくなった場合は、プロシージャーのコピーを作成し、基本的にブロック制御ステートメント以外のすべてを破棄します。そのメソッドは、現在のコードからこれを残します。

    Do While Not onet.EOF
        If ag.RecordCount Mod 2 = 1 Then
            Do While Not ag.EOF
                If thecount = agMedian Then
        End If
        If ag.RecordCount Mod 2 = 0 Then
            Do While Not ag.EOF
                If thecount = agMedian Then
                ElseIf thecount = agMedian + 1 Then
        End If
    Loop

そして、代わりに何が必要かについての私の最善の推測は次のとおりです。それらを適切に照合するのに役立つため、これらのステートメントのいくつかにコメントを追加しました。

    Do While Not onet.EOF
        If ag.RecordCount Mod 2 = 1 Then
            Do While Not ag.EOF
                If thecount = agMedian Then
                End If ' thecount
            Loop ' Not ag.EOF
        End If ' ag.RecordCount Mod 2 = 1
        If ag.RecordCount Mod 2 = 0 Then
            Do While Not ag.EOF
                If thecount = agMedian Then
                ElseIf thecount = agMedian + 1 Then
                End If ' thecount
            Loop ' Not ag.EOF
        End If ' ag.RecordCount Mod 2 = 0
    Loop ' Not onet.EOF
于 2013-08-16T21:08:43.457 に答える