Access2003での質問です。

以下のようなテーブルがあります。
 
id , data
1 , A
1 , B
1 , C
2 , D
2 , E
3 , F
3 , G
3 , H
3 , I
 
このテーブルから以下を導きたいと思っています。
1 , A.B.C
2 , D.E
3 , F.G.H.I
 
クエリでもSQLでもVBAでも何でも可です。
以上よろしくお願いします。

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

ベストアンサー

id:Mook No.1

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

ポイント100pt

コメントで紹介したのは ACCESS を使用した例ですが、なんでもありという前提で、EXCEL での例です。

最初に参照設定をし、実際のmdbファイル名に変更して実行ください。

Option Explicit

'--------------------------------------------------------------------------
' ★★ 参照設定「Microsoft Active Data Object x.x Library : たぶん最新でOK
'--------------------------------------------------------------------------

Sub MyConcatQuery()
    Dim conn
    Set conn = CreateObject("ADODB.Connection")
    conn.Open "Provider=Microsoft.ACE.oledb.12.0;Data Source=D:\soba.mdb;" ' ★★ mdb ファイル名

'-------------------------------------
' 最初に id を取得
'-------------------------------------
    Dim strSQL As String
    strSQL = "SELECT DISTINCT id FROM soba ORDER BY id;" '★★実際のテーブル名、フィールド名に変更
    
    Dim rs
    Set rs = CreateObject("ADODB.Recordset")
    rs.Open strSQL, conn, adOpenKeyset, adLockReadOnly
    
    Dim r As Long
    Range("A1:B1") = Array("id", "data")
    r = 2
    Do Until rs.EOF
        Cells(r, "A").Value = rs.Fields(0).Value
        rs.MoveNext
        r = r + 1
    Loop
    rs.Close
    
'-------------------------------------
' 次に id ごとに data を取得
'-------------------------------------
    Dim lastRow As Long
    Dim res As String
    lastRow = r - 1
    For r = 2 To lastRow
        strSQL = "SELECT data FROM soba WHERE id = " & Cells(r, "A") & ";" '★★実際のテーブル名、フィールド名に変更
        rs.Open strSQL, conn, adOpenKeyset, adLockReadOnly
        res = ""
        Do Until rs.EOF
            res = res & "." & rs.Fields(0).Value
            rs.MoveNext
        Loop
        rs.Close
        Cells(r, "B").Value = Mid(res, 2, 1000)
    Next
End Sub

http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_130_030.html

id:SOBA

なるほど!

参考になります。ありがとうございました!

2010/02/16 15:41:08
  • id:kn1967
    (コメント)
    目的がフォームでの表示やCSV書き出しなど多目的なのか、
    レポートだけなのかなどによって、集計方法はそれぞれ違ってきますよ。

    (余談1)
    昔作ってたものがあったはずなんだけど見当たらないし、
    多分、同じような回答案を持っている人は多数おられるので、
    とりあえず、趣味的&実験的に集約関数的なものを作って、
    クエリから呼び出すものは作ってみた・・・。
    レコードセットをぶん回すほうが安全性は高いと思うので、
    ひとまず静観して、回答が無い。もしくはご要望あらば回答投稿します。

    (余談2)
    新種のハムスターが出現してるようですね。
    回答を開ける前に、回答者の他の回答も見ておいたほうが損はしないと思います。
  • id:SOBA
    >kn1967さん
    目的はレポートへの出力だけなのですが
    後学の為にお教えいただければ幸いですー

    >ハムスター
    なんか最近多いですね
    子供の間で流行ってるのかしら
  • id:kn1967
    あまり検証してないので雑談としてコメントのほうにします。

    >|vba| モジュール
    Option Compare Database

    Dim myOldID As Integer
    Dim myStrSUM As String

    Function MyConcat(id As Integer, s As String) As String
    If id <> myOldID Then
    myStrSUM = s
    myOldID = id
    Else
    myStrSUM = myStrSUM + "." + s
    End If
    MyConcat = myStrSUM
    End Function
    ||<
    >|sql|  クエリ
    SELECT t1.id, Last(t1.結合文字列)
    FROM (
    SELECT id, MyConcat(id, data) AS 結合文字列
    FROM (SELECT * FROM テーブル ORDER BY id, data) AS t2
    ) AS t1
    GROUP BY t1.id;
    ||<

    レポートで集計を行う場合は、レポートの側でidによるグループ化を行い、
    詳細部分のVBAで結合処理を行い、詳細部分の表示は非表示、
    グループフッタ部分で結合したものを出力するという形になると思いますが、
    今、ちょっと手元に無いので、他の方の回答をお待ちください。
  • id:ken3memo
    力業で恥ずかしいので私もコメントで
    昔 横方向に3つまとめるときに作った手前味噌サンプルです。
    http://www.ken3.org/cgi-bin/test/test105-2.asp
    ※横方向の項目数が決まっているなら、こんなコストのかかる(SQLの速度含めて)方法もあるってことで。。。

    kn1967 さんの方法パクって
    http://www.ken3.org/asp/backno/asp105.html
    の記事書き直そうかなぁ(ぉぃぉぃ)

    ※※横方向に展開する数が通常不定だと思うので、参考程度に...
  • id:kn1967
    JETは前世紀からある非常に優れたSQLエンジンの1つですが、
    新しい機能の追加は皆無に等しく、力技に頼るしかないですね。

    先のものはMySQLの@変数みたいなものをイメージして作ったのですが、
    こんなところに同様の仕組みの紹介が既にあったとは・・・!
    http://support.microsoft.com/default.aspx?scid=kb;ja;410756

    まったく別の話ですが、PostgreSQLのようにSQL集約関数を作れるものなら、
    文字列をSUMするなど簡単ですし標準装備の関数と同等の速度が得られます。
    同様に、SQLで配列を扱えるものなら、縦のものを1次元配列に格納して、
    その配列を1つにまとめる事も容易です。こちらの速度は、
    集約関数よりは格段に遅いのですが、その分、自由度は高いです。
    ・・・って、Accessには関係ない話でスミマセン。回答くるといいですね。
  • id:Mook
    以前あった同様の質問です。
    ご参考までに。
    http://q.hatena.ne.jp/1229340822
  • id:SOBA
    なるほどなるほどー
    お三方ともありがとうございました!
    大変勉強になりました。
     
    回答欄に何か書いていただければポイント割り振るのですが…
    よろしくお願いしまス。

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

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

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

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