質問: vbaを使用したデータの抽出について sheet1に下記のような(例)データベースがありa~n列までデータが入力されています。 a b c d e f g h i j n 1 ○○様 ○○ 2名 車 可 東京 *** *** *** 2015/7/1 2 ○○様 ×× 3名 車 不可 埼玉 2015/8/1 3 ○○様 ×□ 2名 電車 不可 愛知 2015/8/12 4 ○○様 □□ 4名 バス 可 新潟 2015/7/13 5 ○○様 ○× 3名 バス 可 宮城 2015/6/1 6 ○○様 ○□ 4名 車 不可 大阪 2015/8/21 7 ○○様 □○ 2名 バス 可 山梨 2015/8/7 「sheet1」b列のデータを元にして、別シート(sheet2)のa2列に抽出したいもの(例:バス)を入力し、 フォームボタン(例:抽出)で検索し、抽出された結果のsheet1のa列~g列、n列のみ(h列~j列は不要)をsheet2のa11以下へ表示したいと考えています。 a b c d e f g n 4 ○○様 □□ 4名 バス 可 新潟 2015/7/13 5 ○○様 ○× 3名 バス 可 宮城 2015/6/1 7 ○○様 □○ 2名 バス 可 山梨 2015/8/7 どのようなvbaのコードを使用すれば良いでしょうか。 宜しくお願いします。
回答: 御質問文の例では、sheet1にはいきなり1行目からデータが入力されている様に書かれていますが、実際にはa列に1と入力されているセルはa1セルなどではなく、そのa列に1と入力されている行の上には何らかの項目名が入力されている行があるのではないでしょうか? 御質問の件の様なvbaのマクロを作るためには、何行目からデータが入力されているのかという事に関する情報も必要になる場合が多いので、実際のデータが何行目から入力されているのかという事も忘れずに説明しておく様にして下さい。 尚、いきなり1行目からデータが入力されている場合には処理が面倒になりますので、いきなり1行目からデータを入力する事はなるべく避けた方が宜しいかと思います。 それで、実際のデータが何行目から入力されているのかという事が不明なため、取り敢えず仮の話として、sheet1において項目名が入力されている行は2行目であり、実際のデータは3行目以下に入力されているものとします。 その場合、色々なやり方がありますが、一例としてオートフィルターを利用した方法では次の様なvbaマクロとなります。 sub qno9008324_vbaを使用したデータの抽出について() dim copysheet as worksheet, pastesheet as worksheet, _ itemrow as long, lastrow as long, pastecell as range, _ copycolumn as string, unwantedcolumn as string, _ referencecolumn as string, mycriteria as variant, _ criteriacell as range set copysheet = sheets("sheet1") '元データが入力されているシート set pastesheet = sheets("sheet2") '貼付け先のシート copycolumn = "a:n" 'コピーする元データが入力されている列の範囲 unwantedcolumn = "h:j" 'コピーする必要のない列の範囲 referencecolumn = "e" '抽出したいものが入力されている列 itemrow = 2 ' 元データの表の項目欄の行番号 set pastecell = pastesheet.range("a11") '貼付け先のセル範囲の中で最も左上にあるセル set criteriacell = pastesheet.range("a2") '抽出したいものが入力されているセル mycriteria = criteriacell.value if mycriteria = "" then msgbox "抽出すべき項目が指定されていないため処理を行う事が出来ません。" & _ "マクロを一旦、終了しますので、抽出すべき項目を" _ & pastecell.parent.name & "!" & pastecell.address(false, false) & _ "セルに入力してから本マクロによる処理をやり直して下さい。", _ vbexclamation, "抽出項目未設定" exit sub end if lastrow = copysheet.range(referencecolumn & rows.count).end(xlup).row if lastrow <= itemrow or worksheetfunction.countif(copysheet. _ range(referencecolumn & itemrow & ":" & referencecolumn & lastrow), _ mycriteria) = 0 then msgbox "抽出すべきデータがありません。", vbinformation, "データ無し" exit sub end if application.screenupdating = false pastecell.resize(pastesheet.cells.specialcells(xlcelltypelastcell).row - pastecell.row + 1, _ columns(copycolumn).columns.count - columns(unwantedcolumn).columns.count).clearcontents with copysheet if .autofiltermode then copysheet.cells.autofilter .columns(unwantedcolumn).entirecolumn.hidden = true .range(referencecolumn & itemrow & ":" & referencecolumn & lastrow). _ autofilter field:=1, criteria1:=mycriteria intersect(.columns(copycolumn), .rows(itemrow & ":" & lastrow)).specialcells(xlcelltypevisible).copy pastecell.pastespecial paste:=xlpastevaluesandnumberformats application.cutcopymode = false .cells.autofilter .columns(unwantedcolumn).entirecolumn.hidden = false end with application.screenupdating = true end sub 尚、もしsheet1において項目名が入力されている行が2行目ではなかった場合には、上記のvbaの構文中の itemrow = 2 という箇所の2という数値の部分を、実際の項目名が入力されている行の行番号に合わせて修正して下さい。