2021年11月15日月曜日

EXCEL のフィルタ作業をvbaにしてみた。でも、currentRegionの分断で、データ破壊してしまったのは、空白列のせいだった。

 EXCELのフィルタ作業をvbaにしてみた。参考にしたのはtanakaさんのvbaページhttp://officetanaka.net/excel/vba/tips/tips155d.htm

 EXCELに様々な条件でフィルターを掛け、絞り込みつつ、色々なセルに値を設定していく。そうすることで、我々の仕事が進む。そんな作業を自動化するにはvbaが一番だ。





Dim R As range
With Range("A1")
  .Autofilter 5,"="
  .Autofilter 3,array("<60","="),xlFilterValues
  If WorksheetFunction.Subtotal(3,Range("A:A")) > 1 then
    With Range("A1").CurrentRegion.Offset(1,0) 
      For Each R in .Resize(.Rows.Count-1).SpecialCells(xlCellTypeVisible).Rows
        R.Range("E1").Value = "C"
      Next R
    End With
  End If
End with

 でも、これだと、CurrentRegionが空白列或いは空白行でいくつかに分断されている(今回は、空白列で分断)と、その塊の単位でCurrentRegionの列なり、行なり(今回は行)を検出するため、意図していないCellにも、得点が60点以下でもないのに、"C"が設定されてしまい、表(データ)破壊をきたしてしまった(下図)。















 

 これはキツいな。そこで、R.Columnが1(A列、つまり、最初のCurrentRegionであるときのみ、得点が60点以下ならば、”C”を設定するようにしてみた。つまり、この    R.Columnが1(つまり、A列だね)のところがミソなのだ。図はEXCELでなく、OpenOfficeなのは、気にしないでね。

Dim R As range
With Range("A1")
  .Autofilter 5,"="
  .Autofilter 3,array("<60","="),xlFilterValues
  If WorksheetFunction.Subtotal(3,Range("A:A")) > 1 then
    With Range("A1").CurrentRegion.Offset(1,0) 
      For Each R in .Resize(.Rows.Count-1).SpecialCells(xlCellTypeVisible).Rows
        If R.Column = 1 then
          R.Range("E1").Value = "C"
        End If
      Next R
    End With
  End If
End with

 これでいいんじゃないのかな?なぜ、CurrentRegionが分断されていると気がつくことができたか?それは、破壊されたセルの規則性と壊れた内容からの類推。そこで、先ほどのrのアドレスを出してみた。Debug.Print r.addressをイミディエートウィンドウで表示すると、複数のエリアに分割されていたのがわかったのだった。

0 件のコメント:

コメントを投稿