0

次の「フィールド」(列のすべてのフィールド、B から G) を持つポイントのリストがあります。

ポイント名(B)、東距(C)、北距(D)、測量員(E)、測量日(F)、測量方法(G)

ユーザーは、
調査クルー (H2)
調査日 (I2)
調査方法 (J2)
ライン (H4) ポイントの名前の最初の部分
開始 (I4)
終了 (J4)を入力する必要があります。

そして私が欲しい:
-ポイントが存在するかどうかを確認する
-ポイントが存在し、「フィールド」が空の場合、ユーザーが特定のセルに
入力する必要がある情報を入力します-表示する情報を取得するためにセルが既に入力されている場合他のいくつかのセル
では、これらのコード行に到達しましたが、動作しますが、チェック プロセスに時間がかかりすぎます。

誰かがそれをより速く行う方法を理解するのを手伝ってくれますか? チェックが実行されるたびに時間がかかりすぎるためです。

私はこれがあまり得意ではありません。もっと速い方法があると思います。コメントや提案は大歓迎です

    Sub CheckProd()
    Dim FR1, Bin, Track, Min, MinBin, Max, MaxBin, Tre As Integer
    Bin = 10 ^ Range("O2").Value
    Track = Range("H4").Value 'Input value (first part of the point name)
    MinBin = Range("I4").Value ' Input Value (second part of the point name - Start)
    MaxBin = Range("J4").Value ' Input Value (second part of the point name - End)
    If MaxBin > MinBin Then ' calculates first and last point to update
        Min = Bin * Track + MinBin
        Max = Bin * Track + MaxBin
        Else
        Min = Bin * Track + MaxBin
        Max = Bin * Track + MinBin
    End If
    Tre = Max - Min + 1 'Counts number of points to update
    FR1 = Range("B65536").End(xlUp).Row 'Counts total design points points
    Range("K2:M65536").ClearContents
    Check = Min - 1
    For i = 1 To Tre
        Check = Check + 1
        Find = False
        For J = 2 To FR1
            Station = Cells(J, "B").Value
            datte = Cells(J, "F").Value
            If (Check = Station) Then
                Find = True
                If IsEmpty(Cells(J, "F")) Then
                    Cells(J, "E").Value = Cells(2, "H").Value 'Updates Crew number
                    Cells(J, "F").Value = Cells(2, "I").Value 'Updates Survey Date
                    Cells(J, "G").Value = Cells(2, "J").Value 'Updates Survey Method
                Else
                    FRL = Range("K65536").End(xlUp).Row
                    Cells(FRL + 1, "K").Value = Station 'Shows the point already reported
                    Cells(FRL + 1, "L").Value = "Reportado" 'Shows the status "Reported"
                    Cells(FRL + 1, "M").Value = datte ' Shows the date when the point was reported
                End If
            End If
            If ((J = FR1) And (Not Find)) Then
                FRM = Range("K65536").End(xlUp).Row
                Cells(FRM + 1, "K").Value = Check 'Shows the point without design coordinates
                Cells(FRM + 1, "L").Value = "No Preplot" 'Shows the status "No Preplot"
            End If
            If (Find) Then J = FR1
        Next J
    Next i
End Sub
4

1 に答える 1

2

For ループまでのすべてが等しくなり、すべてが超高速になります。明らかに、スピード ヒットは二重の For ループにあります。

   For i = 1 To Tre
        Check = Check + 1
        Find = False
        For J = 2 To FR1
              'performance problem happens here...
        Next J
    Next i

コードはめちゃくちゃ悪いわけではありません。

しかし、ルックアップを行って大量のデータを移動していることは明らかです。長いループでこれを何度も行うのは良くありません。基本的に、多数の反復を移動することは、個々のセルの値を常に調べてほとんどメリットがありません (つまり、3 つの値を検索するため)。

代わりに、この「検索アルゴ」を、Cells(J, "B").Value の値を使用して Cells(2, "H") の 3 つの値を見つける VLookup() または Index(Match()) 関数に置き換えることを検討してください。 .Value, Cells(2, "I").Value および Cells(2, "J").Value.

コードを使用するさらに優れた方法は、最初にすべての値を配列に読み込むことです。これを行うには、まずデータを配列にロードします。これで、Excel との対話に時間を無駄にすることはなくなりました。

Dim arr()
arr = Range("H2:J666").Value2

この配列を処理するために「検索アルゴ」を書き直してください。そのためには、For ループを再構築して、変数 arr の要素と次元を反復処理します。すなわち

For rowCount = 0 to 664
   For columnCount = 0 to 2
       If arr(rowCount, columnCount) = CheckValue(GetStationValue(station)) Then
             ' we have found the correct set of values
             Range("E" & J).Value = arr(rowCount,columnCount)
             Range("F" & J).Value = arr(rowCount,columnCount)
             Range("G" & J).Value = arr(rowCount,columnCount)
        Else
              ' do other update of data
        End If
    Next
Next

' ここで、GetStation 値は、元のステーション変数値に基づいて動的な「ステーション」値を取得するための別の関数であり (この値を更新する必要がある場合はグローバル変数を使用します)、CheckValue はこれを使用しているチェックサムと比較します.

お役に立てれば。

于 2013-05-31T00:05:06.993 に答える