Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


9498 / 13646 ツリー ←次へ | 前へ→

【26858】VBA処理速度向上のアドバイス求む! yuki 05/7/21(木) 15:27 質問[未読]
【26859】Re:VBA処理速度向上のアドバイス求む! IROC 05/7/21(木) 15:51 回答[未読]
【26860】Re:VBA処理速度向上のアドバイス求む! yuki 05/7/21(木) 15:59 質問[未読]
【26861】Re:VBA処理速度向上のアドバイス求む! IROC 05/7/21(木) 16:51 回答[未読]
【26862】Re:VBA処理速度向上のアドバイス求む! yuki 05/7/21(木) 17:01 お礼[未読]
【26863】Re:VBA処理速度向上のアドバイス求む! Jaka 05/7/21(木) 17:34 発言[未読]
【26864】Re:VBA処理速度向上のアドバイス求む! yuki 05/7/21(木) 17:49 お礼[未読]
【27007】Re:VBA処理速度向上のアドバイス求む! yuki 05/7/26(火) 13:41 お礼[未読]

【26858】VBA処理速度向上のアドバイス求む!
質問  yuki  - 05/7/21(木) 15:27 -

引用なし
パスワード
   処理速度向上につき、アドバイスを頂きたく、投稿致しました。

下記のロジックの改善点にお気づきの方は、どんなことでも良いので
ご教示頂けると幸いです。

※integer より long が良いのは学びました。

下記は、シートAにある値を、シートBの適切なセルに表示させるもので
シートAを参照する式を埋め込むことで、シートBに値をコピーしています。

入り組んでいて分かり辛いのですが、ループ、分岐、変数の使い方などが
キーになると思ったので、なるべくそのままのコードを記載しました。

◎実際の処理では、下記のようなロジックが10個くらい連なります。

【シートAの特徴】
CSVから読み込んだデータが貼り付いていて、各列、行に名前をつけています。
(例)列名 <10列分> _1 〜 _10 
   行名 <50行分> PHNYL1 〜 PHNYL50

【処理概要】
シートBの"HNY_INPUT_FLAG"と名前がついている列に'1'が入力されている行に
シートAの値を適宜セットしていく。

※シートBの"HNY_INPUT_FLAG"列+3の列に'1'が入力されている行数
=シートAの行数(ここでは50。)

-----------

Public Const INT_HNY_START_ROW As Integer = 5   
Public Const INT_HNY_END_ROW As Integer = 55

Dim intRow As Integer
Dim intInputFlagCol As Integer

  intInputFlagCol = Range("HNY_INPUT_FLAG").Column '入力可能な項目(行)フラグが設定されている列
  i = 1

  For intRow = INT_HNY_START_ROW To INT_HNY_END_ROW Step 1
  
   If Cells(intRow, intInputFlagCol + 3).Value = "1" Then  'iのカウントアップ用Ifブロック

    If Cells(intRow, intInputFlagCol).Value = "1" Then
    
      k = 10
      '前回値を保持するシートを参照する式をセット
      For j = 1 To 10
        Cells(intRow, INT_HNY_PRJSTART_COL - 1 + j).Formula _
        = "=PHNYL" & i & " _" & k
        
        k = k - 1
      Next
      
      '式ではなく値のみ表示するよう設定
      Range(Cells(intRow, INT_HNY_PRJSTART_COL), _
          Cells(intRow, INT_HNY_PRJSTART_COL + 9)).Copy
      Range(Cells(intRow, INT_HNY_PRJSTART_COL), _
          Cells(intRow, INT_HNY_PRJSTART_COL + 9)).PasteSpecial Paste:=xlValues
      Application.CutCopyMode = False
    End If
    
    i = i + 1
   End If
  Next

【26859】Re:VBA処理速度向上のアドバイス求む!
回答  IROC  - 05/7/21(木) 15:51 -

引用なし
パスワード
   配列を利用しては如何ですか?

【26860】Re:VBA処理速度向上のアドバイス求む!
質問  yuki  - 05/7/21(木) 15:59 -

引用なし
パスワード
   ▼IROC さん:
>配列を利用しては如何ですか?

早速、アドバイス、どうも有難うございます。

配列の利用も、自分なりに検討してみたのですが
このロジックのどこで活用出来るのか分かりませんでした…。
コピー&ペーストも分岐があったりして、固まりで行えていない
(と思いこんでるだけかも知れませんが・・)
二次元配列を使用する案が浮かばないのです。

お手数ですが、もう少しアドバイス頂けますでしょうか?
どうぞ宜しくお願い致します。

【26861】Re:VBA処理速度向上のアドバイス求む!
回答  IROC  - 05/7/21(木) 16:51 -

引用なし
パスワード
   名前が定義されている列がどこか分かりませんが、
シート上のデータ領域のセル範囲を二次元配列に見立てて処理し、
最後に配列からセルに出力すれば、処理速度が向上すると思います。

シートごとの必要なデータを配列に格納し、
シート(セル)の代わりに、すべて配列で処理する感じです。

【26862】Re:VBA処理速度向上のアドバイス求む!
お礼  yuki  - 05/7/21(木) 17:01 -

引用なし
パスワード
   !理解しました。早速実験して、また報告(or質問…)させて頂きます!

迅速なご返信に本当に、感謝致します。

【26863】Re:VBA処理速度向上のアドバイス求む!
発言  Jaka  - 05/7/21(木) 17:34 -

引用なし
パスワード
   こんにちは。

>'前回値を保持するシートを参照する式をセット
これが全く解ってませんが..。
解ってないのでほとんど途中ですが、オートフィルタを使ったらどうですか。


  With Range("HNY_INPUT_FLAG")
     With Range(.Cells(1), .Cells(65535).End(xlUp))
       .AutoFilter Field:=1, Criteria1:="1"
       With .Resize(.Rows.Count - 1).Offset(1, 1).SpecialCells(xlCellTypeVisible)
         '.Formula = "=INDIRECT(""PHNYL"" & Row() - 5 & "" _"" & k)"
          上は試行錯誤中、INDIRECTとRow()関数でうまく行くと思うんですが、内容が良く解ってない。
         .Value = .Value
       End With
     End With
  End With
  ActiveSheet.AutoFilterMode = False

【26864】Re:VBA処理速度向上のアドバイス求む!
お礼  yuki  - 05/7/21(木) 17:49 -

引用なし
パスワード
   ▼Jaka さん:
>>'前回値を保持するシートを参照する式をセット
>これが全く解ってませんが..。
>解ってないのでほとんど途中ですが、オートフィルタを使ったらどうですか。

このコメントは業務の内容のまま記載してました。申し訳ありません。

>>'前回値を保持するシートを参照する式をセット
⇒シートAの値を参照する式をセット

と読み替えて頂ければ、一応意味合いは同じになります。

オートフィルタも利用経験がないので、参考にさせて頂きます。
どうも有難うございます。

【27007】Re:VBA処理速度向上のアドバイス求む!
お礼  yuki  - 05/7/26(火) 13:41 -

引用なし
パスワード
   最終的に、以下のようなソースにしたら、5割以上の減速になりました。
−配列を使う
−With を使って、Select をしない
−カウント処理用変数を integer -> long に。

どうも有難うございました。
-----------

Public Const INT_HNY_START_ROW As Integer = 5   
Public Const INT_HNY_END_ROW As Integer = 55

Dim intRow As Integer
Dim intInputFlagCol As Integer

★ Dim vntAryInputData As Variant

★ With Worksheets("シートA")  '▼▼▼


  intInputFlagCol = .Range("HNY_INPUT_FLAG").Column '入力可能な項目(行)フラグが設定されている列
  i = 1

  'INPUTシートのデータを配列に読込
★  With Worksheets("INPUT")
★    vntAryInputData = .Range(.Cells(.Range("PHNYL1").Row, 2), .Cells(.Range("PHNYL53").Row, 15))
★  End With

  For intRow = INT_HNY_START_ROW To INT_HNY_END_ROW Step 1
  
   If .Cells(intRow, intInputFlagCol + 3).Value = "1" Then  'iのカウントアップ用Ifブロック

    If .Cells(intRow, intInputFlagCol).Value = "1" Then
    
      k = 10
      For j = 1 To 10
★       .Cells(intRow, INT_HNY_PRJSTART_COL - 1 + j).Value = vntAryInputData(i, k)
        k = k - 1
      Next
      
    End If
    
    i = i + 1
   End If
  Next

  End With  '▲▲▲

9498 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free