[[20130523155114]] 『Advancedfilterで抽出について』(Koko) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『Advancedfilterで抽出について』(Koko)

まだVBA初心者で、つまづいてしまったので教えてください。
(Excel2007 を使っています)

データ一覧の中から、3つ以上のキーワードを検索するのに
Advancedfilterを使えば良いというのはわかりました。

今下記のように組んでいます。

    Range(Cells(1, 1), Cells(i, 3)).AdvancedFilter _
                Action:=xlFilterInPlace, _
                CriteriaRange:=Sheets("key").Range("a1:d2"), _
                Unique:=False

Range(Cells(1, 1), Cells(i, 3)) の範囲の中で(iは数字が毎回変わります)
キーワード Sheets("key").Range("a1:d2") をフィルターする、という意味ですよね?

ただこれだとand条件になってしまうようで、データ一覧が下記のようなものの場合、
   1、...a....d.............
   2、.........d............
   3、.....ac..d............
   4、..b...................
キーワード "a" and "b" and "c" and "d" をフィルター という条件になってしまい、
一つもヒットしない結果になってしまいます。

キーワード "a" or "b" or "c" and "d" をフィルター、
(上記のデータ一覧からは1、と3、を抽出)
という条件式を作ることは可能でしょうか?


 こちらは参考になりませんか?
http://miyahorinn.fc2web.com/schooltxt/filta15.html
 
(みやほりん)

みやほりんさん、ありがとうございます。

ただ教えていただいたサイト、参考になりました。
でも初心者ゆえ、応用ができないのです…。

キーワードにしたいのが、たとえば、
  商品 場所 数量
  a   東京 10
  b     20
  c
  d
とした場合、
  商品は "a"or"b"or"c"or"d"
   and
  場所は "東京"のみ
   and
  数量は "10"or"20"
とするにはどうしたらよいでしょうか?

ただたんにキーワードをA1〜C5としたら、
すべてのキーワードがor条件になってしまいました。


 こんにちは。

 以下が参考になると思います。
http://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604301.htmlhttp://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604302.html

 (めいぷる)

 >キーワード Sheets("key").Range("a1:d2") をフィルターする、という意味ですよね? 
 keyというシートのA1:D2に書かれている値を、データのあるシートから検索するという意味だけでなく、
並べ方そのものが抽出条件になっています。

 すでにみやほりんさんやめいぷるさんから紹介されているリンク先に、並べ方によってどういう意味をもった
抽出条件になるのかが記載されていますが、たとえばkeyシートに次のように記載されているとしたら、

      [A]  [B]  [C] 
 [1] 商品 場所 数量
 [2] a    東京   10
 [3] b           20
 [4] c             
 [5] d             

 商品は a 又は b 又は c 又は d   
 かつ
 場所は 東京
 かつ
 数量は 10 又は 20 

 つまり縦並びはor条件 横並びはand条件 という意味になります。

 それでkeyという抽出条件を記載したシートを用意しておいて、
                                         ^^^^^^^^^^^^^^^^
アドヴァンスドフィルターのコードを実行するとフィルターが実行されます。

 コードはたとえばこんなかんじ。
 Sub sample() '使うときはシート名を実際のものに
    Dim lastRow As Long
    Dim lastColumn As Long
    Dim myData As Range   'データ範囲
    Dim myCriteria As Range  '抽出条件

        With Worksheets("Sheet1")  'データがあるシートをシート1とする
            lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
            lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
            Set myData = .Range("A1", .Cells(lastRow, lastColumn))
        End With

        Set myCriteria = Worksheets("key").Range("A1").CurrentRegion

    Worksheets("Sheet2").Cells.Clear '抽出先をシート2として、範囲をきれいにする

    myData.AdvancedFilter action:=xlFilterCopy, criteriarange:=myCriteria, _
        copytorange:=Worksheets("Sheet2").Range("A1"), unique:=False
 End Sub

 追記:データ範囲も抽出条件範囲も見出し行が必要です。
 (usamiyu)

 下記のような例で、usamiyuさんのコードを実行すると、
	A	B	C   Worksheets("Sheet1")
[1]	商品	場所	数量
[2]	a	東京	10
[3]	b	福岡	15
[4]	c	東京	20
[5]	d	福岡	25
[6]	e	東京	10
[7]	f	福岡	15
[8]	g	東京	20
[9]	a	福岡	25
[10]	b	東京	10
[11]	c	福岡	15
[12]	d	東京	20
[13]	e	福岡	25
[14]	f	東京	10
[15]	g	福岡	15
[16]	a	東京	20
[17]	b	福岡	25
[18]	c	東京	10
[19]	d	福岡	15
[20]	e	東京	20
[21]	f	福岡	25
[22]	g	東京	10
[23]	a	福岡	15
[24]	b	東京	20
[25]	c	福岡	25
 
	A	B	C   Workshwwts("key")---(1)
[1]	商品	場所	数量
[2]	a	東京	10
[3]	b		20
[4]	c		
[5]	d		

抽出結果は下記の様になります。

	A	B	C    Worksheets("Sheet2")
[1]	商品	場所	数量
[2]	a	東京	10
[3]	c	東京	20
[4]	d	福岡	25
[5]	c	福岡	15
[6]	d	東京	20
[7]	c	東京	10
[8]	d	福岡	15
[9]	b	東京	20
[10]	c	福岡	25
 
(2003での結果なので抽出の仕様がことなるかもしれません)
改善案は以下。
 
【条件羅列によるフィルタ】
Keyを次のように書くとたぶん思い通りの抽出が出来ると思いますが、
何か芸がないですし、作るのが面倒くさいですね。
	A	B	C   Worksheets("key")---(2)
[1]	商品	場所	数量
[2]	a	東京	10
[3]	b	東京	10
[4]	c	東京	10
[5]	d	東京	10
[6]	a	東京	20
[7]	b	東京	20
[8]	c	東京	20
[9]	d	東京	20
 
【数式条件でのフィルタ】
シートKeyの(1)の状態で、例えば、E2に次のような数式を埋め込みます。
=COUNTIF($A:$A,Sheet1!A2)*COUNTIF($B:$B,Sheet1!B2)*COUNTIF($C:$C,Sheet1!C2)
 
変な数値が計算されますが、気にしないで下さい。
このときE2は空白セルです。
 
usamiyuさんのコードで下記の行を書き換えます。
Set myCriteria = Worksheets("key").Range("A1").CurrentRegion
 ↓
Set myCriteria = Worksheets("key").Range("E1:E2")
 
書き換えた上で実行。
(みやほりん)

 条件の設定方法ですが、先に紹介した
http://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604302.html
 の、ページ中ほど
 2.計算検索条件 から下をよく読んでください。
 (2)=OR(担当者= "秋野",担当者= "小倉",担当者= "久留米") とか
 (3)=OR(AND(担当者="秋野",金額>=5000),AND(担当者="小倉",金額>=10000)) の
 説明部分が 参考になると思います。

 今回の条件なら、KEYのシートに以下のように設定しておけば出来そうです。
 まずは手作業で確認してみて下さい。

      [A]   [B]   [C] 
 [1] 条件1 条件2 条件3
 [2]  式     式      式 

 A2の式 =OR(Sheet1!A2="a",Sheet1!A2="b",Sheet1!A2="c",Sheet1!A2="d")
 B2の式 =Sheet1!B2="東京"
 C2の式 =OR(Sheet1!C2="10",Sheet1!C2="20")

 式を全て同じ行にしているので、条件1〜3がAND条件です。
 (条件1 and 条件2 and 条件3)

      [A]   [B]   [C] 
 [1] 条件1 条件2 条件3
 [2]  式        
 [3]         式 
 [4]                式 

 上記のようにそれぞれの条件の行を分けて式を設定すればOR条件です。
 (条件1 or 条件2 or 条件3)

 ※条件1〜3の項目名はなくても可。逆にSheet1の項目名と同じものは不可。
   数量が数値なら、ダブルクォーテーションは外してください。

 (めいぷる)

みやほりんさん、めいぷるさん、usamiyuさん、ありがとうございます。

usamiyuさんのコード、私も実行してみました。
1行1行は理解できなくって完璧にコピペですが、うまく動きました。
ありがとうございます。

もうひとつ。もしデータが文章の場合
@ aを東京に10個
A bを20個福岡に送付
B 東京にcを15個送付
C dを20個、福岡に。

このような場合はどうでしょう?

usamiyuさんのコードが理解できていないので
またまた応用が出来なく。。。申し訳ありません。

(Koko)


 usamiyuさんのコードは、抽出条件をマクロで設定している訳ではありません。
 KEYシートに手作業で抽出条件を設定しておき、それを使った抽出をマクロでしているだけです。
 抽出条件が変わったのであれば、KEYシートの設定だけ変えてあげればマクロの修正無く動くと思います。

 まずは、Kokoさんがフィルタオプションの条件指定の仕方を理解する必要があります。
 手作業でフィルタオプションが使えるように・・・。

 先にも紹介した、以下のページをよく読んで理解してみて下さい。
http://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604301.htmlhttp://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604302.html

 > もうひとつ。もしデータが文章の場合 
 > @ aを東京に10個  
 > A bを20個福岡に送付 
 > B 東京にcを15個送付 
 > C dを20個、福岡に。
 文章ではExcelには伝わりませんよ〜。式に直したらどんな式になりますか?

 (めいぷる) 

   あぁ! またやっちゃっいました・・はずかしい〜 
 Kokoさん あいまいな理解のまま、間違った回答をしてしまって、申し訳ありませんでした。
大変失礼しましたm(__)m  また、私も勉強する機会を与えていただき、感謝しています。

 みやほりんさん いつもお世話になっております。ご指摘とおやさしく、丁寧なフォロー ありがとうございます。

 めいぷるさん ご紹介のページ、以前に読んだつもりだったのが、理解していませんでした。もう一度
見直してみます。
 抽出条件の検索には文字列検索と計算検索とがあって、文字列検索だと見出しが必要だけれど、計算検索
では、見出し不要・・というか同じ見出しは不可なんですね!留意します。ありがとうございます。

 (※書いてる間にKokoさん、めいぷるさんのコメントが上がってましたが、まだ読んでません。とりあえずお詫びとお礼まで)

 (usamiyu)  

  Kokoさん 今日はお休みかな?抽出条件を式にするの、できました?
私もちょっとやってみました。こんなになっちゃったけど。もっといい答えがありそう^_^;
      [A]    [B]    [C]   
 [1] 条件1 条件2 条件3
 [2] TRUE   TRUE   TRUE  

 A2の式 =OR(NOT(ISERROR(SEARCH("*a*",Sheet1!A2))),NOT(ISERROR(SEARCH("*b*",Sheet1!A2))),NOT(ISERROR(SEARCH("*c*",Sheet1!A2))),
         NOT(ISERROR(SEARCH("*d*",Sheet1!A2))))
 B2の式 =NOT(ISERROR(SEARCH("*東京*",Sheet1!A2)))
 C2の式 =OR(NOT(ISERROR(SEARCH("*10*",Sheet1!A2))),NOT(ISERROR(SEARCH("*20*",Sheet1!A2))))

 ※10個でなく、10本など単位が違うものも拾うようになってます。

 これをkeyシートに手作業で設定しておいて、sampleを実行すると抽出できます。
あくまでこのコードは抽出条件を手作業で設定して、それをただ抽出しているだけなので、コードに変更はありません。

 (usamiyu) 

  それと、なんだか数式がくどくなっちゃったので、コードで抽出条件シート自体を文字列で設定するものも書いてみました。
sample2はkeyシートをいじる必要はありません。ただ実行するだけです。
 ただし、このコードは今回の抽出条件にしかあてはまらないので、抽出条件が変わると、書き直す必要があります。
今後もフィルタオプションを使うなら、抽出条件の設定は手作業の方が楽そうですねぇ。
 
 Sub Sample2() '使うときはシート名を実際のものに
    Dim lastRow As Long
    Dim lastColumn As Long
    Dim myData As Range   'データ範囲
    Dim myCriteria As Range  '抽出条件
    Dim w As Variant

        With Worksheets("Sheet1")  'データがあるシートをシート1とする
            lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
            lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
            Set myData = .Range("A1", .Cells(lastRow, lastColumn))
        End With

        'ここから抽出条件をコードで設定 ↓ここから
        '--------------------------------------------------------------
        With Sheets("key")    '抽出条件シート
            .Cells.Clear
            .Range("A1:C1").Value = Worksheets("Sheet1").Range("A1").Value
            w = WorksheetFunction.Transpose(Array("'=*a*", "'=*b*", "'=*c*", "'=*d*"))
            .Range("A2:A9").Value = w
            .Range("A6:A9").Value = w
            .Range("B2:B9").Value = "'=*東京*"
            .Range("C2:C5").Value = "'=*10*"
            .Range("C6:C9").Value = "'=*20*"
            Set myCriteria = .Range("A1").CurrentRegion
        End With
        '--------------------------------------------------------------
        '↑ここまで

        '抽出する
        With Sheets("Sheet2")
            .UsedRange.ClearContents
            myData.AdvancedFilter action:=xlFilterCopy, criteriarange:=myCriteria, _
                copytorange:=.Range("A1"), unique:=False 
            .Select
        End With
 End Sub

 (usamiyu)

皆様、いろいろとご教示ありがとうございます。
すみません、週末はちょっと画面確認できませんでした。

私の質問がそもそもはっきりしていなくて申し訳ありませんでした。

<やろうとした事>
1.データ一覧は文章になっています。
      <内容>
   @ aを東京に10個
   A bを20個福岡に送付
   B 世田谷にcを15個送付
   C dを20個、福岡に。 …
2.キーワードを入力して実行ボタンを押す。
3.そのキーワードを含んだ行がフィルタされる。

ふつうに手作業でフィルタをかけるのは条件2個までしかいれられないので
マクロを組む事にしました。
いろいろと検索して、Advancefilterというのが使えるとわかって

  Range(Cells(1, 1), Cells(i, 3)).AdvancedFilter _

                Action:=xlFilterInPlace, _
                CriteriaRange:=Sheets("key").Range("a1:d2"), _
                Unique:=False

というのを組んでみてうまく動きました。

ただ、上記のコードだと、キーワードが「東京」だった場合、
「世田谷」はヒットしません。

そこで類似語リストを作り、
1.キーワード1を類似語リストから検索。
2.類似語リストになかったらキーワード1はand条件でフィルタ
  もしリストにあったら、キーワード1と類似語はor条件でフィルタ
3.これをキーワード1〜3で繰り返す。

とし、教えていただいたor条件の時は縦並びに、and条件の時は横並びに
キーワードシートを下記のように作ったのですが、

 [1] 内容 内容  内容
 [2] a    東京   10
 [3] b    世田谷 
 [4] c             

うまくできなくて上記のキーワードすべてに対してor条件でフィルタされてしまいました。
これを解決したいと思っているのですが…

うまくご説明できなくてごめんなさい。
上記の事、マクロ組む事可能かどうかもちょっとわからないぐらい初心者なので…
よろしくお願いいたします。

(Koko)


 私の回答の中の【数式条件でのフィルタ】の部分は
そのようなことを見越して提案しております。
(みやほりん)


 ちょっと、整理が付いてないみたいなので、いったん、マクロのことは忘れて、フィルタオプションの設定(Advancedfilterのこと)を
手作業でやってみませんか?

 まずkeyシートに次のように記載してみてください。
       [A]  [B]      [C] 
 [1]  内容 内容     内容
 [2]  *a*  *東京*   *10*
 [3]  *b*  *東京*   *10*
 [4]  *c*  *東京*   *10*
 [5]  *d*  *東京*   *10*
 [6]  *a*  *東京*   *20*
 [7]  *b*  *東京*   *20*
 [8]  *c*  *東京*   *20*
 [9]  *d*  *東京*   *20*
 [10] *a*  *世田谷* *10*
 [11] *b*  *世田谷* *10*
 [12] *c*  *世田谷* *10*
 [13] *d*  *世田谷* *10*
 [14] *a*  *世田谷* *20*
 [15] *b*  *世田谷* *20*
 [16] *c*  *世田谷* *20*
 [17] *d*  *世田谷* *20*

 次にSheet2をデータを削除してきれいにしてから、アクティブにして、
【データ】→【フィルタ】→【フィルタオプションの設定】とし、フィルタオプションの設定ダイアログが出てきたら、
抽出先を「指定した範囲」にチェックし、リスト範囲を設定(右端のボタンをクリックすると簡単に設定できます)します。
 例えば、リスト範囲がSheet1のA1からA8にあるとしたら Sheet1!$A$1:$A$8

 同じ要領で、検索条件範囲を設定
 上の表で記載した範囲が検索条件範囲なので、 key!$A$1:$C$17

 同じ要領で、抽出範囲を設定
 例えば、Sheet2のA1に結果を抽出するとしたら、 Sheet2!$A$1 

 OKボタンをクリック

 これでどうなりますか?

 (usamiyu)


そもそも論ですが、advancefilterって手作業でもできるんですね。
「フィルタの詳細設定」って使った事がありませんでした…。

"Sheet1"に

 内容
aを東京に10個
bを20個世田谷に送付
世田谷にcを10個送付
dを20個、福岡に。
aを世田谷に10個
bを東京に20個
cを東京に25個
bを世田谷に20個
世田谷にdを10個送付
bを福岡に30個
東京に20個cを。

といれて
Sheet2にフィルタオプションの設定をしてOKを押すと、

Sheet2のA1セルに「内容」と、でてきました。

(Koko)


 >フィルタの詳細設定
 こちらの環境は2003なので、ちょっと言葉が違っていて失礼。

 >Sheet2のA1セルに「内容」と、でてきました。

 ???何も検索されなかったっていう結果ですよね。おかしいですよね。
keyシート(検索条件を指定するシート)は、私が記載したように、ワイルドカード(*)も入れてますか?

 (usamiyu) 

 


 > そもそも論ですが、advancefilterって手作業でもできるんですね。 
 >「フィルタの詳細設定」って使った事がありませんでした…。 

 ですから、だまされたと思って(笑)まずは以下のページをよく読んで理解してみて下さい。
 実際に例題の通りにして自分の手で試してみて。
http://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604301.htmlhttp://www11.plala.or.jp/koma_Excel/contents6/mame6043/mame604302.html

 特に後の方のリンクのページには、usamiyuさんが教えて下さっている部分一致の
 指定方法の説明もありますよ。

 抽出条件の指定は、usamiyuさんのように全ての組み合わせを作ってもいいですが、
 条件が変わったときの修正が大変そうなので、以下のようにしてはどうでしょうか。

 条件をそれぞれ、商品の条件、場所の条件、数量の条件と3つに分けて、
 数式で定義します。
 例えば場所の条件が変わったら、場所の数式のみ変更すればOKです。

      [A]     [B]      [C] 
 [1] 商品条件 場所条件 数量条件
 [2]  式1      式2       式3 
 (式1) A2の式 商品がaまたはbまたはc
 =OR(NOT(ISERROR(SEARCH("*a*",A2))),NOT(ISERROR(SEARCH("*b*",A2))),NOT(ISERROR(SEARCH("*c*",A2))))
 (式2) B2の式 場所が東京または世田谷
 =OR(NOT(ISERROR(SEARCH("*東京*",A2))),NOT(ISERROR(SEARCH("*世田谷*",A2))))
 (式3) C2の式 数量が10または20
 =OR(NOT(ISERROR(SEARCH("*10*",A2))),NOT(ISERROR(SEARCH("*20*",A2))))

 (めいぷる)

 めいぷるさん フォローありがとうございます!
質問者さんが文字列検索で、意図しない結果になったということで、まずは文字列による抽出条件、
次に数式って形でお話しようかと思っていましたが、私、なかなか説明するの下手で〜(汗)
(usamiyu)
 

皆様ごめんなさい、やっとフィルタオプション、理解しました!(…と、思います)

usamiyuさん、"key"sheetに入力していたの、ワイルドカード入れていましたが、
キーワードのタイトルに商品・場所・数量、と入れてしまっていました。
キーワードのタイトル行を「内容」になおしたら、出てきました。
申し訳ありません、ケアレスミスでした。。。

めいぷるさん、抽出条件の指定、数式の定義をしたいと思いますが、
現時点でいただいた数式、理解できないので…。考えます。

取り急ぎ、お礼まで。理解が遅くて申し訳ありません!

(Koko)


キーワードは変わる為、
都度すべての組み合わせを毎回作るのは大変なので
数式にしたいと思いましたが、
申し訳ありません、ここになぜiserrorの式が来るのが良く分かりません。。。

教えていただいたサイトの「計算検索条件」もじっくり読んだのですが、
ちょっと理解できませんでした。

たとえば
  A   B   C
1 True False False
となっている、A1〜D4を検索条件範囲、とすれば良いのでしょうか?

あともしかして(これまた組み方が良く分かりませんが)
or条件のものはまず先に検索し、たとえば空白列に記号を入力し、
and条件のものも検索し空白列に記号を入れて、
記号が二つのものをフィルタにかけて表示、というほうが
初心者には作りやすいでしょうか…?

(Koko)


 書いていたら、Kokoさんと衝突。上の質問はまだ読んでないけどアップします。 

 手作業でのフィルタオプション、できたんですね。よかった!とりあえず、急ぎの仕事は、これでしのげるかな。
以下は、ゆっくり理解していけばいいと思いますが、書いておきますね。

 抽出条件("key"sheet)は、文字列で検索するなら、条件を「羅列する」必要があるって体感できましたね。
 でも、羅列して書くのが結構面倒くさいですよね。
 そこで、羅列したくない場合は、数式にて記述する方法があります。

 めいぷるさんの(式2)を見ていただくと、場所条件が、東京だけでなく世田谷というキーワードが増えた場合、

 = OR (NOT(ISERROR(SEARCH("*東京*",A2))),  NOT(ISERROR(SEARCH("*世田谷*",A2))))
  ↑            ↑                   ↑
  OR条件         "*東京*"               "*世田谷*"

 とあり、まったく同じ NOT(ISERROR(SEARCH("*ほにゃらら*",A2))) という式が東京と世田谷と二つ繰り返されています。
そして、この二つの式を =OR(式(東京), 式(世田谷))としているので、 式(東京)か もしくは式(世田谷)の場合 となります。

 つまり  "*東京*"というキーワードがA2セルの中にあって、エラーでない 
                 もしくは
     "*世田谷*"というキーワードがA2セルの中にあって、エラーでない 

 という意味です。

 そして、めいぷるさんの(式1)(式2)(式3)が "key"sheetに横並びに並んでいるので、各OR条件の式1から式3がAnd条件となります。

 数式条件の場合、もうひとつ注意しなければならないのは、数式で条件を記載する場合、見出しの名前はリスト範囲と同じ「内容」では
だめってことです。「条件1」「条件2」と記載するとか、もしくは書かない。これは文字列検索の場合と真逆ですね。

 手が空いたら、数式条件も試してみると手間が省けると思います。

 そして、数式条件での設定ができたら、マクロの方も試してみると、手作業で設定していた「リスト範囲」「抽出範囲」なんかを記載
しなくていいので、さらに楽になります。
 まず、手作業で数式条件を"key"sheetに設定し、sample(最初に書いたほうのコード)を実行して試してみると実感できると思います。

 (usamiyu)


 こんにちは〜。

 Kokoさんの質問に答えを書いていたらusamiyuさんからナイスフォローが・・・。

 とりあえず数式の疑問について。

 > 数式にしたいと思いましたが、 
 > 申し訳ありません、ここになぜiserrorの式が来るのが良く分かりません。。。 
私が提示した
 (式1) A2の式 商品がaまたはbまたはc
 =OR(NOT(ISERROR(SEARCH("*a*",A2))),NOT(ISERROR(SEARCH("*b*",A2))),NOT(ISERROR(SEARCH("*c*",A2))))
 の式ですね。

 Kokoさんのデータは

    [A] 
 1 内容 
 2 aを東京に10個 
 3 bを20個世田谷に送付 
 4 世田谷にcを10個送付 
 5 (以下略)

 ということで、
 例えばA2の「aを東京に10個」という文章の中に"a"という文字が含まれているかを調べるために
 [SEARCH("*a*",A2)]という式を使っています。
 ただし、SEARCH関数のヘルプを見ると、【検索文字列が見つからないと、エラー値 #VALUEを返す】と
 あります。
 なので、『"a"があるもの』=『SEARCH("*a*",A2)の結果がエラーでないもの』ということです。
 『SEARCH("*a*",A2)の結果がエラーでないもの』とは、
  ISERROR(SEARCH("*a*",A2)) → 結果がTrueならばエラーあり
  NOT(ISERROR(SEARCH("*a*",A2))) → NOT をつけることで『エラー有ではない』すなわち
                                      『"a"があるもの』ということです。

 > たとえば 
     A   B   C 
 > 1 True False False 
 > となっている、A1〜D4を検索条件範囲、とすれば良いのでしょうか? 

 数式の上のセルに列見出しを使用することは出来ません。
 数式の上のセルは「空白」にするか、データの列見出しとは異なるものを用います。

 ということで、上記の場合なら数式は2行目に設定して、範囲をA1:C2とすれば良いです。
 (なぜD4?)

 (めいぷる)

なんかわかってきたような気がします!

めいぷるさんのご指摘いただいた

********

   [A]   [B]   [C]
 [1] 商品条件 場所条件 数量条件
 [2]  式1      式2       式3 
 (式1) A2の式 商品がaまたはbまたはc
 =OR(NOT(ISERROR(SEARCH("*a*",A2))),NOT(ISERROR(SEARCH("*b*",A2))),NOT(ISERROR(SEARCH("*c*",A2))))
 (式2) B2の式 場所が東京または世田谷
 =OR(NOT(ISERROR(SEARCH("*東京*",A2))),NOT(ISERROR(SEARCH("*世田谷*",A2))))
 (式3) C2の式 数量が10または20
 =OR(NOT(ISERROR(SEARCH("*10*",A2))),NOT(ISERROR(SEARCH("*20*",A2))))

********

って、A2だけじゃなくて、データ一覧の最後の行まで繰り返し、という事でしょうか?
そして商品条件、場所条件、数量条件すべてにTRUEとなったものをフィルタする、ですか?

ちなみに、
  Dim 商品(1 to 4)
  商品(1) = "a"
  商品(2) = "b"
  商品(3) = "c"
と定義した場合、

********

 =OR(NOT(ISERROR(SEARCH("*a*",A2))),NOT(ISERROR(SEARCH("*b*",A2))),NOT(ISERROR(SEARCH("*c*",A2))))

********

はどう変えればよいでしょう?"*a*"の箇所を素直に商品(1)に変えればよいでしょうか?

あと、キーワードのか所、『"』が2個じゃないと("*a*"も、""*a*"")エラーになっちゃうのですが、
これはOffice2007のせいでしょうか。。。

(Koko)


  >A2だけじゃなくて、データ一覧の最後の行まで繰り返し、という事でしょうか? 
 >そして商品条件、場所条件、数量条件すべてにTRUEとなったものをフィルタする、ですか? 

 そうです、そうです!そういうことですね。

 それで、そのさきのマクロ部分なんですが、ちょっと誤解があるようです。

 フィルターオプションは、Criteria(抽出条件) をセル上に書き込まなくてはなりません。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 だから、  
 >Dim 商品(1 to 4) 
 > 商品(1) = "a" 
 > 商品(2) = "b" 
 > 商品(3) = "c"
 と書いて、マクロに組み込んでも抽出条件にならないんです。

 とにかく、数式検索であれ、文字列検索であれ、条件をコード上ではなく、ワークシート上に記載
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
することが必要です。
^^^^^^^^^^^^^^^^^^^
 そのため、抽出条件(keyシート)だけは、手作業で数式をワークシートに書き込んだほうが効率的だと
思うのです。抽出条件も毎回固定なら別ですけど、

 >キーワードは変わる為、

 ってことだから。

 「まず、手作業で数式条件を"key"sheetに設定し、sample(最初に書いたほうのコード)を実行して試してみると」
って言ったのはそういう意味です。 

 しかし、どうしてもマクロでやりたい、毎回、抽出条件が変わった部分はその都度、コードを書き換える・・・
というのであれば、formulaを使ってシートに数式を書き込むことはできます。
こんなので。
  Sub suusikijyoukennset()
    With Sheets("key")    '抽出条件シート
      .Cells.Clear
      .Range("A1:C1").Value = Array("条件1", "条件2", "条件3")
      .Range("A2").Formula = "=OR(NOT(ISERROR(SEARCH(""*a*"",Sheet1!A2))),NOT(ISERROR(SEARCH(""*b*"",Sheet1!A2))),NOT(ISERROR(SEARCH(""*c*"",Sheet1!A2))))"
      .Range("B2").Formula = "=OR(NOT(ISERROR(SEARCH(""*東京*"",Sheet1!A2))),NOT(ISERROR(SEARCH(""*世田谷*"",Sheet1!A2))))"
      .Range("C2").Formula = "=OR(NOT(ISERROR(SEARCH(""*10*"",Sheet1!A2))),NOT(ISERROR(SEARCH(""*20*"",Sheet1!A2))))"          
    End With
 End Sub 

 (usamiyu) 

ごめんなさい、また理解できないつぼに入ってしまいました。

key(1) = Worksheets("key").Cells(2, 1)
         ← keyシートのA2にあるキーワードをKey(1)に設定。

Worksheets("key2").Cells(i, j) = "=OR(NOT(ISERROR(SEARCH(key(1),Sheet1!RC[-1]))))"
         ← そのKey(1)をSheet1の中でSerchして、key2シートにtrue/falseをかえす

という事ができない、て意味ですか?

(Koko)


 Kokoさん、頑張っておられるようですね。

 > key(1) = Worksheets("key").Cells(2, 1) 
 >          ← keyシートのA2にあるキーワードをKey(1)に設定。 
 > Worksheets("key2").Cells(i, j) = "=OR(NOT(ISERROR(SEARCH(key(1),Sheet1!RC[-1]))))" 
 >          ← そのKey(1)をSheet1の中でSerchして、key2シートにtrue/falseをかえす 

 ↑これは、何をしたいのでしょうか?
 式の意味ではなくて、目的は?

 "key"シートにキーワードを設定 ・・・ これは手作業ですよね。
 "key"シートに設定したキーワードを変数key(1)に格納
 その変数を使って数式を組み立て、それを"key2"シートのセルに設定

 何のためにこんな回りくどいことをしようとしているのですか?

 (めいぷる)

キーワード入力、という箇所を作って、
ボタンを押すとマクロが動いて必要なデータ行だけ抽出、としたいのです。

それだったら他の人がもしそのファイルを使う時にでも、
キーワード入力箇所にキーワードを入力すれば抽出が簡単にできるので。

ファイルを開くとキーワードを入力する画面があり、
そこにキーワード1〜4を入力して(2,3個でも可)
類似語もあったらそれもキーワードに加えて(or条件)
検索してキーワードが入っている行を抽出。

という事をしようと思っています。

シンプルに作りたいんですけど、まず一段階ずつ理解しながら進めてみると、
なんかくどくなっていますか?

(Koko)


 Kokoさん、やりたいことは分かりました。

 > ファイルを開くとキーワードを入力する画面があり、 
 ユーザーフォームを考えているのでしょうか?
 それとも、単にキーワード指定用のシートを作る?

 今回の要件では初め、「商品」「場所」「数量」について以下のように条件を指定していましたよね。

 「商品」の条件:aまたはbまたはc
 「場所」の条件:東京または世田谷
 「数量」の条件:10または20

 そして「商品」の条件、「場所」の条件、「数量」の条件がAND条件。

 > そこにキーワード1〜4を入力して(2,3個でも可)  
 > 類似語もあったらそれもキーワードに加えて(or条件) 
 任意に指定させるとして、【「商品」の条件、「場所」の条件、「数量」の条件がAND条件】
 というのは変わらないのですか?
 "任意"とはどこにどのように入力させるのですか?(指定できるキーワードの個数とかは?)

 (めいぷる) 

すみません、返答遅くなりました。

 > ファイルを開くとキーワードを入力する画面があり、

これは、「検索」というsheetに

         商品  場所  数量  その他
検索キーワード (  )(  )(  )(   )

として、カッコの中(B2,C2,D2,E2)に検索キーワードを自由に入れてもらいます。
(たとえば、B2に「a」、C2に「東京」、D2に「10」、E2はブランクでも)

そしてそのキーワードをみて、類似語リストに上記キーワードが入っているか確認し、
(商品「a」では「b」も「c」も「d」も類似品なので、「b」「c」「d」も検索。
 ただし、AND条件にすると、当然1行には商品名は一つしかないので、)
類似語はor条件、にしたいのです。

「商品」の条件、「場所」の条件、「数量」の条件はAND条件のままです。

(Koko)
 


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.