エクセルのマクロの質問です。

名前から名字を取り出すにはどうしたらよいでしょうか?名前は全角スペース、半角スペース、スペースなしの3種類があり、スペースなしの場合はフルネームのままとします。
namae     namae2
山田 太郎→ 山田
三田村 太郎→三田村
山本花子→  山本花子

namaeはフルネーム、namae2は名字(スペースのない場合はフルネーム)

▼以下のようにしてみましたが3文字の名字「三田村」の場合、2文字「三田」となってしまいます。
Dim namae As String
Dim namae2 As String
namae2 = Left(namae, Len(namae) - InStrRev(namae, " ", -1))

どのように書けばよいか教えてください。
よろしくお願いいたします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2008/07/16 22:01:31
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:Mook No.1

回答回数1314ベストアンサー獲得回数393

ポイント50pt

標準モジュールに下記のように定義して、利用してどうでしょうか。

Function getFirstName(srcName) As String
    Dim names
    names = Split(Replace(srcName, " ", " ")) '--- 全角スペースは半角に置換して処理
    getFirstName = names(0)
End Function

サンプルとしては下記のようになります。

Sub main()
    Debug.Print getFirstName("山田 太郎")
    Debug.Print getFirstName("山田 太郎")
    Debug.Print getFirstName("山田太郎")
End Sub

この方法のメリットは、セルのA1にデータがあった場合 A2セルで

=getFirstName(A1)

というようにも使用できます。

id:SALINGER No.2

回答回数3454ベストアンサー獲得回数969

ポイント50pt

そのまま直すと

    Dim namae As String
    Dim namae2 As String
    namae2 = Left(namae, Len(namae) - InStrRev(StrConv(namae, vbNarrow), " ") + 1)

Mookさんのように関数を作るのもいいかもしれませんね。

でもカタカナの名前の人もいますのでそこは変更しないといけないかもしれません。

  • id:SALINGER
    最後のほうは勘違いして意味不明なことを書いたみたいです。聞き流しておいてください。
  • id:taknt
    何のために InStrRevを使ってるんだろうね。

    この関数の意味をよく知ってれば 間違えるはずがない。

    namae2 = Left(namae, InStrRev(namae, " ", -1))

    これでいいだろ。

    なんで すべての文字数から引く必要があるんだろう?

    ただ 全角と半角があるから
    namae2 = Left(namae, IIf(InStrRev(namae, " ", -1) = 0, InStrRev(namae, " ", -1), InStrRev(namae, " ", -1)))
    としないとダメだが。

    こんなのは この処理をやる前に 全角か半角のどちらか 置換してやれば
    解決する問題。
    一度置換すれば、次は件数が 少なくなるはずだから 置換処理も速くなる。

  • id:taknt
    そういや -1 も いらないな。
  • id:taknt
    で、空白がない場合も考慮して 簡潔にするなら
    namae2 = Left(namae, IIf(InStr(namae, " ") = 0, IIf(InStr(namae, " ") = 0, Len(namae), InStr(namae, " ") - 1), InStr(namae, " ") - 1))

    でいいはず。
  • id:SALINGER
    失礼私の回答はまったくの間違い。
    答えというよりも、何が間違っているのかを知りたいようような気がするので。補足。
    InStrRevは後方から検索し、検索文字列が最初に見つかった位置を'先頭から数えて’その位置を返す関数です。
    引数の検索開始位置を変えても、空白の前からの位置は変わらないので
    namae2 = Left(namae, InStrRev(namae, " ")-1)
    ただし、これだと空白が無い場合エラーを起こすので、
    空白のあるなしで処理を分岐しないといけなくtakntさんのでいいかな。
  • id:SALINGER
    InStrRevを使っているということは、空白が2箇所以上ある名前(あるかどうか知らないが)の最後の空白が姓と名の区切りだと解釈して
    私の回答は次にしておいてください。
    namae2 = Replace(namae, " ", " ")
    If InStr(1, namae2, " ") > 0 Then
    namae2 = Left(namae, InStrRev(namae2, " ") - 1)
    End If
  • id:Mook
    ちょっと見ない間に、コメントが盛り上がってますね。

    自己レスで、機能的には関係ないコメントですが、
    「getFirstName」はよくなかったですね。
    姓であれば「getFamiliName」か「getLastName」の方が良かったかな。
  • id:icta
    >SALINGER さん
    >Mookさん
    >takntさん

    たくさんの回答ありがとうございました。
    すでに使用しているマクロの一部分を変更したかっただけでしたので、いちばん希望に近く導入しやすかったtakntさんの回答を採用させていただきました。
    Mookさんの回答は私にはハードルが高すぎてよく理解ができませんでした。
    SALINGERさんの回答はなぜか私の環境(WinXP、Excel2003)では動作しませんでした。
    みなさんありがとうございました。
  • id:Mook
    あらら、不明な点はお聞きいただければよかったのに。

    taknt さんので解決したのであれば余計なコメントですが、関数を利用するのであれば、
    Function 部分を同じモジュールに記述し、

    namae2 = getFirstName( namae )

    とするれば、同様に利用できます。
  • id:airplant
    横槍になってしまいますが、、、
    マクロでなくてもExcelの操作で一発でできますよ。
    ツール→データ→区切り位置→「カンマやスペースで区切られた文字」→次をチェック
    「タブ」、「スペース」、「連続した文字列は一区切りとして扱う」

    マクロでも簡単に書けますが、多分マクロにする必要はないと思います。又、後で名前を取り出したくなったり、スペースが間に何個か入っていたりすると関数を変更する必要あります。
    でも、Excelの機能で行っておけば、何も変えずに対応できます。

    マクロの勉強であれば、この回答は無視ください。

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

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

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

回答リクエストを送信したユーザーはいません