- ベストアンサー
Accessで重複するデータの処理方法とは?
- Access2007を利用して、重複するデータの処理方法について教えてください。
- 会員の来店月データをグループ化して表示する方法や、1列で処理する方法を知りたいです。
- Accessで会員番号と来店月が複数記録されている場合に、これらをグループ化してまとめる方法を教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
Excel発想から離れる事をお勧めします。 最初の集計方法をAccessでやるのは大変です。 二番目の方は、VBAを使えばできます。 もっとも簡単なのは、Excelにエクスポートしてから処理する事です。 興味本位で最初の集計をやってみました。 1.次のSQL文で表されるクエリを、何番目を抽出するかを変えて、最大重複数だけ作成します。 なお、元のテーブル名をT_来店履歴としています。 SELECT T_来店履歴.会員番号, T_来店履歴.来店月 FROM T_来店履歴 WHERE (((DCount("来店月","T_来店履歴","会員番号='" & [会員番号] & "' and 来店月<'" & [来店月] & "'")+1)=2)); 最後から4文字目の「2」は、各グループ(会員番号が同じデータ)で、古い方から2番目の日付のレコードを抽出する事を示します。 重複数が最大10個あれば、末尾から4文字目の数字を1~10迄振ったクエリを10個作成します。 次に、クエリで、元のテーブルと、上述の例えば10個のクエリを結合して、目的の表を得ます。 3個の事例を画像で添付します。 このときのSQLは次の様になっていました。 SELECT T_来店履歴.会員番号, Q_No1.来店月, Q_No2.来店月, Q_No3.来店月 FROM ((T_来店履歴 INNER JOIN Q_No1 ON T_来店履歴.会員番号 = Q_No1.会員番号) LEFT JOIN Q_No2 ON T_来店履歴.会員番号 = Q_No2.会員番号) LEFT JOIN Q_No3 ON T_来店履歴.会員番号 = Q_No3.会員番号 GROUP BY T_来店履歴.会員番号, Q_No1.来店月, Q_No2.来店月, Q_No3.来店月; 特に最初の方法は断念される事をお勧めします。 VBAを使ってでもやりたいのだという事なら、決意を表明していただくと、2番目の集計法の回答が得られると思います。
その他の回答 (1)
- 30246kiku
- ベストアンサー率73% (370/504)
VBAは大丈夫ですか。 汎用的なものとして、参考できるものに以下があると思います。 1) DJoin 関数 - リスト文字列を取得する方法 http://www.f3.dion.ne.jp/~element/msaccess/AcTipsVbaDJoin.html 専用のものにすると、その関数へ与える引数等を省略させることができます。 ここ最近、本サイトでも同様な質問がありました。 2) アクセスの正規化? http://okwave.jp/qa/q5168984.html ただ、クエリからユーザ定義関数を呼び出す時、何か(エラーが)あったら、 MsgBox で情報を表示する・・・ことは、避けた方がよいと思います。 それは、1)内でも触れられています。 前提条件として テーブル名を「TBL」と、「会員番号」「来店月」は、数値型の長整数と仮定します。 色々と、ユーザ定義関数のパラメータを考えると良いと思います。 どのような情報を渡すか・・・ 以下は、その中の一例になります。 標準モジュールに以下を記述します。 Public Function RenMonth(iNum As Long, Optional sWhere As String) As String Dim rs As New ADODB.Recordset Dim sSql As String Dim sTmp As String On Error Resume Next sTmp = " " ' ★1 ' sTmp = "" ' ★2 sSql = "SELECT DISTINCT 来店月 FROM TBL" sSql = sSql & " WHERE 会員番号 = " & iNum If (Len(sWhere) > 0) Then sSql = sSql & " AND " & BuildCriteria("来店月", dbLong, sWhere) End If sSql = sSql & " ORDER BY 来店月;" rs.Source = sSql rs.Open , CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly If (Not rs.EOF) Then sTmp = rs.GetString(adClipString, , , ",") ' ★1 ' sTmp = rs.GetString(adClipString, , , "") ' ★2 End If rs.Close RenMonth = Left(sTmp, Len(sTmp) - 1) ' ★1 ' RenMonth = sTmp ' ★2 End Function ※ ★1部分を有効、★2部分をコメントにすると、「来店月」部分は、カンマ区切りに ※ ★1部分をコメント、★2部分を有効にすると、「来店月」部分は、ズラズラと 現状、なんかエラーがあった時には、空文字列が返るかと思います。 エラー時にどのような文字列を返すか等の処理は組み込んでください。 クエリから使用する時には、クエリをSQLビュー表示にして、以下を記述してみます。 SELECT TBL.会員番号, RenMonth([会員番号]) AS 来店月 FROM TBL GROUP BY TBL.会員番号; 多分、そうこうするうちに、来店月の範囲を指定したくなると思います。 上記クエリをデザインビューにして、 「来店月」を追加し、集計部分を「Where 条件」にした後、抽出条件を >=201001 And <=201012 とかにした場合には、ユーザ定義関数の記述部分を同様に RenMonth([会員番号],">=201001 And <=201012") に変更します。 ※ 関数内で BuildCriteria("来店月", dbLong, ">=201001 And <=201012") は、 来店月>=201001 And 来店月<=201012 に展開されます。 直に RenMonth([会員番号],"来店月>=201001 And 来店月<=201012") としたい時には、 If (Len(sWhere) > 0) Then sSql = sSql & " AND " & sWhere に変更すると同じ結果になります。 参考にする等は、自己責任にてお願いします。
お礼
VBAでの解決方法ありがとうございました。
お礼
遅くなってすみません! 画像まで丁寧にありがとうございました!