[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『オートフィルタの可視セルのみ移動しコピペしたい』(バーバラ) エクセル2007、WinXPです。 また、お世話になります。 A1:B10に次のようなリストがあります。 項目1 項目2 X1 0 X2 0 X3 10 X4 0 X5 0 X6 5 X7 0 X8 4 X9 3
これについて、B列で0以外を表示でオートフィルタかけます。 項目1 項目2 X3 10 X6 5 X8 4 X9 3
この状態で、B列を上から順に値をコピーして、3列右のセルにコピーする というマクロを作成したいと考えています。 ここで、オートフィルタかけたセルのみを動く、というところを どのように書けばいいのかご教授いただけないでしょうか。
>3列右のセルにコピーする つまり、E列?
要件誤解してたスルーを。 エラーチェックはしていない。
Sub Sample() Intersect(ActiveSheet.AutoFilter.Range, ActiveSheet.AutoFilter.Range.Offset(1)).Columns(2).SpecialCells(xlCellTypeVisible).Copy ActiveSheet.AutoFilterMode = False Range("E2").Select ActiveSheet.Paste Application.CutCopyMode = False End Sub
↑ あぁ、きっと勘違いだ。 もとの行と同じ行にという意味だよね。(追記)
ぶらっと立ち寄り
きっと、こっちだ。
Sub Sample2() Dim r1 As Range Dim r2 As Range Dim c As Range Set r1 = Intersect(ActiveSheet.AutoFilter.Range, ActiveSheet.AutoFilter.Range.Offset(1)).Columns(2).SpecialCells(xlCellTypeVisible) For Each r2 In r1.Areas For Each c In r2 c.Offset(, 3).Value = c.Value Next Next Set r1 = Nothing Set r2 = Nothing End Sub
ぶらっと立ち寄り@もう寝るべ
朝起きて見直したら以下でもよかった。睡魔がある状態でコード書いちゃいけないね。
Sub Sample3() Dim r1 As Range Dim c As Range Set r1 = Intersect(ActiveSheet.AutoFilter.Range, ActiveSheet.AutoFilter.Range.Offset(1)).Columns(2).SpecialCells(xlCellTypeVisible) For Each c In r1 c.Offset(, 3).Value = c.Value Next Set r1 = Nothing End Sub
ぶらっと立ち寄り
ぶらっと立ち寄りさん 確認しました。思い通りに動きました。ありがとうございました。 思った以上にすっきりしていて驚きました。 Sample3について初めて出てくるコードが多く、わからないことだらけなので、 教えていただきたいです。
1.Offset(1)は、今回の例だとOffset(1,0)を意味するようです。 理由は、Offset(1,0)に書き換えたらうまくいきましたが、 Offset(0,1)に書き換えたらうまくいかなかったため、そう判断しました。 なぜ、引数を省略しているのに、エクセルがOffset(0,1)と認識しないのでしょうか。 基本的な私の認識が間違っていますか?
2.Intersectメソッドは、2つの範囲が共有している範囲を返す、ようです。
引数のうち、ActiveSheet.AutoFilter.Rangeは、オートフィルタ状態の可視セルA1:B10を指定し、 ActiveSheet.AutoFilter.Range.Offset(1)は、オートフィルタ状態の可視セルA4:B11を指定する。 各々共有する可視セルA4:B10のうち、2列目(B列)のセルを上から順番に、3列右のセルに コピーする、コードという理解でよろしいでしょうか。 (バーバラ)
以下メモ。
セル領域.Offset(0から始まる行変位,0から始まる列変位) で列変位、行変位は省略可能。省略時の解釈値は 0 。 Offset(n) は列変位が省略されている形、Offset(,n) は行変位が省略されている形。 今回のOffset(1) は、2番目の引数「列変位」が省略されているので Offset(1,0) とみなされる。
Intersect(領域1,領域2,領域3,・・・・・) と、任意の数の領域の指定が可能。 実際には、2つの領域のANDをとるために使用されることが多い。 (似たようなメソッドで Union。これは複数の領域のORをとる)
シート.AutoFilter.Range オートフィルターが相手にしているタイトル行を含んだリスト領域。 今回の例では、理解されたとおり、A1:B10。可視かどうかは関係がない。
シート.AutoFilter.Range.Offset(1) オートフィルターのリスト領域を1つ下に移動させた領域。 これとオートフィルターリスト領域とのAND(Intersect)は、タイトル行を除いた リストのボディ部分の領域。
一口メモ)たとえば1行目にタイトル行があるシートのタイトルのみ残して、残りをクリアする場合、 Intersect(シート.Usedrange,シート.UsedRange.Offset(1)).ClearContents と書くことができる。
Set r1 = Intersect(ActiveSheet.AutoFilter.Range, ActiveSheet.AutoFilter.Range.Offset(1)).Columns(2).SpecialCells(xlCellTypeVisible)
1行で書いたけど、分解すると
@Intersect(ActiveSheet.AutoFilter.Range, ActiveSheet.AutoFilter.Range.Offset(1))
リストのボディ領域。つまり "A2:B10"(上でも書いたけど、可視かどうかは関係がない。)
A.Columns(2)
@の中の2番目の列。つまり、"B2:B10"
B.SpecialCells(xlCellTypeVisible)
Aの中の可視領域(ここではじめて可視が登場)つまり "B4,B7,B9:B10"
このBからセルを取り出しているのが
For Each c In r1 c.Offset(, 3).Value = c.Value Next
このr1がB。Bからセルを1つずつ、cというRangeObject変数に取り出している。
c.Offset(, 3).Value = c.Value
取り出したc (B列の可視セル)の値を、Offset(,3) つまり同じ行の3列右のセルに転記。
ぶらっと立ち寄り
追伸
今回アップしたコードは実は手抜きコード。 Set 変数 = Intersect(・・・・) で、共通の領域がないとき、変数には「何もセットされない」 したがって、ちゃんとしたコードを書くなら、実行前に変数をNothingにしておき(Dimで初期値はNothing) 実行後、If Not 変数 Is Nothig Then と判定を入れて処理必要。
また、SpecialCells(セルの条件) で領域を取得しようとした場合、条件のセルがないと、「実行時エラー」となる。 したがって、ここも、手をぬかずに書くなら、
事前にNothingにしておいた上で、 On Error Resume Next (エラーが発生しても中断せず、次のコードを実行) SpecialCellsによる領域取得 On Error GoTo 0 (エラーをスキップする対応は終了) としておいて、やはり、変数がNothingかどうかの判定を行う。
ぶらっと立ち寄り
ぶらっと立ち寄りさん 解説ありがとうございます。 Offset(1)が、ボディ部分を特定する処理であることに気づくことができました! (バーバラ)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.