VisualBasic2008ExpressEditionでプログラムしています。


(以前した質問が、不完全なものでしたので、再び質問します。)

Module1.vb内に、次のような処理をしてくれるPublic Functionを作りたいです。

つきましては、コードをご教示ください。

0. Public Functionの名前はAaaとする
1. 各種パラメータを受け取る
  1-1. strGiven As String
  1-2. strFlag As String
  1-3. strResult As String
2. strGivenの中に、strFlagに格納されているのと同じ文字列が含まれているか、strGivenの「後尾から」順に探す
3-1. もし発見されなかったら、strResultに"NotExist"を代入する
3-2. もし発見されたら、
  3-1-1. strGivenに格納されている文字列のうち、strFindに格納されている文字列そのものをも含む、その部分から見て「前の側」を、削除する
  3-1-2. strResultに"Exist"を代入する
4. strGivenとstrResultを返す

回答の条件
  • 1人2回まで
  • 登録:2009/10/26 22:13:31
  • 終了:2009/11/02 22:15:02

回答(2件)

id:Mook No.1

Mook回答回数1312ベストアンサー獲得回数3912009/10/26 22:52:51

ポイント35pt

呼び出し側は

    Dim strGiven As String
    strGiven = "ABC DEF GHI"

    Dim strFind As String
    strFind = "DEF"

    Dim strResult As String
    Dim res As String

'// 第一引数と第三引数は ByRef(参照渡し)なので、関数側でこの引数を変更すると呼び出し側の変数も変化する。
'// 第二引数は ByVal(値渡し)なので、関数側でこの引数を変更しても呼び出し側の変数は変化しない。
'// ByRef で使用する変数は"..."のような書き方はできない。
'// 一旦変数に入れて渡す。

    res = Aaa( strGiven, "DEF", strResult)
'// res = Aaa( "ABC DEF GHI", "DEF", strResult) の書き方は NG
'// res = Aaa( "ABC DEF GHI", "DEF", strResult) の書き方は NG
'// res = Aaa( strGiven, strFind, strResult ) の書き方は OK
    msgBox( "引数の結果 = " & strResult ) 
    msgBox( "関数の結果 = " & res ) 

のように使用します。


Module Module1
    Const AAA_NoDirection As Integer = 0 '// 検索のみ
    Const AAA_ToBackward As Integer = 1  '// 後方向
    Const AAA_ToForward As Integer = 2   '// 前方向

    Public Function Aaa(ByRef strGiven As String, ByVal strFind As String, ByRef strResult As String) As String
'//                     ↑                    ↑           ↑
'//                     参照渡し                値渡し          参照渡し
'//                     変更可                  変更不可         変更可
        Const searchDirection As Integer = AAA_NoDirection '★★★検索方向:ここを変更することで動作を変える
        Const deleteDirection As Integer = AAA_NoDirection '★★★削除方向:ここを変更することで動作を変える

        If InStr(strGiven, strFind) > 0 Then
            strResult = "Exist" '// 引数の直接書き換え
            Aaa = "Exist"   '//  戻り値の設定 ★★★  関数名は一つなので二つの結果を返すことはできない。

        Else
            strResult = "NoExist" '// 引数の直接書き換え
            Aaa = "NoExist" '//  戻り値の設定 ★★★  関数名は一つなので二つの結果を返すことはできない。
            Exit Sub
        End If

        Dim strPos As Integer
        Select Case searchDirection
            Case AAA_ToBackward
                strPos = InStr(strGiven, strFind)
            Case AAA_ToForward
                strPos = InStrRev(strGiven, strFind)
            Case Else
                Exit Sub
        End Select

        Select Case deleteDirection
            Case AAA_ToBackward
                strGiven = Right(strGiven, Len(strGiven) - Len(strFind) - strPos + 1)  '// ★引数の直接書き換え
            Case AAA_ToForward
                strGiven = Left(strGiven, strPos - 1)   '// ★引数の直接書き換え
                Exit Sub
        End Select
    End Function
End Module

詳細は下記のあたりをご一読ください。

http://tgws.fromc.jp/prog/prog11.html

http://homepage1.nifty.com/CavalierLab/lab/vb/byvalbyref.html

id:jjkkjpjjkkjp

あの、「検索のみ/前方向/後方向」の選択はいりませんので、最低限のコードをお願い申し上げます。。

2009/10/26 22:56:30
id:rsc96074 No.2

rsc回答回数4394ベストアンサー獲得回数4022009/10/26 23:54:12

ポイント35pt

 こちらはいかがでしょうか。関数は1つの値しか返せないので、strResultを関数の値として返しました。strGivenは、「ByRef」にして値を返しています。

 それから、strFindごと削除したい場合は、Mid(strGiven, n + Len(strFind))に変えて下さい。


Module Module1

    Sub Main()
        Dim strGiven As String = "", strFind As String = "", strResult As String = ""

        'テスト用
        Dim res As String = ""

        strGiven = "ABCDEABCDE"
        strFind = "CD"
        res = Aaa(strGiven, strFind, strResult)
        Console.WriteLine("CD : res: {0}, strResult: {1}, strGiven: {2}", res, strResult, strGiven)

        strGiven = "ABCDEABCDE"
        strFind = "CE"
        res = Aaa(strGiven, strFind, strResult)
        Console.WriteLine("CE : res: {0}, strResult: {1}, strGiven: {2}", res, strResult, strGiven)

        Console.WriteLine("Hit Enter key.")
        Console.ReadLine()

    End Sub

    Public Function Aaa(ByRef strGiven As String, ByVal strFind As String, ByRef strResult As String)
        Dim n As Integer = InStrRev(strGiven, strFind)

        If n = 0 Then
            strResult = "NotExist"
        Else
            strResult = "Exist"
            strGiven = Mid(strGiven, n)
        End If

        Aaa = strResult
    End Function
End Module

※参考URL

●アプリケーションの種類とコンソールアプリケーション - Programming/Visual Basic .NET/言語の基礎

≫アプリケーションの種類とコンソールアプリケーション

http://smdn.invisiblefulmoon.net/programming/vb.net/basics/00_co...

  • id:Mook
    コメントを書きなおしたので、間抜けなことになってしまいました。


    前回の解答は引数として渡された変数に結果を代入していますが、
    その部分が異なるということですか?


    関数の戻り値として返せるのは1つだけです。
    >4. strGivenとstrResultを返す
    というのは、どのような実装を期待しているのでしょうか。
  • id:jjkkjpjjkkjp
    つまり、受け取った変数strGivenとstrResultが、実際にこの関数を使用するForm1.vbの中で使用できるようにしたいということですが…Returnする必要はないのでしょうか?
  • id:jjkkjpjjkkjp
    すみませんが、こういうわけで、もう一度お願いできますか。
    書いてあるだけの機能を満たすシンプルなものをお願いいたします。
  • id:Mook
    シンプルというなら
     Public Function Aaa(ByRef strGiven As String, ByVal strFind As String, ByRef strResult As String) As String
        If InStr(strGiven, strFind) > 0 Then
          strResult = "Exist"
          Aaa = "Exist"
        Else
          strResult = "NoExist"
          Aaa = "NoExist"
          Exit Function
        End If
        strGiven = Right(strGiven, Len(strGiven) - Len(strFind) - strPos + 1)
     End Function
    で終わりです。
  • id:jjkkjpjjkkjp
    ありがとうございます!
  • id:jjkkjpjjkkjp
    strPosですが、
    Dim strPos As Integer
    strPos = InStr(strGiven, strFind)
    でしょうか?それとも、
    Dim strPos As Integer
    strPos = InStrRev(strGiven, strFind)
    でしょうか?
  • id:Mook
    失礼しました。
    後ろから探すときは
    strPos = InStrRev(strGiven, strFind)
    です。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません