[[20170326090845]] 『小学校児童名簿から兄弟関係を抽出したい。』(nonvily) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『小学校児童名簿から兄弟関係を抽出したい。』(nonvily)

 A   B     C        D          E
学年  組    名前       電話      兄弟姉妹関係
1    1  浅利 友以乃   090- 986-5423
1    1  都築 なつみ   090-7835-4999
1    2  石原 さんま   090-5459-2057
1    2  手島 あき    080- 855-4072
1    3  浅見 康文    090-2212-9844
1    3  小久保 信吾   090-3903-1731
3    1  芹沢 憲一    080-9544-3223
3    1  稲垣 誠一    090-5820- 737
3    2  浅利 友恵    090- 986-5423
3    2  勝田 沙耶    080-6871-2920
3    3  石原 ヒロ    090-5459-2057
3    3  影山 慶太    080-6720-1807
3    3  三木 一輝    090-6185-8758
5    1  川添 満     090-3839- 980
5    1  寺本 一輝    090-4324-8613
5    2  坂田 優     080-4950-7610
5    2  中西 彩華    080-3910- 58
5    3  立花 孝太郎   080-3017-2366
5    3  松川 惇     080-2349-1071
5    2  石原 憲一    090-5459-2057
6    3  手島 登     080- 855-4072
上記のような項目の名簿(架空データ)から、同じ電話番号を手がかりに、兄弟姉妹欄を抽出(例:石原 さんま の行なら 3-3ヒロ,5-2憲一)する関数を組みたいのですが、できますか。兄弟姉妹がいない児童は空欄にしたいです。よろしくお願いします。

< 使用 Excel:Excel2013、使用 OS:Windows10 >


 確認だけ。

 1)兄弟姉妹が二人以上いるとき、一人目はE列、二人目はF列・・・というように列を分けてもいいのか?

 2)作業列を使ってもいいのか?

 3)実際の名簿は最大で何行ぐらいになるのか?

 4)実際の名簿は、見出しが何行目で、データは何行目からなのか?

 とりあえず以上です。
(笑) 2017/03/26(日) 13:20

確認コメントありがとうございます。
お答えします。
1)E列に全て納めたいです。
2)作業表を作っていただいても大丈夫です。
3)全校児童600人弱です。
4)見出しは1行です。2行目に項目があって、データは3行目からです。
よろしくお願いします。
(nonvily) 2017/03/26(日) 15:02

 >1)E列に全て納めたいです。

 ちょっと意外なお答え・・・。

 では、確認ばかりで恐縮ですけど、

 1)作業列を使ってもいいということは、いったんどこかに一人一列で抽出して、
   そこから一列にまとめてもいいのか?
   つまり、作業列を何列使っても、E列に全て納まってさえいればそれでオッケーなのか?

 2)兄弟姉妹は、一番多い子で何人ぐらいをみておけばいいのか?
   六つ子が入学してくるかもしれない、みたいなことも想定する必要があるのか?

 3)VBAでもいいのか?
   それでもいいと宣言してもらうと、虎視眈々と狙っているVBAの専門家さんが
   すぐさまアップを始めると思います。

 とりあえず以上です。
(笑) 2017/03/26(日) 17:20

重ねての確認コメントありがとうございます。
お答えします。
1)難し過ぎて、あまりよくわかりませんが、E列に納まってさえすれば大丈夫です。
2)兄弟姉妹は多くて3人兄弟までです。
3)はいVBAで結構です。
よろしくお願いします。
(nonvily) 2017/03/26(日) 19:41

 これを標準モジュールに貼り付け後、データシートをアクティブにして(←重要)、「siling」を実行する。
  ↓

 Enum pos
     学年 = 1
     組 = 2
     名前 = 3
     電話 = 4
     兄弟姉妹関係 = 5
 End Enum

 Sub sibling()
     Dim dicT As Object
     Dim DTrng As Range, DTval, UnitStr, Itm, temp, RowN As Long

     Set dicT = CreateObject("Scripting.Dictionary")

     Set DTrng = Range("A3", Cells(Rows.Count, "C").End(xlUp).Offset(0, 2))
     DTval = DTrng.Value

     For RowN = 1 To UBound(DTval)
         UnitStr = "、" & DTval(RowN, 学年) & "-" & DTval(RowN, 組) & " " & DTval(RowN, 名前)
         dicT(DTval(RowN, 電話)) = dicT(DTval(RowN, 電話)) & UnitStr
     Next RowN

     For RowN = 1 To UBound(DTval)
         Itm = dicT(DTval(RowN, 電話))

         UnitStr = "、" & DTval(RowN, 学年) & "-" & DTval(RowN, 組) & " " & DTval(RowN, 名前)

         temp = Replace(Replace(Itm, UnitStr, ""), Split(DTval(RowN, 名前), " ")(0) & " ", "")

         If temp <> "" Then
             DTval(RowN, 兄弟姉妹関係) = Right(temp, Len(temp) - 1)
         End If
     Next RowN

     Range("E3:E1000").ClearContents
     DTrng.Value = DTval
 End Sub

 <結果図>
 行  __A__  _B_  _____C_____  ______D______  _________E_________
  1                                                             
  2  学年   組   名前         電話           兄弟姉妹関係       
  3     1     1  浅利 友以乃  090-986-5423   3-2 友恵           
  4     1     1  都築 なつみ  090-7835-4999                     
  5     1     2  石原 さんま  090-5459-2057  3-3 ヒロ、5-2 憲一 
  6     1     2  手島 あき    080-855-4072   6-3 登             

  : : : :

(半平太) 2017/03/26(日) 21:09


 書きなぐっただけで、見直しをしていません。
 もう少しスマートに組み立てられると思いますが、とりあえず。

 Sub Sample()
    Dim dic As Object
    Dim ans As Object
    Dim k As Variant
    Dim c As Range
    Dim tel As String
    Dim nm As String

    Set dic = CreateObject("Scripting.Dictionary")
    Set ans = CreateObject("Scripting.Dictionary")

    For Each c In Range("D2", Range("D" & Rows.Count).End(xlUp))
        tel = c.Value
        nm = c.Offset(, -1).Value
        If Not dic.exists(tel) Then Set dic(tel) = CreateObject("Scripting.Dictionary")
        dic(tel)(nm) = c.Offset(, -3).Value & "-" & c.Offset(, -2).Value & Split(c.Offset(, -1).Value)(1)
    Next

    For Each c In Range("C2", Range("C" & Rows.Count).End(xlUp))
        ans.RemoveAll
        nm = c.Value
        tel = c.Offset(, 1).Value
        For Each k In dic(tel)
            If k <> nm Then ans(ans.Count) = dic(tel)(k)
        Next
        If ans.Count > 0 Then
            c.Offset(, 2).Value = Join(ans.items, ",")
        Else
            c.Offset(, 2).ClearContents
        End If
    Next

 End Sub

( β) 2017/03/26(日) 21:48


半平太さん、ありがとうございます。
ちゃんと兄弟姉妹の学年組名前が抽出できました。
凄いですね。ありがとうございます。
ただ、名字からフルネームで出てしまうんです。
やり方間違っているんでしょうか?
すいません。
(nonvily) 2017/03/27(月) 00:16

βさん、ありがとうございます。
やってみたんですが、
「インデックスが有効範囲にありません」とデバッグが出て
なかなか上手くいかないんです。
やり方間違っているんでしょうか。
すいません。
(nonvily) 2017/03/27(月) 00:20

 >「インデックスが有効範囲にありません」

 どのコードでエラーになりましたか?

 それと、私のコードは C列の姓と名前の間が必ず半角スペースという決めつけをしていますが
 実際のデータは、そうなっていますか?

( β) 2017/03/27(月) 07:23


βさん、おはようございます。
お世話になっています。
エラー箇所は、次のコードです。

dic(tel)(nm) = c.Offset(, -3).Value & "-" & c.Offset(, -2).Value & Split(c.Offset(, -1).Value)(1)

それと、姓と名の間は全角スペースです。
よろししくお願いします。
(nonvily) 2017/03/27(月) 07:49


 >名字からフルネームで出てしまうんです。

 区切り文字を半角と思ってしまったためです。 m(__)m  2か所全角にしてください。

                                    ↓     ↓
   temp = Replace(Replace(Itm, UnitStr, ""), Split(DTval(RowN, 名前), " ")(0) & " ", "")

 ※姓を消去するのは最終段階で行っています。
 兄弟姉妹でも、姓が違うケースが現実にあるのと、
 電話番号を入力ミスして他の生徒と同じものを入れた場合、フルネームの方が発見し易いためです。

(半平太) 2017/03/27(月) 08:18


 半平太さん同様、間を半角スペースにしていたためです。

 dic(tel)(nm) = c.Offset(, -3).Value & "-" & c.Offset(, -2).Value & Split(c.Offset(, -1).Value)(1)

 これを

 dic(tel)(nm) = c.Offset(, -3).Value & "-" & c.Offset(, -2).Value & Split(c.Offset(, -1).Value, " ")(1)

 に変更してください。

(β) 2017/03/27(月) 08:36


Sub main()
    Dim c As Range, d As Range
    Range("E:E").Cells.Clear
    For Each c In Range("D:D").SpecialCells(xlCellTypeConstants)
        For Each d In Range("D:D").SpecialCells(xlCellTypeConstants)
            If c.Value = d.Value And c.Row <> d.Row Then
            c.Offset(, 1).Value = IIf(Not c.Offset(, 1).Value = Empty, c.Offset(, 1).Value & ",", "") & d.Offset(, -3).Value & Space(1) & d.Offset(, -2).Value & Space(1) & IIf(InStr(StrConv(d.Offset(, -1).Value, vbWide), " "), Split(StrConv(d.Offset(, -1).Value, vbWide), " ")(1), "")
            End If
        Next d
    Next c
End Sub
(mm) 2017/03/27(月) 13:41

 関数でやってみました 
 F列を作業用列とします

 F3=","&A3&"-"&B3&MID(C3,FIND(" ",C3)+1,5)&IFERROR(INDEX(F4:$F$600,MATCH(D3,D4:$D$600,0)),"")
 といれ 最終行までコピー
 (FIND(" ",C3)+1,5)・・・の5は 名前の文字数が5文字以上が想定される場合最大値以上に変更して下さい)

 E3=MID(SUBSTITUTE(INDEX($F$1:F3,MATCH(D3,$D$1:D3,0)),","&A3&"-"&B3&MID(C3,FIND(" ",C3)+1,5),""),2,100)
 といれ 最終行までコピー
 (最後の100は E列の想定最大文字数以上にして下さい)

(????) 2017/03/27(月) 18:57


いろいろなコードをありがとうございます。
半平太さんのコードはこちらが姓名の間を半角に直したら、前のままでできました。
βさんコードは、やっぱり同じコードでデバッグがでます。
mmさんのコードもうまくいきました。ただ学年と組に間に−があればもっと嬉しいです。
????さんのコードも上手くいきました。ありがとうございます。

実は実際の項目は
No.,学年、組、男女、氏名、ふりがな、生年月日、保護者、保護者、番号、部団名、住所、兄弟姉妹、電話
となります。
こちらで応用をきかしてと甘く考えていたのが間違いでした。列を移動して、コードを実行して兄弟姉妹を抽出してから、また列を戻すことにします。ありがとうございました。

(nonvily) 2017/03/27(月) 21:25


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.