Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 11 Pro : Excel 2021)
表示速度が遅い
投稿日時: 22/07/29 16:18:07
投稿者: isoka

この度、配列をシートへ表示する速度が大変遅いのですがどこが悪いのか分からないのでアドバイスをお願いします。データ数は500程度です
 
簡単なマクロですと瞬時に表示されると思うのですが、丸いマークが出て処理中の時間が思った以上にかかってしまいます。
 
Public Sub 時系列の書き込み()
     
    Dim TV() As My_Data
    Dim Code As String
    Dim Datasu As Long
     
    '描画停止
    Application.ScreenUpdating = False
    '再計算停止
    Application.Calculation = xlCalculationManual
     
    ここでCSVから配列TV()へ読み込む処理をしています(これは瞬時に住みます)
  
  '時系列シートへ書込
    Call 時系列シートへ書込(TV(), Datasu)
  
End Sub
 
Private Sub 時系列シートへ書込(TV() As My_Data, Datasu As Long)
 
    Dim i As Integer, j As Integer
    Dim Ws As Worksheet
         
    Set Ws = ThisWorkbook.Worksheets("時系列") 'アクティブなシート名を取得
    j = 6
    With Ws
        For i = 1 To Datasu
            .Cells(j, 13) = TV(i).Date
            .Cells(j, 14) = TV(i).Open
            .Cells(j, 15) = TV(i).High
            .Cells(j, 16) = TV(i).Low
            .Cells(j, 17) = TV(i).Close
            .Cells(j, 18) = TV(i).UpTrend
            .Cells(j, 19) = TV(i).DownTrend
            .Cells(j, 20) = TV(i).EMA5
            .Cells(j, 22) = TV(i).EMA20
            .Cells(j, 24) = TV(i).EMA40
            .Cells(j, 26) = TV(i).EMA200
            .Cells(j, 28) = TV(i).Stage
            .Cells(j, 29) = TV(i).Volume
            .Cells(j, 30) = TV(i).Volume
            .Cells(j, 31) = TV(i).Stocha40
            .Cells(j, 33) = TV(i).Stocha20
            .Cells(j, 35) = TV(i).Stocha
            .Cells(j, 36) = TV(i).Hist
            .Cells(j, 37) = TV(i).MacNorm
            .Cells(j, 39) = TV(i).Trigger
            .Cells(j, 41) = TV(i).GC
            .Cells(j, 42) = TV(i).DC
            .Cells(j, 43) = TV(i).ATR
            .Cells(j, 44) = TV(i).Mom_PD
            .Cells(j, 45) = TV(i).Mom_PU
            .Cells(j, 46) = TV(i).Mom
            .Cells(j, 47) = TV(i).Highest
            .Cells(j, 48) = TV(i).Lowest
            .Cells(j, 49) = TV(i).Mom_O
            j = j + 1
        Next i
    End With
End Sub
 

回答
投稿日時: 22/07/29 16:22:51
投稿者: simple

もう一度フラットな二次元配列に書き込んで、
それをシートに一括して書き込むとよいのではないですか?
セルにひとつづつ書き込むことが速度低下の要因ですから。

投稿日時: 22/07/29 16:32:30
投稿者: isoka

早速の返信ありがとうございます。
 
2次元配列について、配列をあまりよくわからないのですが、一括で書き込む参考マクロを簡単でよいので教えてください。

回答
投稿日時: 22/07/29 17:42:59
投稿者: WinArrow
投稿者のウェブサイトに移動

参考コード
ものすごく簡単な例
 
Sheets("Sheet1")のA5:H100 をSheets("Sheet2")のG10〜の同範囲に値複写する
 

Sub TEST()
Dim data

    With ActiveWorkbook
        data = Sheets("Sheet1").Range("A5:H100").Value
        Sheets("Sheet2").Range("G10").Resize(UBound(data), UBound(data, 2)).Value = data
    End With

End Sub

投稿日時: 22/07/29 18:42:31
投稿者: isoka

返信ありがとうございます。
 
これでは、CSVファイルから配列へ読み込んだデータを使えません。
 
シート間の転記になると思うのですが?

回答
投稿日時: 22/07/29 19:08:09
投稿者: taitani

CSV も Excelで起動 (表示) できますよね?
 
"ここでCSVから配列TV()へ読み込む処理をしています(これは瞬時に住みます)"
 
ここの Code が大事だと思いますが。。。

回答
投稿日時: 22/07/29 20:14:59
投稿者: simple

こういうことでしょうかね。動作確認はできませんが。
 

Private Sub 時系列シートへ書込(TV() As My_Data, Datasu As Long)
    Dim i As Long, j As Long
    Dim Ws As Worksheet
    
    ReDim mat(6 To Datasu, 13 To 49) As Variant
             
    Set Ws = ThisWorkbook.Worksheets("時系列")
    j = 6
    With Ws
        For i = 1 To Datasu
            mat(j, 13) = TV(i).Date
            mat(j, 14) = TV(i).Open
            mat(j, 15) = TV(i).High
            mat(j, 16) = TV(i).Low
            mat(j, 17) = TV(i).Close
            mat(j, 18) = TV(i).UpTrend
            mat(j, 19) = TV(i).DownTrend
            mat(j, 20) = TV(i).EMA5
            mat(j, 22) = TV(i).EMA20
            mat(j, 24) = TV(i).EMA40
            mat(j, 26) = TV(i).EMA200
            mat(j, 28) = TV(i).Stage
            mat(j, 29) = TV(i).Volume
            mat(j, 30) = TV(i).Volume
            mat(j, 31) = TV(i).Stocha40
            mat(j, 33) = TV(i).Stocha20
            mat(j, 35) = TV(i).Stocha
            mat(j, 36) = TV(i).Hist
            mat(j, 37) = TV(i).MacNorm
            mat(j, 39) = TV(i).Trigger
            mat(j, 41) = TV(i).GC
            mat(j, 42) = TV(i).DC
            mat(j, 43) = TV(i).ATR
            mat(j, 44) = TV(i).Mom_PD
            mat(j, 45) = TV(i).Mom_PU
            mat(j, 46) = TV(i).Mom
            mat(j, 47) = TV(i).Highest
            mat(j, 48) = TV(i).Lowest
            mat(j, 49) = TV(i).Mom_O
            j = j + 1
        Next i
        
        .Cells(6, 13).Resize(UBound(mat, 1) - LBound(mat, 1) + 1, _
                             UBound(mat, 2) - LBound(mat, 2) + 1) = mat
    End With
End Sub

回答
投稿日時: 22/07/29 20:40:11
投稿者: simple

コードに忠実に手をいれましたが、
from scratchで書くなら、以下のようにするでしょうね。

Redim mat(1 To Datasu, 1 To 37) As Variant
という変数宣言、
For i = 1 To Datasu
    mat(i, 1) = TV(i).Date
    mat(i, 2) = TV(i).Open
    mat(i, 3) = TV(i).High
    mat(i, 4) = TV(i).Low
    mat(i, 5) = TV(i).Close
    ・・・・・
Next    
とし、
書き込むところは、
ws.Cells(6,13).Resize(Datasu,37) = mat

投稿日時: 22/07/29 23:05:41
投稿者: isoka

ありがとうございました。
 
最後の参考コードを使わせて頂きました。
 
2次元変数へ一旦入れて、書き込みを実行する考えがありませんでした。
 
これは、勉強になりました。