• ベストアンサー

Excel VBA こういう関数を作りたい

Excel VBAにてこういう関数を作りたいのです。 SInstr(検索する文字列,検索する文字,何番目) INSTRでは一番最初の位置しか返してもらえないので、任意の見つかった場所の位置を返して欲しいのです。 例: SInstr("あいうえおかうえきうえ","うえ",3) 10を返す 2つめくらいのならinstrで見つかった場からネストして+1すればいいんですが、4つめ,5つめという物もあるのです。 当方頭が悪いので思いつきませんでした。 頭の良い方、どういう関数を書いていいか教えていただけないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

こんにちは。お邪魔します。 2例でお応えします。 関数名をご指定のもので揃えましたから、どれかひとつしか使えません。 複数の関数を同時に試したい時は、個々のプロシージャ単位で、 プロシージャ内にある関数名を全置換してから、 新しい関数名を呼ぶようにしてください。 以下に書くものは、 「特定の文字列を使えない」ような制約がありません。 検索結果として見つからないのであれば、#N/A エラーを返します。 もし、他の値を返したい場合は、CVErr(xlErrNA)を書換えて下さい。 と、ここまで書いていて気が付いたのですが、 おもとめの関数は、 ワークシート上で用いるユーザー定義関数でしょうか? それとも、VBAプロジェクト内でCallされる関数でしょうか? 取り敢えず、ワークシート用ユーザー定義関数として書いてあります(※)。 もし、その必要がないようであれば、 以下、As Variant の部分を As String や As Long 等、 適宜書き換えてあげて下さい。 ■置換を用いる方法  簡易版 ワークシート関数のSUBSTITUTE関数等で、 [何番目]に当たる検索文字列だけを一旦置換しておいて、 置換後の文字列をInstr関数で探します。 この場合、置換後の文字列には、 (※)セルの値として決して使われることのない文字列値 (例ではキャリッジリターン)を使う必要があります。 ' ' ======================= Public Function SInstr(ByVal 検索対象 As Variant, _             ByVal 検索文字列 As Variant, _             ByVal 何番目 As Variant _             ) As Variant   検索対象 = WorksheetFunction.Substitute(検索対象, 検索文字列, String(Len(検索文字列), vbCr), 何番目)   SInstr = InStr(検索対象, vbCr)   If SInstr = 0 Then SInstr = CVErr(xlErrNA) End Function ' ' ======================= ■InStrを繰り返し用いる方法 文字列を置換する処理は時間食うので、 処理を軽くしたい場合には、Instr関数で統一します。 (※)現代のユーザー定義関数は、旧バージョンのExcelと比較して、 ワークシート関数との相対的な処理速度が低くなりましたので 少し意識しました。 ' ' ======================= Public Function SInstr(ByVal 検索対象 As Variant, _             ByVal 検索文字列 As Variant, _             ByVal 何番目 As Variant, _             Optional ByVal 開始位置 As Long = 1, _             Optional ByVal 文字比較 As VbCompareMethod = vbBinaryCompare _             ) As Variant Dim i As Long Dim nPos As Long Dim cnt As Long   nPos = 開始位置 - 1   Do     nPos = InStr(nPos + 1, 検索対象, 検索文字列, 文字比較)     If nPos Then       cnt = cnt + 1     Else       Exit Do     End If   Loop While cnt < 何番目   If cnt = 何番目 Then     SInstr = nPos   Else     SInstr = CVErr(xlErrNA)   End If End Function ' ' =======================

nandemoii1234
質問者

お礼

お礼が遅れて申し訳ありません。 たいへんわかりやすく丁寧な説明で、また実用的にも十分な物でした。 同じ物を作ろうとしてもなかなか難しいのでそのままコピペで使わせてもらいました。 本当にありがとうございました。Thanks!!

nandemoii1234
質問者

補足

非常に詳しくいただきありがとうございます。 しばらくにらめっこしながら参考にさせていただきます。 また改めてお礼させていただきます。

その他の回答 (4)

回答No.5

#3です。 VBA用、ということでしたら、 私の答はひとつ、です。 引数指定する文字列に対する制限(例えば、スペースや改行が扱えない) は、ありません。 パフォーマンス的にも(VBAで作成したものとしては)負荷は小さいです。 もし永く使いたいのであれば、アドインとして保存・登録した方が動作が軽くなります。 ユーザー定義関数としてワークシート上でも流用できますが、 Variant方を使う、キチンとエラー値を返す、という方向で書いた方が、 シート上では扱い易いです。 ■以下は、VBA.Instr関数の機能拡張版という意図で書いています。 見つからない場合は、0 値を返します。 ' ' ======================= Public Function SInstrA(ByVal Source As String, ByVal Search As String, _             ByVal NumOrder As Long, Optional ByVal Start As Long = 1&, _             Optional ByVal Compare As VbCompareMethod = vbBinaryCompare _             ) As Long Dim nPos As Long Dim cnt As Long   nPos = Start - 1   Do     nPos = InStr(nPos + 1, Source, Search, Compare)     If nPos Then       cnt = cnt + 1     Else       Exit Do     End If   Loop While cnt < NumOrder   SInstrA = nPos End Function ' ' =======================

回答No.4

Public Function SInstr(ByVal Text1 As String, ByVal Text2 As String, ByVal N As Integer) As Integer   SInstr = InStr(1, Replace(Text1, Text2, Space(Len(Text2)), , N - 1), Text2) End Function スペースに置換する数の指定を間違っていました。 >検索文字を同じ個数のスペースに置換! 当たり前のことが・・・。

回答No.2

>当方頭が悪いので思いつきませんでした。 頭の良し悪しは関係ないと思うが・・・。単なる発想の問題だから・・・。 Public Function SInstr(ByVal Text1 As String, ByVal Text2 As String, ByVal N As Integer) As Integer ON Error Resmu Next   SInstr = InStr(1, Replace(Text1, Text2, Space(N - 1), , N - 1), Text2) End Function テストは3つのみ。だから、完全版と言い難いが・・・。こんな感じで・・・。

nandemoii1234
質問者

お礼

短くてわかりやすいです。 ありがとうございます。

  • Chiquilin
  • ベストアンサー率30% (94/305)
回答No.1

関数をいちいち作らないといけない理由があるのですか? =FIND("♪",SUBSTITUTE("あいうえおかうえきうえ","うえ","♪",3))

nandemoii1234
質問者

お礼

worksheetfunction使ったら簡単ですね。 他でも応用したいので。

関連するQ&A

  • エクセルの関数 or VBAで

    A1に入力されている任意の文字列の先頭から3番目の文字をB1にコピーする 関数 or VBAを知りたいのですが。 宜しくお願いします。

  • エクセルVBAで特定文字列の個数を高速に調べたい

    文字列の入っている変数内で特定の文字列(今回はvbCrLf)が何個発生しているかを、高速に調べたいのですが、どのような方法があるでしょうか? 現在以下のことをやっています。 数千件のテキストファイルから特定文字列を検索しています。 検索を高速化するために、テキストファイルをバイナリーモードで1つの変数に読み込み、instr関数で検索しています。 見つかった場合、その位置から前にあるvbCrLfをInStrRev関数で、後ろにあるvbCrLfをinstr関数で位置を調べ、元の変数からmid関数で該当ラインを取り出しています。 検索はこれで可能ですが、特定文字列を調べたinstr関数の戻り値がテキストファイルの先頭からの位置(何桁目)なので、検索した文字列が何行目にあるか分かりません。 変数の検索文字が見つかった位置までの部分でvbCrLfが何個発生しているかが分かれば行数が判定できます。 vbCrLfを調べるinstr関数を何回も繰り返せば行数の判定は可能ですが、もっと高速に(一つの関数・命令で)調べることはできないでしょうか? また他に行数を特定する良い方法があったら教えてください。 よろしくお願い申し上げます。

  • VBAの書き方

    只今VBAで、あるセルで文字を検索して、その文字があるときに、違うセルに文字を出すマクロを作っています。 例えば、エクセルのI列に記入されている文章に"VBA"という文字が入っているとき、M列に"YES"という文字を出したいです。 どのようなマクロの式を書けばこのような操作が出来るのでしょうか。 FINDやInStr関数を使えばよいのかと思いますが… どなたかお分かりのかたは、教えて頂ければと思います。 よろしくお願い致します<m(__)m>

  • 文字列検索で

    よろしくお願いします。 文字列検索instr関数で、特定文字(スペース)でない文字を検索したいのですが、どのようにしたらいいですか? instr関数では、できないのでしょうか? たとえば、 文字列" osietegoo "  →  3 文字列"    situmon"  →  7 スペースでない文字が出現する位置を知りたいです。 instr(文字列,"o")ではなく、" "ではない、、、としたいのですが、できますか?

  • VBAで使えないワークシート関数は

    エクセルVBAで、ワークシート関数を使う場合に、findやmatchなどの検索関数が使えないのですが、何か別の関数が用意されているのでしょうか? やりたいことは、セルの中の文字列を、区切りのスペース文字で分解したいのですが。区切り文字の位置を知るfindが使えません。

  • エクセルの関数について質問です

    エクセルの関数について質問です A列に任意の個数「1」が入り、続けて「2」が任意の個数入力されています。B列に任意の文字列が入力されています。(うまく説明できないので、図を参照してください。) A列に「2」が入力されているB列の文字列を、関数でD列に取り出したいのですが、どのような関数でできるでしょうか? 「1」も「2」も個数は変動します。一度「2」が入力された以降の行に「1」が入ることはありません。「1」と「2」以外がA列に入力されることはありません。 色々考えたのですが、どうもうまくいきません。 VBAを使用すればできるとは思うのですが、どうしても関数でなければいけない事情があります。どなたか助けていただけないでしょうか?

  • Excel 2010 InStrに当たる関数

    当方、Windows7、Excel2010の環境です。 VBAで組むほどでもなく、単に「=Left(a2, InStr(a2, "-") - 1」と 「-」の手前の文字を取り出したいだけなのですが、 「#NAME」エラーが出てしまいます。 調べて見ると、Excelの関数に「InStr」が見当たりません。 InStrのところを、どう変えれば、良いのでしょうか? 教えてください。

  • 【VBA】 文字列の中から指定の文字列を取り出す

    VBAで文字列から指定の文字のn番目からn+1番目までの文字列を取り出すことは可能でしょうか? A1セルに下記の文字列があった場合、「1番目の半角スペースから2番目の半角スペースまでの文字列」を取り出したいのです。 5 53 00 8R この場合、53を取り出したいというわけです。 また、可能でしたら「最後の半角スペースから文字列の最後まで」を取り出す方法も教えていただけるとありがたいです。 この場合は8Rとなります。 InStr関数を使えばできるかもと思ったのですが、できそうなものが思い浮かびません。 どなたか教えていただけませんでしょうか。 よろしくお願いいたしますm(_ _)m

  • 文字列操作(ExcelのVBAですが)

    特定のExcelセル内にある文字列について、 例えば、 138.40.8.7 と入っている場合、 138.40.08.7 に、 35.9.1.6 と入っている場合、 35.09.01.6 にするVBA関数を作りたいのです。(セル関数でもかまわないですが) つまり、小数点で区切られている2番目と3番目の数字が 一桁の場合、頭に0を付けて、必ず二桁になるようにしたいわけです。 どなたか、ご教授くださいませ。 よろしくお願い致します。

  • VBA/FIND関数を使っての先頭文字列の検索方法

    エクセルVBAにてFIND関数を使って、 文字列検索⇒コピー&ペーストのマクロを作成しているのですが、 どうしても、先頭文字列から検索をする方法がわかりません。 たとえば、 あいうえお いうえおあ おあいうえ えおあいう という文字列から「あいう*」を検索したい場合、 1行目だけを抽出したいのですが、 1,3,4行目が抽出されてしまいます。 find関数では先頭文字からの検索はできないのでしょうか? もし、不可能な場合、先頭文字からの検索を行うにはどのように行えばよいでしょうか? アドバイス、よろしくお願いいたします。

専門家に質問してみよう