[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『VBA オートフィルタの文字列(数値)検索について』(そら)
お忙しいとは思いますがご教示お願いいたします。
○状況
sheetに文字列書式でデータを入力(数値の文字列エラー出ていない状態)
(例)A列
15 115 115/りんご apple
userformにINPUT用のコンボボックス、およびコマンドボタンあり
○手順
userformのコンボボックスよりINPUTデータを取得(FindKey/string)
userformのコマンドボタンよりvba実行
【コード】
Dim FindKey as String
FindKey = ComboBox1.Text
WorkSheets("sheet1").Range("A1").AutoFilter _
Field:=1, _ Criteria1:="*" & FindKey & "*"
コンボボックスで15(Findkey=15)を入力した際、
115/りんごはフィルタでヒットされるも、15や115はヒットされません。
ただ、一度15や115をダブルクリックし、エラー検知(数値が文字列として〜)させると、
ヒットするようになります。(その後、エラーを無視にしてもヒット)
また、ワイルドカードを使用しない場合(*を外す)もヒットします。
色々試しましたが、何か基礎的な考えが抜けてる気がします。。。
ご教示して頂いても宜しいでしょうか?
< 使用 Excel:Excel2010、使用 OS:Windows7 >
こう云うことで悩んだ事がなかったので、今回、実際に試行してみました。
<現象からすると・・ですけど・・>
>コンボボックスで15(Findkey=15)を入力した際、 >115/りんごはフィルタでヒットされるも、15や115はヒットされません。
「ワイルドカード(*)を付加したために、検索対象が文字列だけになってしまった」 と云うことになります。
>一度15や115をダブルクリックし、エラー検知(数値が文字列として〜)させると、 >ヒットするようになります。(その後、エラーを無視にしてもヒット)
これは、セルの書式を文字列にしてある為、ダブルクリックによって、数値が文字列に変化した為です。
>ワイルドカードを使用しない場合(*を外す)もヒットします。
この場合は、数値も文字列も対象になるようです。
<対策としては> (1) 15や115が、数値型にしておく必要がなければ、数字(文字型)に変更してからフィルターに掛ける。
(2) 15や115が、数値型のままにしておく必要があるなら、 別の列に文字型に変えたデータを作り、そっちの列でオートフィルターに掛ける。 ※文字型に変更する数式は簡単です。 E列でやる場合:E1セルに =A1&"" と入力して下にコピーする。
(半平太) 2016/02/24(水) 20:44
説明不足な点がございましたが、現在の状況/必要条件、私がした事も追記させて頂き、
コード内やデータだけでの対策があれば幸いです。
現在の状況/必要条件のおさらいとしては以下の通りです。
○15や115など含め、全てシート書式は「文字列」になっている
(セル編集を行うと数値の文字列エラーが出る⇒その状態であればVBAでヒット⇒現在はセル編集をしていない状態でエラーは出ていない)
○普通に手作業でオートフィルタをすれば「15」でも「*15*」でも全てヒットする
○"*" & FindKey & "*" ⇒ "*" & CStr(FindKey) & "*"に変更しても結果は変わらず
CStr有り無し関わらず、検索前のFindKeyは文字列型(8)です(Vartype関数)
○他の列に追加する対策は除外させて下さい
○データ自体は変更できません(15,115,115/りんご,apple・・・などが複合⇒文字列設定にて)
普通に手作業で行うオートフィルタにあって、
VBAにするオートフィルタには何かオプションが足りないのか、
もしくはシートやデータ自体に問題があるのかが分かりません。
何度も質問してしまい申し訳ございませんが、ご教示宜しくお願いいたします。
(そら) 2016/02/25(木) 10:48
>○普通に手作業でオートフィルタをすれば「15」でも「*15*」でも全てヒットする
この部分は、前回の試行では特に意識していなかったです。
その作業を「マクロの記録」でコードを録ってみると「*15*」を指定しているのではなく、 Criteria1:=Array("115", "115/りんご", "15")
となっていますから、複数の選択項目を配列に入れて「直接指定」していますよね。
それが、手作業で行うことの意味(実体もしくは裏処理)と云えるんじゃないでしょうか? それと同じことをするならば、
Sub FiterByArray() Dim FindKey As String Dim dtAry
FindKey = ComboBox1.Text
dtAry = Filter(Application.Transpose(ActiveSheet.Range("$A$1:$A$6").Value), FindKey, True)
If UBound(dtAry) >= 0 Then Worksheets("sheet1").Range("A1").AutoFilter _ Field:=1, Criteria1:=dtAry, Operator:=xlFilterValues Else MsgBox "該当なし" End If End Sub
’サンプルでは問題なかったですが、選択項目数がすごく多い場合どうなるか、こちらでは確かめておりません。
(半平太) 2016/02/25(木) 12:09
↑ <追記> 配列内(dtAry)の重複項目は排除すべきでした。m(__)m まずは、そちらで考えてみてください。
(半平太) 2016/02/25(木) 12:17
>○普通に手作業でオートフィルタをすれば「15」でも「*15*」でも全てヒットする
この部分は、前回の試行では特に意識していなかったです。
その作業を「マクロの記録」でコードを録ってみると「*15*」を指定しているのではなく、 Criteria1:=Array("115", "115/りんご", "15")
となっていますから、複数の選択項目を配列に入れて「直接指定」していますよね。 それが、手作業で行うことの意味(実体もしくは裏処理)と云えるんじゃないでしょうか?
それと同じことをするならば、
Sub FiterByArray() Dim FindKey As String Dim dtAry, exItem, dicT As Object Dim Ws As Worksheet
FindKey = ComboBox1.Text
Set Ws = Worksheets("sheet1") Set dicT = CreateObject("Scripting.Dictionary")
For Each exItem In Ws.Range("A1", Ws.Cells(Ws.Rows.Count, "A").End(xlUp)).Value dicT(exItem) = Empty Next
dtAry = Filter(dicT.keys, FindKey, True)
If UBound(dtAry) >= 0 Then Ws.Range("A1").AutoFilter _ Field:=1, Criteria1:=dtAry, Operator:=xlFilterValues Else MsgBox "該当なし" End If End Sub
’サンプルでは問題なかったですが、選択項目数がすごく多くなるとどうなるか、こちらでは確かめておりません。
'<追記> ’配列内(dtAry)の重複項目を無くしたバージョンに変更しました。
(半平太) 2016/02/25(木) 17:00
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.